diff mbox series

[v3,2/2] drm: add legacy support for using degamma for gamma

Message ID 20201210140852.1040054-3-tomi.valkeinen@ti.com (mailing list archive)
State New, archived
Headers show
Series drm: automatic legacy gamma support | expand

Commit Message

Tomi Valkeinen Dec. 10, 2020, 2:08 p.m. UTC
The DRM core handles legacy gamma-set ioctl by setting GAMMA_LUT and
clearing CTM and DEGAMMA_LUT.

This works fine on HW where we have either:

degamma -> ctm -> gamma -> out

or

ctm -> gamma -> out

However, if the HW has gamma table before ctm, the atomic property
should be DEGAMMA_LUT, and thus we have:

degamma -> ctm -> out

This is fine for userspace which sets gamma table using the properties,
as the userspace can check for the existence of gamma & degamma, but the
legacy gamma-set ioctl does not work.

Change the DRM core to use DEGAMMA_LUT instead of GAMMA_LUT when the
latter is unavailable.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/drm_color_mgmt.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index c4e4d59c4432..8733d9d95b82 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -238,6 +238,7 @@  EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
 bool drm_crtc_supports_legacy_gamma(struct drm_crtc *crtc)
 {
 	uint32_t gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id;
+	uint32_t degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id;
 
 	if (!crtc->gamma_size)
 		return false;
@@ -245,7 +246,8 @@  bool drm_crtc_supports_legacy_gamma(struct drm_crtc *crtc)
 	if (crtc->funcs->gamma_set)
 		return true;
 
-	return !!drm_mode_obj_find_prop_id(&crtc->base, gamma_id);
+	return !!(drm_mode_obj_find_prop_id(&crtc->base, gamma_id) ||
+		  drm_mode_obj_find_prop_id(&crtc->base, degamma_id));
 }
 EXPORT_SYMBOL(drm_crtc_supports_legacy_gamma);
 
@@ -256,18 +258,28 @@  EXPORT_SYMBOL(drm_crtc_supports_legacy_gamma);
  * @blob: property blob for the gamma ramp
  *
  * Set given gamma ramp to the crtc using GAMMA_LUT property and resetting
- * DEGAMMA_LUT and CTM.
+ * DEGAMMA_LUT and CTM, or if GAMMA_LUT is not available, using DEGAMMA_LUT
+ * and resetting GAMMA_LUT and CTM.
  */
 int drm_crtc_gamma_ramp_set(struct drm_atomic_state *state, struct drm_crtc *crtc,
 		       struct drm_property_blob *blob)
 {
+	uint32_t gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id;
+	uint32_t degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id;
 	struct drm_crtc_state *crtc_state;
 	struct drm_property_blob *gamma_blob;
 	struct drm_property_blob *degamma_blob;
 	bool replaced;
 
-	gamma_blob = blob;
-	degamma_blob = NULL;
+	if (drm_mode_obj_find_prop_id(&crtc->base, gamma_id)) {
+		gamma_blob = blob;
+		degamma_blob = NULL;
+	} else if (drm_mode_obj_find_prop_id(&crtc->base, degamma_id)) {
+		gamma_blob = NULL;
+		degamma_blob = blob;
+	} else {
+		return -ENODEV;
+	}
 
 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
 	if (IS_ERR(crtc_state))