[PATCH] drm/amd/display: Fix BT2020 YCbCr limited range output CSC

Satyajit Roy <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx,org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
From: Satyajit Roy <[email protected]>

COLOR_SPACE_2020_YCBCR_LIMITED and COLOR_SPACE_2020_YCBCR_FULL
currently select the same output CSC matrix. The matrix uses
full-amplitude BT2020 coefficients, so the limited-range output path
does not scale luma and chroma to their limited-range code ranges.

When the output is signaled as limited-range YCbCr, a sink that honors
the quantization range expands those values again. This produces
incorrect output levels and is particularly visible with PQ HDR.

On Navi33/DCN 3.2.1 over HDMI, the AVI InfoFrame advertises limited
range while the existing output CSC produces full-amplitude BT2020
YCbCr values. Using the limited-range matrix restores the expected
PQ HDR output levels.

Add a separate output CSC matrix for BT2020 YCbCr limited range. Scale
luma by 219/255 and chroma by 224/255 while retaining the appropriate
limited-range offsets. Keep the existing matrix unchanged for full
range.

Fixes: 07bc2dcbcf40 ("drm/amd/display: Fix BT2020 YCbCr limited/full range input")
Cc: [email protected]
Signed-off-by: Satyajit Roy <[email protected]>
---
 .../drm/amd/display/dc/core/dc_hw_sequencer.c  | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 90d754d192f1..f264bb880aee 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -61,6 +61,7 @@ enum dc_color_space_type {
 	COLOR_SPACE_YCBCR601_TYPE,
 	COLOR_SPACE_YCBCR709_TYPE,
 	COLOR_SPACE_YCBCR2020_TYPE,
+	COLOR_SPACE_YCBCR2020_LIMITED_TYPE,
 	COLOR_SPACE_YCBCR601_LIMITED_TYPE,
 	COLOR_SPACE_YCBCR709_LIMITED_TYPE,
 	COLOR_SPACE_YCBCR709_BLACK_TYPE,
@@ -116,6 +117,10 @@ static const struct out_csc_color_matrix_type output_csc_matrix[] = {
 		{ 0x1000, 0xF149, 0xFEB7, 0x1004,
 		  0x0868, 0x15B2, 0x01E6, 0x201,
 		  0xFB88, 0xF478, 0x1000, 0x1004} },
+	{ COLOR_SPACE_YCBCR2020_LIMITED_TYPE,
+		{ 0x0E0E, 0xF313, 0xFEDF, 0x1004,
+		  0x0738, 0x12A2, 0x01A1, 0x0201,
+		  0xFC13, 0xF5DF, 0x0E0E, 0x1004} },
 	{ COLOR_SPACE_YCBCR709_BLACK_TYPE,
 		{ 0x0000, 0x0000, 0x0000, 0x1000,
 		  0x0000, 0x0000, 0x0000, 0x0200,
@@ -186,7 +191,16 @@ static bool is_ycbcr2020_type(
 {
 	bool ret = false;
 
-	if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED || color_space == COLOR_SPACE_2020_YCBCR_FULL)
+	if (color_space == COLOR_SPACE_2020_YCBCR_FULL)
+		ret = true;
+	return ret;
+}
+
+static bool is_ycbcr2020_limited_type(enum dc_color_space color_space)
+{
+	bool ret = false;
+
+	if (color_space == COLOR_SPACE_2020_YCBCR_LIMITED)
 		ret = true;
 	return ret;
 }
@@ -217,6 +231,8 @@ static enum dc_color_space_type get_color_space_type(enum dc_color_space color_s
 		type = COLOR_SPACE_YCBCR601_LIMITED_TYPE;
 	else if (is_ycbcr709_limited_type(color_space))
 		type = COLOR_SPACE_YCBCR709_LIMITED_TYPE;
+	else if (is_ycbcr2020_limited_type(color_space))
+		type = COLOR_SPACE_YCBCR2020_LIMITED_TYPE;
 	else if (is_ycbcr2020_type(color_space))
 		type = COLOR_SPACE_YCBCR2020_TYPE;
 	else if (color_space == COLOR_SPACE_YCBCR709)
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.