diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1206-drm-amd-display-DGAM-enabled-for-HDR.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1206-drm-amd-display-DGAM-enabled-for-HDR.patch | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1206-drm-amd-display-DGAM-enabled-for-HDR.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1206-drm-amd-display-DGAM-enabled-for-HDR.patch new file mode 100644 index 00000000..be838168 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/1206-drm-amd-display-DGAM-enabled-for-HDR.patch @@ -0,0 +1,173 @@ +From 3c54a05334e7eb95b50ba01a32e287bc79e707f5 Mon Sep 17 00:00:00 2001 +From: Krunoslav Kovac <Krunoslav.Kovac@amd.com> +Date: Thu, 17 Jan 2019 17:56:51 -0500 +Subject: [PATCH 1206/2940] drm/amd/display: DGAM enabled for HDR + +[Why] +On HW that doesn't have input LUT, we may combine degamma with OS ramp +Problem here is that it assumes DGAM is inverse of PQ or SRGB. It doesn't +handle linear case, it would default to sRGB and always enable DGAM.. + +[How] Add handling for linear case. Also check for null ramp and instead of +blowing up, assume it's identity. + +Change-Id: Ic8061248570d6aaf09ad4c2315a0d82312ebcd71 +Signed-off-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> +Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +--- + .../amd/display/modules/color/color_gamma.c | 89 +++++++++++-------- + 1 file changed, 52 insertions(+), 37 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 eefb85928298..0fbc8fbc3541 100644 +--- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c ++++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +@@ -1765,68 +1765,85 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, + { + struct dc_transfer_func_distributed_points *tf_pts = &input_tf->tf_pts; + struct dividers dividers; +- + struct pwl_float_data *rgb_user = NULL; + struct pwl_float_data_ex *curve = NULL; + struct gamma_pixel *axis_x = NULL; + struct pixel_gamma_point *coeff = NULL; + enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB; ++ uint32_t i; + bool ret = false; + + if (input_tf->type == TF_TYPE_BYPASS) + return false; + +- /* we can use hardcoded curve for plain SRGB TF */ ++ /* we can use hardcoded curve for plain SRGB TF ++ * If linear, it's bypass if on user ramp ++ */ + if (input_tf->type == TF_TYPE_PREDEFINED && +- input_tf->tf == TRANSFER_FUNCTION_SRGB && +- !mapUserRamp) ++ (input_tf->tf == TRANSFER_FUNCTION_SRGB || ++ input_tf->tf == TRANSFER_FUNCTION_LINEAR) && ++ !mapUserRamp) + return true; + + input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; + +- rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, +- sizeof(*rgb_user), +- GFP_KERNEL); +- if (!rgb_user) +- goto rgb_user_alloc_fail; ++ if (mapUserRamp && ramp && ramp->type == GAMMA_RGB_256) { ++ rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, ++ sizeof(*rgb_user), ++ GFP_KERNEL); ++ if (!rgb_user) ++ goto rgb_user_alloc_fail; ++ ++ axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), ++ GFP_KERNEL); ++ if (!axis_x) ++ goto axis_x_alloc_fail; ++ ++ dividers.divider1 = dc_fixpt_from_fraction(3, 2); ++ dividers.divider2 = dc_fixpt_from_int(2); ++ dividers.divider3 = dc_fixpt_from_fraction(5, 2); ++ ++ build_evenly_distributed_points( ++ axis_x, ++ ramp->num_entries, ++ dividers); ++ ++ scale_gamma(rgb_user, ramp, dividers); ++ } ++ + curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve), +- GFP_KERNEL); ++ GFP_KERNEL); + if (!curve) + goto curve_alloc_fail; +- axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), +- GFP_KERNEL); +- if (!axis_x) +- goto axis_x_alloc_fail; ++ + coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff), +- GFP_KERNEL); ++ GFP_KERNEL); + if (!coeff) + goto coeff_alloc_fail; + +- dividers.divider1 = dc_fixpt_from_fraction(3, 2); +- dividers.divider2 = dc_fixpt_from_int(2); +- dividers.divider3 = dc_fixpt_from_fraction(5, 2); +- + tf = input_tf->tf; + +- build_evenly_distributed_points( +- axis_x, +- ramp->num_entries, +- dividers); +- +- if (ramp->type == GAMMA_RGB_256 && mapUserRamp) +- scale_gamma(rgb_user, ramp, dividers); +- else if (ramp->type == GAMMA_RGB_FLOAT_1024) +- scale_gamma_dx(rgb_user, ramp, dividers); +- + if (tf == TRANSFER_FUNCTION_PQ) + build_de_pq(curve, + MAX_HW_POINTS, + coordinates_x); +- else ++ else if (tf == TRANSFER_FUNCTION_SRGB || ++ tf == TRANSFER_FUNCTION_BT709) + build_degamma(curve, + MAX_HW_POINTS, + coordinates_x, +- tf == TRANSFER_FUNCTION_SRGB ? true:false); ++ tf == TRANSFER_FUNCTION_SRGB ? true : false); ++ else if (tf == TRANSFER_FUNCTION_LINEAR) { ++ // just copy coordinates_x into curve ++ i = 0; ++ while (i != MAX_HW_POINTS + 1) { ++ curve[i].r = coordinates_x[i].x; ++ curve[i].g = curve[i].r; ++ curve[i].b = curve[i].r; ++ i++; ++ } ++ } else ++ goto invalid_tf_fail; + + tf_pts->end_exponent = 0; + tf_pts->x_point_at_y1_red = 1; +@@ -1836,23 +1853,21 @@ bool mod_color_calculate_degamma_params(struct dc_transfer_func *input_tf, + map_regamma_hw_to_x_user(ramp, coeff, rgb_user, + coordinates_x, axis_x, curve, + MAX_HW_POINTS, tf_pts, +- mapUserRamp && ramp->type != GAMMA_CUSTOM); +- if (ramp->type == GAMMA_CUSTOM) +- apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts); ++ mapUserRamp && ramp && ramp->type == GAMMA_RGB_256); + + ret = true; + ++invalid_tf_fail: + kvfree(coeff); + coeff_alloc_fail: +- kvfree(axis_x); +-axis_x_alloc_fail: + kvfree(curve); + curve_alloc_fail: ++ kvfree(axis_x); ++axis_x_alloc_fail: + kvfree(rgb_user); + rgb_user_alloc_fail: + + return ret; +- + } + + +-- +2.17.1 + |