]> www.infradead.org Git - users/willy/linux.git/commitdiff
drm: automatic legacy gamma support
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 11 Dec 2020 11:42:36 +0000 (13:42 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Tue, 15 Dec 2020 13:46:03 +0000 (15:46 +0200)
To support legacy gamma ioctls the drivers need to set
drm_crtc_funcs.gamma_set either to a custom implementation or to
drm_atomic_helper_legacy_gamma_set. Most of the atomic drivers do the
latter.

We can simplify this by making the core handle it automatically.

Move the drm_atomic_helper_legacy_gamma_set() functionality into
drm_color_mgmt.c to make drm_mode_gamma_set_ioctl() use
drm_crtc_funcs.gamma_set if set or GAMMA_LUT property if not.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Philippe Cornu <philippe.cornu@st.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201211114237.213288-2-tomi.valkeinen@ti.com
19 files changed:
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
drivers/gpu/drm/arm/malidp_crtc.c
drivers/gpu/drm/armada/armada_crtc.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_color_mgmt.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/ingenic/ingenic-drm-drv.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/nouveau/dispnv50/head.c
drivers/gpu/drm/omapdrm/omap_crtc.c
drivers/gpu/drm/rcar-du/rcar_du_crtc.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/stm/ltdc.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/gpu/drm/vc4/vc4_txp.c
include/drm/drm_atomic_helper.h

index c23896207e9de72a04d2e5b8f1f692d87e6c3c7f..5675c1f9368ad9394ede6188a5f4f5a0ea690acd 100644 (file)
@@ -5452,7 +5452,6 @@ static void dm_disable_vblank(struct drm_crtc *crtc)
 static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
        .reset = dm_crtc_reset_state,
        .destroy = amdgpu_dm_crtc_destroy,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = dm_crtc_duplicate_state,
index 4b485eb512e2e3686b2025aac69b0beb5f0a36eb..59172acb973803d29c853ea4f2ad9a5538770ae3 100644 (file)
@@ -550,7 +550,6 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
-       .gamma_set              = drm_atomic_helper_legacy_gamma_set,
        .destroy                = drm_crtc_cleanup,
        .set_config             = drm_atomic_helper_set_config,
        .page_flip              = drm_atomic_helper_page_flip,
index 108e7a31bd26bed69a4349b3a8c534befb7ce38d..494075ddbef68374aaca8927a1141379925adb38 100644 (file)
@@ -510,7 +510,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_funcs malidp_crtc_funcs = {
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .destroy = drm_crtc_cleanup,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
index 3ebcf5a52c8bc42421e99a90638dc0a1cdc25a3b..b7bb90ae787f7cb209aedff1caf3fa383f340f50 100644 (file)
@@ -820,7 +820,6 @@ static const struct drm_crtc_funcs armada_crtc_funcs = {
        .cursor_set     = armada_drm_crtc_cursor_set,
        .cursor_move    = armada_drm_crtc_cursor_move,
        .destroy        = armada_drm_crtc_destroy,
-       .gamma_set      = drm_atomic_helper_legacy_gamma_set,
        .set_config     = drm_atomic_helper_set_config,
        .page_flip      = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
index 9db371f4054f3c3996e569602d2f37d06863a5a6..5b0ec785c516b23be4545a0043a967452f15cefa 100644 (file)
@@ -903,7 +903,6 @@ static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 
 static const struct drm_crtc_funcs ast_crtc_funcs = {
        .reset = ast_crtc_reset,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .destroy = drm_crtc_cleanup,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
index c58fa00b4848c45b9d8acb0d33d31f46b902dada..05ad75d155e8407f18a3b6af72a835a958cb8d32 100644 (file)
@@ -473,7 +473,6 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
        .atomic_destroy_state = atmel_hlcdc_crtc_destroy_state,
        .enable_vblank = atmel_hlcdc_crtc_enable_vblank,
        .disable_vblank = atmel_hlcdc_crtc_disable_vblank,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
 };
 
 int atmel_hlcdc_crtc_create(struct drm_device *dev)
index 7fcf91ecb1d95c0773bded18938a112a812e22cf..a84dc427cf82301ab783a787e7b0caede18935ea 100644 (file)
@@ -3508,76 +3508,6 @@ fail:
 }
 EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
 
-/**
- * drm_atomic_helper_legacy_gamma_set - set the legacy gamma correction table
- * @crtc: CRTC object
- * @red: red correction table
- * @green: green correction table
- * @blue: green correction table
- * @size: size of the tables
- * @ctx: lock acquire context
- *
- * Implements support for legacy gamma correction table for drivers
- * that support color management through the DEGAMMA_LUT/GAMMA_LUT
- * properties. See drm_crtc_enable_color_mgmt() and the containing chapter for
- * how the atomic color management and gamma tables work.
- */
-int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
-                                      u16 *red, u16 *green, u16 *blue,
-                                      uint32_t size,
-                                      struct drm_modeset_acquire_ctx *ctx)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_atomic_state *state;
-       struct drm_crtc_state *crtc_state;
-       struct drm_property_blob *blob = NULL;
-       struct drm_color_lut *blob_data;
-       int i, ret = 0;
-       bool replaced;
-
-       state = drm_atomic_state_alloc(crtc->dev);
-       if (!state)
-               return -ENOMEM;
-
-       blob = drm_property_create_blob(dev,
-                                       sizeof(struct drm_color_lut) * size,
-                                       NULL);
-       if (IS_ERR(blob)) {
-               ret = PTR_ERR(blob);
-               blob = NULL;
-               goto fail;
-       }
-
-       /* Prepare GAMMA_LUT with the legacy values. */
-       blob_data = blob->data;
-       for (i = 0; i < size; i++) {
-               blob_data[i].red = red[i];
-               blob_data[i].green = green[i];
-               blob_data[i].blue = blue[i];
-       }
-
-       state->acquire_ctx = ctx;
-       crtc_state = drm_atomic_get_crtc_state(state, crtc);
-       if (IS_ERR(crtc_state)) {
-               ret = PTR_ERR(crtc_state);
-               goto fail;
-       }
-
-       /* 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->gamma_lut, blob);
-       crtc_state->color_mgmt_changed |= replaced;
-
-       ret = drm_atomic_commit(state);
-
-fail:
-       drm_atomic_state_put(state);
-       drm_property_blob_put(blob);
-       return ret;
-}
-EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
-
 /**
  * drm_atomic_helper_bridge_propagate_bus_fmt() - Propagate output format to
  *                                               the input end of a bridge
index 3bcabc2f6e0e47bfb7606e7298f9c7f5d288d69b..553f423a8498e91a2f4bdef2f90284028d0398f1 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/uaccess.h>
 
+#include <drm/drm_atomic.h>
 #include <drm/drm_color_mgmt.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
@@ -89,9 +90,8 @@
  *     modes) appropriately.
  *
  * There is also support for a legacy gamma table, which is set up by calling
- * drm_mode_crtc_set_gamma_size(). Drivers which support both should use
- * drm_atomic_helper_legacy_gamma_set() to alias the legacy gamma ramp with the
- * "GAMMA_LUT" property above.
+ * drm_mode_crtc_set_gamma_size(). The DRM core will then alias the legacy gamma
+ * ramp with "GAMMA_LUT".
  *
  * Support for different non RGB color encodings is controlled through
  * &drm_plane specific COLOR_ENCODING and COLOR_RANGE properties. They
@@ -156,9 +156,6 @@ EXPORT_SYMBOL(drm_color_ctm_s31_32_to_qm_n);
  * optional. The gamma and degamma properties are only attached if
  * their size is not 0 and ctm_property is only attached if has_ctm is
  * true.
- *
- * Drivers should use drm_atomic_helper_legacy_gamma_set() to implement the
- * legacy &drm_crtc_funcs.gamma_set callback.
  */
 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
                                uint degamma_lut_size,
@@ -231,6 +228,102 @@ int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
 
+/**
+ * drm_crtc_supports_legacy_gamma - does the crtc support legacy gamma correction table
+ * @crtc: CRTC object
+ *
+ * Returns true/false if the given crtc supports setting the legacy gamma
+ * correction table.
+ */
+static bool drm_crtc_supports_legacy_gamma(struct drm_crtc *crtc)
+{
+       u32 gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id;
+
+       if (!crtc->gamma_size)
+               return false;
+
+       if (crtc->funcs->gamma_set)
+               return true;
+
+       return !!drm_mode_obj_find_prop_id(&crtc->base, gamma_id);
+}
+
+/**
+ * drm_crtc_legacy_gamma_set - set the legacy gamma correction table
+ * @crtc: CRTC object
+ * @red: red correction table
+ * @green: green correction table
+ * @blue: green correction table
+ * @size: size of the tables
+ * @ctx: lock acquire context
+ *
+ * Implements support for legacy gamma correction table for drivers
+ * that have set drm_crtc_funcs.gamma_set or that support color management
+ * through the DEGAMMA_LUT/GAMMA_LUT properties. See
+ * drm_crtc_enable_color_mgmt() and the containing chapter for
+ * how the atomic color management and gamma tables work.
+ *
+ * This function sets the gamma using drm_crtc_funcs.gamma_set if set, or
+ * alternatively using crtc color management properties.
+ */
+static int drm_crtc_legacy_gamma_set(struct drm_crtc *crtc,
+                                    u16 *red, u16 *green, u16 *blue,
+                                    u32 size,
+                                    struct drm_modeset_acquire_ctx *ctx)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_atomic_state *state;
+       struct drm_crtc_state *crtc_state;
+       struct drm_property_blob *blob;
+       struct drm_color_lut *blob_data;
+       int i, ret = 0;
+       bool replaced;
+
+       if (crtc->funcs->gamma_set)
+               return crtc->funcs->gamma_set(crtc, red, green, blue, size, ctx);
+
+       state = drm_atomic_state_alloc(crtc->dev);
+       if (!state)
+               return -ENOMEM;
+
+       blob = drm_property_create_blob(dev,
+                                       sizeof(struct drm_color_lut) * size,
+                                       NULL);
+       if (IS_ERR(blob)) {
+               ret = PTR_ERR(blob);
+               blob = NULL;
+               goto fail;
+       }
+
+       /* Prepare GAMMA_LUT with the legacy values. */
+       blob_data = blob->data;
+       for (i = 0; i < size; i++) {
+               blob_data[i].red = red[i];
+               blob_data[i].green = green[i];
+               blob_data[i].blue = blue[i];
+       }
+
+       state->acquire_ctx = ctx;
+       crtc_state = drm_atomic_get_crtc_state(state, crtc);
+       if (IS_ERR(crtc_state)) {
+               ret = PTR_ERR(crtc_state);
+               goto fail;
+       }
+
+       /* Set GAMMA_LUT and reset DEGAMMA_LUT and CTM */
+       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->gamma_lut, blob);
+       crtc_state->color_mgmt_changed |= replaced;
+
+       ret = drm_atomic_commit(state);
+
+fail:
+       drm_atomic_state_put(state);
+       drm_property_blob_put(blob);
+       return ret;
+}
+
 /**
  * drm_mode_gamma_set_ioctl - set the gamma table
  * @dev: DRM device
@@ -262,7 +355,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
        if (!crtc)
                return -ENOENT;
 
-       if (crtc->funcs->gamma_set == NULL)
+       if (!drm_crtc_supports_legacy_gamma(crtc))
                return -ENOSYS;
 
        /* memcpy into gamma store */
@@ -290,8 +383,8 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
                goto out;
        }
 
-       ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base,
-                                    crtc->gamma_size, &ctx);
+       ret = drm_crtc_legacy_gamma_set(crtc, r_base, g_base, b_base,
+                                       crtc->gamma_size, &ctx);
 
 out:
        DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
index 53a00cf3fa325ef280f649bed2bbd98b3aae20bc..3d53ec508a662cd9f51c53c7b393c0e4bf934889 100644 (file)
@@ -17267,7 +17267,6 @@ fail:
 }
 
 #define INTEL_CRTC_FUNCS \
-       .gamma_set = drm_atomic_helper_legacy_gamma_set, \
        .set_config = drm_atomic_helper_set_config, \
        .destroy = intel_crtc_destroy, \
        .page_flip = drm_atomic_helper_page_flip, \
index 42d335d3a114721ce269f15321ce1cac88e5cf65..7bb31fbee29dac4818d39ed86f6714fdbf1158bb 100644 (file)
@@ -774,8 +774,6 @@ static const struct drm_crtc_funcs ingenic_drm_crtc_funcs = {
 
        .enable_vblank          = ingenic_drm_enable_vblank,
        .disable_vblank         = ingenic_drm_disable_vblank,
-
-       .gamma_set              = drm_atomic_helper_legacy_gamma_set,
 };
 
 static const struct drm_plane_helper_funcs ingenic_drm_plane_helper_funcs = {
index bfe9942305435ee5e9f6b2580feaa56778dc3a23..b665bd498a4a815af6311222d7eb17d1cd63f129 100644 (file)
@@ -619,7 +619,6 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
        .reset                  = mtk_drm_crtc_reset,
        .atomic_duplicate_state = mtk_drm_crtc_duplicate_state,
        .atomic_destroy_state   = mtk_drm_crtc_destroy_state,
-       .gamma_set              = drm_atomic_helper_legacy_gamma_set,
        .enable_vblank          = mtk_drm_crtc_enable_vblank,
        .disable_vblank         = mtk_drm_crtc_disable_vblank,
 };
index 537c1ef2e4646e88518c6f3ed73e905c566c274b..ec361d17e900bec9df47f826e034f17561344cf3 100644 (file)
@@ -503,7 +503,6 @@ nv50_head_destroy(struct drm_crtc *crtc)
 static const struct drm_crtc_funcs
 nv50_head_func = {
        .reset = nv50_head_reset,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .destroy = nv50_head_destroy,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
@@ -518,7 +517,6 @@ nv50_head_func = {
 static const struct drm_crtc_funcs
 nvd9_head_func = {
        .reset = nv50_head_reset,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .destroy = nv50_head_destroy,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
index 7d66269ad998a13df787c64b3109bdcbd9664e28..b97f21cf4a9153f8a49f774af16db937ac86c42f 100644 (file)
@@ -741,7 +741,6 @@ static const struct drm_crtc_funcs omap_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .destroy = omap_crtc_destroy,
        .page_flip = drm_atomic_helper_page_flip,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .atomic_duplicate_state = omap_crtc_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
        .atomic_set_property = omap_crtc_atomic_set_property,
index b5fb941e0f534c590da278445620983599f3e523..f93e0750431df4c9fcc4db4c4e18b65737e45ffa 100644 (file)
@@ -1144,7 +1144,6 @@ static const struct drm_crtc_funcs crtc_funcs_gen3 = {
        .set_crc_source = rcar_du_crtc_set_crc_source,
        .verify_crc_source = rcar_du_crtc_verify_crc_source,
        .get_crc_sources = rcar_du_crtc_get_crc_sources,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
 };
 
 /* -----------------------------------------------------------------------------
index d1e05482641b5f9ca04a90d8507cb5d8b5f9dc12..8d15cabdcb02a8f1f8dc55a682dec0268b895ba5 100644 (file)
@@ -1643,7 +1643,6 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
        .disable_vblank = vop_crtc_disable_vblank,
        .set_crc_source = vop_crtc_set_crc_source,
        .verify_crc_source = vop_crtc_verify_crc_source,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
 };
 
 static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
index 3980677435cbf0a2df5c2af37959ace06a615caa..7812094f93d6b80f198fb59403b90383bc0ab49d 100644 (file)
@@ -713,7 +713,6 @@ static const struct drm_crtc_funcs ltdc_crtc_funcs = {
        .enable_vblank = ltdc_crtc_enable_vblank,
        .disable_vblank = ltdc_crtc_disable_vblank,
        .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
 };
 
 /*
index ee4f657a5ce09b14d00a4c292aaa96f731048545..a8199a2573286a384e645aaf5dade41fbb11edd9 100644 (file)
@@ -871,7 +871,6 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = {
        .reset = vc4_crtc_reset,
        .atomic_duplicate_state = vc4_crtc_duplicate_state,
        .atomic_destroy_state = vc4_crtc_destroy_state,
-       .gamma_set = drm_atomic_helper_legacy_gamma_set,
        .enable_vblank = vc4_enable_vblank,
        .disable_vblank = vc4_disable_vblank,
        .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
index 8aa5220885f4a72bbcb669514a0c36a27b9c29d2..e4b782e42f69b8bdd1b26507c128412a6f7eb6d8 100644 (file)
@@ -382,7 +382,6 @@ static const struct drm_crtc_funcs vc4_txp_crtc_funcs = {
        .reset                  = vc4_crtc_reset,
        .atomic_duplicate_state = vc4_crtc_duplicate_state,
        .atomic_destroy_state   = vc4_crtc_destroy_state,
-       .gamma_set              = drm_atomic_helper_legacy_gamma_set,
        .enable_vblank          = vc4_txp_enable_vblank,
        .disable_vblank         = vc4_txp_disable_vblank,
 };
index 5f47720440fa67af4945bcfcdf739fcb02aab31f..4045e2507e11c438340f2ec61662fc5571c53a21 100644 (file)
@@ -147,10 +147,6 @@ int drm_atomic_helper_page_flip_target(
                                uint32_t flags,
                                uint32_t target,
                                struct drm_modeset_acquire_ctx *ctx);
-int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
-                                      u16 *red, u16 *green, u16 *blue,
-                                      uint32_t size,
-                                      struct drm_modeset_acquire_ctx *ctx);
 
 /**
  * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC