@@ -316,6 +316,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
drm_property_blob_get(state->degamma_lut);
if (state->ctm)
drm_property_blob_get(state->ctm);
+ if (state->gamma_lut)
+ drm_property_blob_get(state->gamma_lut);
state->color_mgmt_changed = false;
}
@@ -366,6 +368,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
drm_property_blob_put(state->fb_damage_clips);
drm_property_blob_put(state->degamma_lut);
drm_property_blob_put(state->ctm);
+ drm_property_blob_put(state->gamma_lut);
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
@@ -615,6 +615,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
return ret;
} else if (property == plane->gamma_mode_property) {
state->gamma_mode = val;
+ } else if (property == plane->gamma_lut_property) {
+ ret = drm_atomic_replace_property_blob_from_id(dev,
+ &state->gamma_lut,
+ val, -1, sizeof(struct drm_color_lut_ext),
+ &replaced);
+ state->color_mgmt_changed |= replaced;
+ return ret;
} else if (property == config->prop_fb_damage_clips) {
ret = drm_atomic_replace_property_blob_from_id(dev,
&state->fb_damage_clips,
@@ -690,6 +697,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
*val = (state->ctm) ? state->ctm->base.id : 0;
} else if (property == plane->gamma_mode_property) {
*val = state->gamma_mode;
+ } else if (property == plane->gamma_lut_property) {
+ *val = (state->gamma_lut) ?
+ state->gamma_lut->base.id : 0;
} else if (property == config->prop_fb_damage_clips) {
*val = (state->fb_damage_clips) ?
state->fb_damage_clips->base.id : 0;
@@ -613,6 +613,11 @@ EXPORT_SYMBOL(drm_plane_create_color_properties);
* to query and get the plane gamma color caps and choose the
* appropriate gamma mode and create lut values accordingly
*
+ * gamma_lut_property:
+ * Blob property which allows a userspace to provide LUT values
+ * to apply gamma curve using the h/w plane degamma processing
+ * engine, thereby making the content as non-linear.
+ *
*/
int drm_plane_create_color_mgmt_properties(struct drm_device *dev,
struct drm_plane *plane,
@@ -648,6 +653,13 @@ int drm_plane_create_color_mgmt_properties(struct drm_device *dev,
plane->gamma_mode_property = prop;
+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB,
+ "PLANE_GAMMA_LUT", 0);
+ if (!prop)
+ return -ENOMEM;
+
+ plane->gamma_lut_property = prop;
+
return 0;
}
EXPORT_SYMBOL(drm_plane_create_color_mgmt_properties);
@@ -685,6 +697,12 @@ void drm_plane_attach_gamma_properties(struct drm_plane *plane)
drm_object_attach_property(&plane->base,
plane->gamma_mode_property, 0);
+
+ if (!plane->gamma_lut_property)
+ return;
+
+ drm_object_attach_property(&plane->base,
+ plane->gamma_lut_property, 0);
}
EXPORT_SYMBOL(drm_plane_attach_gamma_properties);
@@ -270,6 +270,14 @@ struct drm_plane_state {
*/
u32 gamma_mode;
+ /* @gamma_lut:
+ *
+ * Lookup table for converting framebuffer pixel data after applying the
+ * color conversion matrix @ctm. See drm_plane_enable_color_mgmt(). The
+ * blob (if not NULL) is an array of &struct drm_color_lut_ext.
+ */
+ struct drm_property_blob *gamma_lut;
+
u8 color_mgmt_changed : 1;
};
@@ -807,6 +815,12 @@ struct drm_plane {
* used to convert the framebuffer's colors to non-linear gamma.
*/
struct drm_property *gamma_mode_property;
+
+ /**
+ * @gamma_lut_property: Optional Plane property to set the LUT
+ * used to convert the framebuffer's colors to non-linear gamma.
+ */
+ struct drm_property *gamma_lut_property;
};
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
Add Plane Gamma Lut as a blob property. Signed-off-by: Uma Shankar <uma.shankar@intel.com> --- drivers/gpu/drm/drm_atomic_state_helper.c | 3 +++ drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++++++ drivers/gpu/drm/drm_color_mgmt.c | 18 ++++++++++++++++++ include/drm/drm_plane.h | 14 ++++++++++++++ 4 files changed, 45 insertions(+)