diff options
Diffstat (limited to '0207-AMD-HDR.patch')
-rw-r--r-- | 0207-AMD-HDR.patch | 6109 |
1 files changed, 0 insertions, 6109 deletions
diff --git a/0207-AMD-HDR.patch b/0207-AMD-HDR.patch deleted file mode 100644 index 4635f307058a..000000000000 --- a/0207-AMD-HDR.patch +++ /dev/null @@ -1,6109 +0,0 @@ -From e320343eab938d6a6d4c0e4da03c810516bf3bef Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 30 Nov 2022 14:02:15 -0500 -Subject: [PATCH 01/59] drm/connector: Drop COLORIMETRY_NO_DATA -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The value is the same as DEFAULT. The HDMI_COLORIMETRY_NO_DATA -makes sense for the infopacket but it's meaningless for the -connector colorspace. or, in otherwise, just means to go with -driver default. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 619d080523ac5582bb57eecb1d6a3bdd7f614885) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/display/drm_hdmi_helper.c | 2 +- - include/drm/drm_connector.h | 1 - - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/display/drm_hdmi_helper.c b/drivers/gpu/drm/display/drm_hdmi_helper.c -index faf5e9efa7d33..c1e6851b26066 100644 ---- a/drivers/gpu/drm/display/drm_hdmi_helper.c -+++ b/drivers/gpu/drm/display/drm_hdmi_helper.c -@@ -103,7 +103,7 @@ EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata); - #define HDMI_COLORIMETRY_DCI_P3_RGB_THEATER (C(3) | EC(7) | ACE(1)) - - static const u32 hdmi_colorimetry_val[] = { -- [DRM_MODE_COLORIMETRY_NO_DATA] = HDMI_COLORIMETRY_NO_DATA, -+ [DRM_MODE_COLORIMETRY_DEFAULT] = HDMI_COLORIMETRY_NO_DATA, - [DRM_MODE_COLORIMETRY_SMPTE_170M_YCC] = HDMI_COLORIMETRY_SMPTE_170M_YCC, - [DRM_MODE_COLORIMETRY_BT709_YCC] = HDMI_COLORIMETRY_BT709_YCC, - [DRM_MODE_COLORIMETRY_XVYCC_601] = HDMI_COLORIMETRY_XVYCC_601, -diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h -index 7b5048516185c..cfcd88c73a8d6 100644 ---- a/include/drm/drm_connector.h -+++ b/include/drm/drm_connector.h -@@ -431,7 +431,6 @@ enum drm_privacy_screen_status { - /* For Default case, driver will set the colorspace */ - #define DRM_MODE_COLORIMETRY_DEFAULT 0 - /* CEA 861 Normal Colorimetry options */ --#define DRM_MODE_COLORIMETRY_NO_DATA 0 - #define DRM_MODE_COLORIMETRY_SMPTE_170M_YCC 1 - #define DRM_MODE_COLORIMETRY_BT709_YCC 2 - /* CEA 861 Extended Colorimetry Options */ --- -2.40.1 - - -From d98dfe4f63acfa66a646326b7b424274ae40afdc Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 30 Nov 2022 14:18:22 -0500 -Subject: [PATCH 02/59] drm/connector: Convert DRM_MODE_COLORIMETRY to enum -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows us to use strongly typed arguments. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit be90be3eee59546d092e338929d8272d4864398a) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - include/drm/display/drm_dp.h | 2 +- - include/drm/drm_connector.h | 47 ++++++++++++++++++------------------ - 2 files changed, 25 insertions(+), 24 deletions(-) - -diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h -index f8813c1e059be..2ef9a8b2c354e 100644 ---- a/include/drm/display/drm_dp.h -+++ b/include/drm/display/drm_dp.h -@@ -1632,7 +1632,7 @@ enum dp_pixelformat { - * - * This enum is used to indicate DP VSC SDP Colorimetry formats. - * It is based on DP 1.4 spec [Table 2-117: VSC SDP Payload for DB16 through -- * DB18] and a name of enum member follows DRM_MODE_COLORIMETRY definition. -+ * DB18] and a name of enum member follows &enum drm_colorimetry definition. - * - * @DP_COLORIMETRY_DEFAULT: sRGB (IEC 61966-2-1) or - * ITU-R BT.601 colorimetry format -diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h -index cfcd88c73a8d6..657c51043a7f9 100644 ---- a/include/drm/drm_connector.h -+++ b/include/drm/drm_connector.h -@@ -427,28 +427,29 @@ enum drm_privacy_screen_status { - * a colorspace property which will be created and exposed to - * userspace. - */ -- --/* For Default case, driver will set the colorspace */ --#define DRM_MODE_COLORIMETRY_DEFAULT 0 --/* CEA 861 Normal Colorimetry options */ --#define DRM_MODE_COLORIMETRY_SMPTE_170M_YCC 1 --#define DRM_MODE_COLORIMETRY_BT709_YCC 2 --/* CEA 861 Extended Colorimetry Options */ --#define DRM_MODE_COLORIMETRY_XVYCC_601 3 --#define DRM_MODE_COLORIMETRY_XVYCC_709 4 --#define DRM_MODE_COLORIMETRY_SYCC_601 5 --#define DRM_MODE_COLORIMETRY_OPYCC_601 6 --#define DRM_MODE_COLORIMETRY_OPRGB 7 --#define DRM_MODE_COLORIMETRY_BT2020_CYCC 8 --#define DRM_MODE_COLORIMETRY_BT2020_RGB 9 --#define DRM_MODE_COLORIMETRY_BT2020_YCC 10 --/* Additional Colorimetry extension added as part of CTA 861.G */ --#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65 11 --#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER 12 --/* Additional Colorimetry Options added for DP 1.4a VSC Colorimetry Format */ --#define DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED 13 --#define DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT 14 --#define DRM_MODE_COLORIMETRY_BT601_YCC 15 -+enum drm_colorspace { -+ /* For Default case, driver will set the colorspace */ -+ DRM_MODE_COLORIMETRY_DEFAULT, -+ /* CEA 861 Normal Colorimetry options */ -+ DRM_MODE_COLORIMETRY_SMPTE_170M_YCC, -+ DRM_MODE_COLORIMETRY_BT709_YCC, -+ /* CEA 861 Extended Colorimetry Options */ -+ DRM_MODE_COLORIMETRY_XVYCC_601, -+ DRM_MODE_COLORIMETRY_XVYCC_709, -+ DRM_MODE_COLORIMETRY_SYCC_601, -+ DRM_MODE_COLORIMETRY_OPYCC_601, -+ DRM_MODE_COLORIMETRY_OPRGB, -+ DRM_MODE_COLORIMETRY_BT2020_CYCC, -+ DRM_MODE_COLORIMETRY_BT2020_RGB, -+ DRM_MODE_COLORIMETRY_BT2020_YCC, -+ /* Additional Colorimetry extension added as part of CTA 861.G */ -+ DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65, -+ DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, -+ /* Additional Colorimetry Options added for DP 1.4a VSC Colorimetry Format */ -+ DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED, -+ DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT, -+ DRM_MODE_COLORIMETRY_BT601_YCC, -+}; - - /** - * enum drm_bus_flags - bus_flags info for &drm_display_info -@@ -900,7 +901,7 @@ struct drm_connector_state { - * colorspace change on Sink. This is most commonly used to switch - * to wider color gamuts like BT2020. - */ -- u32 colorspace; -+ enum drm_colorspace colorspace; - - /** - * @writeback_job: Writeback job for writeback connectors --- -2.40.1 - - -From 59312e117c9b897060184001f7736d5cb7eb15dd Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 30 Nov 2022 14:42:03 -0500 -Subject: [PATCH 03/59] drm/connector: Pull out common - create_colorspace_property code -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 23badc4de4b1fa3a84689ffc09a9cf30dc927777) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/drm_connector.c | 54 ++++++++++++++++----------------- - 1 file changed, 27 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c -index 48df7a5ea503f..614dd9fd4d3f7 100644 ---- a/drivers/gpu/drm/drm_connector.c -+++ b/drivers/gpu/drm/drm_connector.c -@@ -2135,33 +2135,44 @@ EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property); - * drm_mode_create_dp_colorspace_property() is used for DP connector. - */ - --/** -- * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property -- * @connector: connector to create the Colorspace property on. -- * -- * Called by a driver the first time it's needed, must be attached to desired -- * HDMI connectors. -- * -- * Returns: -- * Zero on success, negative errno on failure. -- */ --int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector) -+static int drm_mode_create_colorspace_property(struct drm_connector *connector, -+ const struct drm_prop_enum_list *colorspaces, -+ int size) - { - struct drm_device *dev = connector->dev; - - if (connector->colorspace_property) - return 0; - -+ if (!colorspaces) -+ return 0; -+ - connector->colorspace_property = - drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace", -- hdmi_colorspaces, -- ARRAY_SIZE(hdmi_colorspaces)); -+ colorspaces, -+ size); - - if (!connector->colorspace_property) - return -ENOMEM; - - return 0; - } -+/** -+ * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property -+ * @connector: connector to create the Colorspace property on. -+ * -+ * Called by a driver the first time it's needed, must be attached to desired -+ * HDMI connectors. -+ * -+ * Returns: -+ * Zero on success, negative errno on failure. -+ */ -+int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector) -+{ -+ return drm_mode_create_colorspace_property(connector, -+ hdmi_colorspaces, -+ ARRAY_SIZE(hdmi_colorspaces)); -+} - EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); - - /** -@@ -2176,20 +2187,9 @@ EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); - */ - int drm_mode_create_dp_colorspace_property(struct drm_connector *connector) - { -- struct drm_device *dev = connector->dev; -- -- if (connector->colorspace_property) -- return 0; -- -- connector->colorspace_property = -- drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace", -- dp_colorspaces, -- ARRAY_SIZE(dp_colorspaces)); -- -- if (!connector->colorspace_property) -- return -ENOMEM; -- -- return 0; -+ return drm_mode_create_colorspace_property(connector, -+ dp_colorspaces, -+ ARRAY_SIZE(dp_colorspaces)); - } - EXPORT_SYMBOL(drm_mode_create_dp_colorspace_property); - --- -2.40.1 - - -From 769d91623bc199b054698e711ab7f31198770147 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Tue, 29 Nov 2022 15:16:31 -0500 -Subject: [PATCH 04/59] drm/connector: Allow drivers to pass list of supported - colorspaces -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Drivers might not support all colorspaces defined in -dp_colorspaces and hdmi_colorspaces. This results in -undefined behavior when userspace is setting an -unsupported colorspace. - -Allow drivers to pass the list of supported colorspaces -when creating the colorspace property. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 671b98e563d65707fb6fcf8e8d1aa04faf0565b8) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/drm_connector.c | 140 +++++++++--------- - .../gpu/drm/i915/display/intel_connector.c | 4 +- - drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- - include/drm/drm_connector.h | 8 +- - 4 files changed, 83 insertions(+), 71 deletions(-) - -diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c -index 614dd9fd4d3f7..5f272599f487f 100644 ---- a/drivers/gpu/drm/drm_connector.c -+++ b/drivers/gpu/drm/drm_connector.c -@@ -1055,64 +1055,57 @@ static const struct drm_prop_enum_list drm_dp_subconnector_enum_list[] = { - DRM_ENUM_NAME_FN(drm_get_dp_subconnector_name, - drm_dp_subconnector_enum_list) - --static const struct drm_prop_enum_list hdmi_colorspaces[] = { -- /* For Default case, driver will set the colorspace */ -- { DRM_MODE_COLORIMETRY_DEFAULT, "Default" }, -- /* Standard Definition Colorimetry based on CEA 861 */ -- { DRM_MODE_COLORIMETRY_SMPTE_170M_YCC, "SMPTE_170M_YCC" }, -- { DRM_MODE_COLORIMETRY_BT709_YCC, "BT709_YCC" }, -- /* Standard Definition Colorimetry based on IEC 61966-2-4 */ -- { DRM_MODE_COLORIMETRY_XVYCC_601, "XVYCC_601" }, -- /* High Definition Colorimetry based on IEC 61966-2-4 */ -- { DRM_MODE_COLORIMETRY_XVYCC_709, "XVYCC_709" }, -- /* Colorimetry based on IEC 61966-2-1/Amendment 1 */ -- { DRM_MODE_COLORIMETRY_SYCC_601, "SYCC_601" }, -- /* Colorimetry based on IEC 61966-2-5 [33] */ -- { DRM_MODE_COLORIMETRY_OPYCC_601, "opYCC_601" }, -- /* Colorimetry based on IEC 61966-2-5 */ -- { DRM_MODE_COLORIMETRY_OPRGB, "opRGB" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_CYCC, "BT2020_CYCC" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_RGB, "BT2020_RGB" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_YCC, "BT2020_YCC" }, -- /* Added as part of Additional Colorimetry Extension in 861.G */ -- { DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65, "DCI-P3_RGB_D65" }, -- { DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-P3_RGB_Theater" }, -+static const char * const colorspace_names[] = { -+ [DRM_MODE_COLORIMETRY_DEFAULT] = "Default", -+ [DRM_MODE_COLORIMETRY_SMPTE_170M_YCC] = "SMPTE_170M_YCC", -+ [DRM_MODE_COLORIMETRY_BT709_YCC] = "BT709_YCC", -+ [DRM_MODE_COLORIMETRY_XVYCC_601] = "XVYCC_601", -+ [DRM_MODE_COLORIMETRY_XVYCC_709] = "XVYCC_709", -+ [DRM_MODE_COLORIMETRY_SYCC_601] = "SYCC_601", -+ [DRM_MODE_COLORIMETRY_OPYCC_601] = "opYCC_601", -+ [DRM_MODE_COLORIMETRY_OPRGB] = "opRGB", -+ [DRM_MODE_COLORIMETRY_BT2020_CYCC] = "BT2020_CYCC", -+ [DRM_MODE_COLORIMETRY_BT2020_RGB] = "BT2020_RGB", -+ [DRM_MODE_COLORIMETRY_BT2020_YCC] = "BT2020_YCC", -+ [DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65] = "P3_RGB_D65", -+ [DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER] = "P3_RGB_Theater", -+ [DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED] = "RGB_WIDE_FIXED", -+ [DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT] = "RGB_WIDE_FLOAT", -+ [DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC", - }; - -+static const u32 hdmi_colorspaces = -+ BIT(DRM_MODE_COLORIMETRY_SMPTE_170M_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_BT709_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_XVYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_XVYCC_709) | -+ BIT(DRM_MODE_COLORIMETRY_SYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_OPYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_OPRGB) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) | -+ BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER); -+ - /* - * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry - * Format Table 2-120 - */ --static const struct drm_prop_enum_list dp_colorspaces[] = { -- /* For Default case, driver will set the colorspace */ -- { DRM_MODE_COLORIMETRY_DEFAULT, "Default" }, -- { DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED, "RGB_Wide_Gamut_Fixed_Point" }, -- /* Colorimetry based on scRGB (IEC 61966-2-2) */ -- { DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT, "RGB_Wide_Gamut_Floating_Point" }, -- /* Colorimetry based on IEC 61966-2-5 */ -- { DRM_MODE_COLORIMETRY_OPRGB, "opRGB" }, -- /* Colorimetry based on SMPTE RP 431-2 */ -- { DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65, "DCI-P3_RGB_D65" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_RGB, "BT2020_RGB" }, -- { DRM_MODE_COLORIMETRY_BT601_YCC, "BT601_YCC" }, -- { DRM_MODE_COLORIMETRY_BT709_YCC, "BT709_YCC" }, -- /* Standard Definition Colorimetry based on IEC 61966-2-4 */ -- { DRM_MODE_COLORIMETRY_XVYCC_601, "XVYCC_601" }, -- /* High Definition Colorimetry based on IEC 61966-2-4 */ -- { DRM_MODE_COLORIMETRY_XVYCC_709, "XVYCC_709" }, -- /* Colorimetry based on IEC 61966-2-1/Amendment 1 */ -- { DRM_MODE_COLORIMETRY_SYCC_601, "SYCC_601" }, -- /* Colorimetry based on IEC 61966-2-5 [33] */ -- { DRM_MODE_COLORIMETRY_OPYCC_601, "opYCC_601" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_CYCC, "BT2020_CYCC" }, -- /* Colorimetry based on ITU-R BT.2020 */ -- { DRM_MODE_COLORIMETRY_BT2020_YCC, "BT2020_YCC" }, --}; -+static const u32 dp_colorspaces = -+ BIT(DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED) | -+ BIT(DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT) | -+ BIT(DRM_MODE_COLORIMETRY_OPRGB) | -+ BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | -+ BIT(DRM_MODE_COLORIMETRY_BT601_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_BT709_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_XVYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_XVYCC_709) | -+ BIT(DRM_MODE_COLORIMETRY_SYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_OPYCC_601) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); - - /** - * DOC: standard connector properties -@@ -2136,21 +2129,34 @@ EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property); - */ - - static int drm_mode_create_colorspace_property(struct drm_connector *connector, -- const struct drm_prop_enum_list *colorspaces, -- int size) -+ u32 supported_colorspaces) - { - struct drm_device *dev = connector->dev; -+ u32 colorspaces = supported_colorspaces | BIT(DRM_MODE_COLORIMETRY_DEFAULT); -+ struct drm_prop_enum_list enum_list[DRM_MODE_COLORIMETRY_MAX]; -+ int i, len; - - if (connector->colorspace_property) - return 0; - -- if (!colorspaces) -- return 0; -+ if (WARN_ON(supported_colorspaces == 0 || -+ (supported_colorspaces & -BIT(DRM_MODE_COLORIMETRY_MAX)) != 0)) -+ return -EINVAL; -+ -+ len = 0; -+ for (i = 0; i < DRM_MODE_COLORIMETRY_MAX; i++) { -+ if ((colorspaces & BIT(i)) == 0) -+ continue; -+ -+ enum_list[len].type = i; -+ enum_list[len].name = colorspace_names[i]; -+ len++; -+ } - - connector->colorspace_property = - drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace", -- colorspaces, -- size); -+ enum_list, -+ len); - - if (!connector->colorspace_property) - return -ENOMEM; -@@ -2167,11 +2173,12 @@ static int drm_mode_create_colorspace_property(struct drm_connector *connector, - * Returns: - * Zero on success, negative errno on failure. - */ --int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector) -+int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector, -+ u32 supported_colorspaces) - { -- return drm_mode_create_colorspace_property(connector, -- hdmi_colorspaces, -- ARRAY_SIZE(hdmi_colorspaces)); -+ u32 colorspaces = supported_colorspaces & hdmi_colorspaces; -+ -+ return drm_mode_create_colorspace_property(connector, colorspaces); - } - EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); - -@@ -2185,11 +2192,12 @@ EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property); - * Returns: - * Zero on success, negative errno on failure. - */ --int drm_mode_create_dp_colorspace_property(struct drm_connector *connector) -+int drm_mode_create_dp_colorspace_property(struct drm_connector *connector, -+ u32 supported_colorspaces) - { -- return drm_mode_create_colorspace_property(connector, -- dp_colorspaces, -- ARRAY_SIZE(dp_colorspaces)); -+ u32 colorspaces = supported_colorspaces & dp_colorspaces; -+ -+ return drm_mode_create_colorspace_property(connector, colorspaces); - } - EXPORT_SYMBOL(drm_mode_create_dp_colorspace_property); - -diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c -index 257afac348397..cefc7ca5bf7bc 100644 ---- a/drivers/gpu/drm/i915/display/intel_connector.c -+++ b/drivers/gpu/drm/i915/display/intel_connector.c -@@ -280,14 +280,14 @@ intel_attach_aspect_ratio_property(struct drm_connector *connector) - void - intel_attach_hdmi_colorspace_property(struct drm_connector *connector) - { -- if (!drm_mode_create_hdmi_colorspace_property(connector)) -+ if (!drm_mode_create_hdmi_colorspace_property(connector, 0xffffffff)) - drm_connector_attach_colorspace_property(connector); - } - - void - intel_attach_dp_colorspace_property(struct drm_connector *connector) - { -- if (!drm_mode_create_dp_colorspace_property(connector)) -+ if (!drm_mode_create_dp_colorspace_property(connector, 0xffffffff)) - drm_connector_attach_colorspace_property(connector); - } - -diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c -index 06713d8b82b5d..e9abdbb8b3c72 100644 ---- a/drivers/gpu/drm/vc4/vc4_hdmi.c -+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c -@@ -631,7 +631,7 @@ static int vc4_hdmi_connector_init(struct drm_device *dev, - if (ret) - return ret; - -- ret = drm_mode_create_hdmi_colorspace_property(connector); -+ ret = drm_mode_create_hdmi_colorspace_property(connector, 0xffffffff); - if (ret) - return ret; - -diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h -index 657c51043a7f9..2d10ea06a7584 100644 ---- a/include/drm/drm_connector.h -+++ b/include/drm/drm_connector.h -@@ -30,6 +30,7 @@ - #include <linux/notifier.h> - #include <drm/drm_mode_object.h> - #include <drm/drm_util.h> -+#include <drm/drm_property.h> - - #include <uapi/drm/drm_mode.h> - -@@ -449,6 +450,7 @@ enum drm_colorspace { - DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED, - DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT, - DRM_MODE_COLORIMETRY_BT601_YCC, -+ DRM_MODE_COLORIMETRY_MAX - }; - - /** -@@ -1925,8 +1927,10 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn - bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state, - struct drm_connector_state *new_state); - int drm_mode_create_aspect_ratio_property(struct drm_device *dev); --int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector); --int drm_mode_create_dp_colorspace_property(struct drm_connector *connector); -+int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector, -+ u32 supported_colorspaces); -+int drm_mode_create_dp_colorspace_property(struct drm_connector *connector, -+ u32 supported_colorspaces); - int drm_mode_create_content_type_property(struct drm_device *dev); - int drm_mode_create_suggested_offset_properties(struct drm_device *dev); - --- -2.40.1 - - -From 0109bbccb4c0e3fcb6d555b31a49ac6186f28abc Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 30 Nov 2022 16:11:30 -0500 -Subject: [PATCH 05/59] drm/connector: Print connector colorspace in state - debugfs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 7e2a454f00f1e200fa8fd89aad628d160c1eba93) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/drm_atomic.c | 1 + - drivers/gpu/drm/drm_connector.c | 15 +++++++++++++++ - include/drm/drm_connector.h | 1 + - 3 files changed, 17 insertions(+) - -diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c -index b4c6ffc438da2..2c454568a607c 100644 ---- a/drivers/gpu/drm/drm_atomic.c -+++ b/drivers/gpu/drm/drm_atomic.c -@@ -1131,6 +1131,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, - drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)"); - drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware); - drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); -+ drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace)); - - if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) - if (state->writeback_job && state->writeback_job->fb) -diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c -index 5f272599f487f..f8bf090c98144 100644 ---- a/drivers/gpu/drm/drm_connector.c -+++ b/drivers/gpu/drm/drm_connector.c -@@ -1074,6 +1074,21 @@ static const char * const colorspace_names[] = { - [DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC", - }; - -+/** -+ * drm_get_color_encoding_name - return a string for color encoding -+ * @encoding: color encoding to compute name of -+ * -+ * In contrast to the other drm_get_*_name functions this one here returns a -+ * const pointer and hence is threadsafe. -+ */ -+const char *drm_get_colorspace_name(enum drm_colorspace colorspace) -+{ -+ if (WARN_ON(colorspace >= ARRAY_SIZE(colorspace_names))) -+ return "unknown"; -+ -+ return colorspace_names[colorspace]; -+} -+ - static const u32 hdmi_colorspaces = - BIT(DRM_MODE_COLORIMETRY_SMPTE_170M_YCC) | - BIT(DRM_MODE_COLORIMETRY_BT709_YCC) | -diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h -index 2d10ea06a7584..919047091c101 100644 ---- a/include/drm/drm_connector.h -+++ b/include/drm/drm_connector.h -@@ -2013,6 +2013,7 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter); - - bool drm_connector_has_possible_encoder(struct drm_connector *connector, - struct drm_encoder *encoder); -+const char *drm_get_colorspace_name(enum drm_colorspace colorspace); - - /** - * drm_for_each_connector_iter - connector_list iterator macro --- -2.40.1 - - -From b840e36bde5711e21191fb9855e7e7ec2cab6d48 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Fri, 1 Apr 2022 13:45:29 -0400 -Subject: [PATCH 06/59] drm/amd/display: Always pass connector_state to stream - validation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We need the connector_state for colorspace and scaling information -and can get it from connector->state. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit f6ab07b44373c865e286bb5e8b8e52d7d350ec66) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 7acd73e5004fb..5f545ef690f39 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5947,15 +5947,14 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, - { - struct drm_display_mode *preferred_mode = NULL; - struct drm_connector *drm_connector; -- const struct drm_connector_state *con_state = -- dm_state ? &dm_state->base : NULL; -+ const struct drm_connector_state *con_state = &dm_state->base; - struct dc_stream_state *stream = NULL; - struct drm_display_mode mode; - struct drm_display_mode saved_mode; - struct drm_display_mode *freesync_mode = NULL; - bool native_mode_found = false; - bool recalculate_timing = false; -- bool scale = dm_state ? (dm_state->scaling != RMX_OFF) : false; -+ bool scale = dm_state->scaling != RMX_OFF; - int mode_refresh; - int preferred_refresh = 0; - enum color_transfer_func tf = TRANSFER_FUNC_UNKNOWN; -@@ -6563,7 +6562,9 @@ enum drm_mode_status amdgpu_dm_connector_mode_valid(struct drm_connector *connec - goto fail; - } - -- stream = create_validate_stream_for_sink(aconnector, mode, NULL, NULL); -+ stream = create_validate_stream_for_sink(aconnector, mode, -+ to_dm_connector_state(connector->state), -+ NULL); - if (stream) { - dc_stream_release(stream); - result = MODE_OK; --- -2.40.1 - - -From 224746fb1cd4c0a5e3db947a593c510e30dd7b4c Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Fri, 25 Mar 2022 15:30:28 -0400 -Subject: [PATCH 07/59] drm/amd/display: Register Colorspace property for DP - and HDMI -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We want compositors to be able to set the output -colorspace on DP and HDMI outputs, based on the -caps reported from the receiver via EDID. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 9246196a65f4b1a06245ad0f7c0a194ab9df6dd4) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 5f545ef690f39..8d188145ab344 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -7211,6 +7211,12 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) - return amdgpu_dm_connector->num_modes; - } - -+static const u32 supported_colorspaces = -+ BIT(DRM_MODE_COLORIMETRY_BT709_YCC) | -+ BIT(DRM_MODE_COLORIMETRY_OPRGB) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) | -+ BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); -+ - void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, - struct amdgpu_dm_connector *aconnector, - int connector_type, -@@ -7291,6 +7297,15 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, - adev->mode_info.abm_level_property, 0); - } - -+ if (connector_type == DRM_MODE_CONNECTOR_HDMIA) { -+ if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces)) -+ drm_connector_attach_colorspace_property(&aconnector->base); -+ } else if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || -+ connector_type == DRM_MODE_CONNECTOR_eDP) { -+ if (!drm_mode_create_dp_colorspace_property(&aconnector->base, supported_colorspaces)) -+ drm_connector_attach_colorspace_property(&aconnector->base); -+ } -+ - if (connector_type == DRM_MODE_CONNECTOR_HDMIA || - connector_type == DRM_MODE_CONNECTOR_DisplayPort || - connector_type == DRM_MODE_CONNECTOR_eDP) { --- -2.40.1 - - -From eff7f31566489b7cf9b546844970ff58ad2ca2df Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Tue, 29 Mar 2022 11:26:23 -0400 -Subject: [PATCH 08/59] drm/amd/display: Set colorspace for HDMI infoframe -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Now that we have the HDMI colorimetry fill the corresponding -AVI infoframe info. Also signal "mode_changed" if colorimetry -changed. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 556619b9a15bb3dec6c92528501be5b51583465e) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 8d188145ab344..6f7d9e0a84115 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5466,6 +5466,7 @@ static void fill_stream_properties_from_drm_display_mode( - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { - drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, (struct drm_connector *)connector, mode_in); - timing_out->vic = avi_frame.video_code; -+ drm_hdmi_avi_infoframe_colorimetry(&avi_frame, connector_state); - drm_hdmi_vendor_infoframe_from_display_mode(&hv_frame, (struct drm_connector *)connector, mode_in); - timing_out->hdmi_vic = hv_frame.vic; - } -@@ -6658,6 +6659,14 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, - if (!crtc) - return 0; - -+ if (new_con_state->colorspace != old_con_state->colorspace) { -+ new_crtc_state = drm_atomic_get_crtc_state(state, crtc); -+ if (IS_ERR(new_crtc_state)) -+ return PTR_ERR(new_crtc_state); -+ -+ new_crtc_state->mode_changed = true; -+ } -+ - if (!drm_connector_atomic_hdr_metadata_equal(old_con_state, new_con_state)) { - struct dc_info_packet hdr_infopacket; - -@@ -6680,7 +6689,7 @@ amdgpu_dm_connector_atomic_check(struct drm_connector *conn, - * set is permissible, however. So only force a - * modeset if we're entering or exiting HDR. - */ -- new_crtc_state->mode_changed = -+ new_crtc_state->mode_changed = new_crtc_state->mode_changed || - !old_con_state->hdr_output_metadata || - !new_con_state->hdr_output_metadata; - } --- -2.40.1 - - -From f350177dba28757eddbe9687d06b9b90cdf85104 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Tue, 29 Mar 2022 15:30:05 -0400 -Subject: [PATCH 09/59] drm/amd/display: Send correct DP colorspace infopacket -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Look at connector->colorimetry to determine output colorspace. - -We don't want to impact current SDR behavior, so -DRM_MODE_COLORIMETRY_DEFAULT preserves current behavior. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 9c9a9db82e4f43f971fdc06ec8825bcb1a4ad391) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 38 +++++++++++-------- - 1 file changed, 22 insertions(+), 16 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 6f7d9e0a84115..a486474e63cb2 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5331,21 +5331,21 @@ get_aspect_ratio(const struct drm_display_mode *mode_in) - } - - static enum dc_color_space --get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) -+get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, -+ const struct drm_connector_state *connector_state) - { - enum dc_color_space color_space = COLOR_SPACE_SRGB; - -- switch (dc_crtc_timing->pixel_encoding) { -- case PIXEL_ENCODING_YCBCR422: -- case PIXEL_ENCODING_YCBCR444: -- case PIXEL_ENCODING_YCBCR420: -- { -+ switch (connector_state->colorspace) { -+ case DRM_MODE_COLORIMETRY_DEFAULT: // ITU601 -+ if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) { -+ color_space = COLOR_SPACE_SRGB; - /* - * 27030khz is the separation point between HDTV and SDTV - * according to HDMI spec, we use YCbCr709 and YCbCr601 - * respectively - */ -- if (dc_crtc_timing->pix_clk_100hz > 270300) { -+ } else if (dc_crtc_timing->pix_clk_100hz > 270300) { - if (dc_crtc_timing->flags.Y_ONLY) - color_space = - COLOR_SPACE_YCBCR709_LIMITED; -@@ -5358,15 +5358,21 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) - else - color_space = COLOR_SPACE_YCBCR601; - } -- -- } -- break; -- case PIXEL_ENCODING_RGB: -- color_space = COLOR_SPACE_SRGB; - break; -- -- default: -- WARN_ON(1); -+ case DRM_MODE_COLORIMETRY_BT709_YCC: -+ if (dc_crtc_timing->flags.Y_ONLY) -+ color_space = COLOR_SPACE_YCBCR709_LIMITED; -+ else -+ color_space = COLOR_SPACE_YCBCR709; -+ break; -+ case DRM_MODE_COLORIMETRY_OPRGB: -+ color_space = COLOR_SPACE_ADOBERGB; -+ break; -+ case DRM_MODE_COLORIMETRY_BT2020_RGB: -+ color_space = COLOR_SPACE_2020_RGB_FULLRANGE; -+ break; -+ case DRM_MODE_COLORIMETRY_BT2020_YCC: -+ color_space = COLOR_SPACE_2020_YCBCR; - break; - } - -@@ -5506,7 +5512,7 @@ static void fill_stream_properties_from_drm_display_mode( - } - } - -- stream->output_color_space = get_output_color_space(timing_out); -+ stream->output_color_space = get_output_color_space(timing_out, connector_state); - } - - static void fill_audio_info(struct audio_info *audio_info, --- -2.40.1 - - -From a22bdccba1e118d82ce39a8085345d3d060aa350 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Mon, 14 Nov 2022 19:52:30 +0000 -Subject: [PATCH 10/59] drm/amd/display: Always set crtcinfo from - create_stream_for_sink -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Given that we always pass dm_state into here now, this won't ever -trigger anymore. - -This is needed for we will always fail mode validation with invalid -clocks or link bandwidth errors. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 069221689191b3001a171aa086ba01bb675d54c4) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index a486474e63cb2..6e7ef3bdb5c3a 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -6040,7 +6040,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, - - if (recalculate_timing) - drm_mode_set_crtcinfo(&saved_mode, 0); -- else if (!dm_state) -+ else - drm_mode_set_crtcinfo(&mode, 0); - - /* --- -2.40.1 - - -From 7cce4d19d1b20da69331b50de1d908f5a2dc4be5 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Tue, 29 Nov 2022 14:58:10 -0500 -Subject: [PATCH 11/59] drm/amd/display: Add support for explicit BT601_YCC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We use this by default but if userspace passes this explicitly -we should respect it. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 468f3103082ec31b5923da84db1733a836f7fec9) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 6e7ef3bdb5c3a..4c63ed14ed610 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5359,6 +5359,12 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, - color_space = COLOR_SPACE_YCBCR601; - } - break; -+ case DRM_MODE_COLORIMETRY_BT601_YCC: -+ if (dc_crtc_timing->flags.Y_ONLY) -+ color_space = COLOR_SPACE_YCBCR601_LIMITED; -+ else -+ color_space = COLOR_SPACE_YCBCR601; -+ break; - case DRM_MODE_COLORIMETRY_BT709_YCC: - if (dc_crtc_timing->flags.Y_ONLY) - color_space = COLOR_SPACE_YCBCR709_LIMITED; --- -2.40.1 - - -From b12036a28c6d5b4f6d0798962d7a76e1c02e9d9d Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Tue, 29 Nov 2022 17:24:52 -0500 -Subject: [PATCH 12/59] drm/amd/display: Add debugfs for testing output - colorspace -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In order to IGT test colorspace we'll want to print -the currently enabled colorspace on a stream. We add -a new debugfs to do so, using the same scheme as -current bpc reporting. - -This might also come in handy when debugging display -issues. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 4783cc7b534ebd8cd64d6d7b1c26d102f93b0576) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 57 +++++++++++++++++++ - 1 file changed, 57 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -index 827fcb4fb3b3b..b865570756933 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c -@@ -906,6 +906,61 @@ static int amdgpu_current_bpc_show(struct seq_file *m, void *data) - } - DEFINE_SHOW_ATTRIBUTE(amdgpu_current_bpc); - -+/* -+ * Returns the current bpc for the crtc. -+ * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/amdgpu_current_colorspace -+ */ -+static int amdgpu_current_colorspace_show(struct seq_file *m, void *data) -+{ -+ struct drm_crtc *crtc = m->private; -+ struct drm_device *dev = crtc->dev; -+ struct dm_crtc_state *dm_crtc_state = NULL; -+ int res = -ENODEV; -+ -+ mutex_lock(&dev->mode_config.mutex); -+ drm_modeset_lock(&crtc->mutex, NULL); -+ if (crtc->state == NULL) -+ goto unlock; -+ -+ dm_crtc_state = to_dm_crtc_state(crtc->state); -+ if (dm_crtc_state->stream == NULL) -+ goto unlock; -+ -+ switch (dm_crtc_state->stream->output_color_space) { -+ case COLOR_SPACE_SRGB: -+ seq_printf(m, "RGB"); -+ break; -+ case COLOR_SPACE_YCBCR601: -+ case COLOR_SPACE_YCBCR601_LIMITED: -+ seq_printf(m, "BT601_YCC"); -+ break; -+ case COLOR_SPACE_YCBCR709: -+ case COLOR_SPACE_YCBCR709_LIMITED: -+ seq_printf(m, "BT709_YCC"); -+ break; -+ case COLOR_SPACE_ADOBERGB: -+ seq_printf(m, "opRGB"); -+ break; -+ case COLOR_SPACE_2020_RGB_FULLRANGE: -+ seq_printf(m, "BT2020_RGB"); -+ break; -+ case COLOR_SPACE_2020_YCBCR: -+ seq_printf(m, "BT2020_YCC"); -+ break; -+ default: -+ goto unlock; -+ } -+ res = 0; -+ -+unlock: -+ drm_modeset_unlock(&crtc->mutex); -+ mutex_unlock(&dev->mode_config.mutex); -+ -+ return res; -+} -+DEFINE_SHOW_ATTRIBUTE(amdgpu_current_colorspace); -+ -+ - /* - * Example usage: - * Disable dsc passthrough, i.e.,: have dsc decoding at converver, not external RX -@@ -3246,6 +3301,8 @@ void crtc_debugfs_init(struct drm_crtc *crtc) - #endif - debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry, - crtc, &amdgpu_current_bpc_fops); -+ debugfs_create_file("amdgpu_current_colorspace", 0644, crtc->debugfs_entry, -+ crtc, &amdgpu_current_colorspace_fops); - } - - /* --- -2.40.1 - - -From ffb5d236189cfdf92f7bdd47c70140791c332860 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 30 Nov 2022 14:17:14 -0500 -Subject: [PATCH 13/59] drm/amd/display: Add default case for - output_color_space switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Cc: Pekka Paalanen <ppaalanen@gmail.com> -Cc: Sebastian Wick <sebastian.wick@redhat.com> -Cc: Vitaly.Prosyak@amd.com -Cc: Uma Shankar <uma.shankar@intel.com> -Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> -Cc: Joshua Ashton <joshua@froggi.es> -Cc: dri-devel@lists.freedesktop.org -Cc: amd-gfx@lists.freedesktop.org -(cherry picked from commit 1c98f57342c976b12775155746d56801b1231463) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 43 ++++++++++--------- - 1 file changed, 22 insertions(+), 21 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 4c63ed14ed610..353bc03f30cb7 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5337,7 +5337,29 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, - enum dc_color_space color_space = COLOR_SPACE_SRGB; - - switch (connector_state->colorspace) { -+ case DRM_MODE_COLORIMETRY_BT601_YCC: -+ if (dc_crtc_timing->flags.Y_ONLY) -+ color_space = COLOR_SPACE_YCBCR601_LIMITED; -+ else -+ color_space = COLOR_SPACE_YCBCR601; -+ break; -+ case DRM_MODE_COLORIMETRY_BT709_YCC: -+ if (dc_crtc_timing->flags.Y_ONLY) -+ color_space = COLOR_SPACE_YCBCR709_LIMITED; -+ else -+ color_space = COLOR_SPACE_YCBCR709; -+ break; -+ case DRM_MODE_COLORIMETRY_OPRGB: -+ color_space = COLOR_SPACE_ADOBERGB; -+ break; -+ case DRM_MODE_COLORIMETRY_BT2020_RGB: -+ color_space = COLOR_SPACE_2020_RGB_FULLRANGE; -+ break; -+ case DRM_MODE_COLORIMETRY_BT2020_YCC: -+ color_space = COLOR_SPACE_2020_YCBCR; -+ break; - case DRM_MODE_COLORIMETRY_DEFAULT: // ITU601 -+ default: - if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) { - color_space = COLOR_SPACE_SRGB; - /* -@@ -5359,27 +5381,6 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, - color_space = COLOR_SPACE_YCBCR601; - } - break; -- case DRM_MODE_COLORIMETRY_BT601_YCC: -- if (dc_crtc_timing->flags.Y_ONLY) -- color_space = COLOR_SPACE_YCBCR601_LIMITED; -- else -- color_space = COLOR_SPACE_YCBCR601; -- break; -- case DRM_MODE_COLORIMETRY_BT709_YCC: -- if (dc_crtc_timing->flags.Y_ONLY) -- color_space = COLOR_SPACE_YCBCR709_LIMITED; -- else -- color_space = COLOR_SPACE_YCBCR709; -- break; -- case DRM_MODE_COLORIMETRY_OPRGB: -- color_space = COLOR_SPACE_ADOBERGB; -- break; -- case DRM_MODE_COLORIMETRY_BT2020_RGB: -- color_space = COLOR_SPACE_2020_RGB_FULLRANGE; -- break; -- case DRM_MODE_COLORIMETRY_BT2020_YCC: -- color_space = COLOR_SPACE_2020_YCBCR; -- break; - } - - return color_space; --- -2.40.1 - - -From 0e442c9a946e78ca5078c00a5ce5b5686622b5dd Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 10 Jan 2023 19:17:08 +0000 -Subject: [PATCH 14/59] drm/amd/display: Fallback to 2020_YCBCR if the pixel - encoding is not RGB - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -(cherry picked from commit 4d5fe77e2cd4444756790466c573b54b108445fe) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 353bc03f30cb7..9b9b0b7706522 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5353,7 +5353,10 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, - color_space = COLOR_SPACE_ADOBERGB; - break; - case DRM_MODE_COLORIMETRY_BT2020_RGB: -- color_space = COLOR_SPACE_2020_RGB_FULLRANGE; -+ if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) -+ color_space = COLOR_SPACE_2020_RGB_FULLRANGE; -+ else -+ color_space = COLOR_SPACE_2020_YCBCR; - break; - case DRM_MODE_COLORIMETRY_BT2020_YCC: - color_space = COLOR_SPACE_2020_YCBCR; --- -2.40.1 - - -From 2bd640d40bcc2b2445d6e4d5791199d26bf0b909 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 10 Jan 2023 19:14:06 +0000 -Subject: [PATCH 15/59] drm/amd/display: Refactor avi_info_frame colorimetry - determination - -Replace the messy two if-else chains here that were on the same value with a switch on the enum. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -(cherry picked from commit 88558ba9c35a3e2d0e2df7b90692ffbcea1fc9dd) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../gpu/drm/amd/display/dc/core/dc_resource.c | 28 +++++++++++-------- - 1 file changed, 17 insertions(+), 11 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -index fe1551393b264..4b80091b6021a 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -3034,23 +3034,29 @@ static void set_avi_info_frame( - hdmi_info.bits.S0_S1 = scan_type; - - /* C0, C1 : Colorimetry */ -- if (color_space == COLOR_SPACE_YCBCR709 || -- color_space == COLOR_SPACE_YCBCR709_LIMITED) -+ switch (color_space) { -+ case COLOR_SPACE_YCBCR709: -+ case COLOR_SPACE_YCBCR709_LIMITED: - hdmi_info.bits.C0_C1 = COLORIMETRY_ITU709; -- else if (color_space == COLOR_SPACE_YCBCR601 || -- color_space == COLOR_SPACE_YCBCR601_LIMITED) -+ break; -+ case COLOR_SPACE_YCBCR601: -+ case COLOR_SPACE_YCBCR601_LIMITED: - hdmi_info.bits.C0_C1 = COLORIMETRY_ITU601; -- else { -- hdmi_info.bits.C0_C1 = COLORIMETRY_NO_DATA; -- } -- if (color_space == COLOR_SPACE_2020_RGB_FULLRANGE || -- color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE || -- color_space == COLOR_SPACE_2020_YCBCR) { -+ break; -+ case COLOR_SPACE_2020_RGB_FULLRANGE: -+ case COLOR_SPACE_2020_RGB_LIMITEDRANGE: -+ case COLOR_SPACE_2020_YCBCR: - hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR; - hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; -- } else if (color_space == COLOR_SPACE_ADOBERGB) { -+ break; -+ case COLOR_SPACE_ADOBERGB: - hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_ADOBERGB; - hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; -+ break; -+ case COLOR_SPACE_SRGB: -+ default: -+ hdmi_info.bits.C0_C1 = COLORIMETRY_NO_DATA; -+ break; - } - - if (pixel_encoding && color_space == COLOR_SPACE_2020_YCBCR && --- -2.40.1 - - -From abd25d352b9c9f9b8f1ed7e6824f3369bef10e8d Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 10 Jan 2023 19:26:07 +0000 -Subject: [PATCH 16/59] drm/amd/display: Use COLORIMETRYEX_BT2020YCC for - COLOR_SPACE_2020_YCBCR for avi info frame - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -(cherry picked from commit 622ce9770fdf2ffbff6110b6e61f01a08cd8c35c) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -index 4b80091b6021a..de8bc5c0d28ca 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -3045,10 +3045,13 @@ static void set_avi_info_frame( - break; - case COLOR_SPACE_2020_RGB_FULLRANGE: - case COLOR_SPACE_2020_RGB_LIMITEDRANGE: -- case COLOR_SPACE_2020_YCBCR: - hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020RGBYCBCR; - hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; - break; -+ case COLOR_SPACE_2020_YCBCR: -+ hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_BT2020YCC; -+ hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; -+ break; - case COLOR_SPACE_ADOBERGB: - hdmi_info.bits.EC0_EC2 = COLORIMETRYEX_ADOBERGB; - hdmi_info.bits.C0_C1 = COLORIMETRY_EXTENDED; --- -2.40.1 - - -From 45fffdcdc68a22e073966d7c864842c292a13f20 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Mon, 16 Jan 2023 04:20:17 +0000 -Subject: [PATCH 17/59] drm/amd/display: Hook up content_type property - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -(cherry picked from commit dc91bc9addbe058894a78ae72a13b20d76636b0c) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 21 ++++++ - .../gpu/drm/amd/display/dc/core/dc_resource.c | 69 ++++++------------- - drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 + - 3 files changed, 43 insertions(+), 48 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 9b9b0b7706522..6deec192ae04e 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5389,6 +5389,24 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing, - return color_space; - } - -+static enum display_content_type -+get_output_content_type(const struct drm_connector_state *connector_state) -+{ -+ switch (connector_state->content_type) { -+ default: -+ case DRM_MODE_CONTENT_TYPE_NO_DATA: -+ return DISPLAY_CONTENT_TYPE_NO_DATA; -+ case DRM_MODE_CONTENT_TYPE_GRAPHICS: -+ return DISPLAY_CONTENT_TYPE_GRAPHICS; -+ case DRM_MODE_CONTENT_TYPE_PHOTO: -+ return DISPLAY_CONTENT_TYPE_PHOTO; -+ case DRM_MODE_CONTENT_TYPE_CINEMA: -+ return DISPLAY_CONTENT_TYPE_CINEMA; -+ case DRM_MODE_CONTENT_TYPE_GAME: -+ return DISPLAY_CONTENT_TYPE_GAME; -+ } -+} -+ - static bool adjust_colour_depth_from_display_info( - struct dc_crtc_timing *timing_out, - const struct drm_display_info *info) -@@ -5523,6 +5541,7 @@ static void fill_stream_properties_from_drm_display_mode( - } - - stream->output_color_space = get_output_color_space(timing_out, connector_state); -+ stream->content_type = get_output_content_type(connector_state); - } - - static void fill_audio_info(struct audio_info *audio_info, -@@ -7322,6 +7341,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, - adev->mode_info.abm_level_property, 0); - } - -+ drm_connector_attach_content_type_property(&aconnector->base); -+ - if (connector_type == DRM_MODE_CONNECTOR_HDMIA) { - if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces)) - drm_connector_attach_colorspace_property(&aconnector->base); -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -index de8bc5c0d28ca..29757f39707cc 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c -@@ -2967,14 +2967,9 @@ static void set_avi_info_frame( - uint32_t pixel_encoding = 0; - enum scanning_type scan_type = SCANNING_TYPE_NODATA; - enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA; -- bool itc = false; -- uint8_t itc_value = 0; -- uint8_t cn0_cn1 = 0; -- unsigned int cn0_cn1_value = 0; - uint8_t *check_sum = NULL; - uint8_t byte_index = 0; - union hdmi_info_packet hdmi_info; -- union display_content_support support = {0}; - unsigned int vic = pipe_ctx->stream->timing.vic; - unsigned int rid = pipe_ctx->stream->timing.rid; - unsigned int fr_ind = pipe_ctx->stream->timing.fr_index; -@@ -3087,49 +3082,27 @@ static void set_avi_info_frame( - /* Active Format Aspect ratio - same as Picture Aspect Ratio. */ - hdmi_info.bits.R0_R3 = ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE; - -- /* TODO: un-hardcode cn0_cn1 and itc */ -- -- cn0_cn1 = 0; -- cn0_cn1_value = 0; -- -- itc = true; -- itc_value = 1; -- -- support = stream->content_support; -- -- if (itc) { -- if (!support.bits.valid_content_type) { -- cn0_cn1_value = 0; -- } else { -- if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GRAPHICS) { -- if (support.bits.graphics_content == 1) { -- cn0_cn1_value = 0; -- } -- } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_PHOTO) { -- if (support.bits.photo_content == 1) { -- cn0_cn1_value = 1; -- } else { -- cn0_cn1_value = 0; -- itc_value = 0; -- } -- } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_CINEMA) { -- if (support.bits.cinema_content == 1) { -- cn0_cn1_value = 2; -- } else { -- cn0_cn1_value = 0; -- itc_value = 0; -- } -- } else if (cn0_cn1 == DISPLAY_CONTENT_TYPE_GAME) { -- if (support.bits.game_content == 1) { -- cn0_cn1_value = 3; -- } else { -- cn0_cn1_value = 0; -- itc_value = 0; -- } -- } -- } -- hdmi_info.bits.CN0_CN1 = cn0_cn1_value; -- hdmi_info.bits.ITC = itc_value; -+ switch (stream->content_type) { -+ case DISPLAY_CONTENT_TYPE_NO_DATA: -+ hdmi_info.bits.CN0_CN1 = 0; -+ hdmi_info.bits.ITC = 0; -+ break; -+ case DISPLAY_CONTENT_TYPE_GRAPHICS: -+ hdmi_info.bits.CN0_CN1 = 0; -+ hdmi_info.bits.ITC = 1; -+ break; -+ case DISPLAY_CONTENT_TYPE_PHOTO: -+ hdmi_info.bits.CN0_CN1 = 1; -+ hdmi_info.bits.ITC = 1; -+ break; -+ case DISPLAY_CONTENT_TYPE_CINEMA: -+ hdmi_info.bits.CN0_CN1 = 2; -+ hdmi_info.bits.ITC = 1; -+ break; -+ case DISPLAY_CONTENT_TYPE_GAME: -+ hdmi_info.bits.CN0_CN1 = 3; -+ hdmi_info.bits.ITC = 1; -+ break; - } - - if (stream->qs_bit == 1) { -diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h -index 25284006019c3..82dcef4dbe782 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc_stream.h -+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h -@@ -206,6 +206,7 @@ struct dc_stream_state { - struct dc_csc_transform csc_color_matrix; - - enum dc_color_space output_color_space; -+ enum display_content_type content_type; - enum dc_dither_option dither_option; - - enum view_3d_format view_format; --- -2.40.1 - - -From daedb3f12312fe6e3a1c6147fa15148477f163a9 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 17 Jan 2023 06:03:02 +0000 -Subject: [PATCH 18/59] drm/amd/display: Remove unused display_content_support - -This was never filled in and thus never truly used. - -Checking the EDID for content_type support is not required for sending the avi infoframe packet. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -(cherry picked from commit a3b57c86fae88c74c9ff8b48d44b8d7a1e3824cb) -Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com> ---- - drivers/gpu/drm/amd/display/dc/dc_stream.h | 1 - - drivers/gpu/drm/amd/display/dc/dc_types.h | 14 -------------- - 2 files changed, 15 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h -index 82dcef4dbe782..9f2c6fa501d16 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc_stream.h -+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h -@@ -182,7 +182,6 @@ struct dc_stream_state { - */ - struct link_encoder *link_enc; - struct dc_panel_patch sink_patches; -- union display_content_support content_support; - struct dc_crtc_timing timing; - struct dc_crtc_timing_adjust adjust; - struct dc_info_packet vrr_infopacket; -diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h -index 45ab48fe5d004..fd92e09eb6932 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc_types.h -+++ b/drivers/gpu/drm/amd/display/dc/dc_types.h -@@ -170,18 +170,6 @@ struct dc_edid { - - #define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20 - --union display_content_support { -- unsigned int raw; -- struct { -- unsigned int valid_content_type :1; -- unsigned int game_content :1; -- unsigned int cinema_content :1; -- unsigned int photo_content :1; -- unsigned int graphics_content :1; -- unsigned int reserved :27; -- } bits; --}; -- - struct dc_panel_patch { - unsigned int dppowerup_delay; - unsigned int extra_t12_ms; -@@ -214,8 +202,6 @@ struct dc_edid_caps { - uint32_t audio_latency; - uint32_t video_latency; - -- union display_content_support content_support; -- - uint8_t qs_bit; - uint8_t qy_bit; - --- -2.40.1 - - -From ea7f73e73a0c102b5c51dc0ed2c5fbd18616b689 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Fri, 21 Apr 2023 22:39:34 -0100 -Subject: [PATCH 19/59] drm/drm_mode_object: increase max objects to - accommodate new color props - -DRM_OBJECT_MAX_PROPERTY limits the number of properties to be attached -and we are increasing that value all time we add a new property (generic -or driver-specific). - -In this series, we are adding 13 new KMS driver-specific properties for -AMD color manage: -- CRTC Gamma enumerated Transfer Function -- Plane: Degamma LUT+size+TF, HDR multiplier, shaper LUT+size+TF, 3D - LUT+size, blend LUT+size+TF (12) - -Therefore, just increase DRM_OBJECT_MAX_PROPERTY to a number (64) that -accomodates these new properties and gives some room for others, -avoiding change this number everytime we add a new KMS property. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - include/drm/drm_mode_object.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h -index 912f1e4156853..08d7a7f0188fe 100644 ---- a/include/drm/drm_mode_object.h -+++ b/include/drm/drm_mode_object.h -@@ -60,7 +60,7 @@ struct drm_mode_object { - void (*free_cb)(struct kref *kref); - }; - --#define DRM_OBJECT_MAX_PROPERTY 24 -+#define DRM_OBJECT_MAX_PROPERTY 64 - /** - * struct drm_object_properties - property tracking for &drm_mode_object - */ --- -2.40.1 - - -From 57f0e8749ce5a87138d83e4022ea5e95d82d0370 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Fri, 12 May 2023 15:15:26 -0100 -Subject: [PATCH 20/59] drm/drm_property: make replace_property_blob_from_id a - DRM helper - -Place it in drm_property where drm_property_replace_blob and -drm_property_lookup_blob live. Then we can use the DRM helper for -driver-specific KMS properties too. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/arm/malidp_crtc.c | 2 +- - drivers/gpu/drm/drm_atomic_uapi.c | 43 ++++----------------------- - drivers/gpu/drm/drm_property.c | 49 +++++++++++++++++++++++++++++++ - include/drm/drm_property.h | 6 ++++ - 4 files changed, 61 insertions(+), 39 deletions(-) - -diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c -index dc01c43f61930..d72c22dcf6855 100644 ---- a/drivers/gpu/drm/arm/malidp_crtc.c -+++ b/drivers/gpu/drm/arm/malidp_crtc.c -@@ -221,7 +221,7 @@ static int malidp_crtc_atomic_check_ctm(struct drm_crtc *crtc, - - /* - * The size of the ctm is checked in -- * drm_atomic_replace_property_blob_from_id. -+ * drm_property_replace_blob_from_id. - */ - ctm = (struct drm_color_ctm *)state->ctm->data; - for (i = 0; i < ARRAY_SIZE(ctm->matrix); ++i) { -diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c -index d867e7f9f2cd5..a6a9ee5086ddb 100644 ---- a/drivers/gpu/drm/drm_atomic_uapi.c -+++ b/drivers/gpu/drm/drm_atomic_uapi.c -@@ -362,39 +362,6 @@ static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state, - return fence_ptr; - } - --static int --drm_atomic_replace_property_blob_from_id(struct drm_device *dev, -- struct drm_property_blob **blob, -- uint64_t blob_id, -- ssize_t expected_size, -- ssize_t expected_elem_size, -- bool *replaced) --{ -- struct drm_property_blob *new_blob = NULL; -- -- if (blob_id != 0) { -- new_blob = drm_property_lookup_blob(dev, blob_id); -- if (new_blob == NULL) -- return -EINVAL; -- -- if (expected_size > 0 && -- new_blob->length != expected_size) { -- drm_property_blob_put(new_blob); -- return -EINVAL; -- } -- if (expected_elem_size > 0 && -- new_blob->length % expected_elem_size != 0) { -- drm_property_blob_put(new_blob); -- return -EINVAL; -- } -- } -- -- *replaced |= drm_property_replace_blob(blob, new_blob); -- drm_property_blob_put(new_blob); -- -- return 0; --} -- - static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - struct drm_crtc_state *state, struct drm_property *property, - uint64_t val) -@@ -415,7 +382,7 @@ 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) { -- ret = drm_atomic_replace_property_blob_from_id(dev, -+ ret = drm_property_replace_blob_from_id(dev, - &state->degamma_lut, - val, - -1, sizeof(struct drm_color_lut), -@@ -423,7 +390,7 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->ctm_property) { -- ret = drm_atomic_replace_property_blob_from_id(dev, -+ ret = drm_property_replace_blob_from_id(dev, - &state->ctm, - val, - sizeof(struct drm_color_ctm), -1, -@@ -431,7 +398,7 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, - state->color_mgmt_changed |= replaced; - return ret; - } else if (property == config->gamma_lut_property) { -- ret = drm_atomic_replace_property_blob_from_id(dev, -+ ret = drm_property_replace_blob_from_id(dev, - &state->gamma_lut, - val, - -1, sizeof(struct drm_color_lut), -@@ -563,7 +530,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, - } else if (property == plane->color_range_property) { - state->color_range = val; - } else if (property == config->prop_fb_damage_clips) { -- ret = drm_atomic_replace_property_blob_from_id(dev, -+ ret = drm_property_replace_blob_from_id(dev, - &state->fb_damage_clips, - val, - -1, -@@ -729,7 +696,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, - if (state->link_status != DRM_LINK_STATUS_GOOD) - state->link_status = val; - } else if (property == config->hdr_output_metadata_property) { -- ret = drm_atomic_replace_property_blob_from_id(dev, -+ ret = drm_property_replace_blob_from_id(dev, - &state->hdr_output_metadata, - val, - sizeof(struct hdr_output_metadata), -1, -diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c -index dfec479830e49..f72ef6493340a 100644 ---- a/drivers/gpu/drm/drm_property.c -+++ b/drivers/gpu/drm/drm_property.c -@@ -751,6 +751,55 @@ bool drm_property_replace_blob(struct drm_property_blob **blob, - } - EXPORT_SYMBOL(drm_property_replace_blob); - -+/** -+ * drm_property_replace_blob_from_id - replace a blob property taking a reference -+ * @dev: DRM device -+ * @blob: a pointer to the member blob to be replaced -+ * @blob_id: the id of the new blob to replace with -+ * @expected_size: expected size of the blob property -+ * @expected_elem_size: expected size of an element in the blob property -+ * @replaced: if the blob was in fact replaced -+ * -+ * Look up the new blob from id, take its reference, check expected sizes of -+ * the blob and its element and replace the old blob by the new one. Advertise -+ * if the replacement operation was successful. -+ * -+ * Return: true if the blob was in fact replaced. -EINVAL if the new blob was -+ * not found or sizes don't match. -+ */ -+int drm_property_replace_blob_from_id(struct drm_device *dev, -+ struct drm_property_blob **blob, -+ uint64_t blob_id, -+ ssize_t expected_size, -+ ssize_t expected_elem_size, -+ bool *replaced) -+{ -+ struct drm_property_blob *new_blob = NULL; -+ -+ if (blob_id != 0) { -+ new_blob = drm_property_lookup_blob(dev, blob_id); -+ if (new_blob == NULL) -+ return -EINVAL; -+ -+ if (expected_size > 0 && -+ new_blob->length != expected_size) { -+ drm_property_blob_put(new_blob); -+ return -EINVAL; -+ } -+ if (expected_elem_size > 0 && -+ new_blob->length % expected_elem_size != 0) { -+ drm_property_blob_put(new_blob); -+ return -EINVAL; -+ } -+ } -+ -+ *replaced |= drm_property_replace_blob(blob, new_blob); -+ drm_property_blob_put(new_blob); -+ -+ return 0; -+} -+EXPORT_SYMBOL(drm_property_replace_blob_from_id); -+ - int drm_mode_getblob_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv) - { -diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h -index 65bc9710a4702..082f29156b3e3 100644 ---- a/include/drm/drm_property.h -+++ b/include/drm/drm_property.h -@@ -279,6 +279,12 @@ struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, - const void *data); - struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, - uint32_t id); -+int drm_property_replace_blob_from_id(struct drm_device *dev, -+ struct drm_property_blob **blob, -+ uint64_t blob_id, -+ ssize_t expected_size, -+ ssize_t expected_elem_size, -+ bool *replaced); - int drm_property_replace_global_blob(struct drm_device *dev, - struct drm_property_blob **replace, - size_t length, --- -2.40.1 - - -From c28dbee4f2aec811aa1fbfd2339cc1a886272d00 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Tue, 21 Mar 2023 15:30:20 -0100 -Subject: [PATCH 21/59] drm/drm_plane: track color mgmt changes per plane - -We will add color mgmt properties to DRM planes in the next patches and -we want to track when one of this properties change to define atomic -commit behaviors. Using a similar approach from CRTC color props, we set -a color_mgmt_changed boolean whenever a plane color prop changes. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/drm_atomic.c | 1 + - drivers/gpu/drm/drm_atomic_state_helper.c | 1 + - include/drm/drm_plane.h | 7 +++++++ - 3 files changed, 9 insertions(+) - -diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c -index 2c454568a607c..2925371d230da 100644 ---- a/drivers/gpu/drm/drm_atomic.c -+++ b/drivers/gpu/drm/drm_atomic.c -@@ -724,6 +724,7 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, - drm_get_color_encoding_name(state->color_encoding)); - drm_printf(p, "\tcolor-range=%s\n", - drm_get_color_range_name(state->color_range)); -+ drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed); - - if (plane->funcs->atomic_print_state) - plane->funcs->atomic_print_state(p, state); -diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c -index 784e63d70a421..25bb0859fda74 100644 ---- a/drivers/gpu/drm/drm_atomic_state_helper.c -+++ b/drivers/gpu/drm/drm_atomic_state_helper.c -@@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, - state->fence = NULL; - state->commit = NULL; - state->fb_damage_clips = NULL; -+ state->color_mgmt_changed = false; - } - EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); - -diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h -index 51291983ea445..52c3287da0daa 100644 ---- a/include/drm/drm_plane.h -+++ b/include/drm/drm_plane.h -@@ -237,6 +237,13 @@ struct drm_plane_state { - - /** @state: backpointer to global drm_atomic_state */ - struct drm_atomic_state *state; -+ -+ /** -+ * @color_mgmt_changed: Color management properties have changed. Used -+ * by the atomic helpers and drivers to steer the atomic commit control -+ * flow. -+ */ -+ bool color_mgmt_changed : 1; - }; - - static inline struct drm_rect --- -2.40.1 - - -From 92c38e005f574eac3d0461d400606f1c4649a785 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Wed, 29 Mar 2023 11:30:31 -0400 -Subject: [PATCH 22/59] drm/amd/display: fix segment distribution for linear - LUTs - -The region and segment calculation was incapable of dealing -with regions of more than 16 segments. We first fix this. - -Now that we can support regions up to 256 elements we can -define a better segment distribution for near-linear LUTs -for our maximum of 256 HW-supported points. - -With these changes an "identity" LUT looks visually -indistinguishable from bypass and allows us to use -our 3DLUT. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/dc/dcn10/dcn10_cm_common.c | 95 +++++++++++++++---- - 1 file changed, 76 insertions(+), 19 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -index 7a00fe525dfba..f27413e942801 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -@@ -346,20 +346,37 @@ bool cm_helper_translate_curve_to_hw_format( - * segment is from 2^-10 to 2^1 - * There are less than 256 points, for optimization - */ -- seg_distr[0] = 3; -- seg_distr[1] = 4; -- seg_distr[2] = 4; -- seg_distr[3] = 4; -- seg_distr[4] = 4; -- seg_distr[5] = 4; -- seg_distr[6] = 4; -- seg_distr[7] = 4; -- seg_distr[8] = 4; -- seg_distr[9] = 4; -- seg_distr[10] = 1; -- -- region_start = -10; -- region_end = 1; -+ if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) { -+ seg_distr[0] = 0; /* 2 */ -+ seg_distr[1] = 1; /* 4 */ -+ seg_distr[2] = 2; /* 4 */ -+ seg_distr[3] = 3; /* 8 */ -+ seg_distr[4] = 4; /* 16 */ -+ seg_distr[5] = 5; /* 32 */ -+ seg_distr[6] = 6; /* 64 */ -+ seg_distr[7] = 7; /* 128 */ -+ -+ region_start = -8; -+ region_end = 1; -+ } else { -+ seg_distr[0] = 3; /* 8 */ -+ seg_distr[1] = 4; /* 16 */ -+ seg_distr[2] = 4; -+ seg_distr[3] = 4; -+ seg_distr[4] = 4; -+ seg_distr[5] = 4; -+ seg_distr[6] = 4; -+ seg_distr[7] = 4; -+ seg_distr[8] = 4; -+ seg_distr[9] = 4; -+ seg_distr[10] = 1; /* 2 */ -+ /* total = 8*16 + 8 + 64 + 2 = */ -+ -+ region_start = -10; -+ region_end = 1; -+ } -+ -+ - } - - for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) -@@ -372,16 +389,56 @@ bool cm_helper_translate_curve_to_hw_format( - - j = 0; - for (k = 0; k < (region_end - region_start); k++) { -- increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); -+ /* -+ * We're using an ugly-ish hack here. Our HW allows for -+ * 256 segments per region but SW_SEGMENTS is 16. -+ * SW_SEGMENTS has some undocumented relationship to -+ * the number of points in the tf_pts struct, which -+ * is 512, unlike what's suggested TRANSFER_FUNC_POINTS. -+ * -+ * In order to work past this dilemma we'll scale our -+ * increment by (1 << 4) and then do the inverse (1 >> 4) -+ * when accessing the elements in tf_pts. -+ * -+ * TODO: find a better way using SW_SEGMENTS and -+ * TRANSFER_FUNC_POINTS definitions -+ */ -+ increment = (NUMBER_SW_SEGMENTS << 4) / (1 << seg_distr[k]); - start_index = (region_start + k + MAX_LOW_POINT) * - NUMBER_SW_SEGMENTS; -- for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; -+ for (i = (start_index << 4); i < (start_index << 4) + (NUMBER_SW_SEGMENTS << 4); - i += increment) { -+ struct fixed31_32 in_plus_one, in; -+ struct fixed31_32 value, red_value, green_value, blue_value; -+ uint32_t t = i & 0xf; -+ - if (j == hw_points - 1) - break; -- rgb_resulted[j].red = output_tf->tf_pts.red[i]; -- rgb_resulted[j].green = output_tf->tf_pts.green[i]; -- rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; -+ -+ in_plus_one = output_tf->tf_pts.red[(i >> 4) + 1]; -+ in = output_tf->tf_pts.red[i >> 4]; -+ value = dc_fixpt_sub(in_plus_one, in); -+ value = dc_fixpt_shr(dc_fixpt_mul_int(value, t), 4); -+ value = dc_fixpt_add(in, value); -+ red_value = value; -+ -+ in_plus_one = output_tf->tf_pts.green[(i >> 4) + 1]; -+ in = output_tf->tf_pts.green[i >> 4]; -+ value = dc_fixpt_sub(in_plus_one, in); -+ value = dc_fixpt_shr(dc_fixpt_mul_int(value, t), 4); -+ value = dc_fixpt_add(in, value); -+ green_value = value; -+ -+ in_plus_one = output_tf->tf_pts.blue[(i >> 4) + 1]; -+ in = output_tf->tf_pts.blue[i >> 4]; -+ value = dc_fixpt_sub(in_plus_one, in); -+ value = dc_fixpt_shr(dc_fixpt_mul_int(value, t), 4); -+ value = dc_fixpt_add(in, value); -+ blue_value = value; -+ -+ rgb_resulted[j].red = red_value; -+ rgb_resulted[j].green = green_value; -+ rgb_resulted[j].blue = blue_value; - j++; - } - } --- -2.40.1 - - -From daa6f9f1521c43a419cd4bf30eaed63408c9d497 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Thu, 6 Apr 2023 18:06:27 -0400 -Subject: [PATCH 23/59] drm/amd/display: fix the delta clamping for shaper LUT - -The shaper LUT requires a 10-bit value of the delta between -segments. We were using dc_fixpt_clamp_u0d10() to do that -but it doesn't do what we want it to do. It will preserve -10-bit precision after the decimal point, but that's not -quite what we want. We want 14-bit precision and discard -the 4 most-significant bytes. - -To do that we'll do dc_fixpt_clamp_u0d14() & 0x3ff instead. - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -index f27413e942801..efa6cee649d0a 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -@@ -539,10 +539,18 @@ bool cm_helper_translate_curve_to_hw_format( - rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); - rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); - -+ - if (fixpoint == true) { -- rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red); -- rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green); -- rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue); -+ uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red); -+ uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green); -+ uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue); -+ -+ if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10) -+ DC_LOG_WARNING("Losing delta precision while programming shaper LUT."); -+ -+ rgb->delta_red_reg = red_clamp & 0x3ff; -+ rgb->delta_green_reg = green_clamp & 0x3ff; -+ rgb->delta_blue_reg = blue_clamp & 0x3ff; - rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red); - rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green); - rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue); --- -2.40.1 - - -From ecd0e951362b05025bb49ba9fdf9ec8ef58da1a4 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 22 May 2023 14:21:23 -0100 -Subject: [PATCH 24/59] drm/amd/display: add CRTC driver-specific property for - gamma TF - -Hook up driver-specific atomic operations for managing AMD color -properties and create AMD driver-specific color management properties -and attach them according to HW capabilities defined by `struct -dc_color_caps`. Add enumerated transfer function property to DRM CRTC -gamma to convert to wire encoding with or without a user gamma LUT. -Enumerated TFs are not supported yet by the DRM color pipeline, -therefore, create a DRM enum list with the predefined TFs supported by -the AMD display driver. - -Co-developed-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 36 ++++++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 8 +++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 22 ++++++ - .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 72 ++++++++++++++++++- - 4 files changed, 137 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index d60fe7eb5579a..73a1ce45ad4ce 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1248,6 +1248,38 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, - return &amdgpu_fb->base; - } - -+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = { -+ { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" }, -+ { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" }, -+ { DRM_TRANSFER_FUNCTION_BT709, "BT.709" }, -+ { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" }, -+ { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" }, -+ { DRM_TRANSFER_FUNCTION_UNITY, "Unity" }, -+ { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, -+}; -+ -+#ifdef AMD_PRIVATE_COLOR -+static int -+amdgpu_display_create_color_properties(struct amdgpu_device *adev) -+{ -+ struct drm_property *prop; -+ -+ prop = drm_property_create_enum(adev_to_drm(adev), -+ DRM_MODE_PROP_ENUM, -+ "AMD_REGAMMA_TF", -+ drm_transfer_function_enum_list, -+ ARRAY_SIZE(drm_transfer_function_enum_list)); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.regamma_tf_property = prop; -+ -+ return 0; -+} -+#endif -+ - const struct drm_mode_config_funcs amdgpu_mode_funcs = { - .fb_create = amdgpu_display_user_framebuffer_create, - }; -@@ -1324,6 +1356,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev) - return -ENOMEM; - } - -+#ifdef AMD_PRIVATE_COLOR -+ if (amdgpu_display_create_color_properties(adev)) -+ return -ENOMEM; -+#endif - return 0; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 32fe05c810c6f..156067c53c21a 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -343,6 +343,14 @@ struct amdgpu_mode_info { - int disp_priority; - const struct amdgpu_display_funcs *funcs; - const enum drm_plane_type *plane_type; -+ -+ /* Driver-private color mgmt props */ -+ -+ /* @regamma_tf_property: Transfer function for CRTC regamma -+ * (post-blending). Possible values are defined by `enum -+ * drm_transfer_function`. -+ */ -+ struct drm_property *regamma_tf_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index 2e2413fd73a4f..ad5ee28b83dcd 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -699,6 +699,20 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status, - - extern const struct amdgpu_ip_block_version dm_ip_block; - -+enum drm_transfer_function { -+ DRM_TRANSFER_FUNCTION_DEFAULT, -+ DRM_TRANSFER_FUNCTION_SRGB, -+ DRM_TRANSFER_FUNCTION_BT709, -+ DRM_TRANSFER_FUNCTION_PQ, -+ DRM_TRANSFER_FUNCTION_LINEAR, -+ DRM_TRANSFER_FUNCTION_UNITY, -+ DRM_TRANSFER_FUNCTION_HLG, -+ DRM_TRANSFER_FUNCTION_GAMMA22, -+ DRM_TRANSFER_FUNCTION_GAMMA24, -+ DRM_TRANSFER_FUNCTION_GAMMA26, -+ DRM_TRANSFER_FUNCTION_MAX, -+}; -+ - struct dm_plane_state { - struct drm_plane_state base; - struct dc_plane_state *dc_state; -@@ -726,6 +740,14 @@ struct dm_crtc_state { - struct dc_info_packet vrr_infopacket; - - int abm_level; -+ -+ /** -+ * @regamma_tf: -+ * -+ * Pre-defined transfer function for converting internal FB -> wire -+ * encoding. -+ */ -+ enum drm_transfer_function regamma_tf; - }; - - #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base) -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index 440fc0869a34b..4a725aeef3e84 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -@@ -219,7 +219,6 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc, - if (cur->stream) - dc_stream_release(cur->stream); - -- - __drm_atomic_helper_crtc_destroy_state(state); - - -@@ -253,6 +252,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc) - state->freesync_config = cur->freesync_config; - state->cm_has_degamma = cur->cm_has_degamma; - state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; -+ state->regamma_tf = cur->regamma_tf; - state->crc_skip_count = cur->crc_skip_count; - state->mpo_requested = cur->mpo_requested; - /* TODO Duplicate dc_stream after objects are stream object is flattened */ -@@ -289,6 +289,69 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc) - } - #endif - -+#ifdef AMD_PRIVATE_COLOR -+/** -+ * drm_crtc_additional_color_mgmt - enable additional color properties -+ * @crtc: DRM CRTC -+ * -+ * This function lets the driver enable the 3D LUT color correction property -+ * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper -+ * LUT and 3D LUT property is only attached if its size is not 0. -+ */ -+static void -+dm_crtc_additional_color_mgmt(struct drm_crtc *crtc) -+{ -+ struct amdgpu_device *adev = drm_to_adev(crtc->dev); -+ -+ if(adev->dm.dc->caps.color.mpc.ogam_ram) -+ drm_object_attach_property(&crtc->base, -+ adev->mode_info.regamma_tf_property, -+ DRM_TRANSFER_FUNCTION_DEFAULT); -+} -+ -+static int -+amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc, -+ struct drm_crtc_state *state, -+ struct drm_property *property, -+ uint64_t val) -+{ -+ struct amdgpu_device *adev = drm_to_adev(crtc->dev); -+ struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state); -+ -+ if (property == adev->mode_info.regamma_tf_property) { -+ if (acrtc_state->regamma_tf != val) { -+ acrtc_state->regamma_tf = val; -+ acrtc_state->base.color_mgmt_changed |= 1; -+ } -+ } else { -+ drm_dbg_atomic(crtc->dev, -+ "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n", -+ crtc->base.id, crtc->name, -+ property->base.id, property->name); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc, -+ const struct drm_crtc_state *state, -+ struct drm_property *property, -+ uint64_t *val) -+{ -+ struct amdgpu_device *adev = drm_to_adev(crtc->dev); -+ struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state); -+ -+ if (property == adev->mode_info.regamma_tf_property) -+ *val = acrtc_state->regamma_tf; -+ else -+ return -EINVAL; -+ -+ return 0; -+} -+#endif -+ - /* Implemented only the options currently available for the driver */ - static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { - .reset = dm_crtc_reset_state, -@@ -307,6 +370,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { - #if defined(CONFIG_DEBUG_FS) - .late_register = amdgpu_dm_crtc_late_register, - #endif -+#ifdef AMD_PRIVATE_COLOR -+ .atomic_set_property = amdgpu_dm_atomic_crtc_set_property, -+ .atomic_get_property = amdgpu_dm_atomic_crtc_get_property, -+#endif - }; - - static void dm_crtc_helper_disable(struct drm_crtc *crtc) -@@ -470,6 +537,9 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, - - drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); - -+#ifdef AMD_PRIVATE_COLOR -+ dm_crtc_additional_color_mgmt(&acrtc->base); -+#endif - return 0; - - fail: --- -2.40.1 - - -From 74f4e9d658f61f4aef5ecd79dbfcfb9cd8262353 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Tue, 16 May 2023 14:55:28 -0100 -Subject: [PATCH 25/59] drm/amd/display: add plane driver-specific properties - for degamma LUT - -Create and attach driver-private properties for plane color management. -First add plane degamma LUT properties that means user-blob and its -size. We will add more plane color properties in the next commits. In -addition, we keep these driver-private plane properties limited by -defining AMD_PRIVATE_COLOR. - -Co-developed-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 ++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 8 ++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 +++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 77 +++++++++++++++++++ - 4 files changed, 108 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 73a1ce45ad4ce..eb13ac46da7b2 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1276,6 +1276,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.regamma_tf_property = prop; - -+ prop = drm_property_create(adev_to_drm(adev), -+ DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_DEGAMMA_LUT", 0); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_degamma_lut_property = prop; -+ -+ prop = drm_property_create_range(adev_to_drm(adev), -+ DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_degamma_lut_size_property = prop; -+ - return 0; - } - #endif -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 156067c53c21a..f420799e38593 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -351,6 +351,14 @@ struct amdgpu_mode_info { - * drm_transfer_function`. - */ - struct drm_property *regamma_tf_property; -+ /* @plane_degamma_lut_property: Plane property to set a degamma LUT to -+ * convert color space before blending. -+ */ -+ struct drm_property *plane_degamma_lut_property; -+ /* @plane_degamma_lut_size_property: Plane property to define the max -+ * size of degamma LUT as supported by the driver (read-only). -+ */ -+ struct drm_property *plane_degamma_lut_size_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index ad5ee28b83dcd..22e1266547676 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -716,6 +716,15 @@ enum drm_transfer_function { - struct dm_plane_state { - struct drm_plane_state base; - struct dc_plane_state *dc_state; -+ -+ /* Plane color mgmt */ -+ /** -+ * @degamma_lut: -+ * -+ * LUT for converting plane pixel data before going into plane merger. -+ * The blob (if not NULL) is an array of &struct drm_color_lut. -+ */ -+ struct drm_property_blob *degamma_lut; - }; - - struct dm_crtc_state { -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index 3226689737479..e9cedc4068f13 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1338,6 +1338,9 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - dc_plane_state_retain(dm_plane_state->dc_state); - } - -+ if (dm_plane_state->degamma_lut) -+ drm_property_blob_get(dm_plane_state->degamma_lut); -+ - return &dm_plane_state->base; - } - -@@ -1405,12 +1408,79 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, - { - struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); - -+ if (dm_plane_state->degamma_lut) -+ drm_property_blob_put(dm_plane_state->degamma_lut); -+ - if (dm_plane_state->dc_state) - dc_plane_state_release(dm_plane_state->dc_state); - - drm_atomic_helper_plane_destroy_state(plane, state); - } - -+#ifdef AMD_PRIVATE_COLOR -+static void -+dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, -+ struct drm_plane *plane) -+{ -+ if (dm->dc->caps.color.dpp.dgam_ram || dm->dc->caps.color.dpp.gamma_corr ) { -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_degamma_lut_property, 0); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_degamma_lut_size_property, -+ MAX_COLOR_LUT_ENTRIES); -+ } -+} -+ -+static int -+dm_atomic_plane_set_property(struct drm_plane *plane, -+ struct drm_plane_state *state, -+ struct drm_property *property, -+ uint64_t val) -+{ -+ struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); -+ struct amdgpu_device *adev = drm_to_adev(plane->dev); -+ bool replaced = false; -+ int ret; -+ -+ if (property == adev->mode_info.plane_degamma_lut_property) { -+ ret = drm_property_replace_blob_from_id(plane->dev, -+ &dm_plane_state->degamma_lut, -+ val, -+ -1, sizeof(struct drm_color_lut), -+ &replaced); -+ dm_plane_state->base.color_mgmt_changed |= replaced; -+ return ret; -+ } else { -+ drm_dbg_atomic(plane->dev, -+ "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", -+ plane->base.id, plane->name, -+ property->base.id, property->name); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+dm_atomic_plane_get_property(struct drm_plane *plane, -+ const struct drm_plane_state *state, -+ struct drm_property *property, -+ uint64_t *val) -+{ -+ struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); -+ struct amdgpu_device *adev = drm_to_adev(plane->dev); -+ -+ if (property == adev->mode_info.plane_degamma_lut_property) { -+ *val = (dm_plane_state->degamma_lut) ? -+ dm_plane_state->degamma_lut->base.id : 0; -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+#endif -+ - static const struct drm_plane_funcs dm_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, -@@ -1419,6 +1489,10 @@ static const struct drm_plane_funcs dm_plane_funcs = { - .atomic_duplicate_state = dm_drm_plane_duplicate_state, - .atomic_destroy_state = dm_drm_plane_destroy_state, - .format_mod_supported = dm_plane_format_mod_supported, -+#ifdef AMD_PRIVATE_COLOR -+ .atomic_set_property = dm_atomic_plane_set_property, -+ .atomic_get_property = dm_atomic_plane_get_property, -+#endif - }; - - int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, -@@ -1489,6 +1563,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, - - drm_plane_helper_add(plane, &dm_plane_helper_funcs); - -+#ifdef AMD_PRIVATE_COLOR -+ dm_atomic_plane_attach_color_mgmt_properties(dm, plane); -+#endif - /* Create (reset) the plane state */ - if (plane->funcs->reset) - plane->funcs->reset(plane); --- -2.40.1 - - -From c80fcb0d0c947c741a5f93c9d5a774b6a45097c1 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 20 Apr 2023 15:07:34 -0100 -Subject: [PATCH 26/59] drm/amd/display: add plane degamma TF driver-specific - property - -Allow userspace to tell the kernel driver the input space and, -therefore, uses correct predefined transfer function (TF) to delinearize -content with or without LUT. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 9 ++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 5 +++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 ++++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 32 +++++++++++++++++-- - 4 files changed, 51 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index eb13ac46da7b2..7b63812b27e28 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1290,6 +1290,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_degamma_lut_size_property = prop; - -+ prop = drm_property_create_enum(adev_to_drm(adev), -+ DRM_MODE_PROP_ENUM, -+ "AMD_PLANE_DEGAMMA_TF", -+ drm_transfer_function_enum_list, -+ ARRAY_SIZE(drm_transfer_function_enum_list)); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_degamma_tf_property = prop; -+ - return 0; - } - #endif -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index f420799e38593..58cc91ec3100d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -359,6 +359,11 @@ struct amdgpu_mode_info { - * size of degamma LUT as supported by the driver (read-only). - */ - struct drm_property *plane_degamma_lut_size_property; -+ /** -+ * @plane_degamma_tf_property: Predefined transfer function to -+ * linearize content with or without LUT. -+ */ -+ struct drm_property *plane_degamma_tf_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index 22e1266547676..b8e432cc80781 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -725,6 +725,13 @@ struct dm_plane_state { - * The blob (if not NULL) is an array of &struct drm_color_lut. - */ - struct drm_property_blob *degamma_lut; -+ /** -+ * @degamma_tf: -+ * -+ * Predefined transfer function to tell DC driver the input space to -+ * linearize. -+ */ -+ enum drm_transfer_function degamma_tf; - }; - - struct dm_crtc_state { -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index e9cedc4068f13..6b71777a525ce 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1317,8 +1317,11 @@ static void dm_drm_plane_reset(struct drm_plane *plane) - amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); - WARN_ON(amdgpu_state == NULL); - -- if (amdgpu_state) -- __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); -+ if (!amdgpu_state) -+ return; -+ -+ __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); -+ amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT; - } - - static struct drm_plane_state * -@@ -1341,6 +1344,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - if (dm_plane_state->degamma_lut) - drm_property_blob_get(dm_plane_state->degamma_lut); - -+ dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; -+ - return &dm_plane_state->base; - } - -@@ -1417,6 +1422,19 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, - drm_atomic_helper_plane_destroy_state(plane, state); - } - -+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = { -+ { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" }, -+ { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" }, -+ { DRM_TRANSFER_FUNCTION_BT709, "BT.709" }, -+ { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" }, -+ { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" }, -+ { DRM_TRANSFER_FUNCTION_UNITY, "Unity" }, -+ { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" }, -+ { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, -+}; -+ - #ifdef AMD_PRIVATE_COLOR - static void - dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, -@@ -1428,6 +1446,9 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - drm_object_attach_property(&plane->base, - dm->adev->mode_info.plane_degamma_lut_size_property, - MAX_COLOR_LUT_ENTRIES); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_degamma_tf_property, -+ DRM_TRANSFER_FUNCTION_DEFAULT); - } - } - -@@ -1450,6 +1471,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - &replaced); - dm_plane_state->base.color_mgmt_changed |= replaced; - return ret; -+ } else if (property == adev->mode_info.plane_degamma_tf_property) { -+ if (dm_plane_state->degamma_tf != val) { -+ dm_plane_state->degamma_tf = val; -+ dm_plane_state->base.color_mgmt_changed = 1; -+ } - } else { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", -@@ -1473,6 +1499,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - if (property == adev->mode_info.plane_degamma_lut_property) { - *val = (dm_plane_state->degamma_lut) ? - dm_plane_state->degamma_lut->base.id : 0; -+ } else if (property == adev->mode_info.plane_degamma_tf_property) { -+ *val = dm_plane_state->degamma_tf; - } else { - return -EINVAL; - } --- -2.40.1 - - -From ce5029c84e4232375be266d960c101581047476a Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 20 Apr 2023 15:33:22 -0100 -Subject: [PATCH 27/59] drm/amd/display: add plane HDR multiplier - driver-specific property - -Multiplier to 'gain' the plane. When PQ is decoded using the fixed func -transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at -least) When sRGB is decoded, 1.0 -> 1.0. Therefore, 1.0 multiplier = 80 -nits for SDR content. So if you want, 203 nits for SDR content, pass in -(203.0 / 80.0). - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 6 ++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 4 ++++ - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 ++++++++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 13 +++++++++++++ - 4 files changed, 35 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 7b63812b27e28..3002128980077 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1299,6 +1299,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_degamma_tf_property = prop; - -+ prop = drm_property_create_range(adev_to_drm(adev), -+ 0, "AMD_PLANE_HDR_MULT", 0, U64_MAX); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_hdr_mult_property = prop; -+ - return 0; - } - #endif -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 58cc91ec3100d..899708f1e7d85 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -364,6 +364,10 @@ struct amdgpu_mode_info { - * linearize content with or without LUT. - */ - struct drm_property *plane_degamma_tf_property; -+ /** -+ * @plane_hdr_mult_property: -+ */ -+ struct drm_property *plane_hdr_mult_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index b8e432cc80781..dadbef561606d 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -51,6 +51,7 @@ - - #define AMDGPU_DMUB_NOTIFICATION_MAX 5 - -+#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL) - /* - #include "include/amdgpu_dal_power_if.h" - #include "amdgpu_dm_irq.h" -@@ -732,6 +733,17 @@ struct dm_plane_state { - * linearize. - */ - enum drm_transfer_function degamma_tf; -+ /** -+ * @hdr_mult: -+ * -+ * Multiplier to 'gain' the plane. When PQ is decoded using the fixed -+ * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on -+ * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously. -+ * Therefore, 1.0 multiplier = 80 nits for SDR content. So if you -+ * want, 203 nits for SDR content, pass in (203.0 / 80.0). Format is -+ * S31.32 sign-magnitude. -+ */ -+ __u64 hdr_mult; - }; - - struct dm_crtc_state { -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index 6b71777a525ce..bbbf25dd2515b 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1322,6 +1322,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane) - - __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); - amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -+ amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; - } - - static struct drm_plane_state * -@@ -1345,6 +1346,7 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - drm_property_blob_get(dm_plane_state->degamma_lut); - - dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; -+ dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; - - return &dm_plane_state->base; - } -@@ -1450,6 +1452,10 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - dm->adev->mode_info.plane_degamma_tf_property, - DRM_TRANSFER_FUNCTION_DEFAULT); - } -+ /* HDR MULT is always available */ -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_hdr_mult_property, -+ AMDGPU_HDR_MULT_DEFAULT); - } - - static int -@@ -1476,6 +1482,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - dm_plane_state->degamma_tf = val; - dm_plane_state->base.color_mgmt_changed = 1; - } -+ } else if (property == adev->mode_info.plane_hdr_mult_property) { -+ if (dm_plane_state->hdr_mult != val) { -+ dm_plane_state->hdr_mult = val; -+ dm_plane_state->base.color_mgmt_changed = 1; -+ } - } else { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", -@@ -1501,6 +1512,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - dm_plane_state->degamma_lut->base.id : 0; - } else if (property == adev->mode_info.plane_degamma_tf_property) { - *val = dm_plane_state->degamma_tf; -+ } else if (property == adev->mode_info.plane_hdr_mult_property) { -+ *val = dm_plane_state->hdr_mult; - } else { - return -EINVAL; - } --- -2.40.1 - - -From c14719939780ba3ba812011a4e2d5c56218a633e Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Thu, 20 Apr 2023 16:03:11 -0100 -Subject: [PATCH 28/59] drm/amd/display: add plane 3D LUT driver-specific - properties - -Add 3D LUT property for plane gamma correction using a 3D lookup table. -Since a 3D LUT has a limited number of entries in each dimension we want -to use them in an optimal fashion. This means using the 3D LUT in a -colorspace that is optimized for human vision, such as sRGB, PQ, or -another non-linear space. Therefore, userpace may need one 1D LUT -(shaper) before it to delinearize content and another 1D LUT after 3D -LUT (blend) to linearize content again for blending. The next patches -add these 1D LUTs to the plane color mgmt pipeline. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 +++++++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 10 ++++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 ++++++++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 23 +++++++++++++++++++ - 4 files changed, 56 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 3002128980077..3b4b01ee9f07f 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1305,6 +1305,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_hdr_mult_property = prop; - -+ prop = drm_property_create(adev_to_drm(adev), -+ DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_LUT3D", 0); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_lut3d_property = prop; -+ -+ prop = drm_property_create_range(adev_to_drm(adev), -+ DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_lut3d_size_property = prop; -+ - return 0; - } - #endif -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 899708f1e7d85..cde06717360a0 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -368,6 +368,16 @@ struct amdgpu_mode_info { - * @plane_hdr_mult_property: - */ - struct drm_property *plane_hdr_mult_property; -+ /** -+ * @plane_lut3d_property: Plane property for gamma correction using a -+ * 3D LUT (pre-blending). -+ */ -+ struct drm_property *plane_lut3d_property; -+ /** -+ * @plane_degamma_lut_size_property: Plane property to define the max -+ * size of 3D LUT as supported by the driver (read-only). -+ */ -+ struct drm_property *plane_lut3d_size_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index dadbef561606d..7e4978c2f2538 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -744,6 +744,11 @@ struct dm_plane_state { - * S31.32 sign-magnitude. - */ - __u64 hdr_mult; -+ /** -+ * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of -+ * &struct drm_color_lut. -+ */ -+ struct drm_property_blob *lut3d; - }; - - struct dm_crtc_state { -@@ -837,6 +842,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector, - - void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); - -+/* 3D LUT max size is 17x17x17 */ -+#define MAX_COLOR_3DLUT_ENTRIES 4913 -+#define MAX_COLOR_3DLUT_BITDEPTH 12 -+/* 1D LUT size */ - #define MAX_COLOR_LUT_ENTRIES 4096 - /* Legacy gamm LUT users such as X doesn't like large LUT sizes */ - #define MAX_COLOR_LEGACY_LUT_ENTRIES 256 -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index bbbf25dd2515b..5fc3855448d04 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1344,6 +1344,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - - if (dm_plane_state->degamma_lut) - drm_property_blob_get(dm_plane_state->degamma_lut); -+ if (dm_plane_state->lut3d) -+ drm_property_blob_get(dm_plane_state->lut3d); - - dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; - dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; -@@ -1417,6 +1419,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, - - if (dm_plane_state->degamma_lut) - drm_property_blob_put(dm_plane_state->degamma_lut); -+ if (dm_plane_state->lut3d) -+ drm_property_blob_put(dm_plane_state->lut3d); - - if (dm_plane_state->dc_state) - dc_plane_state_release(dm_plane_state->dc_state); -@@ -1456,6 +1460,14 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - drm_object_attach_property(&plane->base, - dm->adev->mode_info.plane_hdr_mult_property, - AMDGPU_HDR_MULT_DEFAULT); -+ -+ if (dm->dc->caps.color.dpp.hw_3d_lut) { -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_lut3d_property, 0); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_lut3d_size_property, -+ MAX_COLOR_3DLUT_ENTRIES); -+ } - } - - static int -@@ -1487,6 +1499,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - dm_plane_state->hdr_mult = val; - dm_plane_state->base.color_mgmt_changed = 1; - } -+ } else if (property == adev->mode_info.plane_lut3d_property) { -+ ret = drm_property_replace_blob_from_id(plane->dev, -+ &dm_plane_state->lut3d, -+ val, -1, -+ sizeof(struct drm_color_lut), -+ &replaced); -+ dm_plane_state->base.color_mgmt_changed |= replaced; -+ return ret; - } else { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", -@@ -1514,6 +1534,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - *val = dm_plane_state->degamma_tf; - } else if (property == adev->mode_info.plane_hdr_mult_property) { - *val = dm_plane_state->hdr_mult; -+ } else if (property == adev->mode_info.plane_lut3d_property) { -+ *val = (dm_plane_state->lut3d) ? -+ dm_plane_state->lut3d->base.id : 0; - } else { - return -EINVAL; - } --- -2.40.1 - - -From 433312a60d8b1c2a4df7e66d56b7e90cdeeea15f Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Thu, 20 Apr 2023 16:30:39 -0100 -Subject: [PATCH 29/59] drm/amd/display: add plane shaper LUT driver-specific - properties - -On AMD HW, 3D LUT always assumes a preceding shaper 1D LUT used for -delinearizing and/or normalizing the color space before applying a 3D -LUT. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 +++++++++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 10 ++++++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 5 +++++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 +++++++++++++++++++ - 4 files changed, 49 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 3b4b01ee9f07f..891cf16ebfa06 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1305,6 +1305,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_hdr_mult_property = prop; - -+ prop = drm_property_create(adev_to_drm(adev), -+ DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_SHAPER_LUT", 0); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_shaper_lut_property = prop; -+ -+ prop = drm_property_create_range(adev_to_drm(adev), -+ DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_shaper_lut_size_property = prop; -+ - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, - "AMD_PLANE_LUT3D", 0); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index cde06717360a0..52dfffafe23f9 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -368,6 +368,16 @@ struct amdgpu_mode_info { - * @plane_hdr_mult_property: - */ - struct drm_property *plane_hdr_mult_property; -+ /** -+ * @shaper_lut_property: Plane property to set pre-blending shaper LUT -+ * that converts color content before 3D LUT. -+ */ -+ struct drm_property *plane_shaper_lut_property; -+ /** -+ * @shaper_lut_size_property: Plane property for the size of -+ * pre-blending shaper LUT as supported by the driver (read-only). -+ */ -+ struct drm_property *plane_shaper_lut_size_property; - /** - * @plane_lut3d_property: Plane property for gamma correction using a - * 3D LUT (pre-blending). -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index 7e4978c2f2538..fa0bb6a5c5984 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -744,6 +744,11 @@ struct dm_plane_state { - * S31.32 sign-magnitude. - */ - __u64 hdr_mult; -+ /** -+ * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an -+ * array of &struct drm_color_lut. -+ */ -+ struct drm_property_blob *shaper_lut; - /** - * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of - * &struct drm_color_lut. -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index 5fc3855448d04..abc5b9a353a03 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1344,6 +1344,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - - if (dm_plane_state->degamma_lut) - drm_property_blob_get(dm_plane_state->degamma_lut); -+ if (dm_plane_state->shaper_lut) -+ drm_property_blob_get(dm_plane_state->shaper_lut); - if (dm_plane_state->lut3d) - drm_property_blob_get(dm_plane_state->lut3d); - -@@ -1421,6 +1423,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, - drm_property_blob_put(dm_plane_state->degamma_lut); - if (dm_plane_state->lut3d) - drm_property_blob_put(dm_plane_state->lut3d); -+ if (dm_plane_state->shaper_lut) -+ drm_property_blob_put(dm_plane_state->shaper_lut); - - if (dm_plane_state->dc_state) - dc_plane_state_release(dm_plane_state->dc_state); -@@ -1462,6 +1466,11 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - AMDGPU_HDR_MULT_DEFAULT); - - if (dm->dc->caps.color.dpp.hw_3d_lut) { -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_shaper_lut_property, 0); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_shaper_lut_size_property, -+ MAX_COLOR_LUT_ENTRIES); - drm_object_attach_property(&plane->base, - dm->adev->mode_info.plane_lut3d_property, 0); - drm_object_attach_property(&plane->base, -@@ -1499,6 +1508,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - dm_plane_state->hdr_mult = val; - dm_plane_state->base.color_mgmt_changed = 1; - } -+ } else if (property == adev->mode_info.plane_shaper_lut_property) { -+ ret = drm_property_replace_blob_from_id(plane->dev, -+ &dm_plane_state->shaper_lut, -+ val, -1, -+ sizeof(struct drm_color_lut), -+ &replaced); -+ dm_plane_state->base.color_mgmt_changed |= replaced; -+ return ret; - } else if (property == adev->mode_info.plane_lut3d_property) { - ret = drm_property_replace_blob_from_id(plane->dev, - &dm_plane_state->lut3d, -@@ -1534,6 +1551,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - *val = dm_plane_state->degamma_tf; - } else if (property == adev->mode_info.plane_hdr_mult_property) { - *val = dm_plane_state->hdr_mult; -+ } else if (property == adev->mode_info.plane_shaper_lut_property) { -+ *val = (dm_plane_state->shaper_lut) ? -+ dm_plane_state->shaper_lut->base.id : 0; - } else if (property == adev->mode_info.plane_lut3d_property) { - *val = (dm_plane_state->lut3d) ? - dm_plane_state->lut3d->base.id : 0; --- -2.40.1 - - -From 3cb40107c641ef07f63ecceb40683309aee5c743 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Thu, 20 Apr 2023 16:36:46 -0100 -Subject: [PATCH 30/59] drm/amd/display: add plane shaper TF driver-private - property - -Add property to set predefined transfer function to enable delinearizing -content with or without shaper LUT. Drivers should advertize this -property acoording to HW caps. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 9 +++++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 6 ++++++ - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 6 ++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 12 ++++++++++++ - 4 files changed, 33 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 891cf16ebfa06..b267873cdddde 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1319,6 +1319,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_shaper_lut_size_property = prop; - -+ prop = drm_property_create_enum(adev_to_drm(adev), -+ DRM_MODE_PROP_ENUM, -+ "AMD_PLANE_SHAPER_TF", -+ drm_transfer_function_enum_list, -+ ARRAY_SIZE(drm_transfer_function_enum_list)); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_shaper_tf_property = prop; -+ - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, - "AMD_PLANE_LUT3D", 0); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 52dfffafe23f9..1154babd2b671 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -378,6 +378,12 @@ struct amdgpu_mode_info { - * pre-blending shaper LUT as supported by the driver (read-only). - */ - struct drm_property *plane_shaper_lut_size_property; -+ /** -+ * @plane_shaper_tf_property: Plane property to set a predefined -+ * transfer function for pre-blending shaper (before applying 3D LUT) -+ * with or without LUT. -+ */ -+ struct drm_property *plane_shaper_tf_property; - /** - * @plane_lut3d_property: Plane property for gamma correction using a - * 3D LUT (pre-blending). -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index fa0bb6a5c5984..663ffc7d648e6 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -749,6 +749,12 @@ struct dm_plane_state { - * array of &struct drm_color_lut. - */ - struct drm_property_blob *shaper_lut; -+ /** -+ * @shaper_tf: -+ * -+ * Predefined transfer function to delinearize color space. -+ */ -+ enum drm_transfer_function shaper_tf; - /** - * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of - * &struct drm_color_lut. -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index abc5b9a353a03..61e47bdecde4e 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1323,6 +1323,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane) - __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); - amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT; - amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; -+ amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT; - } - - static struct drm_plane_state * -@@ -1351,6 +1352,7 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - - dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; - dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; -+ dm_plane_state->shaper_tf = old_dm_plane_state->shaper_tf; - - return &dm_plane_state->base; - } -@@ -1471,6 +1473,9 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - drm_object_attach_property(&plane->base, - dm->adev->mode_info.plane_shaper_lut_size_property, - MAX_COLOR_LUT_ENTRIES); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_shaper_tf_property, -+ DRM_TRANSFER_FUNCTION_DEFAULT); - drm_object_attach_property(&plane->base, - dm->adev->mode_info.plane_lut3d_property, 0); - drm_object_attach_property(&plane->base, -@@ -1516,6 +1521,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - &replaced); - dm_plane_state->base.color_mgmt_changed |= replaced; - return ret; -+ } else if (property == adev->mode_info.plane_shaper_tf_property) { -+ if (dm_plane_state->shaper_tf != val) { -+ dm_plane_state->shaper_tf = val; -+ dm_plane_state->base.color_mgmt_changed = 1; -+ } - } else if (property == adev->mode_info.plane_lut3d_property) { - ret = drm_property_replace_blob_from_id(plane->dev, - &dm_plane_state->lut3d, -@@ -1554,6 +1564,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - } else if (property == adev->mode_info.plane_shaper_lut_property) { - *val = (dm_plane_state->shaper_lut) ? - dm_plane_state->shaper_lut->base.id : 0; -+ } else if (property == adev->mode_info.plane_shaper_tf_property) { -+ *val = dm_plane_state->shaper_tf; - } else if (property == adev->mode_info.plane_lut3d_property) { - *val = (dm_plane_state->lut3d) ? - dm_plane_state->lut3d->base.id : 0; --- -2.40.1 - - -From 1eb847da50db7a06c32eb6116a645f9f840e587a Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 20 Apr 2023 16:54:38 -0100 -Subject: [PATCH 31/59] drm/amd/display: add plane blend LUT and TF - driver-specific properties - -Blend 1D LUT or a predefined transfer function can be set to linearize -content before blending, so that it's positioned just before blending -planes in the AMD color mgmt pipeline, and after 3D LUT (non-linear -space). Shaper and Blend LUTs are 1D LUTs that sandwich 3D LUT. Drivers -should advertize blend properties according to HW caps. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 23 ++++++++++++ - drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 18 ++++++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 36 +++++++++++++++++++ - 4 files changed, 89 insertions(+) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index b267873cdddde..708866da78633 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1342,6 +1342,29 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - return -ENOMEM; - adev->mode_info.plane_lut3d_size_property = prop; - -+ prop = drm_property_create(adev_to_drm(adev), -+ DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_BLEND_LUT", 0); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_blend_lut_property = prop; -+ -+ prop = drm_property_create_range(adev_to_drm(adev), -+ DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_blend_lut_size_property = prop; -+ -+ prop = drm_property_create_enum(adev_to_drm(adev), -+ DRM_MODE_PROP_ENUM, -+ "AMD_PLANE_BLEND_TF", -+ drm_transfer_function_enum_list, -+ ARRAY_SIZE(drm_transfer_function_enum_list)); -+ if (!prop) -+ return -ENOMEM; -+ adev->mode_info.plane_blend_tf_property = prop; -+ - return 0; - } - #endif -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 1154babd2b671..34291cd134a1b 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -@@ -394,6 +394,24 @@ struct amdgpu_mode_info { - * size of 3D LUT as supported by the driver (read-only). - */ - struct drm_property *plane_lut3d_size_property; -+ /** -+ * @plane_blend_lut_property: Plane property for output gamma before -+ * blending. Userspace set a blend LUT to convert colors after 3D LUT -+ * conversion. It works as a post-3D LUT 1D LUT, with shaper LUT, they -+ * are sandwiching 3D LUT with two 1D LUT. -+ */ -+ struct drm_property *plane_blend_lut_property; -+ /** -+ * @plane_blend_lut_size_property: Plane property to define the max -+ * size of blend LUT as supported by the driver (read-only). -+ */ -+ struct drm_property *plane_blend_lut_size_property; -+ /** -+ * @plane_blend_tf_property: Plane property to set a predefined -+ * transfer function for pre-blending blend (before applying 3D LUT) -+ * with or without LUT. -+ */ -+ struct drm_property *plane_blend_tf_property; - }; - - #define AMDGPU_MAX_BL_LEVEL 0xFF -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index 663ffc7d648e6..ac430a23d3e14 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -760,6 +760,18 @@ struct dm_plane_state { - * &struct drm_color_lut. - */ - struct drm_property_blob *lut3d; -+ /** -+ * @blend_lut: blend lut lookup table blob. The blob (if not NULL) is an -+ * array of &struct drm_color_lut. -+ */ -+ struct drm_property_blob *blend_lut; -+ /** -+ * @blend_tf: -+ * -+ * Pre-defined transfer function for converting plane pixel data before -+ * applying blend LUT. -+ */ -+ enum drm_transfer_function blend_tf; - }; - - struct dm_crtc_state { -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index 61e47bdecde4e..ea13b49fa0215 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1324,6 +1324,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane) - amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT; - amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; - amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -+ amdgpu_state->blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT; - } - - static struct drm_plane_state * -@@ -1349,10 +1350,13 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) - drm_property_blob_get(dm_plane_state->shaper_lut); - if (dm_plane_state->lut3d) - drm_property_blob_get(dm_plane_state->lut3d); -+ if (dm_plane_state->blend_lut) -+ drm_property_blob_get(dm_plane_state->blend_lut); - - dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; - dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; - dm_plane_state->shaper_tf = old_dm_plane_state->shaper_tf; -+ dm_plane_state->blend_tf = old_dm_plane_state->blend_tf; - - return &dm_plane_state->base; - } -@@ -1427,6 +1431,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, - drm_property_blob_put(dm_plane_state->lut3d); - if (dm_plane_state->shaper_lut) - drm_property_blob_put(dm_plane_state->shaper_lut); -+ if (dm_plane_state->blend_lut) -+ drm_property_blob_put(dm_plane_state->blend_lut); - - if (dm_plane_state->dc_state) - dc_plane_state_release(dm_plane_state->dc_state); -@@ -1482,6 +1488,17 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - dm->adev->mode_info.plane_lut3d_size_property, - MAX_COLOR_3DLUT_ENTRIES); - } -+ -+ if (dm->dc->caps.color.dpp.ogam_ram) { -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_blend_lut_property, 0); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_blend_lut_size_property, -+ MAX_COLOR_LUT_ENTRIES); -+ drm_object_attach_property(&plane->base, -+ dm->adev->mode_info.plane_blend_tf_property, -+ DRM_TRANSFER_FUNCTION_DEFAULT); -+ } - } - - static int -@@ -1534,6 +1551,19 @@ dm_atomic_plane_set_property(struct drm_plane *plane, - &replaced); - dm_plane_state->base.color_mgmt_changed |= replaced; - return ret; -+ } else if (property == adev->mode_info.plane_blend_lut_property) { -+ ret = drm_property_replace_blob_from_id(plane->dev, -+ &dm_plane_state->blend_lut, -+ val, -1, -+ sizeof(struct drm_color_lut), -+ &replaced); -+ dm_plane_state->base.color_mgmt_changed |= replaced; -+ return ret; -+ } else if (property == adev->mode_info.plane_blend_tf_property) { -+ if (dm_plane_state->blend_tf != val) { -+ dm_plane_state->blend_tf = val; -+ dm_plane_state->base.color_mgmt_changed = 1; -+ } - } else { - drm_dbg_atomic(plane->dev, - "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", -@@ -1569,6 +1599,12 @@ dm_atomic_plane_get_property(struct drm_plane *plane, - } else if (property == adev->mode_info.plane_lut3d_property) { - *val = (dm_plane_state->lut3d) ? - dm_plane_state->lut3d->base.id : 0; -+ } else if (property == adev->mode_info.plane_blend_lut_property) { -+ *val = (dm_plane_state->blend_lut) ? -+ dm_plane_state->blend_lut->base.id : 0; -+ } else if (property == adev->mode_info.plane_blend_tf_property) { -+ *val = dm_plane_state->blend_tf; -+ - } else { - return -EINVAL; - } --- -2.40.1 - - -From b6b0b5ba464cc962394016a25a63729b684ff0da Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 22 Aug 2022 19:07:56 -0100 -Subject: [PATCH 32/59] drm/amd/display: add comments to describe DM crtc color - mgmt behavior - -Describe some expected behavior of the AMD DM color mgmt programming. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index a4cb23d059bd6..fe779d10834e7 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -440,12 +440,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) - stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; - stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; - -+ /* Note: although we pass has_rom as parameter here, we never -+ * actually use ROM because the color module only takes the ROM -+ * path if transfer_func->type == PREDEFINED. -+ * -+ * See more in mod_color_calculate_regamma_params() -+ */ - r = __set_legacy_tf(stream->out_transfer_func, regamma_lut, - regamma_size, has_rom); - if (r) - return r; - } else if (has_regamma) { -- /* If atomic regamma, CRTC RGM goes into RGM LUT. */ -+ /* CRTC RGM goes into RGM LUT. -+ * -+ * Note: there is no implicit sRGB regamma here. We are using -+ * degamma calculation from color module to calculate the curve -+ * from a linear base. -+ */ - stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; - stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; - --- -2.40.1 - - -From 48f91e65a89f55c4aafffb287f54c3531050d04d Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Thu, 9 Mar 2023 13:28:18 -0100 -Subject: [PATCH 33/59] drm/amd/display: encapsulate atomic regamma operation - -We will wire up MPC 3D LUT to DM CRTC color pipeline in the next patch, -but so far, only for atomic interface. By checking -set_output_transfer_func in DC drivers with MPC 3D LUT support, we can -verify that regamma is only programmed when 3D LUT programming fails. As -a groundwork to introduce 3D LUT programming and better understand each -step, detach atomic regamma programming from the crtc colocr updating -code. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 53 ++++++++++++------- - 1 file changed, 34 insertions(+), 19 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index fe779d10834e7..fe03f1ec326e7 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -303,6 +303,36 @@ static int __set_output_tf(struct dc_transfer_func *func, - return res ? 0 : -ENOMEM; - } - -+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, -+ const struct drm_color_lut *regamma_lut, -+ uint32_t regamma_size, bool has_rom) -+{ -+ struct dc_transfer_func *out_tf = stream->out_transfer_func; -+ int ret = 0; -+ -+ if (regamma_size) { -+ /* CRTC RGM goes into RGM LUT. -+ * -+ * Note: there is no implicit sRGB regamma here. We are using -+ * degamma calculation from color module to calculate the curve -+ * from a linear base. -+ */ -+ out_tf->type = TF_TYPE_DISTRIBUTED_POINTS; -+ out_tf->tf = TRANSFER_FUNCTION_LINEAR; -+ -+ ret = __set_output_tf(out_tf, regamma_lut, regamma_size, has_rom); -+ } else { -+ /* -+ * No CRTC RGM means we can just put the block into bypass -+ * since we don't have any plane level adjustments using it. -+ */ -+ out_tf->type = TF_TYPE_BYPASS; -+ out_tf->tf = TRANSFER_FUNCTION_LINEAR; -+ } -+ -+ return ret; -+} -+ - /** - * __set_input_tf - calculates the input transfer function based on expected - * input space. -@@ -450,27 +480,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) - regamma_size, has_rom); - if (r) - return r; -- } else if (has_regamma) { -- /* CRTC RGM goes into RGM LUT. -- * -- * Note: there is no implicit sRGB regamma here. We are using -- * degamma calculation from color module to calculate the curve -- * from a linear base. -- */ -- stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; -- stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; -- -- r = __set_output_tf(stream->out_transfer_func, regamma_lut, -- regamma_size, has_rom); -+ } else { -+ regamma_size = has_regamma ? regamma_size : 0; -+ r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut, -+ regamma_size, has_rom); - if (r) - return r; -- } else { -- /* -- * No CRTC RGM means we can just put the block into bypass -- * since we don't have any plane level adjustments using it. -- */ -- stream->out_transfer_func->type = TF_TYPE_BYPASS; -- stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; - } - - /* --- -2.40.1 - - -From 0a9956269468523d7b641df97782242c26530c7d Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Wed, 31 Aug 2022 23:39:29 -0100 -Subject: [PATCH 34/59] drm/amd/display: update lut3d and shaper lut to stream - -It follows the same path of out_transfer_func for stream updates, since -shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func() -and this function is called in the atomic commit_tail when -update_flags.bits.out_tf is set. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index 7cde67b7f0c33..da1689de5d68a 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -2606,7 +2606,7 @@ static enum surface_update_type check_update_surfaces_for_stream( - stream_update->integer_scaling_update) - su_flags->bits.scaling = 1; - -- if (stream_update->out_transfer_func) -+ if (stream_update->out_transfer_func || stream_update->lut3d_func) - su_flags->bits.out_tf = 1; - - if (stream_update->abm_level) -@@ -2955,6 +2955,14 @@ static void copy_stream_update_to_stream(struct dc *dc, - sizeof(struct dc_transfer_func_distributed_points)); - } - -+ if (update->func_shaper && -+ stream->func_shaper != update->func_shaper) -+ stream->func_shaper = update->func_shaper; -+ -+ if (update->lut3d_func && -+ stream->lut3d_func != update->lut3d_func) -+ stream->lut3d_func = update->lut3d_func; -+ - if (update->hdr_static_metadata) - stream->hdr_static_metadata = *update->hdr_static_metadata; - --- -2.40.1 - - -From c44420194f73444b8cab5e33faadc5b5e2b1f770 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 20 Dec 2022 16:29:13 -0100 -Subject: [PATCH 35/59] drm/amd/display: copy 3D LUT settings from crtc state - to stream_update - -When commiting planes, we copy color mgmt resources to the stream state. -Do the same for shaper and 3D LUTs. - -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Joshua Ashton <joshua@froggi.es> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 6deec192ae04e..7936fcb05afcc 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -8260,6 +8260,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - &acrtc_state->stream->csc_color_matrix; - bundle->stream_update.out_transfer_func = - acrtc_state->stream->out_transfer_func; -+ bundle->stream_update.lut3d_func = -+ (struct dc_3dlut *) acrtc_state->stream->lut3d_func; -+ bundle->stream_update.func_shaper = -+ (struct dc_transfer_func *) acrtc_state->stream->func_shaper; - } - - acrtc_state->stream->abm_level = acrtc_state->abm_level; --- -2.40.1 - - -From f886b44c68e1af7033ab8974eb73ab3d794b033f Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Wed, 15 Mar 2023 12:43:16 -0100 -Subject: [PATCH 36/59] drm/amd/display: allow BYPASS 3D LUT but keep shaper - LUT settings - -HW allows us to program shaper LUT without 3D LUT settings and it is -also good for testing shaper LUT behavior, therefore, DC driver should -allow acquiring both 3D and shaper LUT, but programing shaper LUT -without 3D LUT (not initialized). - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -index 32121db2851e6..fd2428871c8a9 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -@@ -113,7 +113,6 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx, - } - - if (stream->lut3d_func && -- stream->lut3d_func->state.bits.initialized == 1 && - stream->lut3d_func->state.bits.rmu_idx_valid == 1) { - if (stream->lut3d_func->state.bits.rmu_mux_num == 0) - mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux; -@@ -131,8 +130,12 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx, - if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num) - BREAK_TO_DEBUGGER(); - -- result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d, -- stream->lut3d_func->state.bits.rmu_mux_num); -+ if (stream->lut3d_func->state.bits.initialized == 1) -+ result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d, -+ stream->lut3d_func->state.bits.rmu_mux_num); -+ else -+ result = mpc->funcs->program_3dlut(mpc, NULL, -+ stream->lut3d_func->state.bits.rmu_mux_num); - result = mpc->funcs->program_shaper(mpc, shaper_lut, - stream->lut3d_func->state.bits.rmu_mux_num); - } else { --- -2.40.1 - - -From 8fd6a7323d448430a14d8e61c12069dbebcc32e6 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 5 Dec 2022 15:01:48 -0100 -Subject: [PATCH 37/59] drm/amd/display: handle MPC 3D LUT resources for a - given context - -In the original dc_acquire_release_mpc_3dlut(), only current ctx is -considered, which doesn't fit the steps for atomic checking new ctx. -Therefore, create a function to handle 3D LUT resource for a given -context, so that we can check resources availability in atomic_check -time and handle failures properly. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/dc/core/dc.c | 39 ++++++++++++++++++++++++ - drivers/gpu/drm/amd/display/dc/dc.h | 8 +++++ - 2 files changed, 47 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c -index da1689de5d68a..615d7c41f49bf 100644 ---- a/drivers/gpu/drm/amd/display/dc/core/dc.c -+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c -@@ -2123,6 +2123,45 @@ bool dc_acquire_release_mpc_3dlut( - return ret; - } - -+bool -+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc, -+ bool acquire, -+ struct dc_state *state, -+ struct dc_stream_state *stream, -+ struct dc_3dlut **lut, -+ struct dc_transfer_func **shaper) -+{ -+ int pipe_idx; -+ bool ret = false; -+ bool found_pipe_idx = false; -+ const struct resource_pool *pool = dc->res_pool; -+ struct resource_context *res_ctx = &state->res_ctx; -+ int mpcc_id = 0; -+ -+ if (pool && res_ctx) { -+ if (acquire) { -+ /*find pipe idx for the given stream*/ -+ for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) { -+ if (res_ctx->pipe_ctx[pipe_idx].stream == stream) { -+ found_pipe_idx = true; -+ mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst; -+ break; -+ } -+ } -+ } else -+ found_pipe_idx = true;/*for release pipe_idx is not required*/ -+ -+ if (found_pipe_idx) { -+ if (acquire && pool->funcs->acquire_post_bldn_3dlut) -+ ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper); -+ else if (!acquire && pool->funcs->release_post_bldn_3dlut) -+ ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper); -+ } -+ } -+ return ret; -+} -+ -+ - static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) - { - int i; -diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h -index 30f0ba05a6e6c..549ef605bb2b8 100644 ---- a/drivers/gpu/drm/amd/display/dc/dc.h -+++ b/drivers/gpu/drm/amd/display/dc/dc.h -@@ -1348,6 +1348,14 @@ bool dc_acquire_release_mpc_3dlut( - struct dc_3dlut **lut, - struct dc_transfer_func **shaper); - -+bool -+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc, -+ bool acquire, -+ struct dc_state *state, -+ struct dc_stream_state *stream, -+ struct dc_3dlut **lut, -+ struct dc_transfer_func **shaper); -+ - void dc_resource_state_copy_construct( - const struct dc_state *src_ctx, - struct dc_state *dst_ctx); --- -2.40.1 - - -From b0b4bcea109bc5fcba96c9e7447bfe0247ab3c6b Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Tue, 14 Mar 2023 15:08:34 -0100 -Subject: [PATCH 38/59] drm/amd/display: dynamically acquire 3DLUT resources - for color changes - -dc_acquire_release_mpc_3dlut_for_ctx initializes the bits required to -program 3DLUT in DC MPC hw block, applied in set_output_transfer_func(). -Since acquire/release can fail, we should check resources availability -during atomic check considering the new context created. We dynamically -acquire 3D LUT resources when we actually use them, so we don't limit -ourselves with the stream count. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 +- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 55 ++++++++++++++++++- - .../amd/display/dc/dcn301/dcn301_resource.c | 26 ++++++++- - 4 files changed, 87 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 7936fcb05afcc..97baaa674137b 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -9452,7 +9452,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, - */ - if (dm_new_crtc_state->base.color_mgmt_changed || - drm_atomic_crtc_needs_modeset(new_crtc_state)) { -- ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state); -+ if (!dm_state) { -+ ret = dm_atomic_get_state(state, &dm_state); -+ if (ret) -+ goto fail; -+ } -+ ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state, dm_state->context); - if (ret) - goto fail; - } -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index ac430a23d3e14..e5f9db5a43f47 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -875,7 +875,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); - - void amdgpu_dm_init_color_mod(void); - int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state); --int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc); -+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, -+ struct dc_state *ctx); - int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - struct dc_plane_state *dc_plane_state); - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index fe03f1ec326e7..161807e198869 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -364,6 +364,49 @@ static int __set_input_tf(struct dc_transfer_func *func, - return res ? 0 : -ENOMEM; - } - -+/* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC -+ * interface -+ * @dc: Display Core control structure -+ * @ctx: new DC state information -+ * @stream: DC stream state to set shaper LUT and 3D LUT -+ * @drm_shaper_lut: DRM CRTC (user) shaper LUT -+ * @drm_shaper_size: size of shaper LUT -+ * @drm_lut3d: DRM CRTC (user) 3D LUT -+ * @drm_lut3d_size: size of 3D LUT -+ * -+ * Returns: -+ * 0 on success. -+ */ -+static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc, -+ struct dc_state *ctx, -+ struct dc_stream_state *stream, -+ const struct drm_color_lut *drm_shaper_lut, -+ uint32_t drm_shaper_size, -+ const struct drm_color_lut *drm_lut3d, -+ uint32_t drm_lut3d_size) -+{ -+ struct dc_3dlut *lut3d_func; -+ struct dc_transfer_func *func_shaper; -+ bool acquire = drm_shaper_size || drm_lut3d_size; -+ -+ lut3d_func = (struct dc_3dlut *)stream->lut3d_func; -+ func_shaper = (struct dc_transfer_func *)stream->func_shaper; -+ -+ ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper)); -+ if ((acquire && !lut3d_func && !func_shaper) || -+ (!acquire && lut3d_func && func_shaper)) -+ { -+ if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, acquire, ctx, stream, -+ &lut3d_func, &func_shaper)) -+ return DC_ERROR_UNEXPECTED; -+ } -+ -+ stream->func_shaper = func_shaper; -+ stream->lut3d_func = lut3d_func; -+ -+ return 0; -+} -+ - /** - * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes - * @crtc_state: the DRM CRTC state -@@ -403,6 +446,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) - /** - * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream. - * @crtc: amdgpu_dm crtc state -+ * @ctx: new DC state information - * - * With no plane level color management properties we're free to use any - * of the HW blocks as long as the CRTC CTM always comes before the -@@ -422,7 +466,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) - * Returns: - * 0 on success. Error code if setup fails. - */ --int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) -+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, -+ struct dc_state *ctx) - { - struct dc_stream_state *stream = crtc->stream; - struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev); -@@ -481,6 +526,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) - if (r) - return r; - } else { -+ r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream, -+ NULL, 0, NULL, 0); -+ if (r) -+ return r; -+ /* Note: OGAM is disabled if 3D LUT is successfully programmed. -+ * See params and set_output_gamma in -+ * dcn30_set_output_transfer_func() -+ */ - regamma_size = has_regamma ? regamma_size : 0; - r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut, - regamma_size, has_rom); -diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -index 5ac2a272c380f..a6d6fcaaca1c2 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c -@@ -1258,6 +1258,30 @@ static struct display_stream_compressor *dcn301_dsc_create( - return &dsc->base; - } - -+static enum dc_status -+dcn301_remove_stream_from_ctx(struct dc *dc, -+ struct dc_state *new_ctx, -+ struct dc_stream_state *dc_stream) -+{ -+ struct dc_3dlut *lut3d_func; -+ struct dc_transfer_func *func_shaper; -+ -+ lut3d_func = (struct dc_3dlut *)dc_stream->lut3d_func; -+ func_shaper = (struct dc_transfer_func *)dc_stream->func_shaper; -+ -+ ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper)); -+ if (lut3d_func && func_shaper) -+ { -+ if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, false, new_ctx, dc_stream, -+ &lut3d_func, &func_shaper)) -+ return DC_ERROR_UNEXPECTED; -+ } -+ -+ dc_stream->lut3d_func = lut3d_func; -+ dc_stream->func_shaper = func_shaper; -+ -+ return dcn20_remove_stream_from_ctx(dc, new_ctx, dc_stream); -+} - - static void dcn301_destroy_resource_pool(struct resource_pool **pool) - { -@@ -1406,7 +1430,7 @@ static struct resource_funcs dcn301_res_pool_funcs = { - .acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer, - .add_stream_to_ctx = dcn30_add_stream_to_ctx, - .add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource, -- .remove_stream_from_ctx = dcn20_remove_stream_from_ctx, -+ .remove_stream_from_ctx = dcn301_remove_stream_from_ctx, - .populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context, - .set_mcif_arb_params = dcn30_set_mcif_arb_params, - .find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link, --- -2.40.1 - - -From 25d40859e077e977bd1a1661dc5cc1ec5c80028c Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 22 Aug 2022 22:02:09 -0100 -Subject: [PATCH 39/59] drm/amd/display: add CRTC 3D LUT support - -Wire up DC 3D LUT to DM CRTC color management (post-blending). On AMD -display HW, we have to set a shaper LUT to delinearize or normalize the -color space before applying a 3D LUT (since we have a reduced number of -LUT entries). Therefore, we map DC shaper LUT to DM CRTC color mgmt in -the next patch. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 + - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 17 ++ - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 158 +++++++++++++++++- - 3 files changed, 180 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 97baaa674137b..513cf9c557f2e 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -10018,6 +10018,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, - goto fail; - } - -+ ret = amdgpu_dm_verify_lut3d_size(adev, new_crtc_state); -+ if (ret) { -+ drm_dbg_driver(dev, "amdgpu_dm_verify_lut_sizes() failed\n"); -+ goto fail; -+ } -+ - if (!new_crtc_state->enable) - continue; - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index e5f9db5a43f47..eebe12c353ad8 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -797,6 +797,21 @@ struct dm_crtc_state { - - int abm_level; - -+ /* AMD driver-private CRTC color management -+ * -+ * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW -+ * has a larger set of post-blending color calibration. Here, DC MPC -+ * color caps are wired up to DM CRTC state: -+ */ -+ /** -+ * @lut3d: -+ * -+ * Post-blending 3D Lookup table for converting pixel data. When -+ * supported by HW (DCN 3+), it is positioned just before post-blending -+ * regamma and always assumes a preceding shaper LUT. The blob (if not -+ * NULL) is an array of &struct drm_color_lut. -+ */ -+ struct drm_property_blob *lut3d; - /** - * @regamma_tf: - * -@@ -868,6 +883,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); - /* 3D LUT max size is 17x17x17 */ - #define MAX_COLOR_3DLUT_ENTRIES 4913 - #define MAX_COLOR_3DLUT_BITDEPTH 12 -+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, -+ const struct drm_crtc_state *crtc_state); - /* 1D LUT size */ - #define MAX_COLOR_LUT_ENTRIES 4096 - /* Legacy gamm LUT users such as X doesn't like large LUT sizes */ -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 161807e198869..cef8d0d7f37b5 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -364,6 +364,96 @@ static int __set_input_tf(struct dc_transfer_func *func, - return res ? 0 : -ENOMEM; - } - -+static void __to_dc_lut3d_color(struct dc_rgb *rgb, -+ const struct drm_color_lut lut, -+ int bit_precision) -+{ -+ rgb->red = drm_color_lut_extract(lut.red, bit_precision); -+ rgb->green = drm_color_lut_extract(lut.green, bit_precision); -+ rgb->blue = drm_color_lut_extract(lut.blue, bit_precision); -+} -+ -+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut, -+ uint32_t lut3d_size, -+ struct tetrahedral_params *params, -+ bool use_tetrahedral_9, -+ int bit_depth) -+{ -+ struct dc_rgb *lut0; -+ struct dc_rgb *lut1; -+ struct dc_rgb *lut2; -+ struct dc_rgb *lut3; -+ int lut_i, i; -+ -+ -+ if (use_tetrahedral_9) { -+ lut0 = params->tetrahedral_9.lut0; -+ lut1 = params->tetrahedral_9.lut1; -+ lut2 = params->tetrahedral_9.lut2; -+ lut3 = params->tetrahedral_9.lut3; -+ } else { -+ lut0 = params->tetrahedral_17.lut0; -+ lut1 = params->tetrahedral_17.lut1; -+ lut2 = params->tetrahedral_17.lut2; -+ lut3 = params->tetrahedral_17.lut3; -+ } -+ -+ for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) { -+ /* We should consider the 3dlut RGB values are distributed -+ * along four arrays lut0-3 where the first sizes 1229 and the -+ * other 1228. The bit depth supported for 3dlut channel is -+ * 12-bit, but DC also supports 10-bit. -+ * -+ * TODO: improve color pipeline API to enable the userspace set -+ * bit depth and 3D LUT size/stride, as specified by VA-API. -+ */ -+ __to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth); -+ __to_dc_lut3d_color(&lut1[lut_i], lut[i + 1], bit_depth); -+ __to_dc_lut3d_color(&lut2[lut_i], lut[i + 2], bit_depth); -+ __to_dc_lut3d_color(&lut3[lut_i], lut[i + 3], bit_depth); -+ } -+ /* lut0 has 1229 points (lut_size/4 + 1) */ -+ __to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth); -+} -+ -+/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream -+ * @drm_lut3d: DRM CRTC (user) 3D LUT -+ * @drm_lut3d_size: size of 3D LUT -+ * @lut3d: DC 3D LUT -+ * -+ * Map DRM CRTC 3D LUT to DC 3D LUT and all necessary bits to program it -+ * on DCN MPC accordingly. -+ */ -+static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut, -+ uint32_t drm_lut3d_size, -+ struct dc_3dlut *lut) -+{ -+ if (!drm_lut3d_size) { -+ lut->state.bits.initialized = 0; -+ } else { -+ /* Stride and bit depth are not programmable by API yet. -+ * Therefore, only supports 17x17x17 3D LUT (12-bit). -+ */ -+ lut->lut_3d.use_tetrahedral_9 = false; -+ lut->lut_3d.use_12bits = true; -+ lut->state.bits.initialized = 1; -+ __drm_3dlut_to_dc_3dlut(drm_lut, drm_lut3d_size, &lut->lut_3d, -+ lut->lut_3d.use_tetrahedral_9, -+ MAX_COLOR_3DLUT_BITDEPTH); -+ } -+} -+ -+static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper) -+{ -+ /* We don't get DRM shaper LUT yet. We assume the input color space is already -+ * delinearized, so we don't need a shaper LUT and we can just BYPASS -+ */ -+ func_shaper->type = TF_TYPE_BYPASS; -+ func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -+ -+ return 0; -+} -+ - /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC - * interface - * @dc: Display Core control structure -@@ -404,6 +494,57 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc, - stream->func_shaper = func_shaper; - stream->lut3d_func = lut3d_func; - -+ if (!acquire) -+ return 0; -+ -+ amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func); -+ -+ return amdgpu_dm_atomic_shaper_lut(func_shaper); -+} -+ -+/** -+ * amdgpu_dm_lut3d_size - get expected size according to hw color caps -+ * @adev: amdgpu device -+ * @lut_size: default size -+ * -+ * Return: -+ * lut_size if DC 3D LUT is supported, zero otherwise. -+ */ -+static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev, -+ uint32_t lut_size) -+{ -+ return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0; -+} -+ -+/** -+ * amdgpu_dm_verify_lut3d_size - verifies if 3D LUT is supported and if DRM 3D -+ * LUT matches the hw supported size -+ * @adev: amdgpu device -+ * @crtc_state: the DRM CRTC state -+ * -+ * Verifies if post-blending (MPC) 3D LUT is supported by the HW (DCN 3.0 or -+ * newer) and if the DRM 3D LUT matches the supported size. -+ * -+ * Returns: -+ * 0 on success. -EINVAL if lut size are invalid. -+ */ -+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, -+ const struct drm_crtc_state *crtc_state) -+{ -+ const struct drm_color_lut *lut3d = NULL; -+ struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state); -+ uint32_t exp_size, size; -+ -+ exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES); -+ -+ lut3d = __extract_blob_lut(acrtc_state->lut3d, &size); -+ -+ if (lut3d && size != exp_size) { -+ drm_dbg(&adev->ddev, "Invalid 3D LUT size. Should be %u but got %u.\n", -+ exp_size, size); -+ return -EINVAL; -+ } -+ - return 0; - } - -@@ -478,6 +619,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - bool has_regamma, has_degamma; - bool is_legacy; - int r; -+ const struct drm_color_lut *lut3d; -+ uint32_t lut3d_size; -+ -+ r = amdgpu_dm_verify_lut3d_size(adev, &crtc->base); -+ if (r) -+ return r; -+ -+ lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size); - - r = amdgpu_dm_verify_lut_sizes(&crtc->base); - if (r) -@@ -526,10 +675,17 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - if (r) - return r; - } else { -+ /* We are not exposing CRTC 3D LUT properties yet, so DC 3D LUT -+ * programming is expected to be set to bypass mode, since -+ * there is no user-blob. -+ */ -+ lut3d_size = lut3d != NULL ? lut3d_size : 0; - r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream, -- NULL, 0, NULL, 0); -+ NULL, 0, -+ lut3d, lut3d_size); - if (r) - return r; -+ - /* Note: OGAM is disabled if 3D LUT is successfully programmed. - * See params and set_output_gamma in - * dcn30_set_output_transfer_func() --- -2.40.1 - - -From e846b1078ce3980fd36c7eeda5a87c4e1cf66c68 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 22 Aug 2022 22:08:18 -0100 -Subject: [PATCH 40/59] drm/amd/display: add CRTC shaper LUT support - -Map DC shaper LUT to DM CRTC color management. Shaper LUT can be used to -delinearize and/or normalize the color space for computational -efficiency and achiving specific visual styles. Blending usually occurs -in linear space and if a CRTC degamma 1D LUT is set to linearize the -color space, a custom shaper 1D LUT can be used just before applying 3D -LUT. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 7 +++ - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 54 ++++++++++++++----- - 2 files changed, 47 insertions(+), 14 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index eebe12c353ad8..ea76c29578483 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -803,6 +803,13 @@ struct dm_crtc_state { - * has a larger set of post-blending color calibration. Here, DC MPC - * color caps are wired up to DM CRTC state: - */ -+ /** -+ * @shaper_lut: -+ * -+ * Post-blending 1D Lookup table used to de-linearize pixel data for 3D -+ * LUT. The blob (if not NULL) is an array of &struct drm_color_lut. -+ */ -+ struct drm_property_blob *shaper_lut; - /** - * @lut3d: - * -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index cef8d0d7f37b5..934636d7b8d3f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -443,15 +443,26 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut, - } - } - --static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper) -+static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut, -+ uint32_t shaper_size, -+ struct dc_transfer_func *func_shaper) - { -- /* We don't get DRM shaper LUT yet. We assume the input color space is already -- * delinearized, so we don't need a shaper LUT and we can just BYPASS -- */ -- func_shaper->type = TF_TYPE_BYPASS; -- func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -+ int ret = 0; - -- return 0; -+ if (shaper_size) { -+ /* If DRM shaper LUT is set, we assume a linear color space -+ * (linearized by DRM degamma 1D LUT or not) -+ */ -+ func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS; -+ func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -+ -+ ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false); -+ } else { -+ func_shaper->type = TF_TYPE_BYPASS; -+ func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -+ } -+ -+ return ret; - } - - /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC -@@ -499,7 +510,8 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc, - - amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func); - -- return amdgpu_dm_atomic_shaper_lut(func_shaper); -+ return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, -+ drm_shaper_size, func_shaper); - } - - /** -@@ -531,12 +543,22 @@ static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev, - int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, - const struct drm_crtc_state *crtc_state) - { -- const struct drm_color_lut *lut3d = NULL; - struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state); -+ const struct drm_color_lut *shaper = NULL, *lut3d = NULL; - uint32_t exp_size, size; - -- exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES); -+ /* shaper LUT is only available if 3D LUT color caps*/ -+ exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_LUT_ENTRIES); -+ shaper = __extract_blob_lut(acrtc_state->shaper_lut, &size); -+ -+ if (shaper && size != exp_size) { -+ drm_dbg(&adev->ddev, -+ "Invalid Shaper LUT size. Should be %u but got %u.\n", -+ exp_size, size); -+ return -EINVAL; -+ } - -+ exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES); - lut3d = __extract_blob_lut(acrtc_state->lut3d, &size); - - if (lut3d && size != exp_size) { -@@ -618,15 +640,16 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - uint32_t degamma_size, regamma_size; - bool has_regamma, has_degamma; - bool is_legacy; -+ const struct drm_color_lut *shaper_lut, *lut3d; -+ uint32_t shaper_size, lut3d_size; - int r; -- const struct drm_color_lut *lut3d; -- uint32_t lut3d_size; - - r = amdgpu_dm_verify_lut3d_size(adev, &crtc->base); - if (r) - return r; - - lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size); -+ shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size); - - r = amdgpu_dm_verify_lut_sizes(&crtc->base); - if (r) -@@ -680,11 +703,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - * there is no user-blob. - */ - lut3d_size = lut3d != NULL ? lut3d_size : 0; -+ shaper_size = shaper_lut != NULL ? shaper_size : 0; - r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream, -- NULL, 0, -+ shaper_lut, shaper_size, - lut3d, lut3d_size); -- if (r) -+ if (r) { -+ drm_dbg(&adev->ddev, "Failed on shaper/3D LUTs setup\n"); - return r; -+ } - - /* Note: OGAM is disabled if 3D LUT is successfully programmed. - * See params and set_output_gamma in --- -2.40.1 - - -From feecbdff070930ca09d3de7a08ee6b908b800720 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Wed, 12 Apr 2023 22:17:56 -0100 -Subject: [PATCH 41/59] drm/amd/display: add CRTC regamma TF support - -Add predefined transfer function programming. There is no out gamma ROM, -but we can use AMD color modules to program LUT parameters from a -predefined TF and an empty regamma LUT (or bump up LUT parameters with -predefined TF setup). - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 58 ++++++++++++++----- - 1 file changed, 42 insertions(+), 16 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 934636d7b8d3f..146363363ef07 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -268,16 +268,18 @@ static int __set_output_tf(struct dc_transfer_func *func, - struct calculate_buffer cal_buffer = {0}; - bool res; - -- ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES); -- - cal_buffer.buffer_index = -1; - -- gamma = dc_create_gamma(); -- if (!gamma) -- return -ENOMEM; -+ if (lut_size) { -+ ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES); - -- gamma->num_entries = lut_size; -- __drm_lut_to_dc_gamma(lut, gamma, false); -+ gamma = dc_create_gamma(); -+ if (!gamma) -+ return -ENOMEM; -+ -+ gamma->num_entries = lut_size; -+ __drm_lut_to_dc_gamma(lut, gamma, false); -+ } - - if (func->tf == TRANSFER_FUNCTION_LINEAR) { - /* -@@ -285,32 +287,36 @@ static int __set_output_tf(struct dc_transfer_func *func, - * on top of a linear input. But degamma params can be used - * instead to simulate this. - */ -- gamma->type = GAMMA_CUSTOM; -+ if (gamma) -+ gamma->type = GAMMA_CUSTOM; - res = mod_color_calculate_degamma_params(NULL, func, -- gamma, true); -+ gamma, gamma != NULL); - } else { - /* - * Assume sRGB. The actual mapping will depend on whether the - * input was legacy or not. - */ -- gamma->type = GAMMA_CS_TFM_1D; -- res = mod_color_calculate_regamma_params(func, gamma, false, -+ if (gamma) -+ gamma->type = GAMMA_CS_TFM_1D; -+ res = mod_color_calculate_regamma_params(func, gamma, gamma != NULL, - has_rom, NULL, &cal_buffer); - } - -- dc_gamma_release(&gamma); -+ if (gamma) -+ dc_gamma_release(&gamma); - - return res ? 0 : -ENOMEM; - } - - static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, - const struct drm_color_lut *regamma_lut, -- uint32_t regamma_size, bool has_rom) -+ uint32_t regamma_size, bool has_rom, -+ enum dc_transfer_func_predefined tf) - { - struct dc_transfer_func *out_tf = stream->out_transfer_func; - int ret = 0; - -- if (regamma_size) { -+ if (regamma_size || tf != TRANSFER_FUNCTION_LINEAR) { - /* CRTC RGM goes into RGM LUT. - * - * Note: there is no implicit sRGB regamma here. We are using -@@ -318,7 +324,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, - * from a linear base. - */ - out_tf->type = TF_TYPE_DISTRIBUTED_POINTS; -- out_tf->tf = TRANSFER_FUNCTION_LINEAR; -+ out_tf->tf = tf; - - ret = __set_output_tf(out_tf, regamma_lut, regamma_size, has_rom); - } else { -@@ -364,6 +370,24 @@ static int __set_input_tf(struct dc_transfer_func *func, - return res ? 0 : -ENOMEM; - } - -+static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum drm_transfer_function drm_tf) -+{ -+ switch (drm_tf) -+ { -+ default: -+ case DRM_TRANSFER_FUNCTION_DEFAULT: return TRANSFER_FUNCTION_LINEAR; -+ case DRM_TRANSFER_FUNCTION_SRGB: return TRANSFER_FUNCTION_SRGB; -+ case DRM_TRANSFER_FUNCTION_BT709: return TRANSFER_FUNCTION_BT709; -+ case DRM_TRANSFER_FUNCTION_PQ: return TRANSFER_FUNCTION_PQ; -+ case DRM_TRANSFER_FUNCTION_LINEAR: return TRANSFER_FUNCTION_LINEAR; -+ case DRM_TRANSFER_FUNCTION_UNITY: return TRANSFER_FUNCTION_UNITY; -+ case DRM_TRANSFER_FUNCTION_HLG: return TRANSFER_FUNCTION_HLG; -+ case DRM_TRANSFER_FUNCTION_GAMMA22: return TRANSFER_FUNCTION_GAMMA22; -+ case DRM_TRANSFER_FUNCTION_GAMMA24: return TRANSFER_FUNCTION_GAMMA24; -+ case DRM_TRANSFER_FUNCTION_GAMMA26: return TRANSFER_FUNCTION_GAMMA26; -+ } -+} -+ - static void __to_dc_lut3d_color(struct dc_rgb *rgb, - const struct drm_color_lut lut, - int bit_precision) -@@ -639,6 +663,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - const struct drm_color_lut *degamma_lut, *regamma_lut; - uint32_t degamma_size, regamma_size; - bool has_regamma, has_degamma; -+ enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_LINEAR; - bool is_legacy; - const struct drm_color_lut *shaper_lut, *lut3d; - uint32_t shaper_size, lut3d_size; -@@ -650,6 +675,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - - lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size); - shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size); -+ tf = drm_tf_to_dc_tf(crtc->regamma_tf); - - r = amdgpu_dm_verify_lut_sizes(&crtc->base); - if (r) -@@ -718,7 +744,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - */ - regamma_size = has_regamma ? regamma_size : 0; - r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut, -- regamma_size, has_rom); -+ regamma_size, has_rom, tf); - if (r) - return r; - } --- -2.40.1 - - -From 9162f97abaee9f28c92cb1d14969c6072c9290d6 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 16 Mar 2023 14:14:39 +0000 -Subject: [PATCH 42/59] drm/amd/display: set sdr_ref_white_level to 80 for - out_transfer_func - -Otherwise this is just initialized to 0. This needs to actually have a -value so that compute_curve can work for PQ EOTF. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 146363363ef07..7cf35ac3fad38 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -72,6 +72,7 @@ - */ - - #define MAX_DRM_LUT_VALUE 0xFFFF -+#define SDR_WHITE_LEVEL_INIT_VALUE 80 - - /** - * amdgpu_dm_init_color_mod - Initialize the color module. -@@ -325,6 +326,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, - */ - out_tf->type = TF_TYPE_DISTRIBUTED_POINTS; - out_tf->tf = tf; -+ out_tf->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE; - - ret = __set_output_tf(out_tf, regamma_lut, regamma_size, has_rom); - } else { --- -2.40.1 - - -From 05e9422ea6732679681826c9a0030f9400647148 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Wed, 12 Apr 2023 22:01:43 -0100 -Subject: [PATCH 43/59] drm/amd/display: add CRTC shaper TF support - -Inspired by regamma TF, follow similar steps to add TF + 1D LUT for -shaper func. Reuse regamma_tf property, since the driver doesn't support -shaper and out gamma at the same time. Only set shaper TF if setting -shaper LUT or 3D LUT. We could rename regamma_tf - if necessary to avoid -misunderstandings - or add a specific property for shaper TF when. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 7cf35ac3fad38..5650b85cc28ec 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -470,19 +470,22 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut, - } - - static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut, -+ bool has_rom, -+ enum dc_transfer_func_predefined tf, - uint32_t shaper_size, - struct dc_transfer_func *func_shaper) - { - int ret = 0; - -- if (shaper_size) { -+ if (shaper_size || tf != TRANSFER_FUNCTION_LINEAR) { - /* If DRM shaper LUT is set, we assume a linear color space - * (linearized by DRM degamma 1D LUT or not) - */ - func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS; -- func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -+ func_shaper->tf = tf; -+ func_shaper->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE; - -- ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false); -+ ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, has_rom); - } else { - func_shaper->type = TF_TYPE_BYPASS; - func_shaper->tf = TRANSFER_FUNCTION_LINEAR; -@@ -509,6 +512,8 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc, - struct dc_stream_state *stream, - const struct drm_color_lut *drm_shaper_lut, - uint32_t drm_shaper_size, -+ bool has_rom, -+ enum dc_transfer_func_predefined tf, - const struct drm_color_lut *drm_lut3d, - uint32_t drm_lut3d_size) - { -@@ -536,7 +541,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc, - - amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func); - -- return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, -+ return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, has_rom, tf, - drm_shaper_size, func_shaper); - } - -@@ -734,6 +739,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - shaper_size = shaper_lut != NULL ? shaper_size : 0; - r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream, - shaper_lut, shaper_size, -+ has_rom, tf, - lut3d, lut3d_size); - if (r) { - drm_dbg(&adev->ddev, "Failed on shaper/3D LUTs setup\n"); --- -2.40.1 - - -From 02b87d4ea9cdb6c55bdb2b66e57b6abb3ce03b7a Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Fri, 14 Apr 2023 22:19:49 -0100 -Subject: [PATCH 44/59] drm/amd/display: mark plane as needing reset if plane - color mgmt changes - -We took a similar path for CRTC color mgmt changes, since we remap CRTC -degamma to plane/DPP block. Here we can use the status of -`plane->color_mgmt_changed` to detect when a plane color property -changed and recreate the plane accordingly. - -Co-developed-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 513cf9c557f2e..0f3a10bcddc04 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -9513,6 +9513,9 @@ static bool should_reset_plane(struct drm_atomic_state *state, - if (drm_atomic_crtc_needs_modeset(new_crtc_state)) - return true; - -+ if (new_plane_state->color_mgmt_changed) -+ return true; -+ - /* - * If there are any new primary or overlay planes being added or - * removed then the z-order can potentially change. To ensure --- -2.40.1 - - -From d95ad19cbf7713eaac40f04676be1d2b5b6456e6 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Fri, 14 Apr 2023 16:06:42 -0100 -Subject: [PATCH 45/59] drm/amd/display: decouple steps for mapping CRTC - degamma to DC plane - -The next patch adds pre-blending degamma to AMD color mgmt pipeline, but -pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC -atomic degamma or implict degamma on legacy gamma. Detach degamma usage -regarging CRTC color properties to manage plane and CRTC color -correction combinations. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 59 +++++++++++++------ - 1 file changed, 41 insertions(+), 18 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 5650b85cc28ec..246f12532c48f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -790,20 +790,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - return 0; - } - --/** -- * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. -- * @crtc: amdgpu_dm crtc state -- * @dc_plane_state: target DC surface -- * -- * Update the underlying dc_stream_state's input transfer function (ITF) in -- * preparation for hardware commit. The transfer function used depends on -- * the preparation done on the stream for color management. -- * -- * Returns: -- * 0 on success. -ENOMEM if mem allocation fails. -- */ --int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, -- struct dc_plane_state *dc_plane_state) -+static int -+map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, -+ struct dc_plane_state *dc_plane_state) - { - const struct drm_color_lut *degamma_lut; - enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; -@@ -826,8 +815,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - °amma_size); - ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES); - -- dc_plane_state->in_transfer_func->type = -- TF_TYPE_DISTRIBUTED_POINTS; -+ dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; - - /* - * This case isn't fully correct, but also fairly -@@ -863,7 +851,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - degamma_lut, degamma_size); - if (r) - return r; -- } else if (crtc->cm_is_degamma_srgb) { -+ } else { - /* - * For legacy gamma support we need the regamma input - * in linear space. Assume that the input is sRGB. -@@ -873,8 +861,43 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - - if (tf != TRANSFER_FUNCTION_SRGB && - !mod_color_calculate_degamma_params(NULL, -- dc_plane_state->in_transfer_func, NULL, false)) -+ dc_plane_state->in_transfer_func, -+ NULL, false)) - return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+/** -+ * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. -+ * @crtc: amdgpu_dm crtc state -+ * @dc_plane_state: target DC surface -+ * -+ * Update the underlying dc_stream_state's input transfer function (ITF) in -+ * preparation for hardware commit. The transfer function used depends on -+ * the preparation done on the stream for color management. -+ * -+ * Returns: -+ * 0 on success. -ENOMEM if mem allocation fails. -+ */ -+int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, -+ struct dc_plane_state *dc_plane_state) -+{ -+ bool has_crtc_cm_degamma; -+ int ret; -+ -+ has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); -+ if (has_crtc_cm_degamma){ -+ /* AMD HW doesn't have post-blending degamma caps. When DRM -+ * CRTC atomic degamma is set, we maps it to DPP degamma block -+ * (pre-blending) or, on legacy gamma, we use DPP degamma to -+ * linearize (implicit degamma) from sRGB/BT709 according to -+ * the input space. -+ */ -+ ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state); -+ if (ret) -+ return ret; - } else { - /* ...Otherwise we can just bypass the DGM block. */ - dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; --- -2.40.1 - - -From f33acbd896a1d9379c1eba8d9eec2a4da973d5f6 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Wed, 12 Apr 2023 10:04:27 -0100 -Subject: [PATCH 46/59] drm/amd/display: add support for plane degamma TF and - LUT properties - -Set DC plane with user degamma LUT or predefined TF from driver-specific -plane color properties. If plane and CRTC degamma are set in the same -time, plane degamma has priority. That means, we only set CRTC degamma -if we don't have plane degamma LUT or TF to configure. We return -EINVAL -if we don't have plane degamma settings, so we can continue and check -CRTC degamma. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 70 +++++++++++++++++-- - 3 files changed, 69 insertions(+), 6 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 0f3a10bcddc04..c7f98503a750e 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -5045,7 +5045,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, - * Always set input transfer function, since plane state is refreshed - * every time. - */ -- ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state); -+ ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, -+ plane_state, -+ dc_plane_state); - if (ret) - return ret; - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index ea76c29578483..bf4a1d6be99e6 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -902,6 +902,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state); - int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - struct dc_state *ctx); - int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, -+ struct drm_plane_state *plane_state, - struct dc_plane_state *dc_plane_state); - - void amdgpu_dm_update_connector_after_detect( -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 246f12532c48f..89178b7f636f1 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -869,9 +869,58 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, - return 0; - } - -+static int -+__set_dm_plane_degamma(struct drm_plane_state *plane_state, -+ struct dc_plane_state *dc_plane_state) -+{ -+ struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); -+ const struct drm_color_lut *degamma_lut; -+ enum drm_transfer_function drm_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -+ uint32_t degamma_size; -+ bool has_degamma_lut; -+ int ret; -+ -+ degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, -+ °amma_size); -+ -+ has_degamma_lut = degamma_lut && -+ !__is_lut_linear(degamma_lut, degamma_size); -+ -+ drm_tf = dm_plane_state->degamma_tf; -+ -+ /* If we don't have plane degamma LUT nor TF to set on DC, we have -+ * nothing to do here, return. -+ */ -+ if (!has_degamma_lut && drm_tf == DRM_TRANSFER_FUNCTION_DEFAULT) -+ return -EINVAL; -+ -+ dc_plane_state->in_transfer_func->tf = drm_tf_to_dc_tf(drm_tf); -+ -+ if (has_degamma_lut) { -+ ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES); -+ -+ dc_plane_state->in_transfer_func->type = -+ TF_TYPE_DISTRIBUTED_POINTS; -+ -+ ret = __set_input_tf(dc_plane_state->in_transfer_func, -+ degamma_lut, degamma_size); -+ if (ret) -+ return ret; -+ } else { -+ dc_plane_state->in_transfer_func->type = -+ TF_TYPE_PREDEFINED; -+ -+ if (!mod_color_calculate_degamma_params(NULL, -+ dc_plane_state->in_transfer_func, NULL, false)) -+ return -ENOMEM; -+ } -+ return 0; -+} -+ - /** - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. - * @crtc: amdgpu_dm crtc state -+ * @plane_state: DRM plane state - * @dc_plane_state: target DC surface - * - * Update the underlying dc_stream_state's input transfer function (ITF) in -@@ -882,13 +931,28 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, - * 0 on success. -ENOMEM if mem allocation fails. - */ - int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, -+ struct drm_plane_state *plane_state, - struct dc_plane_state *dc_plane_state) - { - bool has_crtc_cm_degamma; - int ret; - -+ /* Initially, we can just bypass the DGM block. */ -+ dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; -+ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; -+ -+ /* After, we start to update values according to color props */ - has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); -- if (has_crtc_cm_degamma){ -+ -+ ret = __set_dm_plane_degamma(plane_state, dc_plane_state); -+ if (ret != -EINVAL) -+ return ret; -+ -+ /* If we are here, it means we don't have plane degamma settings, check -+ * if we have CRTC degamma waiting for mapping to pre-blending degamma -+ * block -+ */ -+ if (has_crtc_cm_degamma) { - /* AMD HW doesn't have post-blending degamma caps. When DRM - * CRTC atomic degamma is set, we maps it to DPP degamma block - * (pre-blending) or, on legacy gamma, we use DPP degamma to -@@ -898,10 +962,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state); - if (ret) - return ret; -- } else { -- /* ...Otherwise we can just bypass the DGM block. */ -- dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; -- dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; - } - - return 0; --- -2.40.1 - - -From ac4146a88212a242e8fea0b01bf14333ccd41033 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Fri, 14 Apr 2023 16:50:34 -0100 -Subject: [PATCH 47/59] drm/amd/display: reject atomic commit if setting both - plane and CRTC degamma - -DC only has pre-blending degamma caps (plane/DPP) that is currently in -use for CRTC/post-blending degamma, so that we don't have HW caps to -perform plane and CRTC degamma at the same time. Reject atomic updates -when serspace sets both plane and CRTC degamma properties. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 89178b7f636f1..8452519cabe8b 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -945,9 +945,20 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); - - ret = __set_dm_plane_degamma(plane_state, dc_plane_state); -- if (ret != -EINVAL) -+ if (ret == -ENOMEM) - return ret; - -+ /* We only have one degamma block available (pre-blending) for the -+ * whole color correction pipeline, so that we can't actually perform -+ * plane and CRTC degamma at the same time. Explicitly reject atomic -+ * updates when userspace sets both plane and CRTC degamma properties. -+ */ -+ if (has_crtc_cm_degamma && ret != -EINVAL){ -+ drm_dbg_kms(crtc->base.crtc->dev, -+ "doesn't support plane and CRTC degamma at the same time\n"); -+ return -EINVAL; -+ } -+ - /* If we are here, it means we don't have plane degamma settings, check - * if we have CRTC degamma waiting for mapping to pre-blending degamma - * block --- -2.40.1 - - -From f5943c06d541016a2f8e3c7764eca33ca1e6f9f7 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 16 Mar 2023 12:00:59 +0000 -Subject: [PATCH 48/59] drm/amd/display: add dc_fixpt_from_s3132 helper - -Detach value translation from CTM to reuse it for programming HDR -multiplier property. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 8 +------- - drivers/gpu/drm/amd/display/include/fixed31_32.h | 12 ++++++++++++ - 2 files changed, 13 insertions(+), 7 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 8452519cabe8b..629ba10fbee93 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -183,7 +183,6 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, - static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, - struct fixed31_32 *matrix) - { -- int64_t val; - int i; - - /* -@@ -202,12 +201,7 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, - } - - /* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */ -- val = ctm->matrix[i - (i / 4)]; -- /* If negative, convert to 2's complement. */ -- if (val & (1ULL << 63)) -- val = -(val & ~(1ULL << 63)); -- -- matrix[i].value = val; -+ matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]); - } - } - -diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h -index ece97ae0e826c..f4cc7f97329fc 100644 ---- a/drivers/gpu/drm/amd/display/include/fixed31_32.h -+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h -@@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL }; - static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL }; - static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL }; - -+static inline struct fixed31_32 dc_fixpt_from_s3132(__u64 x) -+{ -+ struct fixed31_32 val; -+ -+ /* If negative, convert to 2's complement. */ -+ if (x & (1ULL << 63)) -+ x = -(x & ~(1ULL << 63)); -+ -+ val.value = x; -+ return val; -+} -+ - /* - * @brief - * Initialization routines --- -2.40.1 - - -From 00da10be582bf8bc9295653aefb7c9ae5055ef8a Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Wed, 12 Apr 2023 21:42:51 -0100 -Subject: [PATCH 49/59] drm/adm/display: add HDR multiplier support - -With `dc_fixpt_from_s3132()` translation, we can just use it to set -hdr_mult. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 +++ - 2 files changed, 4 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index c7f98503a750e..4530ce1d06ef8 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -8061,6 +8061,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction; - bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func; - bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; -+ bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult; - } - - amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 629ba10fbee93..57d6aab762954 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -928,6 +928,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - struct drm_plane_state *plane_state, - struct dc_plane_state *dc_plane_state) - { -+ struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - bool has_crtc_cm_degamma; - int ret; - -@@ -938,6 +939,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - /* After, we start to update values according to color props */ - has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); - -+ dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult); -+ - ret = __set_dm_plane_degamma(plane_state, dc_plane_state); - if (ret == -ENOMEM) - return ret; --- -2.40.1 - - -From f7ff5f0bf1c46bcde2b0af3f0c203803c1178ced Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Mon, 22 May 2023 15:31:31 -0100 -Subject: [PATCH 50/59] drm/amd/display: program DPP shaper and 3D LUT if - updated - -If shaper and 3D LUT data updates, lut_3d bit in update_flag is updated -and we need to call set_input_transfer_func to program DPP shaper and 3D -LUTs. Small cleanup of code style in the related if-condition. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -index 5403e9399a465..b39880d26c6df 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c -@@ -1755,8 +1755,9 @@ static void dcn20_program_pipe( - hws->funcs.set_hdr_multiplier(pipe_ctx); - - if (pipe_ctx->update_flags.bits.enable || -- pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || -- pipe_ctx->plane_state->update_flags.bits.gamma_change) -+ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || -+ pipe_ctx->plane_state->update_flags.bits.gamma_change || -+ pipe_ctx->plane_state->update_flags.bits.lut_3d) - hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); - - /* dcn10_translate_regamma_to_hw_format takes 750us to finish --- -2.40.1 - - -From 5bf24f48ca55fb1470d752b5cb9b758b520441fb Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Wed, 22 Mar 2023 18:37:12 -0100 -Subject: [PATCH 51/59] drm/amd/display: add plane shaper/3D LUT and shaper TF - support - -We already have the steps to program post-blending shaper/3D LUT on AMD -display driver, but unlike MPC 3D LUT, we don't need to acquire/release -DPP 3D LUT. We can reuse programming steps to map plane properties to -DC plane for pre-blending (plane) shaper/3D LUT setup. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 35 ++++++++++++++++--- - 2 files changed, 33 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 4530ce1d06ef8..9a9c3cbf77693 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -8062,6 +8062,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func; - bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; - bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult; -+ bundle->surface_updates[planes_count].func_shaper = dc_plane->in_shaper_func; -+ bundle->surface_updates[planes_count].lut3d_func = dc_plane->lut3d_func; - } - - amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 57d6aab762954..b075c9f6e7179 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -911,6 +911,35 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, - return 0; - } - -+static int -+amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, -+ struct dc_plane_state *dc_plane_state) -+{ -+ struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); -+ enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -+ const struct drm_color_lut *shaper_lut, *lut3d; -+ uint32_t lut3d_size, shaper_size; -+ -+ /* We have nothing to do here, return */ -+ if (!plane_state->color_mgmt_changed) -+ return 0; -+ -+ dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult); -+ -+ shaper_tf = dm_plane_state->shaper_tf; -+ shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, &shaper_size); -+ lut3d = __extract_blob_lut(dm_plane_state->lut3d, &lut3d_size); -+ lut3d_size = lut3d != NULL ? lut3d_size : 0; -+ shaper_size = shaper_lut != NULL ? shaper_size : 0; -+ -+ amdgpu_dm_atomic_lut3d(lut3d, lut3d_size, dc_plane_state->lut3d_func); -+ ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false, -+ drm_tf_to_dc_tf(shaper_tf), -+ shaper_size, dc_plane_state->in_shaper_func); -+ -+ return ret; -+} -+ - /** - * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane. - * @crtc: amdgpu_dm crtc state -@@ -928,7 +957,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - struct drm_plane_state *plane_state, - struct dc_plane_state *dc_plane_state) - { -- struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - bool has_crtc_cm_degamma; - int ret; - -@@ -939,8 +967,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - /* After, we start to update values according to color props */ - has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); - -- dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult); -- - ret = __set_dm_plane_degamma(plane_state, dc_plane_state); - if (ret == -ENOMEM) - return ret; -@@ -972,5 +998,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - return ret; - } - -- return 0; -+ return amdgpu_dm_plane_set_color_properties(plane_state, -+ dc_plane_state); - } --- -2.40.1 - - -From ec19bcb7f9c99ed36c64497c54952aa72769e1c1 Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Sun, 2 Apr 2023 22:46:46 +0100 -Subject: [PATCH 52/59] drm/amd/display: handle empty LUTs in __set_input_tf - -Unlike degamma, blend gamma doesn't support hardcoded curve -(predefined/ROM), but we can use AMD color module to fill blend gamma -parameters when we have non-linear plane gamma TF without plane gamma -LUT. The regular degamma path doesn't hit this. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 20 +++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index b075c9f6e7179..a441c02380f24 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -351,17 +351,21 @@ static int __set_input_tf(struct dc_transfer_func *func, - struct dc_gamma *gamma = NULL; - bool res; - -- gamma = dc_create_gamma(); -- if (!gamma) -- return -ENOMEM; -+ if (lut_size) { -+ gamma = dc_create_gamma(); -+ if (!gamma) -+ return -ENOMEM; - -- gamma->type = GAMMA_CUSTOM; -- gamma->num_entries = lut_size; -+ gamma->type = GAMMA_CUSTOM; -+ gamma->num_entries = lut_size; - -- __drm_lut_to_dc_gamma(lut, gamma, false); -+ __drm_lut_to_dc_gamma(lut, gamma, false); -+ } - -- res = mod_color_calculate_degamma_params(NULL, func, gamma, true); -- dc_gamma_release(&gamma); -+ res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL); -+ -+ if (gamma) -+ dc_gamma_release(&gamma); - - return res ? 0 : -ENOMEM; - } --- -2.40.1 - - -From b3145cac534368103353e04099c484924bee630b Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Wed, 12 Apr 2023 21:53:32 -0100 -Subject: [PATCH 53/59] drm/amd/display: add DRM plane blend LUT and TF support - -Map DRM plane blend properties to DPP blend gamma. Plane blend is a -post-3D LUT curve that linearizes color space for blending. It may be -defined by a user-blob LUT and/or predefined transfer function. As -hardcoded curve (ROM) is not supported on blend gamma, we use AMD color -module to fill parameters when setting non-linear TF with empty LUT. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 58 ++++++++++++++++++- - 2 files changed, 56 insertions(+), 3 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 9a9c3cbf77693..cecf3dba945c5 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -8064,6 +8064,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, - bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult; - bundle->surface_updates[planes_count].func_shaper = dc_plane->in_shaper_func; - bundle->surface_updates[planes_count].lut3d_func = dc_plane->lut3d_func; -+ bundle->surface_updates[planes_count].blend_tf = dc_plane->blend_tf; - } - - amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index a441c02380f24..4a2b66568451f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -492,6 +492,34 @@ static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut, - return ret; - } - -+static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut, -+ bool has_rom, -+ enum dc_transfer_func_predefined tf, -+ uint32_t blend_size, -+ struct dc_transfer_func *func_blend) -+{ -+ int ret = 0; -+ -+ if (blend_size || tf != TRANSFER_FUNCTION_LINEAR) { -+ /* DRM plane gamma LUT or TF means we are linearizing color -+ * space before blending (similar to degamma programming). As -+ * we don't have hardcoded curve support, or we use AMD color -+ * module to fill the parameters that will be translated to HW -+ * points. -+ */ -+ func_blend->type = TF_TYPE_DISTRIBUTED_POINTS; -+ func_blend->tf = tf; -+ func_blend->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE; -+ -+ ret = __set_input_tf(func_blend, blend_lut, blend_size); -+ } else { -+ func_blend->type = TF_TYPE_BYPASS; -+ func_blend->tf = TRANSFER_FUNCTION_LINEAR; -+ } -+ -+ return ret; -+} -+ - /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC - * interface - * @dc: Display Core control structure -@@ -921,8 +949,10 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, - { - struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -- const struct drm_color_lut *shaper_lut, *lut3d; -- uint32_t lut3d_size, shaper_size; -+ enum drm_transfer_function blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -+ const struct drm_color_lut *shaper_lut, *lut3d, *blend_lut; -+ uint32_t lut3d_size, shaper_size, blend_size; -+ int ret; - - /* We have nothing to do here, return */ - if (!plane_state->color_mgmt_changed) -@@ -940,8 +970,30 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, - ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false, - drm_tf_to_dc_tf(shaper_tf), - shaper_size, dc_plane_state->in_shaper_func); -+ if (ret) { -+ drm_dbg_kms(plane_state->plane->dev, -+ "setting plane %d shaper/3d lut failed.\n", -+ plane_state->plane->index); - -- return ret; -+ return ret; -+ } -+ -+ blend_tf = dm_plane_state->blend_tf; -+ blend_lut = __extract_blob_lut(dm_plane_state->blend_lut, &blend_size); -+ blend_size = blend_lut != NULL ? blend_size : 0; -+ -+ ret = amdgpu_dm_atomic_blend_lut(blend_lut, false, -+ drm_tf_to_dc_tf(blend_tf), -+ blend_size, dc_plane_state->blend_tf); -+ if (ret) { -+ drm_dbg_kms(plane_state->plane->dev, -+ "setting plane %d gamma lut failed.\n", -+ plane_state->plane->index); -+ -+ return ret; -+ } -+ -+ return 0; - } - - /** --- -2.40.1 - - -From 8eb5e95733656b2a7b4ef8c3b7f6fc5cc2b5822c Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Fri, 21 Apr 2023 01:05:39 +0100 -Subject: [PATCH 54/59] drm/amd/display: allow newer DC hardware to use degamma - ROM for PQ/HLG - -Need to funnel the color caps through to these functions so it can check -that the hardware is capable. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 35 ++++++++++++------- - 1 file changed, 23 insertions(+), 12 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index 4a2b66568451f..714f07bb9c9ca 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -@@ -338,6 +338,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, - /** - * __set_input_tf - calculates the input transfer function based on expected - * input space. -+ * @caps: dc color capabilities - * @func: transfer function - * @lut: lookup table that defines the color space - * @lut_size: size of respective lut. -@@ -345,7 +346,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream, - * Returns: - * 0 in case of success. -ENOMEM if fails. - */ --static int __set_input_tf(struct dc_transfer_func *func, -+static int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func *func, - const struct drm_color_lut *lut, uint32_t lut_size) - { - struct dc_gamma *gamma = NULL; -@@ -362,7 +363,7 @@ static int __set_input_tf(struct dc_transfer_func *func, - __drm_lut_to_dc_gamma(lut, gamma, false); - } - -- res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL); -+ res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != NULL); - - if (gamma) - dc_gamma_release(&gamma); -@@ -511,7 +512,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut, - func_blend->tf = tf; - func_blend->sdr_ref_white_level = SDR_WHITE_LEVEL_INIT_VALUE; - -- ret = __set_input_tf(func_blend, blend_lut, blend_size); -+ ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size); - } else { - func_blend->type = TF_TYPE_BYPASS; - func_blend->tf = TRANSFER_FUNCTION_LINEAR; -@@ -818,7 +819,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc, - - static int - map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, -- struct dc_plane_state *dc_plane_state) -+ struct dc_plane_state *dc_plane_state, -+ struct dc_color_caps *caps) - { - const struct drm_color_lut *degamma_lut; - enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; -@@ -873,7 +875,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, - dc_plane_state->in_transfer_func->tf = - TRANSFER_FUNCTION_LINEAR; - -- r = __set_input_tf(dc_plane_state->in_transfer_func, -+ r = __set_input_tf(caps, dc_plane_state->in_transfer_func, - degamma_lut, degamma_size); - if (r) - return r; -@@ -886,7 +888,7 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, - dc_plane_state->in_transfer_func->tf = tf; - - if (tf != TRANSFER_FUNCTION_SRGB && -- !mod_color_calculate_degamma_params(NULL, -+ !mod_color_calculate_degamma_params(caps, - dc_plane_state->in_transfer_func, - NULL, false)) - return -ENOMEM; -@@ -897,7 +899,8 @@ map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc, - - static int - __set_dm_plane_degamma(struct drm_plane_state *plane_state, -- struct dc_plane_state *dc_plane_state) -+ struct dc_plane_state *dc_plane_state, -+ struct dc_color_caps *color_caps) - { - struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - const struct drm_color_lut *degamma_lut; -@@ -906,6 +909,9 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, - bool has_degamma_lut; - int ret; - -+ if (dc_plane_state->ctx && dc_plane_state->ctx->dc) -+ color_caps = &dc_plane_state->ctx->dc->caps.color; -+ - degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, - °amma_size); - -@@ -928,7 +934,7 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, - dc_plane_state->in_transfer_func->type = - TF_TYPE_DISTRIBUTED_POINTS; - -- ret = __set_input_tf(dc_plane_state->in_transfer_func, -+ ret = __set_input_tf(color_caps, dc_plane_state->in_transfer_func, - degamma_lut, degamma_size); - if (ret) - return ret; -@@ -945,7 +951,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state, - - static int - amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, -- struct dc_plane_state *dc_plane_state) -+ struct dc_plane_state *dc_plane_state, -+ struct dc_color_caps *color_caps) - { - struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT; -@@ -1013,9 +1020,13 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - struct drm_plane_state *plane_state, - struct dc_plane_state *dc_plane_state) - { -+ struct dc_color_caps *color_caps = NULL; - bool has_crtc_cm_degamma; - int ret; - -+ if (dc_plane_state->ctx && dc_plane_state->ctx->dc) -+ color_caps = &dc_plane_state->ctx->dc->caps.color; -+ - /* Initially, we can just bypass the DGM block. */ - dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; - dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; -@@ -1023,7 +1034,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - /* After, we start to update values according to color props */ - has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb); - -- ret = __set_dm_plane_degamma(plane_state, dc_plane_state); -+ ret = __set_dm_plane_degamma(plane_state, dc_plane_state, color_caps); - if (ret == -ENOMEM) - return ret; - -@@ -1049,11 +1060,11 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, - * linearize (implicit degamma) from sRGB/BT709 according to - * the input space. - */ -- ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state); -+ ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state, color_caps); - if (ret) - return ret; - } - - return amdgpu_dm_plane_set_color_properties(plane_state, -- dc_plane_state); -+ dc_plane_state, color_caps); - } --- -2.40.1 - - -From c547b55f0c40d52be6d885865ae3a8c9b707e25b Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Thu, 20 Apr 2023 20:39:00 -0100 -Subject: [PATCH 55/59] HACK: Prefix new color mgmt properties with VALVE1_ - -Plane color mgmt properties, predefined transfer functions and CRTC -shaper/3D LUT aren't upstream properties yet, add a prefix to indicate -they are downstream props. - -Signed-off-by: Joshua Ashton <joshua@froggi.es> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 26 ++++++++++----------- - 1 file changed, 13 insertions(+), 13 deletions(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 708866da78633..8b3933a77e7b5 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1269,7 +1269,7 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - - prop = drm_property_create_enum(adev_to_drm(adev), - DRM_MODE_PROP_ENUM, -- "AMD_REGAMMA_TF", -+ "VALVE1_CRTC_REGAMMA_TF", - drm_transfer_function_enum_list, - ARRAY_SIZE(drm_transfer_function_enum_list)); - if (!prop) -@@ -1278,21 +1278,21 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, -- "AMD_PLANE_DEGAMMA_LUT", 0); -+ "VALVE1_PLANE_DEGAMMA_LUT", 0); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_degamma_lut_property = prop; - - prop = drm_property_create_range(adev_to_drm(adev), - DRM_MODE_PROP_IMMUTABLE, -- "AMD_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX); -+ "VALVE1_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_degamma_lut_size_property = prop; - - prop = drm_property_create_enum(adev_to_drm(adev), - DRM_MODE_PROP_ENUM, -- "AMD_PLANE_DEGAMMA_TF", -+ "VALVE1_PLANE_DEGAMMA_TF", - drm_transfer_function_enum_list, - ARRAY_SIZE(drm_transfer_function_enum_list)); - if (!prop) -@@ -1300,28 +1300,28 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - adev->mode_info.plane_degamma_tf_property = prop; - - prop = drm_property_create_range(adev_to_drm(adev), -- 0, "AMD_PLANE_HDR_MULT", 0, U64_MAX); -+ 0, "VALVE1_PLANE_HDR_MULT", 0, U64_MAX); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_hdr_mult_property = prop; - - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, -- "AMD_PLANE_SHAPER_LUT", 0); -+ "VALVE1_PLANE_SHAPER_LUT", 0); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_shaper_lut_property = prop; - - prop = drm_property_create_range(adev_to_drm(adev), - DRM_MODE_PROP_IMMUTABLE, -- "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); -+ "VALVE1_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_shaper_lut_size_property = prop; - - prop = drm_property_create_enum(adev_to_drm(adev), - DRM_MODE_PROP_ENUM, -- "AMD_PLANE_SHAPER_TF", -+ "VALVE1_PLANE_SHAPER_TF", - drm_transfer_function_enum_list, - ARRAY_SIZE(drm_transfer_function_enum_list)); - if (!prop) -@@ -1330,35 +1330,35 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) - - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, -- "AMD_PLANE_LUT3D", 0); -+ "VALVE1_PLANE_LUT3D", 0); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_lut3d_property = prop; - - prop = drm_property_create_range(adev_to_drm(adev), - DRM_MODE_PROP_IMMUTABLE, -- "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX); -+ "VALVE1_PLANE_LUT3D_SIZE", 0, UINT_MAX); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_lut3d_size_property = prop; - - prop = drm_property_create(adev_to_drm(adev), - DRM_MODE_PROP_BLOB, -- "AMD_PLANE_BLEND_LUT", 0); -+ "VALVE1_PLANE_BLEND_LUT", 0); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_blend_lut_property = prop; - - prop = drm_property_create_range(adev_to_drm(adev), - DRM_MODE_PROP_IMMUTABLE, -- "AMD_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX); -+ "VALVE1_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX); - if (!prop) - return -ENOMEM; - adev->mode_info.plane_blend_lut_size_property = prop; - - prop = drm_property_create_enum(adev_to_drm(adev), - DRM_MODE_PROP_ENUM, -- "AMD_PLANE_BLEND_TF", -+ "VALVE1_PLANE_BLEND_TF", - drm_transfer_function_enum_list, - ARRAY_SIZE(drm_transfer_function_enum_list)); - if (!prop) --- -2.40.1 - - -From 382168425feb5a2019cd0982e96b0e6e813fd33b Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Fri, 12 May 2023 18:43:46 +0000 -Subject: [PATCH 56/59] drm/amd/display: Reset CRTC color mgmt state if commit - fails - -If we failed our commit, if our new crtc was dirty color-wise, make -sure we forward that dirty bit on our old state now so we don't -forget to revert the work we did before we failed this commit on -the next commit. - -Fixes a bug in SteamOS/Gamescope where we could fail a -commit that changed the gamma of the CRTC and it would -persist even after we did a new commit with a different -gamma (as we were doing single plane optimizations -and didn't need degamma + gamma for correct blending) - -Signed-off-by: Joshua Ashton <joshua@froggi.es> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 32 +++++++++++++++++++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + - .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 1 + - 3 files changed, 34 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index cecf3dba945c5..b2158c17e9bbc 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -10012,6 +10012,21 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, - } - } - } -+ -+ /* Propogate CM reset state */ -+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { -+ dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); -+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); -+ -+ if (dm_old_crtc_state->cm_needs_reset || dm_new_crtc_state->cm_needs_reset) -+ { -+ dm_old_crtc_state->cm_needs_reset = false; -+ dm_new_crtc_state->cm_needs_reset = false; -+ -+ dm_new_crtc_state->base.color_mgmt_changed = true; -+ } -+ } -+ - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - -@@ -10363,6 +10378,23 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, - return ret; - - fail: -+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { -+ /* -+ * If we failed our commit, if our new crtc was dirty color-wise, make sure we forward that -+ * dirty bit on our old state now so we don't forget to revert the work we did before -+ * we failed this commit on the next commit. -+ * -+ * Store it on old and new state so we don't lose track of it for this CRTC. -+ */ -+ dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); -+ dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); -+ -+ if (new_crtc_state->color_mgmt_changed) { -+ dm_old_crtc_state->cm_needs_reset = true; -+ dm_new_crtc_state->cm_needs_reset = true; -+ } -+ } -+ - if (ret == -EDEADLK) - DRM_DEBUG_DRIVER("Atomic check stopped to avoid deadlock.\n"); - else if (ret == -EINTR || ret == -EAGAIN || ret == -ERESTARTSYS) -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index bf4a1d6be99e6..ec56a555721e3 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -@@ -796,6 +796,7 @@ struct dm_crtc_state { - struct dc_info_packet vrr_infopacket; - - int abm_level; -+ bool cm_needs_reset; - - /* AMD driver-private CRTC color management - * -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index 4a725aeef3e84..73f7970a08ceb 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -@@ -255,6 +255,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc) - state->regamma_tf = cur->regamma_tf; - state->crc_skip_count = cur->crc_skip_count; - state->mpo_requested = cur->mpo_requested; -+ state->cm_needs_reset = cur->cm_needs_reset; - /* TODO Duplicate dc_stream after objects are stream object is flattened */ - - return &state->base; --- -2.40.1 - - -From ee349e3c6c78e085909da04232d6be7872ac820e Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Sat, 22 Apr 2023 14:08:47 -0100 -Subject: [PATCH 57/59] HACK: add KConfig to enable driver-specific color mgmt - props - -We are enabling a large set of color calibration features to enhance KMS -color mgmt but these properties are specific of AMD display HW, and -cannot be provided by other vendors. Therefore, set a config option to -enable AMD driver-private properties used on Steam Deck color mgmt -pipeline. Replace the agreed name `AMD_PRIVATE_COLOR` with -our downstream version `CONFIG_DRM_AMD_COLOR_STEAMDECK`. - -Signed-off-by: Melissa Wen <mwen@igalia.com> ---- - drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 ++-- - drivers/gpu/drm/amd/display/Kconfig | 6 ++++++ - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 6 +++--- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 6 +++--- - 4 files changed, 14 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -index 8b3933a77e7b5..12e8db8f04209 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c -@@ -1261,7 +1261,7 @@ static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = { - { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, - }; - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - static int - amdgpu_display_create_color_properties(struct amdgpu_device *adev) - { -@@ -1445,7 +1445,7 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev) - return -ENOMEM; - } - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - if (amdgpu_display_create_color_properties(adev)) - return -ENOMEM; - #endif -diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig -index 2d8e55e29637f..2357d2ef6fe60 100644 ---- a/drivers/gpu/drm/amd/display/Kconfig -+++ b/drivers/gpu/drm/amd/display/Kconfig -@@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY - of crc of specific region via debugfs. - Cooperate with specific DMCU FW. - -+config DRM_AMD_COLOR_STEAMDECK -+ bool "Enable color calibration features for Steam Deck" -+ depends on DRM_AMD_DC -+ help -+ Choose this option if you want to use AMDGPU features for broader -+ color management support on Steam Deck. - - endmenu -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index 73f7970a08ceb..98a2877642997 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -@@ -290,7 +290,7 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc) - } - #endif - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - /** - * drm_crtc_additional_color_mgmt - enable additional color properties - * @crtc: DRM CRTC -@@ -371,7 +371,7 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { - #if defined(CONFIG_DEBUG_FS) - .late_register = amdgpu_dm_crtc_late_register, - #endif --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - .atomic_set_property = amdgpu_dm_atomic_crtc_set_property, - .atomic_get_property = amdgpu_dm_atomic_crtc_get_property, - #endif -@@ -538,7 +538,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, - - drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - dm_crtc_additional_color_mgmt(&acrtc->base); - #endif - return 0; -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index ea13b49fa0215..5a03fba687b42 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -1453,7 +1453,7 @@ static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = { - { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" }, - }; - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - static void - dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, - struct drm_plane *plane) -@@ -1621,7 +1621,7 @@ static const struct drm_plane_funcs dm_plane_funcs = { - .atomic_duplicate_state = dm_drm_plane_duplicate_state, - .atomic_destroy_state = dm_drm_plane_destroy_state, - .format_mod_supported = dm_plane_format_mod_supported, --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - .atomic_set_property = dm_atomic_plane_set_property, - .atomic_get_property = dm_atomic_plane_get_property, - #endif -@@ -1695,7 +1695,7 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, - - drm_plane_helper_add(plane, &dm_plane_helper_funcs); - --#ifdef AMD_PRIVATE_COLOR -+#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK - dm_atomic_plane_attach_color_mgmt_properties(dm, plane); - #endif - /* Create (reset) the plane state */ --- -2.40.1 - - -From c029477e4ed957af0b3dc75e9cce2a6630b70393 Mon Sep 17 00:00:00 2001 -From: Melissa Wen <mwen@igalia.com> -Date: Sun, 11 Jun 2023 13:34:02 -0100 -Subject: [PATCH 58/59] Revert "drm/amd/display: mark plane as needing reset if - plane color mgmt changes" - -This reverts commit f3a18707a984d82ab842bd8b8666a442c1943d59. ---- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index b2158c17e9bbc..ba2e43ab8df56 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -9519,9 +9519,6 @@ static bool should_reset_plane(struct drm_atomic_state *state, - if (drm_atomic_crtc_needs_modeset(new_crtc_state)) - return true; - -- if (new_plane_state->color_mgmt_changed) -- return true; -- - /* - * If there are any new primary or overlay planes being added or - * removed then the z-order can potentially change. To ensure --- -2.40.1 - - -From a5d8fb5b89a34ba97ffb423dceafc6d3cb5c35bf Mon Sep 17 00:00:00 2001 -From: Joshua Ashton <joshua@froggi.es> -Date: Fri, 14 Apr 2023 22:19:49 -0100 -Subject: [PATCH 59/59] drm/amd/display: mark plane as needing reset if color - props change - -Co-developed-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Melissa Wen <mwen@igalia.com> -Signed-off-by: Joshua Ashton <joshua@froggi.es> ---- - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index ba2e43ab8df56..50bf1cd900156 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -9529,6 +9529,11 @@ static bool should_reset_plane(struct drm_atomic_state *state, - */ - for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { - struct amdgpu_framebuffer *old_afb, *new_afb; -+ struct dm_plane_state *dm_new_other_state, *dm_old_other_state; -+ -+ dm_new_other_state = to_dm_plane_state(new_other_state); -+ dm_old_other_state = to_dm_plane_state(old_other_state); -+ - if (other->type == DRM_PLANE_TYPE_CURSOR) - continue; - -@@ -9564,6 +9569,17 @@ static bool should_reset_plane(struct drm_atomic_state *state, - old_other_state->color_encoding != new_other_state->color_encoding) - return true; - -+ /* HDR/Transfer Function changes. */ -+ if (dm_old_other_state->degamma_tf != dm_new_other_state->degamma_tf || -+ dm_old_other_state->degamma_lut != dm_new_other_state->degamma_lut || -+ dm_old_other_state->hdr_mult != dm_new_other_state->hdr_mult || -+ dm_old_other_state->shaper_lut != dm_new_other_state->shaper_lut || -+ dm_old_other_state->shaper_tf != dm_new_other_state->shaper_tf || -+ dm_old_other_state->lut3d != dm_new_other_state->lut3d || -+ dm_old_other_state->blend_lut != dm_new_other_state->blend_lut || -+ dm_old_other_state->blend_tf != dm_new_other_state->blend_tf) -+ return true; -+ - /* Framebuffer checks fall at the end. */ - if (!old_other_state->fb || !new_other_state->fb) - continue; --- -2.40.1 - |