From: Dmytro Laktyushkin Date: Tue, 28 Nov 2017 16:20:45 -0500 Subject: drm/amd/display: use clamping rather than truncation for CM fp conversions Git-commit: 78b56c52349596374dd47584d1f1db4d08609b7b Patch-mainline: v4.16-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 Signed-off-by: Dmytro Laktyushkin Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher Acked-by: Petr Tesarik --- drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c | 24 ++++++++++++++--- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 14 ++++----- drivers/gpu/drm/amd/display/include/fixed31_32.h | 4 +- 3 files changed, 29 insertions(+), 13 deletions(-) --- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c +++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c @@ -554,6 +554,22 @@ static inline uint32_t ux_dy( return result | fractional_part; } +static inline uint32_t clamp_ux_dy( + int64_t value, + uint32_t integer_bits, + uint32_t fractional_bits, + uint32_t min_clamp) +{ + uint32_t truncated_val = ux_dy(value, integer_bits, fractional_bits); + + if (value >= (1LL << (integer_bits + FIXED31_32_BITS_PER_FRACTIONAL_PART))) + return (1 << (integer_bits + fractional_bits)) - 1; + else if (truncated_val > min_clamp) + return truncated_val; + else + return min_clamp; +} + uint32_t dal_fixed31_32_u2d19( struct fixed31_32 arg) { @@ -566,14 +582,14 @@ uint32_t dal_fixed31_32_u0d19( return ux_dy(arg.value, 0, 19); } -uint32_t dal_fixed31_32_u0d14( +uint32_t dal_fixed31_32_clamp_u0d14( struct fixed31_32 arg) { - return ux_dy(arg.value, 1, 14); + return clamp_ux_dy(arg.value, 0, 14, 1); } -uint32_t dal_fixed31_32_u0d10( +uint32_t dal_fixed31_32_clamp_u0d10( struct fixed31_32 arg) { - return ux_dy(arg.value, 1, 10); + return clamp_ux_dy(arg.value, 0, 10, 1); } --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -169,7 +169,7 @@ bool cm_helper_convert_to_custom_float( } if (fixpoint == true) - arr_points[1].custom_float_y = dal_fixed31_32_u0d14(arr_points[1].y); + arr_points[1].custom_float_y = dal_fixed31_32_clamp_u0d14(arr_points[1].y); else if (!convert_to_custom_float_format(arr_points[1].y, &fmt, &arr_points[1].custom_float_y)) { BREAK_TO_DEBUGGER(); @@ -395,12 +395,12 @@ bool cm_helper_translate_curve_to_hw_for rgb->delta_blue = dal_fixed31_32_sub(rgb_plus_1->blue, rgb->blue); if (fixpoint == true) { - rgb->delta_red_reg = dal_fixed31_32_u0d10(rgb->delta_red); - rgb->delta_green_reg = dal_fixed31_32_u0d10(rgb->delta_green); - rgb->delta_blue_reg = dal_fixed31_32_u0d10(rgb->delta_blue); - rgb->red_reg = dal_fixed31_32_u0d14(rgb->red); - rgb->green_reg = dal_fixed31_32_u0d14(rgb->green); - rgb->blue_reg = dal_fixed31_32_u0d14(rgb->blue); + rgb->delta_red_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_red); + rgb->delta_green_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_green); + rgb->delta_blue_reg = dal_fixed31_32_clamp_u0d10(rgb->delta_blue); + rgb->red_reg = dal_fixed31_32_clamp_u0d14(rgb->red); + rgb->green_reg = dal_fixed31_32_clamp_u0d14(rgb->green); + rgb->blue_reg = dal_fixed31_32_clamp_u0d14(rgb->blue); } ++rgb_plus_1; --- a/drivers/gpu/drm/amd/display/include/fixed31_32.h +++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h @@ -464,10 +464,10 @@ uint32_t dal_fixed31_32_u0d19( struct fixed31_32 arg); -uint32_t dal_fixed31_32_u0d14( +uint32_t dal_fixed31_32_clamp_u0d14( struct fixed31_32 arg); -uint32_t dal_fixed31_32_u0d10( +uint32_t dal_fixed31_32_clamp_u0d10( struct fixed31_32 arg); #endif