drm: extend color correction to support 3D-CLU
Extend the existing color management properties to support provision
of a 3D cubic look up table, allowing for color specific adjustments.
Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 85d163f..cbcf712 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3525,6 +3525,7 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
/* Reset DEGAMMA_LUT and CTM properties. */
replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
+ replaced |= drm_property_replace_blob(&crtc_state->clu, NULL);
replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
crtc_state->color_mgmt_changed |= replaced;
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 8fce6a1..ff4821d 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -137,6 +137,8 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
drm_property_blob_get(state->ctm);
if (state->gamma_lut)
drm_property_blob_get(state->gamma_lut);
+ if (state->clu)
+ drm_property_blob_get(state->clu);
state->mode_changed = false;
state->active_changed = false;
state->planes_changed = false;
@@ -209,6 +211,7 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
drm_property_blob_put(state->degamma_lut);
drm_property_blob_put(state->ctm);
drm_property_blob_put(state->gamma_lut);
+ drm_property_blob_put(state->clu);
}
EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index a1e5e26..01cba3f 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -459,6 +459,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
&replaced);
state->color_mgmt_changed |= replaced;
return ret;
+ } else if (property == config->clu_property) {
+ ret = drm_atomic_replace_property_blob_from_id(dev,
+ &state->clu,
+ val,
+ -1, sizeof(struct drm_color_lut),
+ &replaced);
+ state->color_mgmt_changed |= replaced;
+ return ret;
} else if (property == config->prop_out_fence_ptr) {
s32 __user *fence_ptr = u64_to_user_ptr(val);
@@ -501,6 +509,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->ctm) ? state->ctm->base.id : 0;
else if (property == config->gamma_lut_property)
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
+ else if (property == config->clu_property)
+ *val = (state->clu) ? state->clu->base.id : 0;
else if (property == config->prop_out_fence_ptr)
*val = 0;
else if (crtc->funcs->atomic_get_property)
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 5761f83..091a56c 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -365,6 +365,20 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
dev->mode_config.gamma_lut_size_property = prop;
prop = drm_property_create(dev,
+ DRM_MODE_PROP_BLOB,
+ "CLU", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.clu_property = prop;
+
+ prop = drm_property_create_range(dev,
+ DRM_MODE_PROP_IMMUTABLE,
+ "CLU_SIZE", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.clu_size_property = prop;
+
+ prop = drm_property_create(dev,
DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
"IN_FORMATS", 0);
if (!prop)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 59b51a0..55ca064 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -289,6 +289,15 @@ struct drm_crtc_state {
struct drm_property_blob *gamma_lut;
/**
+ * @clu:
+ *
+ * Cubic Lookup table for converting pixel data. See
+ * drm_crtc_enable_color_mgmt(). The blob (if not NULL) is a 3d array
+ * of &struct drm_color_lut.
+ */
+ struct drm_property_blob *clu;
+
+ /**
* @target_vblank:
*
* Target vertical blank period when a page flip
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 6c3ef49..9b28522 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -789,6 +789,17 @@ struct drm_mode_config {
struct drm_property *gamma_lut_size_property;
/**
+ * @clu_property: Optional CRTC property to set the 3D CLU used to
+ * convert color spaces.
+ */
+ struct drm_property *clu_property;
+ /**
+ * @clu_size_property: Optional CRTC property for the size of the
+ * 3D CLU as supported by the driver (read-only).
+ */
+ struct drm_property *clu_size_property;
+
+ /**
* @suggested_x_property: Optional connector property with a hint for
* the position of the output on the host's screen.
*/