Commit 34fa493a authored by Calvin Hou's avatar Calvin Hou Committed by Alex Deucher

drm/amd/display: Correct algorithm for reversed gamma

[Why]
DCN30 needs to correctly program reversed gamma curve, which DCN20
already has.
Also needs to fix a bug that 252-255 values are clipped.

[How]
Apply two fixes into DCN30.

Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1513Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarCalvin Hou <Calvin.Hou@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Reviewed-by: default avatarKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Acked-by: default avatarSolomon Chiu <solomon.chiu@amd.com>
Acked-by: default avatarVladimir Stempen <Vladimir.Stempen@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent 73076790
...@@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -113,6 +113,7 @@ bool cm3_helper_translate_curve_to_hw_format(
struct pwl_result_data *rgb_resulted; struct pwl_result_data *rgb_resulted;
struct pwl_result_data *rgb; struct pwl_result_data *rgb;
struct pwl_result_data *rgb_plus_1; struct pwl_result_data *rgb_plus_1;
struct pwl_result_data *rgb_minus_1;
struct fixed31_32 end_value; struct fixed31_32 end_value;
int32_t region_start, region_end; int32_t region_start, region_end;
...@@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -140,7 +141,7 @@ bool cm3_helper_translate_curve_to_hw_format(
region_start = -MAX_LOW_POINT; region_start = -MAX_LOW_POINT;
region_end = NUMBER_REGIONS - MAX_LOW_POINT; region_end = NUMBER_REGIONS - MAX_LOW_POINT;
} else { } else {
/* 10 segments /* 11 segments
* segment is from 2^-10 to 2^0 * segment is from 2^-10 to 2^0
* There are less than 256 points, for optimization * There are less than 256 points, for optimization
*/ */
...@@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -154,9 +155,10 @@ bool cm3_helper_translate_curve_to_hw_format(
seg_distr[7] = 4; seg_distr[7] = 4;
seg_distr[8] = 4; seg_distr[8] = 4;
seg_distr[9] = 4; seg_distr[9] = 4;
seg_distr[10] = 1;
region_start = -10; region_start = -10;
region_end = 0; region_end = 1;
} }
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
...@@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -189,6 +191,10 @@ bool cm3_helper_translate_curve_to_hw_format(
rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index];
rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index];
rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red;
rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green;
rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue;
// All 3 color channels have same x // All 3 color channels have same x
corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2),
dc_fixpt_from_int(region_start)); dc_fixpt_from_int(region_start));
...@@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -259,15 +265,18 @@ bool cm3_helper_translate_curve_to_hw_format(
rgb = rgb_resulted; rgb = rgb_resulted;
rgb_plus_1 = rgb_resulted + 1; rgb_plus_1 = rgb_resulted + 1;
rgb_minus_1 = rgb;
i = 1; i = 1;
while (i != hw_points + 1) { while (i != hw_points + 1) {
if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) if (i >= hw_points - 1) {
rgb_plus_1->red = rgb->red; if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red);
rgb_plus_1->green = rgb->green; if (dc_fixpt_lt(rgb_plus_1->green, rgb->green))
if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green);
rgb_plus_1->blue = rgb->blue; if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue))
rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue);
}
rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red);
rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
...@@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_format( ...@@ -283,6 +292,7 @@ bool cm3_helper_translate_curve_to_hw_format(
} }
++rgb_plus_1; ++rgb_plus_1;
rgb_minus_1 = rgb;
++rgb; ++rgb;
++i; ++i;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment