Blob Blame History Raw
From 15ac2b8fccf7d958ecd17aebd0299db018de5778 Mon Sep 17 00:00:00 2001
From: Jaehyun Chung <jaehyun.chung@amd.com>
Date: Tue, 24 Aug 2021 14:05:48 -0400
Subject: drm/amd/display: Add regamma/degamma coefficients and set sRGB when
 TF is BT709
Git-commit: d020970959169627d59a711769f8c4b87bf5f90c
Patch-mainline: v5.16-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

[Why]
In YUV case, need to set the input TF to sRGB instead of BT709,
even though the input TF type is distributed. SRGB was not
being used because pixel format was not being set in the
surface update sequence.
Also, we were using the same coefficients for degamma and
regamma formula, causing the cutoff point of the linear
section of the curve to be incorrect.

[How]
Set pixel format in the surface update sequence. Add separate
coefficient arrays for regamma and degamma.

Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Jaehyun Chung <jaehyun.chung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../amd/display/modules/color/color_gamma.c   | 60 ++++++++++++-------
 1 file changed, 40 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
index ef742d95ef05..275f11f8bea3 100644
--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
+++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c
@@ -54,12 +54,18 @@ static struct hw_x_point coordinates_x[MAX_HW_POINTS + 2];
  * just multiply with 2^gamma which can be computed once, and save the result so we
  * recursively compute all the values.
  */
-										/*sRGB	 709 2.2 2.4 P3*/
-static const int32_t gamma_numerator01[] = { 31308,	180000,	0,	0,	0};
-static const int32_t gamma_numerator02[] = { 12920,	4500,	0,	0,	0};
-static const int32_t gamma_numerator03[] = { 55,	99,		0,	0,	0};
-static const int32_t gamma_numerator04[] = { 55,	99,		0,	0,	0};
-static const int32_t gamma_numerator05[] = { 2400,	2200,	2200, 2400, 2600};
+											 /*sRGB     709     2.2 2.4 P3*/
+static const int32_t regamma_numerator01[] = { 31308,   180000, 0,  0,  0};
+static const int32_t regamma_numerator02[] = { 12920,   4500,   0,  0,  0};
+static const int32_t regamma_numerator03[] = { 55,      99,     0,  0,  0};
+static const int32_t regamma_numerator04[] = { 55,      99,     0,  0,  0};
+static const int32_t regamma_numerator05[] = { 2400,    2200,   2200, 2400, 2600};
+
+static const int32_t degamma_numerator01[] = { 40450,   810000, 0,  0,  0};
+static const int32_t degamma_numerator02[] = { 12920,   4500,   0,  0,  0};
+static const int32_t degamma_numerator03[] = { 55,      99,     0,  0,  0};
+static const int32_t degamma_numerator04[] = { 55,      99,     0,  0,  0};
+static const int32_t degamma_numerator05[] = { 2400,    2200,   2200, 2400, 2600};
 
 /* one-time setup of X points */
 void setup_x_points_distribution(void)
@@ -288,7 +294,8 @@ struct dividers {
 };
 
 
-static bool build_coefficients(struct gamma_coefficients *coefficients, enum dc_transfer_func_predefined type)
+static bool build_coefficients(struct gamma_coefficients *coefficients,
+		enum dc_transfer_func_predefined type, bool isRegamma)
 {
 
 	uint32_t i = 0;
@@ -311,16 +318,29 @@ static bool build_coefficients(struct gamma_coefficients *coefficients, enum dc_
 	}
 
 	do {
-		coefficients->a0[i] = dc_fixpt_from_fraction(
-			gamma_numerator01[index], 10000000);
-		coefficients->a1[i] = dc_fixpt_from_fraction(
-			gamma_numerator02[index], 1000);
-		coefficients->a2[i] = dc_fixpt_from_fraction(
-			gamma_numerator03[index], 1000);
-		coefficients->a3[i] = dc_fixpt_from_fraction(
-			gamma_numerator04[index], 1000);
-		coefficients->user_gamma[i] = dc_fixpt_from_fraction(
-			gamma_numerator05[index], 1000);
+		if (isRegamma) {
+			coefficients->a0[i] = dc_fixpt_from_fraction(
+				regamma_numerator01[index], 10000000);
+			coefficients->a1[i] = dc_fixpt_from_fraction(
+				regamma_numerator02[index], 1000);
+			coefficients->a2[i] = dc_fixpt_from_fraction(
+				regamma_numerator03[index], 1000);
+			coefficients->a3[i] = dc_fixpt_from_fraction(
+				regamma_numerator04[index], 1000);
+			coefficients->user_gamma[i] = dc_fixpt_from_fraction(
+				regamma_numerator05[index], 1000);
+		} else {
+			coefficients->a0[i] = dc_fixpt_from_fraction(
+				degamma_numerator01[index], 10000000);
+			coefficients->a1[i] = dc_fixpt_from_fraction(
+				degamma_numerator02[index], 1000);
+			coefficients->a2[i] = dc_fixpt_from_fraction(
+				degamma_numerator03[index], 1000);
+			coefficients->a3[i] = dc_fixpt_from_fraction(
+				degamma_numerator04[index], 1000);
+			coefficients->user_gamma[i] = dc_fixpt_from_fraction(
+				degamma_numerator05[index], 1000);
+		}
 
 		++i;
 	} while (i != ARRAY_SIZE(coefficients->a0));
@@ -833,7 +853,7 @@ static bool build_regamma(struct pwl_float_data_ex *rgb_regamma,
 	if (!coeff)
 		goto release;
 
-	if (!build_coefficients(coeff, type))
+	if (!build_coefficients(coeff, type, true))
 		goto release;
 
 	memset(cal_buffer->buffer, 0, NUM_PTS_IN_REGION * sizeof(struct fixed31_32));
@@ -1082,7 +1102,7 @@ static bool build_degamma(struct pwl_float_data_ex *curve,
 	uint32_t begin_index, end_index;
 	bool ret = false;
 
-	if (!build_coefficients(&coeff, type))
+	if (!build_coefficients(&coeff, type, false))
 		goto release;
 
 	i = 0;
@@ -1685,7 +1705,7 @@ static void apply_degamma_for_user_regamma(struct pwl_float_data_ex *rgb_regamma
 	struct pwl_float_data_ex *rgb = rgb_regamma;
 	const struct hw_x_point *coord_x = coordinates_x;
 
-	build_coefficients(&coeff, TRANSFER_FUNCTION_SRGB);
+	build_coefficients(&coeff, TRANSFER_FUNCTION_SRGB, true);
 
 	i = 0;
 	while (i != hw_points_num + 1) {
-- 
2.38.1