drm/amd/display: DGAM enabled for HDR
authorKrunoslav Kovac <Krunoslav.Kovac@amd.com>
Thu, 17 Jan 2019 22:56:51 +0000 (17:56 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 6 Feb 2019 02:16:23 +0000 (21:16 -0500)
[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.

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>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/modules/color/color_gamma.c

index eefb85928298b11aed866f5d9f677d5be3c49d56..0fbc8fbc354160e66b6a8cfc75b228241723b326 100644 (file)
@@ -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;
-
 }