From patchwork Wed Sep 14 12:47:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [01/10] INTEL_DII: drm/color: Add pipe degamma mode property From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503081 Message-Id: <20220914124803.2359004-2-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:54 +0530 Add degamma mode property for CRTC. This is an enum property with values as blob_id's. The blob that the blob id refers to is used to pass information regarding the mode supported and the range of degamma mode supported with number of lut coefficients to the user space. The userspace can select any of the supported degamma mode using this enum property. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/drm_atomic_uapi.c | 5 ++++ drivers/gpu/drm/drm_color_mgmt.c | 43 ++++++++++++++++++++++++++----- include/drm/drm_color_mgmt.h | 11 +++++--- include/drm/drm_crtc.h | 19 +++++++++++++- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index ba881f783ebded..e657eb860f0ace 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -477,6 +477,9 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, } else if (property == crtc->gamma_mode_property) { state->gamma_mode = val; state->color_mgmt_changed |= true; + } else if (property == crtc->degamma_mode_property) { + state->degamma_mode = val; + state->color_mgmt_changed |= true; } else if (property == config->prop_out_fence_ptr) { s32 __user *fence_ptr = u64_to_user_ptr(val); @@ -518,6 +521,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = state->vrr_enabled; else if (property == crtc->gamma_mode_property) *val = state->gamma_mode; + else if (property == crtc->degamma_mode_property) + *val = state->degamma_mode; else if (property == config->degamma_lut_property) *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; else if (property == config->ctm_property) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index fb62b0625b610c..309a5067fb21fe 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -218,17 +218,48 @@ int drm_color_create_gamma_mode_property(struct drm_crtc *crtc, } EXPORT_SYMBOL(drm_color_create_gamma_mode_property); -int drm_color_add_gamma_mode_range(struct drm_crtc *crtc, - const char *name, - const struct drm_color_lut_range *ranges, - size_t length) +void drm_crtc_attach_degamma_mode_property(struct drm_crtc *crtc) +{ + if (!crtc->degamma_mode_property) + return; + + drm_object_attach_property(&crtc->base, + crtc->degamma_mode_property, 0); +} +EXPORT_SYMBOL(drm_crtc_attach_degamma_mode_property); + +int drm_color_create_degamma_mode_property(struct drm_crtc *crtc, + int num_values) +{ + struct drm_property *prop; + + prop = drm_property_create(crtc->dev, + DRM_MODE_PROP_ENUM, + "DEGAMMA_MODE", num_values); + if (!prop) + return -ENOMEM; + + crtc->degamma_mode_property = prop; + + return 0; +} +EXPORT_SYMBOL(drm_color_create_degamma_mode_property); + +int drm_color_add_gamma_degamma_mode_range(struct drm_crtc *crtc, + const char *name, + const struct drm_color_lut_range *ranges, + size_t length, enum lut_type type) { struct drm_property_blob *blob; struct drm_property *prop; int num_ranges = length / sizeof(ranges[0]); int i, ret, num_types_0; - prop = crtc->gamma_mode_property; + if (type == LUT_TYPE_DEGAMMA) + prop = crtc->degamma_mode_property; + else + prop = crtc->gamma_mode_property; + if (!prop) return -EINVAL; @@ -264,7 +295,7 @@ int drm_color_add_gamma_mode_range(struct drm_crtc *crtc, return 0; } -EXPORT_SYMBOL(drm_color_add_gamma_mode_range); +EXPORT_SYMBOL(drm_color_add_gamma_degamma_mode_range); /** * drm_mode_crtc_set_gamma_size - set the gamma table size diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index db68f42f6d121a..8599e063974037 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -77,10 +77,13 @@ static inline int drm_color_lut_size(const struct drm_property_blob *blob) int drm_color_create_gamma_mode_property(struct drm_crtc *crtc, int num_values); void drm_crtc_attach_gamma_mode_property(struct drm_crtc *crtc); -int drm_color_add_gamma_mode_range(struct drm_crtc *crtc, - const char *name, - const struct drm_color_lut_range *ranges, - size_t length); +int drm_color_create_degamma_mode_property(struct drm_crtc *crtc, + int num_values); +void drm_crtc_attach_degamma_mode_property(struct drm_crtc *crtc); +int drm_color_add_gamma_degamma_mode_range(struct drm_crtc *crtc, + const char *name, + const struct drm_color_lut_range *ranges, + size_t length, enum lut_type type); enum drm_color_encoding { DRM_COLOR_YCBCR_BT601, diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 27dcc92667992a..e20c4d396071d7 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -277,6 +277,16 @@ struct drm_crtc_state { /** Gamma mode type programmed on the pipe */ u32 gamma_mode_type; + /** + * @degamma_mode: This is a blob_id and exposes the platform capabilities + * wrt to various degamma modes and the respective lut ranges. This also + * helps user select a degamma mode amongst the supported ones. + */ + u32 degamma_mode; + + /** @degamma_mode_type: degamma mode type programmed on the pipe */ + u32 degamma_mode_type; + /** * @degamma_lut: * @@ -1140,11 +1150,18 @@ struct drm_crtc { /** * @gamma_mode_property: Optional CRTC property to enumerate and - * select the mode of the crtc gamma/degmama LUTs. This also exposes + * select the mode of the crtc gamma LUTs. This also exposes * the lut ranges of the various supported gamma modes to userspace. */ struct drm_property *gamma_mode_property; + /** + * @degamma_mode_property: Optional CRTC property to enumerate and + * select the mode of the crtc degmama LUTs. This also exposes + * the lut ranges of the various supported gamma modes to userspace. + */ + struct drm_property *degamma_mode_property; + /** * @state: * From patchwork Wed Sep 14 12:47:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [02/10] INTEL_DII: drm/i915/color: Use new helper function From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503090 Message-Id: <20220914124803.2359004-3-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:55 +0530 drm_color_add_gamma_mode_range function has been refactored to drm_color_add_gamma_degamma_mode_range to support both gamma and degamma ranges. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 7ecf32a0375050..4dd5c5c8fd5727 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -3215,12 +3215,14 @@ void intel_color_init(struct intel_crtc *crtc) if (DISPLAY_VER(dev_priv) >= 13) { dev_priv->color_funcs = &xelpd_color_funcs; drm_color_create_gamma_mode_property(&crtc->base, 2); - drm_color_add_gamma_mode_range(&crtc->base, - "no gamma", NULL, 0); - drm_color_add_gamma_mode_range(&crtc->base, - "logarithmic gamma", - xelpd_logarithmic_gamma, - sizeof(xelpd_logarithmic_gamma)); + drm_color_add_gamma_degamma_mode_range(&crtc->base, + "no gamma", NULL, 0, + LUT_TYPE_GAMMA); + drm_color_add_gamma_degamma_mode_range(&crtc->base, + "logarithmic gamma", + xelpd_logarithmic_gamma, + sizeof(xelpd_logarithmic_gamma), + LUT_TYPE_GAMMA); drm_crtc_attach_gamma_mode_property(&crtc->base); } else if (DISPLAY_VER(dev_priv) >= 11) { dev_priv->color_funcs = &icl_color_funcs; From patchwork Wed Sep 14 12:47:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [03/10] INTEL_DII: drm/i915/mtl: Add degamma lut range for 24 bit degamma LUT From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503083 Message-Id: <20220914124803.2359004-4-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:56 +0530 Add a lut range to support high precision degamma LUT. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 4dd5c5c8fd5727..6921827b548762 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -120,6 +120,8 @@ struct intel_color_funcs { #define GAMMA_MODE_SPLIT_12BIT BIT(4) #define GAMMA_MODE_LOGARITHMIC_12BIT BIT(5) /* XELPD+ */ +#define DEGAMMA_MODE_24BIT BIT(0) /* MTL/D14+ */ + #define INTEL_GAMMA_MODE_MASK (\ GAMMA_MODE_LEGACY_PALETTE_8BIT | \ GAMMA_MODE_PRECISION_PALETTE_10BIT | \ @@ -3136,6 +3138,21 @@ static const struct drm_color_lut_range xelpd_gamma_hdr[] = { }, }; +static const struct drm_color_lut_range mtl_24bit_degamma[] = { + /* segment 0 */ + { + .flags = (DRM_MODE_LUT_DEGAMMA | + DRM_MODE_LUT_REFLECT_NEGATIVE | + DRM_MODE_LUT_INTERPOLATE | + DRM_MODE_LUT_REUSE_LAST | + DRM_MODE_LUT_NON_DECREASING), + .count = 131, + .input_bpc = 24, .output_bpc = 24, + .start = 0, .end = (1 << 24) - 1, + .min = 0, .max = (1 << 24) - 1, + } +}; + int intel_color_plane_init(struct drm_plane *plane) { struct drm_i915_private *dev_priv = to_i915(plane->dev); @@ -3224,6 +3241,19 @@ void intel_color_init(struct intel_crtc *crtc) sizeof(xelpd_logarithmic_gamma), LUT_TYPE_GAMMA); drm_crtc_attach_gamma_mode_property(&crtc->base); + + if (DISPLAY_VER(dev_priv) >= 14) { + drm_color_create_degamma_mode_property(&crtc->base, 2); + drm_color_add_gamma_degamma_mode_range(&crtc->base, + "no degamma", NULL, 0, + LUT_TYPE_DEGAMMA); + drm_color_add_gamma_degamma_mode_range(&crtc->base, + "extended degamma", + mtl_24bit_degamma, + sizeof(mtl_24bit_degamma), + LUT_TYPE_DEGAMMA); + } + } else if (DISPLAY_VER(dev_priv) >= 11) { dev_priv->color_funcs = &icl_color_funcs; } else if (DISPLAY_VER(dev_priv) == 10) { From patchwork Wed Sep 14 12:47:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [04/10] INTEL_DII: drm/i915/mtl: Attach degamma mode property From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503082 Message-Id: <20220914124803.2359004-5-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:57 +0530 Attach degamma mode property to allow userspace to set the degamma mode and provide lut for the same. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 6921827b548762..bb45e6809bbf7d 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -3252,6 +3252,7 @@ void intel_color_init(struct intel_crtc *crtc) mtl_24bit_degamma, sizeof(mtl_24bit_degamma), LUT_TYPE_DEGAMMA); + drm_crtc_attach_degamma_mode_property(&crtc->base); } } else if (DISPLAY_VER(dev_priv) >= 11) { From patchwork Wed Sep 14 12:47:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [05/10] INTEL_DII: drm: Add Client Cap for advance degamma mode From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503088 Message-Id: <20220914124803.2359004-6-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:58 +0530 A client cap advance degamma mode is introduced. Minimum requirement for a client to set this capability is if it can use 64 bit LUT values as defined by the structure drm_color_lut_ext on a supported platform. If not set driver will work in legacy mode. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/drm_atomic_uapi.c | 8 +++++++- drivers/gpu/drm/drm_ioctl.c | 5 +++++ include/drm/drm_atomic.h | 1 + include/drm/drm_crtc.h | 8 ++++++++ include/drm/drm_file.h | 8 ++++++++ include/uapi/drm/drm.h | 10 ++++++++++ 6 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index e657eb860f0ace..daa39daa319d8d 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -451,10 +451,13 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, } else if (property == config->prop_vrr_enabled) { state->vrr_enabled = val; } else if (property == config->degamma_lut_property) { + ssize_t size = state->advance_degamma_mode_active ? + sizeof(struct drm_color_lut_ext) : + sizeof(struct drm_color_lut); ret = drm_atomic_replace_property_blob_from_id(dev, &state->degamma_lut, val, - -1, sizeof(struct drm_color_lut), + -1, size, &replaced); state->color_mgmt_changed |= replaced; return ret; @@ -1084,6 +1087,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state, crtc_state->advance_gamma_mode_active = state->advance_gamma_mode_active; + crtc_state->advance_degamma_mode_active = + state->advance_degamma_mode_active; ret = drm_atomic_crtc_set_property(crtc, crtc_state, prop, prop_value); break; @@ -1422,6 +1427,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, state->acquire_ctx = &ctx; state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); state->advance_gamma_mode_active = file_priv->advance_gamma_mode_active; + state->advance_degamma_mode_active = file_priv->advance_degamma_mode_active; retry: copied_objs = 0; diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 034b2fa1552984..214d27ce545384 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -367,6 +367,11 @@ drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv) return -EINVAL; file_priv->advance_gamma_mode_active = req->value; break; + case DRM_CLIENT_CAP_ADVANCE_DEGAMMA_MODES: + if (req->value > 1) + return -EINVAL; + file_priv->advance_degamma_mode_active = req->value; + break; default: return -EINVAL; } diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 77400b7096c38f..fe7ba8a4243e35 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -380,6 +380,7 @@ struct drm_atomic_state { */ bool duplicated : 1; bool advance_gamma_mode_active : 1; + bool advance_degamma_mode_active : 1; struct __drm_planes_state *planes; struct __drm_crtcs_state *crtcs; int num_connector; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index e20c4d396071d7..9ed728c2275f02 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -175,6 +175,11 @@ struct drm_crtc_state { */ bool advance_gamma_mode_active : 1; + /** + * This is to indicate advance degamma mode support + */ + bool advance_degamma_mode_active : 1; + /** * @no_vblank: * @@ -1072,6 +1077,9 @@ struct drm_crtc { /** To handle advance gamma mode support */ bool advance_gamma_mode_active : 1; + /** To handle advance degamma mode support */ + bool advance_degamma_mode_active : 1; + /** * @mode: * diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index bde582cacf339b..41a34d2bbe7b19 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -208,6 +208,14 @@ struct drm_file { */ bool advance_gamma_mode_active : 1; + /** + * This is to enable advance degamma modes using + * 64 bit LUT values + * + * True if client understands advance gamma + */ + bool advance_degamma_mode_active : 1; + /** * @was_master: * diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 4e63495ad9cdee..8d6dfc9bfd1407 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -846,6 +846,16 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES 6 +/** + * DRM_CLIENT_CAP_ADVANCE_DEGAMMA_MODES + * + * Add support for advance degamma mode UAPI + * If set to 1, DRM will enable advance degamma mode + * UAPI to process degamma mode with 64 bit LUT + * values + */ +#define DRM_CLIENT_CAP_ADVANCE_DEGAMMA_MODES 7 + /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; From patchwork Wed Sep 14 12:47:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [06/10] INTEL_DII: drm: Add helper functions for extended LUT From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503085 Message-Id: <20220914124803.2359004-7-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:17:59 +0530 Add helper functions for 64 bit extended LUT Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/drm_color_mgmt.c | 43 ++++++++++++++++++++++++++++++++ include/drm/drm_color_mgmt.h | 13 ++++++++++ 2 files changed, 56 insertions(+) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 309a5067fb21fe..cdffa99fbcfdfb 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -909,3 +909,46 @@ int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests) return 0; } EXPORT_SYMBOL(drm_color_lut_check); + +/** + * drm_color_lut_ext_check - check validity of extended lookup table + * @lut: property blob containing extended LUT to check + * @tests: bitmask of tests to run + * + * Helper to check whether a userspace-provided extended lookup table is valid and + * satisfies hardware requirements. Drivers pass a bitmask indicating which of + * the tests in &drm_color_lut_tests should be performed. + * + * Returns 0 on success, -EINVAL on failure. + */ +int drm_color_lut_ext_check(const struct drm_property_blob *lut, u32 tests) +{ + const struct drm_color_lut_ext *entry; + int i; + + if (!lut || !tests) + return 0; + + entry = lut->data; + for (i = 0; i < drm_color_lut_ext_size(lut); i++) { + if (tests & DRM_COLOR_LUT_EQUAL_CHANNELS) { + if (entry[i].red != entry[i].blue || + entry[i].red != entry[i].green) { + DRM_DEBUG_KMS("All LUT entries must have equal r/g/b\n"); + return -EINVAL; + } + } + + if (i > 0 && tests & DRM_COLOR_LUT_NON_DECREASING) { + if (entry[i].red < entry[i - 1].red || + entry[i].green < entry[i - 1].green || + entry[i].blue < entry[i - 1].blue) { + DRM_DEBUG_KMS("LUT entries must never decrease.\n"); + return -EINVAL; + } + } + } + + return 0; +} +EXPORT_SYMBOL(drm_color_lut_ext_check); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 8599e063974037..58b1fe3d337fe6 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -74,6 +74,18 @@ static inline int drm_color_lut_size(const struct drm_property_blob *blob) return blob->length / sizeof(struct drm_color_lut); } +/** + * drm_color_lut_ext_size - calculate the number of entries in the extended LUT + * @blob: blob containing the LUT + * + * Returns: + * The number of entries in the color LUT stored in @blob. + */ +static inline int drm_color_lut_ext_size(const struct drm_property_blob *blob) +{ + return blob->length / sizeof(struct drm_color_lut_ext); +} + int drm_color_create_gamma_mode_property(struct drm_crtc *crtc, int num_values); void drm_crtc_attach_gamma_mode_property(struct drm_crtc *crtc); @@ -131,4 +143,5 @@ enum drm_color_lut_tests { }; int drm_color_lut_check(const struct drm_property_blob *lut, u32 tests); +int drm_color_lut_ext_check(const struct drm_property_blob *lut, u32 tests); #endif From patchwork Wed Sep 14 12:48:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [07/10] INTEL_DII: drm/i915/color: Add checks for extended luts From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503084 Message-Id: <20220914124803.2359004-8-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:18:00 +0530 Add functions to check extended LUTs with type struct drm_color_lut_ext Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index bb45e6809bbf7d..016e67c2aa5343 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1434,6 +1434,46 @@ intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state) return 0; } +static int check_lut_ext_size(const struct drm_property_blob *lut, int expected) +{ + int len; + + if (!lut) + return 0; + + len = drm_color_lut_ext_size(lut); + if (len != expected) { + DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n", + len, expected); + return -EINVAL; + } + + return 0; +} + +static int check_ext_luts(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut; + int degamma_length; + u32 degamma_tests; + + if (degamma_lut) + degamma_length = drm_color_lut_ext_size(degamma_lut); + else + degamma_length = INTEL_INFO(i915)->display.color.degamma_lut_size; + + degamma_tests = INTEL_INFO(i915)->display.color.degamma_lut_tests; + + if (check_lut_ext_size(degamma_lut, degamma_length)) + return -EINVAL; + + if (drm_color_lut_ext_check(degamma_lut, degamma_tests)) + return -EINVAL; + + return 0; +} + static int check_lut_size(const struct drm_property_blob *lut, int expected) { int len; @@ -1463,6 +1503,10 @@ static int check_luts(const struct intel_crtc_state *crtc_state) if (crtc_state_is_legacy_gamma(crtc_state)) return 0; + /* If extended degamma property set*/ + if (degamma_lut && crtc_state->uapi.advance_degamma_mode_active) + return check_ext_luts(crtc_state); + /* C8 relies on its palette being stored in the legacy LUT */ if (crtc_state->c8_planes) { drm_dbg_kms(&dev_priv->drm, From patchwork Wed Sep 14 12:48:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [08/10] INTEL_DII: drm/i915/mtl: Add check for 24 bit precision DG LUT From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503089 Message-Id: <20220914124803.2359004-9-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:18:01 +0530 There are two scenarios when 24 bit degamma lut will be configured correctly. 1. New user space must select "extended degamma" as degamma mode, set advance degamma client capability flag. 2. Legacy user space sends lut values without setting advance degamma client capability and without selecting a degamma mode Any other combinations should lead to error. The patch adds checks for these conditions Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 45 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 016e67c2aa5343..ecab52ed715428 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1541,6 +1541,27 @@ static int check_luts(const struct intel_crtc_state *crtc_state) return 0; } +static int mtl_check_degamma_lut(const struct intel_crtc_state *crtc_state) +{ + const struct drm_property_blob *degamma_lut_blob = crtc_state->hw.gamma_lut; + + if (!degamma_lut_blob) + return 0; + + if (crtc_state->uapi.degamma_mode_type == DEGAMMA_MODE_24BIT && + crtc_state->uapi.advance_degamma_mode_active) + return 0; + + /* 16 bit LUT value usecase */ + if (crtc_state->uapi.degamma_mode_type == 0 && + !crtc_state->uapi.advance_degamma_mode_active) + return 0; + + DRM_ERROR("%s check failed\n", __func__); + + return -EINVAL; +} + static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state) { if (!crtc_state->gamma_enable || @@ -1859,7 +1880,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->uapi.crtc->dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_property *property = crtc_state->uapi.crtc->gamma_mode_property; + struct drm_property *gamma_mode_property = crtc_state->uapi.crtc->gamma_mode_property; + struct drm_property *degamma_mode_property = crtc_state->uapi.crtc->degamma_mode_property; struct drm_property_enum *prop_enum; u32 index = 0; int ret; @@ -1868,8 +1890,27 @@ static int icl_color_check(struct intel_crtc_state *crtc_state) if (ret) return ret; + if (DISPLAY_VER(dev_priv) >= 14) { + list_for_each_entry(prop_enum, °amma_mode_property->enum_list, head) { + if (prop_enum->value == crtc_state->uapi.degamma_mode) { + if (!strcmp(prop_enum->name, + "extended degamma")) { + crtc_state->uapi.degamma_mode_type = + DEGAMMA_MODE_24BIT; + drm_dbg_kms(dev, + "extended degamma enabled\n"); + } + break; + } + } + + ret = mtl_check_degamma_lut(crtc_state); + if (ret) + return ret; + } + if (DISPLAY_VER(dev_priv) >= 13) { - list_for_each_entry(prop_enum, &property->enum_list, head) { + list_for_each_entry(prop_enum, &gamma_mode_property->enum_list, head) { if (prop_enum->value == crtc_state->uapi.gamma_mode) { if (!strcmp(prop_enum->name, "logarithmic gamma")) { From patchwork Wed Sep 14 12:48:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [09/10] INTEL_DII: drm/i915/mtl: Add support for 24 bit precision DG LUT From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503086 Message-Id: <20220914124803.2359004-10-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:18:02 +0530 D14 onwards Degamma LUT/PRE-CSC LUT precision has been increased from 16 bit to 24 bits. For LUT values greater than or equal to 0 and less than 1.0, the LUT value is used to linearly interpolate between two adjacent points of the first 129 gamma entries to create the result value. The first 128 entries are stored as 24 bits per color in an unsigned 0.24 format with 0 integer and 24 fractional. The 129th, 130th and 131th entries are stored as 27 bits per color in an unsigned 3.24 format with 3 integer and 24 fractional bits. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 54 +++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index ecab52ed715428..70cef8edcb6606 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -987,6 +987,51 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) } } +static void mtl_load_degamma_lut(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + const struct drm_property_blob *degamma_lut_blob = crtc_state->hw.degamma_lut; + struct drm_color_lut_ext *degamma_lut = degamma_lut_blob->data; + u32 i, lut_size = INTEL_INFO(i915)->display.color.degamma_lut_size; + enum pipe pipe = crtc->pipe; + + /* + * When setting the auto-increment bit, the hardware seems to + * ignore the index bits, so we need to reset it to index 0 + * separately. + */ + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0); + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), + PRE_CSC_GAMC_AUTO_INCREMENT); + + if (degamma_lut_blob) { + degamma_lut = degamma_lut_blob->data; + for (i = 0; i < lut_size; i++) { + u64 word = drm_color_lut_extract_ext(degamma_lut[i].green, 24); + u32 lut_val = (word & 0xffffff); + + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), + lut_val); + } + + while (i++ < glk_degamma_lut_size(i915)) + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), degamma_lut[i].green); + } else { + for (i = 0; i < lut_size; i++) { + u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1); + + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), v); + } + + /* Clamp values > 1.0. */ + while (i++ < glk_degamma_lut_size(i915)) + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), 1 << 24); + } + + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0); +} + /* ilk+ "12.4" interpolated format (high 10 bits) */ static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color) { @@ -1179,9 +1224,14 @@ static void xelpd_load_luts(const struct intel_crtc_state *crtc_state) { const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); - if (crtc_state->hw.degamma_lut) - glk_load_degamma_lut(crtc_state); + if (crtc_state->hw.degamma_lut) { + if ((DISPLAY_VER(i915) >= 14)) + mtl_load_degamma_lut(crtc_state); + else + glk_load_degamma_lut(crtc_state); + } switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) { case GAMMA_MODE_MODE_8BIT: From patchwork Wed Sep 14 12:48:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [10/10] INTEL_DII: drm/i915/mtl: Add legacy degamma lut support From: "Borah, Chaitanya Kumar" X-Patchwork-Id: 503087 Message-Id: <20220914124803.2359004-11-chaitanya.kumar.borah@intel.com> To: intel-gfx-trybot@lists.freedesktop.org Cc: chaitanya.kumar.borah@intel.com Date: Wed, 14 Sep 2022 18:18:03 +0530 Legacy applications which will send lut values with struct drm_color_lut still needs to be supported on MTL. This patch scales up 16 bit lut values to 24 bit lut values before programming the HW in case legacy application wants to set degamma lut values. Signed-off-by: Borah, Chaitanya Kumar --- drivers/gpu/drm/i915/display/intel_color.c | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 70cef8edcb6606..ab15d01fce817f 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -987,6 +987,38 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) } } +static void mtl_load_legacy_lut(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + const struct drm_property_blob *degamma_lut_blob = crtc_state->hw.degamma_lut; + struct drm_color_lut *degamma_lut = degamma_lut_blob->data; + enum pipe pipe = crtc->pipe; + int i, lut_size = drm_color_lut_size(degamma_lut_blob); + + /* + * When setting the auto-increment bit, the hardware seems to + * ignore the index bits, so we need to reset it to index 0 + * separately. + */ + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0); + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), + PRE_CSC_GAMC_AUTO_INCREMENT); + + for (i = 0; i < lut_size; i++) { + u64 word = mul_u32_u32(degamma_lut[i].green, (1 << 24)) / (1 << 16); + u32 lut_val = (word & 0xffffff); + + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), + lut_val); + } + /* Clamp values > 1.0. */ + while (i++ < glk_degamma_lut_size(i915)) + intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), 1 << 24); + + intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0); +} + static void mtl_load_degamma_lut(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -996,6 +1028,10 @@ static void mtl_load_degamma_lut(const struct intel_crtc_state *crtc_state) u32 i, lut_size = INTEL_INFO(i915)->display.color.degamma_lut_size; enum pipe pipe = crtc->pipe; + if (crtc_state->uapi.degamma_mode_type == 0 && + !crtc_state->uapi.advance_degamma_mode_active) + return mtl_load_legacy_lut(crtc_state); + /* * When setting the auto-increment bit, the hardware seems to * ignore the index bits, so we need to reset it to index 0