drm/amd/display: Output Transfer Function Regamma Refactor
authorAmy Zhang <Amy.Zhang@amd.com>
Thu, 5 Jan 2017 22:12:20 +0000 (17:12 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 21:09:48 +0000 (17:09 -0400)
- Create translation function to translate logical format to hw format
- Refactor to use transfer function in dc instead of input gamma

Signed-off-by: Amy Zhang <Amy.Zhang@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
drivers/gpu/drm/amd/display/dc/calcs/Makefile
drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c [deleted file]
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h [deleted file]
drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
drivers/gpu/drm/amd/display/include/fixed31_32.h

index 5a6e468..546ed67 100644 (file)
@@ -246,6 +246,15 @@ struct fixed31_32 dal_fixed31_32_add(
        return res;
 }
 
+struct fixed31_32 dal_fixed31_32_add_int(
+       struct fixed31_32 arg1,
+       int32_t arg2)
+{
+       return dal_fixed31_32_add(
+               arg1,
+               dal_fixed31_32_from_int(arg2));
+}
+
 struct fixed31_32 dal_fixed31_32_sub_int(
        struct fixed31_32 arg1,
        int32_t arg2)
index 4001933..4bb08ae 100644 (file)
@@ -3,7 +3,7 @@
 # It calculates Bandwidth and Watermarks values for HW programming
 #
 
-BW_CALCS = bandwidth_calcs.o bw_fixed.o gamma_calcs.o
+BW_CALCS = bandwidth_calcs.o bw_fixed.o
 
 AMD_DAL_BW_CALCS = $(addprefix $(AMDDALPATH)/dc/calcs/,$(BW_CALCS))
 
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
deleted file mode 100644 (file)
index fd300db..0000000
+++ /dev/null
@@ -1,1481 +0,0 @@
-/*
- * Copyright 2015 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: AMD
- *
- */
-
-#include "dm_services.h"
-#include "gamma_calcs.h"
-
-struct curve_config {
-       uint32_t offset;
-       int8_t segments[16];
-       int8_t begin;
-};
-
-static bool build_custom_float(
-       struct fixed31_32 value,
-       const struct custom_float_format *format,
-       bool *negative,
-       uint32_t *mantissa,
-       uint32_t *exponenta)
-{
-       uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
-
-       const struct fixed31_32 mantissa_constant_plus_max_fraction =
-               dal_fixed31_32_from_fraction(
-                       (1LL << (format->mantissa_bits + 1)) - 1,
-                       1LL << format->mantissa_bits);
-
-       struct fixed31_32 mantiss;
-
-       if (dal_fixed31_32_eq(
-               value,
-               dal_fixed31_32_zero)) {
-               *negative = false;
-               *mantissa = 0;
-               *exponenta = 0;
-               return true;
-       }
-
-       if (dal_fixed31_32_lt(
-               value,
-               dal_fixed31_32_zero)) {
-               *negative = format->sign;
-               value = dal_fixed31_32_neg(value);
-       } else {
-               *negative = false;
-       }
-
-       if (dal_fixed31_32_lt(
-               value,
-               dal_fixed31_32_one)) {
-               uint32_t i = 1;
-
-               do {
-                       value = dal_fixed31_32_shl(value, 1);
-                       ++i;
-               } while (dal_fixed31_32_lt(
-                       value,
-                       dal_fixed31_32_one));
-
-               --i;
-
-               if (exp_offset <= i) {
-                       *mantissa = 0;
-                       *exponenta = 0;
-                       return true;
-               }
-
-               *exponenta = exp_offset - i;
-       } else if (dal_fixed31_32_le(
-               mantissa_constant_plus_max_fraction,
-               value)) {
-               uint32_t i = 1;
-
-               do {
-                       value = dal_fixed31_32_shr(value, 1);
-                       ++i;
-               } while (dal_fixed31_32_lt(
-                       mantissa_constant_plus_max_fraction,
-                       value));
-
-               *exponenta = exp_offset + i - 1;
-       } else {
-               *exponenta = exp_offset;
-       }
-
-       mantiss = dal_fixed31_32_sub(
-               value,
-               dal_fixed31_32_one);
-
-       if (dal_fixed31_32_lt(
-                       mantiss,
-                       dal_fixed31_32_zero) ||
-               dal_fixed31_32_lt(
-                       dal_fixed31_32_one,
-                       mantiss))
-               mantiss = dal_fixed31_32_zero;
-       else
-               mantiss = dal_fixed31_32_shl(
-                       mantiss,
-                       format->mantissa_bits);
-
-       *mantissa = dal_fixed31_32_floor(mantiss);
-
-       return true;
-}
-
-static bool setup_custom_float(
-       const struct custom_float_format *format,
-       bool negative,
-       uint32_t mantissa,
-       uint32_t exponenta,
-       uint32_t *result)
-{
-       uint32_t i = 0;
-       uint32_t j = 0;
-
-       uint32_t value = 0;
-
-       /* verification code:
-        * once calculation is ok we can remove it
-        */
-
-       const uint32_t mantissa_mask =
-               (1 << (format->mantissa_bits + 1)) - 1;
-
-       const uint32_t exponenta_mask =
-               (1 << (format->exponenta_bits + 1)) - 1;
-
-       if (mantissa & ~mantissa_mask) {
-               BREAK_TO_DEBUGGER();
-               mantissa = mantissa_mask;
-       }
-
-       if (exponenta & ~exponenta_mask) {
-               BREAK_TO_DEBUGGER();
-               exponenta = exponenta_mask;
-       }
-
-       /* end of verification code */
-
-       while (i < format->mantissa_bits) {
-               uint32_t mask = 1 << i;
-
-               if (mantissa & mask)
-                       value |= mask;
-
-               ++i;
-       }
-
-       while (j < format->exponenta_bits) {
-               uint32_t mask = 1 << j;
-
-               if (exponenta & mask)
-                       value |= mask << i;
-
-               ++j;
-       }
-
-       if (negative && format->sign)
-               value |= 1 << (i + j);
-
-       *result = value;
-
-       return true;
-}
-
-static bool build_hw_curve_configuration(
-       const struct curve_config *curve_config,
-       struct gamma_curve *gamma_curve,
-       struct curve_points *curve_points,
-       struct hw_x_point *points,
-       uint32_t *number_of_points)
-{
-       const int8_t max_regions_number = ARRAY_SIZE(curve_config->segments);
-
-       int8_t i;
-
-       uint8_t segments_calculation[8] = { 0 };
-
-       struct fixed31_32 region1 = dal_fixed31_32_zero;
-       struct fixed31_32 region2;
-       struct fixed31_32 increment;
-
-       uint32_t index = 0;
-       uint32_t segments = 0;
-       uint32_t max_number;
-
-       int8_t num_regions = 0;
-
-       bool result = false;
-
-       if (!number_of_points) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       max_number = *number_of_points;
-
-       i = 0;
-
-       while (i != max_regions_number) {
-               gamma_curve[i].offset = 0;
-               gamma_curve[i].segments_num = 0;
-
-               ++i;
-       }
-
-       i = 0;
-
-       while (i != max_regions_number) {
-               /* number should go in uninterruptible sequence */
-               if (curve_config->segments[i] == -1)
-                       break;
-
-               ASSERT(curve_config->segments[i] >= 0);
-
-               segments += (1 << curve_config->segments[i]);
-               ++num_regions;
-
-               ++i;
-       }
-
-       if (segments > max_number) {
-               BREAK_TO_DEBUGGER();
-       } else {
-               int32_t divisor;
-               uint32_t offset = 0;
-               int8_t begin = curve_config->begin;
-               int32_t region_number = 0;
-
-               i = begin;
-
-               while ((index < max_number) &&
-                       (region_number < max_regions_number) &&
-                       (i < (begin + num_regions))) {
-                       int32_t j = 0;
-
-                       segments = curve_config->segments[region_number];
-                       divisor = 1 << segments;
-
-                       if (segments == -1) {
-                               if (i > 0) {
-                                       region1 = dal_fixed31_32_shl(
-                                               dal_fixed31_32_one,
-                                               i - 1);
-                                       region2 = dal_fixed31_32_shl(
-                                               dal_fixed31_32_one,
-                                               i);
-                               } else {
-                                       region1 = dal_fixed31_32_shr(
-                                               dal_fixed31_32_one,
-                                               -(i - 1));
-                                       region2 = dal_fixed31_32_shr(
-                                               dal_fixed31_32_one,
-                                               -i);
-                               }
-
-                               break;
-                       }
-
-                       if (i > -1) {
-                               region1 = dal_fixed31_32_shl(
-                                       dal_fixed31_32_one,
-                                       i);
-                               region2 = dal_fixed31_32_shl(
-                                       dal_fixed31_32_one,
-                                       i + 1);
-                       } else {
-                               region1 = dal_fixed31_32_shr(
-                                       dal_fixed31_32_one,
-                                       -i);
-                               region2 = dal_fixed31_32_shr(
-                                       dal_fixed31_32_one,
-                                       -(i + 1));
-                       }
-
-                       gamma_curve[region_number].offset = offset;
-                       gamma_curve[region_number].segments_num = segments;
-
-                       offset += divisor;
-
-                       ++segments_calculation[segments];
-
-                       increment = dal_fixed31_32_div_int(
-                               dal_fixed31_32_sub(
-                                       region2,
-                                       region1),
-                               divisor);
-
-                       points[index].x = region1;
-                       points[index].adjusted_x = region1;
-
-                       ++index;
-                       ++region_number;
-
-                       while ((index < max_number) && (j < divisor - 1)) {
-                               region1 = dal_fixed31_32_add(
-                                       region1,
-                                       increment);
-
-                               points[index].x = region1;
-                               points[index].adjusted_x = region1;
-
-                               ++index;
-                               ++j;
-                       }
-
-                       ++i;
-               }
-
-               points[index].x = region1;
-               points[index].adjusted_x = region1;
-
-               *number_of_points = index;
-
-               result = true;
-       }
-
-       curve_points[0].x = points[0].adjusted_x;
-       curve_points[0].offset = dal_fixed31_32_zero;
-
-       curve_points[1].x = points[index - 1].adjusted_x;
-       curve_points[1].offset = dal_fixed31_32_zero;
-
-       curve_points[2].x = points[index].adjusted_x;
-       curve_points[2].offset = dal_fixed31_32_zero;
-
-       return result;
-}
-
-static bool setup_distribution_points_pq(
-               struct gamma_curve *arr_curve_points,
-               struct curve_points *arr_points,
-               uint32_t *hw_points_num,
-               struct hw_x_point *coordinates_x,
-               enum surface_pixel_format format)
-{
-       struct curve_config cfg;
-
-       cfg.offset = 0;
-       cfg.segments[0] = 2;
-       cfg.segments[1] = 2;
-       cfg.segments[2] = 2;
-       cfg.segments[3] = 2;
-       cfg.segments[4] = 2;
-       cfg.segments[5] = 2;
-       cfg.segments[6] = 3;
-       cfg.segments[7] = 4;
-       cfg.segments[8] = 4;
-       cfg.segments[9] = 4;
-       cfg.segments[10] = 4;
-       cfg.segments[11] = 5;
-       cfg.segments[12] = 5;
-       cfg.segments[13] = 5;
-       cfg.segments[14] = 5;
-       cfg.segments[15] = 5;
-
-       if (format == SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F ||
-                       format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F)
-               cfg.begin = -11;
-       else
-               cfg.begin = -16;
-
-       if (!build_hw_curve_configuration(
-               &cfg, arr_curve_points,
-               arr_points,
-               coordinates_x, hw_points_num)) {
-               ASSERT_CRITICAL(false);
-               return false;
-       }
-       return true;
-}
-
-static bool setup_distribution_points(
-               struct gamma_curve *arr_curve_points,
-               struct curve_points *arr_points,
-               uint32_t *hw_points_num,
-               struct hw_x_point *coordinates_x)
-{
-       struct curve_config cfg;
-
-       cfg.offset = 0;
-       cfg.segments[0] = 3;
-       cfg.segments[1] = 4;
-       cfg.segments[2] = 4;
-       cfg.segments[3] = 4;
-       cfg.segments[4] = 4;
-       cfg.segments[5] = 4;
-       cfg.segments[6] = 4;
-       cfg.segments[7] = 4;
-       cfg.segments[8] = 5;
-       cfg.segments[9] = 5;
-       cfg.segments[10] = 0;
-       cfg.segments[11] = -1;
-       cfg.segments[12] = -1;
-       cfg.segments[13] = -1;
-       cfg.segments[14] = -1;
-       cfg.segments[15] = -1;
-
-       cfg.begin = -10;
-
-       if (!build_hw_curve_configuration(
-               &cfg, arr_curve_points,
-               arr_points,
-               coordinates_x, hw_points_num)) {
-               ASSERT_CRITICAL(false);
-               return false;
-       }
-       return true;
-}
-
-struct dividers {
-       struct fixed31_32 divider1;
-       struct fixed31_32 divider2;
-       struct fixed31_32 divider3;
-};
-
-static void build_regamma_coefficients(struct gamma_coefficients *coefficients)
-{
-       /* sRGB should apply 2.4 */
-       static const int32_t numerator01[3] = { 31308, 31308, 31308 };
-       static const int32_t numerator02[3] = { 12920, 12920, 12920 };
-       static const int32_t numerator03[3] = { 55, 55, 55 };
-       static const int32_t numerator04[3] = { 55, 55, 55 };
-       static const int32_t numerator05[3] = { 2400, 2400, 2400 };
-
-       const int32_t *numerator1;
-       const int32_t *numerator2;
-       const int32_t *numerator3;
-       const int32_t *numerator4;
-       const int32_t *numerator5;
-
-       uint32_t i = 0;
-
-       numerator1 = numerator01;
-       numerator2 = numerator02;
-       numerator3 = numerator03;
-       numerator4 = numerator04;
-       numerator5 = numerator05;
-
-       do {
-               coefficients->a0[i] = dal_fixed31_32_from_fraction(
-                       numerator1[i], 10000000);
-               coefficients->a1[i] = dal_fixed31_32_from_fraction(
-                       numerator2[i], 1000);
-               coefficients->a2[i] = dal_fixed31_32_from_fraction(
-                       numerator3[i], 1000);
-               coefficients->a3[i] = dal_fixed31_32_from_fraction(
-                       numerator4[i], 1000);
-               coefficients->user_gamma[i] = dal_fixed31_32_from_fraction(
-                       numerator5[i], 1000);
-
-               ++i;
-       } while (i != ARRAY_SIZE(coefficients->a0));
-}
-
-static struct fixed31_32 translate_from_linear_space(
-       struct fixed31_32 arg,
-       struct fixed31_32 a0,
-       struct fixed31_32 a1,
-       struct fixed31_32 a2,
-       struct fixed31_32 a3,
-       struct fixed31_32 gamma)
-{
-       const struct fixed31_32 one = dal_fixed31_32_from_int(1);
-
-       if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0)))
-               return dal_fixed31_32_sub(
-                       a2,
-                       dal_fixed31_32_mul(
-                               dal_fixed31_32_add(
-                                       one,
-                                       a3),
-                               dal_fixed31_32_pow(
-                                       dal_fixed31_32_neg(arg),
-                                       dal_fixed31_32_recip(gamma))));
-       else if (dal_fixed31_32_le(a0, arg))
-               return dal_fixed31_32_sub(
-                       dal_fixed31_32_mul(
-                               dal_fixed31_32_add(
-                                       one,
-                                       a3),
-                               dal_fixed31_32_pow(
-                                       arg,
-                                       dal_fixed31_32_recip(gamma))),
-                       a2);
-       else
-               return dal_fixed31_32_mul(
-                       arg,
-                       a1);
-}
-
-static inline struct fixed31_32 translate_from_linear_space_ex(
-       struct fixed31_32 arg,
-       struct gamma_coefficients *coeff,
-       uint32_t color_index)
-{
-       return translate_from_linear_space(
-               arg,
-               coeff->a0[color_index],
-               coeff->a1[color_index],
-               coeff->a2[color_index],
-               coeff->a3[color_index],
-               coeff->user_gamma[color_index]);
-}
-
-static bool find_software_points(
-       const struct gamma_pixel *axis_x_256,
-       struct fixed31_32 hw_point,
-       enum channel_name channel,
-       uint32_t *index_to_start,
-       uint32_t *index_left,
-       uint32_t *index_right,
-       enum hw_point_position *pos)
-{
-       const uint32_t max_number = INPUT_LUT_ENTRIES + 3;
-
-       struct fixed31_32 left, right;
-
-       uint32_t i = *index_to_start;
-
-       while (i < max_number) {
-               if (channel == CHANNEL_NAME_RED) {
-                       left = axis_x_256[i].r;
-
-                       if (i < max_number - 1)
-                               right = axis_x_256[i + 1].r;
-                       else
-                               right = axis_x_256[max_number - 1].r;
-               } else if (channel == CHANNEL_NAME_GREEN) {
-                       left = axis_x_256[i].g;
-
-                       if (i < max_number - 1)
-                               right = axis_x_256[i + 1].g;
-                       else
-                               right = axis_x_256[max_number - 1].g;
-               } else {
-                       left = axis_x_256[i].b;
-
-                       if (i < max_number - 1)
-                               right = axis_x_256[i + 1].b;
-                       else
-                               right = axis_x_256[max_number - 1].b;
-               }
-
-               if (dal_fixed31_32_le(left, hw_point) &&
-                       dal_fixed31_32_le(hw_point, right)) {
-                       *index_to_start = i;
-                       *index_left = i;
-
-                       if (i < max_number - 1)
-                               *index_right = i + 1;
-                       else
-                               *index_right = max_number - 1;
-
-                       *pos = HW_POINT_POSITION_MIDDLE;
-
-                       return true;
-               } else if ((i == *index_to_start) &&
-                       dal_fixed31_32_le(hw_point, left)) {
-                       *index_to_start = i;
-                       *index_left = i;
-                       *index_right = i;
-
-                       *pos = HW_POINT_POSITION_LEFT;
-
-                       return true;
-               } else if ((i == max_number - 1) &&
-                       dal_fixed31_32_le(right, hw_point)) {
-                       *index_to_start = i;
-                       *index_left = i;
-                       *index_right = i;
-
-                       *pos = HW_POINT_POSITION_RIGHT;
-
-                       return true;
-               }
-
-               ++i;
-       }
-
-       return false;
-}
-
-static bool build_custom_gamma_mapping_coefficients_worker(
-       struct pixel_gamma_point *coeff,
-       const struct hw_x_point *coordinates_x,
-       const struct gamma_pixel *axis_x_256,
-       enum channel_name channel,
-       uint32_t number_of_points,
-       enum surface_pixel_format pixel_format)
-{
-       uint32_t i = 0;
-
-       while (i <= number_of_points) {
-               struct fixed31_32 coord_x;
-
-               uint32_t index_to_start = 0;
-               uint32_t index_left = 0;
-               uint32_t index_right = 0;
-
-               enum hw_point_position hw_pos;
-
-               struct gamma_point *point;
-
-               struct fixed31_32 left_pos;
-               struct fixed31_32 right_pos;
-
-               /*
-                * TODO: confirm enum in surface_pixel_format
-                * if (pixel_format == PIXEL_FORMAT_FP16)
-                *coord_x = coordinates_x[i].adjusted_x;
-                *else
-                */
-               if (channel == CHANNEL_NAME_RED)
-                       coord_x = coordinates_x[i].regamma_y_red;
-               else if (channel == CHANNEL_NAME_GREEN)
-                       coord_x = coordinates_x[i].regamma_y_green;
-               else
-                       coord_x = coordinates_x[i].regamma_y_blue;
-
-               if (!find_software_points(
-                       axis_x_256, coord_x, channel,
-                       &index_to_start, &index_left, &index_right, &hw_pos)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (index_left >= INPUT_LUT_ENTRIES + 3) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (index_right >= INPUT_LUT_ENTRIES + 3) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (channel == CHANNEL_NAME_RED) {
-                       point = &coeff[i].r;
-
-                       left_pos = axis_x_256[index_left].r;
-                       right_pos = axis_x_256[index_right].r;
-               } else if (channel == CHANNEL_NAME_GREEN) {
-                       point = &coeff[i].g;
-
-                       left_pos = axis_x_256[index_left].g;
-                       right_pos = axis_x_256[index_right].g;
-               } else {
-                       point = &coeff[i].b;
-
-                       left_pos = axis_x_256[index_left].b;
-                       right_pos = axis_x_256[index_right].b;
-               }
-
-               if (hw_pos == HW_POINT_POSITION_MIDDLE)
-                       point->coeff = dal_fixed31_32_div(
-                               dal_fixed31_32_sub(
-                                       coord_x,
-                                       left_pos),
-                               dal_fixed31_32_sub(
-                                       right_pos,
-                                       left_pos));
-               else if (hw_pos == HW_POINT_POSITION_LEFT)
-                       point->coeff = dal_fixed31_32_zero;
-               else if (hw_pos == HW_POINT_POSITION_RIGHT)
-                       point->coeff = dal_fixed31_32_from_int(2);
-               else {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               point->left_index = index_left;
-               point->right_index = index_right;
-               point->pos = hw_pos;
-
-               ++i;
-       }
-
-       return true;
-}
-
-static inline bool build_oem_custom_gamma_mapping_coefficients(
-       struct pixel_gamma_point *coeff128_oem,
-       const struct hw_x_point *coordinates_x,
-       const struct gamma_pixel *axis_x_256,
-       uint32_t number_of_points,
-       enum surface_pixel_format pixel_format)
-{
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               if (!build_custom_gamma_mapping_coefficients_worker(
-                               coeff128_oem, coordinates_x, axis_x_256, i,
-                               number_of_points, pixel_format))
-                       return false;
-       }
-       return true;
-}
-
-static struct fixed31_32 calculate_mapped_value(
-       struct pwl_float_data *rgb,
-       const struct pixel_gamma_point *coeff,
-       enum channel_name channel,
-       uint32_t max_index)
-{
-       const struct gamma_point *point;
-
-       struct fixed31_32 result;
-
-       if (channel == CHANNEL_NAME_RED)
-               point = &coeff->r;
-       else if (channel == CHANNEL_NAME_GREEN)
-               point = &coeff->g;
-       else
-               point = &coeff->b;
-
-       if ((point->left_index < 0) || (point->left_index > max_index)) {
-               BREAK_TO_DEBUGGER();
-               return dal_fixed31_32_zero;
-       }
-
-       if ((point->right_index < 0) || (point->right_index > max_index)) {
-               BREAK_TO_DEBUGGER();
-               return dal_fixed31_32_zero;
-       }
-
-       if (point->pos == HW_POINT_POSITION_MIDDLE)
-               if (channel == CHANNEL_NAME_RED)
-                       result = dal_fixed31_32_add(
-                               dal_fixed31_32_mul(
-                                       point->coeff,
-                                       dal_fixed31_32_sub(
-                                               rgb[point->right_index].r,
-                                               rgb[point->left_index].r)),
-                               rgb[point->left_index].r);
-               else if (channel == CHANNEL_NAME_GREEN)
-                       result = dal_fixed31_32_add(
-                               dal_fixed31_32_mul(
-                                       point->coeff,
-                                       dal_fixed31_32_sub(
-                                               rgb[point->right_index].g,
-                                               rgb[point->left_index].g)),
-                               rgb[point->left_index].g);
-               else
-                       result = dal_fixed31_32_add(
-                               dal_fixed31_32_mul(
-                                       point->coeff,
-                                       dal_fixed31_32_sub(
-                                               rgb[point->right_index].b,
-                                               rgb[point->left_index].b)),
-                               rgb[point->left_index].b);
-       else if (point->pos == HW_POINT_POSITION_LEFT) {
-               BREAK_TO_DEBUGGER();
-               result = dal_fixed31_32_zero;
-       } else {
-               BREAK_TO_DEBUGGER();
-               result = dal_fixed31_32_one;
-       }
-
-       return result;
-}
-
-static inline struct fixed31_32 calculate_oem_mapped_value(
-       struct pwl_float_data *rgb_oem,
-       const struct pixel_gamma_point *coeff,
-       uint32_t index,
-       enum channel_name channel,
-       uint32_t max_index)
-{
-       return calculate_mapped_value(
-                       rgb_oem,
-                       coeff + index,
-                       channel,
-                       max_index);
-}
-
-static void compute_pq(struct fixed31_32 in_x, struct fixed31_32 *out_y)
-{
-       /* consts for PQ gamma formula. */
-       const struct fixed31_32 m1 =
-               dal_fixed31_32_from_fraction(159301758, 1000000000);
-       const struct fixed31_32 m2 =
-               dal_fixed31_32_from_fraction(7884375, 100000);
-       const struct fixed31_32 c1 =
-               dal_fixed31_32_from_fraction(8359375, 10000000);
-       const struct fixed31_32 c2 =
-               dal_fixed31_32_from_fraction(188515625, 10000000);
-       const struct fixed31_32 c3 =
-               dal_fixed31_32_from_fraction(186875, 10000);
-
-       struct fixed31_32 l_pow_m1;
-       struct fixed31_32 base;
-
-       if (dal_fixed31_32_lt(in_x, dal_fixed31_32_zero))
-               in_x = dal_fixed31_32_zero;
-
-       l_pow_m1 = dal_fixed31_32_pow(in_x, m1);
-       base = dal_fixed31_32_div(
-                       dal_fixed31_32_add(c1,
-                                       (dal_fixed31_32_mul(c2, l_pow_m1))),
-                       dal_fixed31_32_add(dal_fixed31_32_one,
-                                       (dal_fixed31_32_mul(c3, l_pow_m1))));
-       *out_y = dal_fixed31_32_pow(base, m2);
-}
-
-static void build_regamma_curve_pq(struct pwl_float_data_ex *rgb_regamma,
-               struct pwl_float_data *rgb_oem,
-               struct pixel_gamma_point *coeff128_oem,
-               const struct core_gamma *ramp,
-               const struct core_surface *surface,
-               uint32_t hw_points_num,
-               const struct hw_x_point *coordinate_x,
-               const struct gamma_pixel *axis_x,
-               struct dividers dividers)
-{
-       uint32_t i;
-
-       struct pwl_float_data_ex *rgb = rgb_regamma;
-       const struct hw_x_point *coord_x = coordinate_x;
-       struct fixed31_32 x;
-       struct fixed31_32 output;
-       struct fixed31_32 scaling_factor =
-                       dal_fixed31_32_from_fraction(8, 1000);
-
-       /* use coord_x to retrieve coordinates chosen base on given user curve
-        * the x values are exponentially distributed and currently it is hard
-        * coded, the user curve shape is ignored. Need to recalculate coord_x
-        * based on input curve, translation from 256/1025 to 128 PWL points.
-        */
-       for (i = 0; i <= hw_points_num; i++) {
-               /* Multiply 0.008 as regamma is 0-1 and FP16 input is 0-125.
-                * FP 1.0 = 80nits
-                */
-               x = dal_fixed31_32_mul(coord_x->adjusted_x, scaling_factor);
-
-               compute_pq(x, &output);
-
-               /* should really not happen? */
-               if (dal_fixed31_32_lt(output, dal_fixed31_32_zero))
-                       output = dal_fixed31_32_zero;
-               else if (dal_fixed31_32_lt(dal_fixed31_32_one, output))
-                       output = dal_fixed31_32_one;
-
-               rgb->r = output;
-               rgb->g = output;
-               rgb->b = output;
-
-               ++coord_x;
-               ++rgb;
-       }
-}
-
-static void build_regamma_curve(struct pwl_float_data_ex *rgb_regamma,
-               struct pwl_float_data *rgb_oem,
-               struct pixel_gamma_point *coeff128_oem,
-               const struct core_gamma *ramp,
-               const struct core_surface *surface,
-               uint32_t hw_points_num,
-               const struct hw_x_point *coordinate_x,
-               const struct gamma_pixel *axis_x,
-               struct dividers dividers)
-{
-       uint32_t i;
-
-       struct gamma_coefficients coeff;
-       struct pwl_float_data_ex *rgb = rgb_regamma;
-       const struct hw_x_point *coord_x = coordinate_x;
-
-       build_regamma_coefficients(&coeff);
-
-       /* Use opp110->regamma.coordinates_x to retrieve
-        * coordinates chosen base on given user curve (future task).
-        * The x values are exponentially distributed and currently
-        * it is hard-coded, the user curve shape is ignored.
-        * The future task is to recalculate opp110-
-        * regamma.coordinates_x based on input/user curve,
-        * translation from 256/1025 to 128 pwl points.
-        */
-
-       i = 0;
-
-       while (i != hw_points_num + 1) {
-               rgb->r = translate_from_linear_space_ex(
-                       coord_x->adjusted_x, &coeff, 0);
-               rgb->g = translate_from_linear_space_ex(
-                       coord_x->adjusted_x, &coeff, 1);
-               rgb->b = translate_from_linear_space_ex(
-                       coord_x->adjusted_x, &coeff, 2);
-
-               ++coord_x;
-               ++rgb;
-               ++i;
-       }
-}
-
-static bool scale_gamma(struct pwl_float_data *pwl_rgb,
-               const struct core_gamma *ramp,
-               struct dividers dividers)
-{
-       const struct dc_gamma *gamma = &ramp->public;
-       const uint16_t max_driver = 0xFFFF;
-       const uint16_t max_os = 0xFF00;
-       uint16_t scaler = max_os;
-       uint32_t i = 0;
-       struct pwl_float_data *rgb = pwl_rgb;
-       struct pwl_float_data *rgb_last = rgb + INPUT_LUT_ENTRIES - 1;
-
-       do {
-               if ((gamma->red[i] > max_os) ||
-                       (gamma->green[i] > max_os) ||
-                       (gamma->blue[i] > max_os)) {
-                       scaler = max_driver;
-                       break;
-               }
-               ++i;
-       } while (i != INPUT_LUT_ENTRIES);
-
-       i = 0;
-
-       do {
-               rgb->r = dal_fixed31_32_from_fraction(
-                       gamma->red[i], scaler);
-               rgb->g = dal_fixed31_32_from_fraction(
-                       gamma->green[i], scaler);
-               rgb->b = dal_fixed31_32_from_fraction(
-                       gamma->blue[i], scaler);
-
-               ++rgb;
-               ++i;
-       } while (i != INPUT_LUT_ENTRIES);
-
-       rgb->r = dal_fixed31_32_mul(rgb_last->r,
-                       dividers.divider1);
-       rgb->g = dal_fixed31_32_mul(rgb_last->g,
-                       dividers.divider1);
-       rgb->b = dal_fixed31_32_mul(rgb_last->b,
-                       dividers.divider1);
-
-       ++rgb;
-
-       rgb->r = dal_fixed31_32_mul(rgb_last->r,
-                       dividers.divider2);
-       rgb->g = dal_fixed31_32_mul(rgb_last->g,
-                       dividers.divider2);
-       rgb->b = dal_fixed31_32_mul(rgb_last->b,
-                       dividers.divider2);
-
-       ++rgb;
-
-       rgb->r = dal_fixed31_32_mul(rgb_last->r,
-                       dividers.divider3);
-       rgb->g = dal_fixed31_32_mul(rgb_last->g,
-                       dividers.divider3);
-       rgb->b = dal_fixed31_32_mul(rgb_last->b,
-                       dividers.divider3);
-
-       return true;
-}
-
-static void build_evenly_distributed_points(
-       struct gamma_pixel *points,
-       uint32_t numberof_points,
-       struct fixed31_32 max_value,
-       struct dividers dividers)
-{
-       struct gamma_pixel *p = points;
-       struct gamma_pixel *p_last = p + numberof_points - 1;
-
-       uint32_t i = 0;
-
-       do {
-               struct fixed31_32 value = dal_fixed31_32_div_int(
-                       dal_fixed31_32_mul_int(max_value, i),
-                       numberof_points - 1);
-
-               p->r = value;
-               p->g = value;
-               p->b = value;
-
-               ++p;
-               ++i;
-       } while (i != numberof_points);
-
-       p->r = dal_fixed31_32_div(p_last->r, dividers.divider1);
-       p->g = dal_fixed31_32_div(p_last->g, dividers.divider1);
-       p->b = dal_fixed31_32_div(p_last->b, dividers.divider1);
-
-       ++p;
-
-       p->r = dal_fixed31_32_div(p_last->r, dividers.divider2);
-       p->g = dal_fixed31_32_div(p_last->g, dividers.divider2);
-       p->b = dal_fixed31_32_div(p_last->b, dividers.divider2);
-
-       ++p;
-
-       p->r = dal_fixed31_32_div(p_last->r, dividers.divider3);
-       p->g = dal_fixed31_32_div(p_last->g, dividers.divider3);
-       p->b = dal_fixed31_32_div(p_last->b, dividers.divider3);
-}
-
-static inline void copy_rgb_regamma_to_coordinates_x(
-               struct hw_x_point *coordinates_x,
-               uint32_t hw_points_num,
-               const struct pwl_float_data_ex *rgb_ex)
-{
-       struct hw_x_point *coords = coordinates_x;
-       uint32_t i = 0;
-       const struct pwl_float_data_ex *rgb_regamma = rgb_ex;
-
-       while (i <= hw_points_num) {
-               coords->regamma_y_red = rgb_regamma->r;
-               coords->regamma_y_green = rgb_regamma->g;
-               coords->regamma_y_blue = rgb_regamma->b;
-
-               ++coords;
-               ++rgb_regamma;
-               ++i;
-       }
-}
-
-static bool calculate_interpolated_hardware_curve(
-       struct pwl_result_data *rgb,
-       struct pixel_gamma_point *coeff128,
-       struct pwl_float_data *rgb_user,
-       const struct hw_x_point *coordinates_x,
-       const struct gamma_pixel *axis_x_256,
-       uint32_t number_of_points,
-       enum surface_pixel_format pixel_format)
-{
-
-       const struct pixel_gamma_point *coeff;
-       struct pixel_gamma_point *coeff_128 = coeff128;
-       uint32_t max_entries = 3 - 1;
-       struct pwl_result_data *rgb_resulted = rgb;
-
-       uint32_t i = 0;
-
-       if (!build_oem_custom_gamma_mapping_coefficients(
-                       coeff_128, coordinates_x, axis_x_256,
-                       number_of_points,
-                       pixel_format))
-               return false;
-
-       coeff = coeff128;
-       max_entries += INPUT_LUT_ENTRIES;
-
-       /* TODO: float point case */
-
-       while (i <= number_of_points) {
-               rgb_resulted->red = calculate_mapped_value(
-                       rgb_user, coeff, CHANNEL_NAME_RED, max_entries);
-               rgb_resulted->green = calculate_mapped_value(
-                       rgb_user, coeff, CHANNEL_NAME_GREEN, max_entries);
-               rgb_resulted->blue = calculate_mapped_value(
-                       rgb_user, coeff, CHANNEL_NAME_BLUE, max_entries);
-
-               ++coeff;
-               ++rgb_resulted;
-               ++i;
-       }
-
-       return true;
-}
-
-static bool map_regamma_hw_to_x_user(
-       struct pixel_gamma_point *coeff128,
-       struct pwl_float_data *rgb_oem,
-       struct pwl_result_data *rgb_resulted,
-       struct pwl_float_data *rgb_user,
-       struct hw_x_point *coords_x,
-       const struct gamma_pixel *axis_x,
-       const struct dc_gamma *gamma,
-       const struct pwl_float_data_ex *rgb_regamma,
-       struct dividers dividers,
-       uint32_t hw_points_num,
-       const struct core_surface *surface)
-{
-       /* setup to spare calculated ideal regamma values */
-
-       struct pixel_gamma_point *coeff = coeff128;
-
-       struct hw_x_point *coords = coords_x;
-
-       copy_rgb_regamma_to_coordinates_x(coords, hw_points_num, rgb_regamma);
-
-       return calculate_interpolated_hardware_curve(
-                       rgb_resulted, coeff, rgb_user, coords, axis_x,
-                       hw_points_num, surface->public.format);
-}
-
-static void build_new_custom_resulted_curve(
-       struct pwl_result_data *rgb_resulted,
-       uint32_t hw_points_num)
-{
-       struct pwl_result_data *rgb = rgb_resulted;
-       struct pwl_result_data *rgb_plus_1 = rgb + 1;
-
-       uint32_t i;
-
-       i = 0;
-
-       while (i != hw_points_num + 1) {
-               rgb->red = dal_fixed31_32_clamp(
-                       rgb->red, dal_fixed31_32_zero,
-                       dal_fixed31_32_one);
-               rgb->green = dal_fixed31_32_clamp(
-                       rgb->green, dal_fixed31_32_zero,
-                       dal_fixed31_32_one);
-               rgb->blue = dal_fixed31_32_clamp(
-                       rgb->blue, dal_fixed31_32_zero,
-                       dal_fixed31_32_one);
-
-               ++rgb;
-               ++i;
-       }
-
-       rgb = rgb_resulted;
-
-       i = 1;
-
-       while (i != hw_points_num + 1) {
-               if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
-                       rgb_plus_1->red = rgb->red;
-               if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
-                       rgb_plus_1->green = rgb->green;
-               if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
-                       rgb_plus_1->blue = rgb->blue;
-
-               rgb->delta_red = dal_fixed31_32_sub(
-                       rgb_plus_1->red,
-                       rgb->red);
-               rgb->delta_green = dal_fixed31_32_sub(
-                       rgb_plus_1->green,
-                       rgb->green);
-               rgb->delta_blue = dal_fixed31_32_sub(
-                       rgb_plus_1->blue,
-                       rgb->blue);
-
-               ++rgb_plus_1;
-               ++rgb;
-               ++i;
-       }
-}
-
-static void rebuild_curve_configuration_magic(
-               struct curve_points *arr_points,
-               struct pwl_result_data *rgb_resulted,
-               const struct hw_x_point *coordinates_x,
-               uint32_t hw_points_num,
-               enum dc_transfer_func_predefined tf)
-{
-       struct fixed31_32 y_r;
-       struct fixed31_32 y_g;
-       struct fixed31_32 y_b;
-
-       struct fixed31_32 y1_min;
-       struct fixed31_32 y3_max;
-
-       y_r = rgb_resulted[0].red;
-       y_g = rgb_resulted[0].green;
-       y_b = rgb_resulted[0].blue;
-
-       y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
-
-       arr_points[0].x = coordinates_x[0].adjusted_x;
-       arr_points[0].y = y1_min;
-       arr_points[0].slope = dal_fixed31_32_div(
-                                       arr_points[0].y,
-                                       arr_points[0].x);
-
-       /* this should be cleaned up as it's confusing my understanding (KK) is
-        * that REGAMMA_CNTLA_EXP_REGION_END is the X value for the region end
-        * REGAMMA_CNTLA_EXP_REGION_END_BASE is Y value for the above X
-        * REGAMMA_CNTLA_EXP_REGION_END_SLOPE is the slope beyond (X,Y) above
-        * currently when programming REGION_END = m_arrPoints[1].x,
-        * REGION_END_BASE = m_arrPoints[1].y, REGION_END_SLOPE=1
-        * we don't use m_arrPoints[2] at all after this function,
-        * and its purpose isn't clear to me
-        */
-       arr_points[1].x = coordinates_x[hw_points_num].adjusted_x;
-       arr_points[2].x = coordinates_x[hw_points_num].adjusted_x;
-
-       y_r = rgb_resulted[hw_points_num].red;
-       y_g = rgb_resulted[hw_points_num].green;
-       y_b = rgb_resulted[hw_points_num].blue;
-
-       /* see comment above, m_arrPoints[1].y should be the Y value for the
-        * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
-        */
-       y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
-
-       arr_points[1].y = y3_max;
-       arr_points[2].y = y3_max;
-
-       arr_points[2].slope = dal_fixed31_32_zero;
-
-       /* for PQ, we want to have a straight line from last HW X point, and the
-        * slope to be such that we hit 1.0 at 10000 nits.
-        */
-       if (tf == TRANSFER_FUNCTION_PQ) {
-               const struct fixed31_32 end_value =
-                               dal_fixed31_32_from_int(125);
-
-               arr_points[2].slope = dal_fixed31_32_div(
-                       dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
-                       dal_fixed31_32_sub(end_value, arr_points[1].x));
-       }
-}
-
-static bool convert_to_custom_float_format(
-       struct fixed31_32 value,
-       const struct custom_float_format *format,
-       uint32_t *result)
-{
-       uint32_t mantissa;
-       uint32_t exponenta;
-       bool negative;
-
-       return build_custom_float(
-               value, format, &negative, &mantissa, &exponenta) &&
-       setup_custom_float(
-               format, negative, mantissa, exponenta, result);
-}
-
-static bool convert_to_custom_float(
-               struct pwl_result_data *rgb_resulted,
-               struct curve_points *arr_points,
-               uint32_t hw_points_num)
-{
-       struct custom_float_format fmt;
-
-       struct pwl_result_data *rgb = rgb_resulted;
-
-       uint32_t i = 0;
-
-       fmt.exponenta_bits = 6;
-       fmt.mantissa_bits = 12;
-       fmt.sign = true;
-
-       if (!convert_to_custom_float_format(
-               arr_points[0].x,
-               &fmt,
-               &arr_points[0].custom_float_x)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(
-               arr_points[0].offset,
-               &fmt,
-               &arr_points[0].custom_float_offset)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(
-               arr_points[0].slope,
-               &fmt,
-               &arr_points[0].custom_float_slope)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       fmt.mantissa_bits = 10;
-       fmt.sign = false;
-
-       if (!convert_to_custom_float_format(
-               arr_points[1].x,
-               &fmt,
-               &arr_points[1].custom_float_x)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(
-               arr_points[1].y,
-               &fmt,
-               &arr_points[1].custom_float_y)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       if (!convert_to_custom_float_format(
-               arr_points[2].slope,
-               &fmt,
-               &arr_points[2].custom_float_slope)) {
-               BREAK_TO_DEBUGGER();
-               return false;
-       }
-
-       fmt.mantissa_bits = 12;
-       fmt.sign = true;
-
-       while (i != hw_points_num) {
-               if (!convert_to_custom_float_format(
-                       rgb->red,
-                       &fmt,
-                       &rgb->red_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(
-                       rgb->green,
-                       &fmt,
-                       &rgb->green_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(
-                       rgb->blue,
-                       &fmt,
-                       &rgb->blue_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(
-                       rgb->delta_red,
-                       &fmt,
-                       &rgb->delta_red_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(
-                       rgb->delta_green,
-                       &fmt,
-                       &rgb->delta_green_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               if (!convert_to_custom_float_format(
-                       rgb->delta_blue,
-                       &fmt,
-                       &rgb->delta_blue_reg)) {
-                       BREAK_TO_DEBUGGER();
-                       return false;
-               }
-
-               ++rgb;
-               ++i;
-       }
-
-       return true;
-}
-
-bool calculate_regamma_params(struct pwl_params *params,
-               const struct core_gamma *ramp,
-               const struct core_surface *surface,
-               const struct core_stream *stream)
-{
-       struct gamma_curve *arr_curve_points = params->arr_curve_points;
-       struct curve_points *arr_points = params->arr_points;
-       struct pwl_result_data *rgb_resulted = params->rgb_resulted;
-       struct dividers dividers;
-
-       struct hw_x_point *coordinates_x = NULL;
-       struct pwl_float_data *rgb_user = NULL ;
-       struct pwl_float_data_ex *rgb_regamma = NULL;
-       struct pwl_float_data *rgb_oem = NULL;
-       struct gamma_pixel *axix_x_256 = NULL;
-       struct pixel_gamma_point *coeff128_oem = NULL;
-       struct pixel_gamma_point *coeff128 = NULL;
-
-       enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
-
-       bool ret = false;
-
-       coordinates_x = dm_alloc(sizeof(*coordinates_x)*(256 + 3));
-       if (!coordinates_x)
-               goto coordinates_x_alloc_fail;
-       rgb_user = dm_alloc(sizeof(*rgb_user) * (TRANSFER_FUNC_POINTS + 3));
-       if (!rgb_user)
-               goto rgb_user_alloc_fail;
-       rgb_regamma = dm_alloc(sizeof(*rgb_regamma) * (256 + 3));
-       if (!rgb_regamma)
-               goto rgb_regamma_alloc_fail;
-       rgb_oem = dm_alloc(sizeof(*rgb_oem) * (TRANSFER_FUNC_POINTS + 3));
-       if (!rgb_oem)
-               goto rgb_oem_alloc_fail;
-       axix_x_256 = dm_alloc(sizeof(*axix_x_256) * (256 + 3));
-       if (!axix_x_256)
-               goto axix_x_256_alloc_fail;
-       coeff128_oem = dm_alloc(sizeof(*coeff128_oem) * (256 + 3));
-       if (!coeff128_oem)
-               goto coeff128_oem_alloc_fail;
-       coeff128 = dm_alloc(sizeof(*coeff128) * (256 + 3));
-       if (!coeff128)
-               goto coeff128_alloc_fail;
-
-       dividers.divider1 = dal_fixed31_32_from_fraction(3, 2);
-       dividers.divider2 = dal_fixed31_32_from_int(2);
-       dividers.divider3 = dal_fixed31_32_from_fraction(5, 2);
-
-       if (stream->public.out_transfer_func)
-               tf = stream->public.out_transfer_func->tf;
-
-       build_evenly_distributed_points(
-                       axix_x_256,
-                       256,
-                       dal_fixed31_32_one,
-                       dividers);
-
-       scale_gamma(rgb_user, ramp, dividers);
-
-       if (tf == TRANSFER_FUNCTION_PQ) {
-               setup_distribution_points_pq(arr_curve_points, arr_points,
-                               &params->hw_points_num, coordinates_x,
-                               surface->public.format);
-               build_regamma_curve_pq(rgb_regamma, rgb_oem, coeff128_oem,
-                               ramp, surface, params->hw_points_num,
-                               coordinates_x, axix_x_256, dividers);
-       } else {
-               setup_distribution_points(arr_curve_points, arr_points,
-                               &params->hw_points_num, coordinates_x);
-               build_regamma_curve(rgb_regamma, rgb_oem, coeff128_oem,
-                               ramp, surface, params->hw_points_num,
-                               coordinates_x, axix_x_256, dividers);
-       }
-
-       map_regamma_hw_to_x_user(coeff128, rgb_oem, rgb_resulted, rgb_user,
-                       coordinates_x, axix_x_256, &ramp->public, rgb_regamma,
-                       dividers, params->hw_points_num, surface);
-
-       build_new_custom_resulted_curve(rgb_resulted, params->hw_points_num);
-
-       rebuild_curve_configuration_magic(
-                       arr_points,
-                       rgb_resulted,
-                       coordinates_x,
-                       params->hw_points_num,
-                       tf);
-
-       convert_to_custom_float(rgb_resulted, arr_points,
-                       params->hw_points_num);
-
-       ret = true;
-
-       dm_free(coeff128);
-coeff128_alloc_fail:
-       dm_free(coeff128_oem);
-coeff128_oem_alloc_fail:
-       dm_free(axix_x_256);
-axix_x_256_alloc_fail:
-       dm_free(rgb_oem);
-rgb_oem_alloc_fail:
-       dm_free(rgb_regamma);
-rgb_regamma_alloc_fail:
-       dm_free(rgb_user);
-rgb_user_alloc_fail:
-       dm_free(coordinates_x);
-coordinates_x_alloc_fail:
-       return ret;
-
-}
-
index 7d4299b..948f82a 100644 (file)
@@ -1519,23 +1519,23 @@ void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *upda
                        if (dc->debug.disable_color_module)
                                continue;  /* skip below color updates */
 
-                       if (updates[i].hdr_static_metadata) {
-                               resource_build_info_frame(pipe_ctx);
-                               core_dc->hwss.update_info_frame(pipe_ctx);
-                       }
                        if (is_new_pipe_surface[j] ||
                                        updates[i].in_transfer_func)
                                core_dc->hwss.set_input_transfer_func(
                                                pipe_ctx, pipe_ctx->surface);
 
                        if (is_new_pipe_surface[j] ||
-                                       updates[i].gamma ||
                                        updates[i].out_transfer_func)
                                core_dc->hwss.set_output_transfer_func(
                                                pipe_ctx,
                                                pipe_ctx->surface,
                                                pipe_ctx->stream);
 
+                       if (updates[i].hdr_static_metadata) {
+                               resource_build_info_frame(pipe_ctx);
+                               core_dc->hwss.update_info_frame(pipe_ctx);
+                       }
+
                }
                if (apply_ctx) {
                        core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
index b814e7b..f53b413 100644 (file)
@@ -213,11 +213,14 @@ enum dc_transfer_func_type {
 };
 
 struct dc_transfer_func_distributed_points {
-       uint16_t red[TRANSFER_FUNC_POINTS];
-       uint16_t green[TRANSFER_FUNC_POINTS];
-       uint16_t blue[TRANSFER_FUNC_POINTS];
+       struct fixed31_32 red[TRANSFER_FUNC_POINTS];
+       struct fixed31_32 green[TRANSFER_FUNC_POINTS];
+       struct fixed31_32 blue[TRANSFER_FUNC_POINTS];
+
        uint16_t end_exponent;
-       uint16_t x_point_at_y1;
+       uint16_t x_point_at_y1_red;
+       uint16_t x_point_at_y1_green;
+       uint16_t x_point_at_y1_blue;
 };
 
 enum dc_transfer_func_predefined {
index 415b12a..6e70cf7 100644 (file)
@@ -42,7 +42,6 @@
 #include "stream_encoder.h"
 #include "link_encoder.h"
 #include "clock_source.h"
-#include "gamma_calcs.h"
 #include "audio.h"
 #include "dce/dce_hwseq.h"
 
@@ -286,6 +285,436 @@ static bool dce110_set_input_transfer_func(
        return result;
 }
 
+static bool build_custom_float(
+       struct fixed31_32 value,
+       const struct custom_float_format *format,
+       bool *negative,
+       uint32_t *mantissa,
+       uint32_t *exponenta)
+{
+       uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
+
+       const struct fixed31_32 mantissa_constant_plus_max_fraction =
+               dal_fixed31_32_from_fraction(
+                       (1LL << (format->mantissa_bits + 1)) - 1,
+                       1LL << format->mantissa_bits);
+
+       struct fixed31_32 mantiss;
+
+       if (dal_fixed31_32_eq(
+               value,
+               dal_fixed31_32_zero)) {
+               *negative = false;
+               *mantissa = 0;
+               *exponenta = 0;
+               return true;
+       }
+
+       if (dal_fixed31_32_lt(
+               value,
+               dal_fixed31_32_zero)) {
+               *negative = format->sign;
+               value = dal_fixed31_32_neg(value);
+       } else {
+               *negative = false;
+       }
+
+       if (dal_fixed31_32_lt(
+               value,
+               dal_fixed31_32_one)) {
+               uint32_t i = 1;
+
+               do {
+                       value = dal_fixed31_32_shl(value, 1);
+                       ++i;
+               } while (dal_fixed31_32_lt(
+                       value,
+                       dal_fixed31_32_one));
+
+               --i;
+
+               if (exp_offset <= i) {
+                       *mantissa = 0;
+                       *exponenta = 0;
+                       return true;
+               }
+
+               *exponenta = exp_offset - i;
+       } else if (dal_fixed31_32_le(
+               mantissa_constant_plus_max_fraction,
+               value)) {
+               uint32_t i = 1;
+
+               do {
+                       value = dal_fixed31_32_shr(value, 1);
+                       ++i;
+               } while (dal_fixed31_32_lt(
+                       mantissa_constant_plus_max_fraction,
+                       value));
+
+               *exponenta = exp_offset + i - 1;
+       } else {
+               *exponenta = exp_offset;
+       }
+
+       mantiss = dal_fixed31_32_sub(
+               value,
+               dal_fixed31_32_one);
+
+       if (dal_fixed31_32_lt(
+                       mantiss,
+                       dal_fixed31_32_zero) ||
+               dal_fixed31_32_lt(
+                       dal_fixed31_32_one,
+                       mantiss))
+               mantiss = dal_fixed31_32_zero;
+       else
+               mantiss = dal_fixed31_32_shl(
+                       mantiss,
+                       format->mantissa_bits);
+
+       *mantissa = dal_fixed31_32_floor(mantiss);
+
+       return true;
+}
+
+static bool setup_custom_float(
+       const struct custom_float_format *format,
+       bool negative,
+       uint32_t mantissa,
+       uint32_t exponenta,
+       uint32_t *result)
+{
+       uint32_t i = 0;
+       uint32_t j = 0;
+
+       uint32_t value = 0;
+
+       /* verification code:
+        * once calculation is ok we can remove it
+        */
+
+       const uint32_t mantissa_mask =
+               (1 << (format->mantissa_bits + 1)) - 1;
+
+       const uint32_t exponenta_mask =
+               (1 << (format->exponenta_bits + 1)) - 1;
+
+       if (mantissa & ~mantissa_mask) {
+               BREAK_TO_DEBUGGER();
+               mantissa = mantissa_mask;
+       }
+
+       if (exponenta & ~exponenta_mask) {
+               BREAK_TO_DEBUGGER();
+               exponenta = exponenta_mask;
+       }
+
+       /* end of verification code */
+
+       while (i < format->mantissa_bits) {
+               uint32_t mask = 1 << i;
+
+               if (mantissa & mask)
+                       value |= mask;
+
+               ++i;
+       }
+
+       while (j < format->exponenta_bits) {
+               uint32_t mask = 1 << j;
+
+               if (exponenta & mask)
+                       value |= mask << i;
+
+               ++j;
+       }
+
+       if (negative && format->sign)
+               value |= 1 << (i + j);
+
+       *result = value;
+
+       return true;
+}
+
+static bool convert_to_custom_float_format(
+       struct fixed31_32 value,
+       const struct custom_float_format *format,
+       uint32_t *result)
+{
+       uint32_t mantissa;
+       uint32_t exponenta;
+       bool negative;
+
+       return build_custom_float(
+               value, format, &negative, &mantissa, &exponenta) &&
+       setup_custom_float(
+               format, negative, mantissa, exponenta, result);
+}
+
+static bool convert_to_custom_float(
+               struct pwl_result_data *rgb_resulted,
+               struct curve_points *arr_points,
+               uint32_t hw_points_num)
+{
+       struct custom_float_format fmt;
+
+       struct pwl_result_data *rgb = rgb_resulted;
+
+       uint32_t i = 0;
+
+       fmt.exponenta_bits = 6;
+       fmt.mantissa_bits = 12;
+       fmt.sign = true;
+
+       if (!convert_to_custom_float_format(
+               arr_points[0].x,
+               &fmt,
+               &arr_points[0].custom_float_x)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(
+               arr_points[0].offset,
+               &fmt,
+               &arr_points[0].custom_float_offset)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(
+               arr_points[0].slope,
+               &fmt,
+               &arr_points[0].custom_float_slope)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       fmt.mantissa_bits = 10;
+       fmt.sign = false;
+
+       if (!convert_to_custom_float_format(
+               arr_points[1].x,
+               &fmt,
+               &arr_points[1].custom_float_x)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(
+               arr_points[1].y,
+               &fmt,
+               &arr_points[1].custom_float_y)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       if (!convert_to_custom_float_format(
+               arr_points[2].slope,
+               &fmt,
+               &arr_points[2].custom_float_slope)) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       fmt.mantissa_bits = 12;
+       fmt.sign = true;
+
+       while (i != hw_points_num) {
+               if (!convert_to_custom_float_format(
+                       rgb->red,
+                       &fmt,
+                       &rgb->red_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(
+                       rgb->green,
+                       &fmt,
+                       &rgb->green_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(
+                       rgb->blue,
+                       &fmt,
+                       &rgb->blue_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(
+                       rgb->delta_red,
+                       &fmt,
+                       &rgb->delta_red_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(
+                       rgb->delta_green,
+                       &fmt,
+                       &rgb->delta_green_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               if (!convert_to_custom_float_format(
+                       rgb->delta_blue,
+                       &fmt,
+                       &rgb->delta_blue_reg)) {
+                       BREAK_TO_DEBUGGER();
+                       return false;
+               }
+
+               ++rgb;
+               ++i;
+       }
+
+       return true;
+}
+
+static bool dce110_translate_regamma_to_hw_format(const struct dc_transfer_func
+               *output_tf, struct pwl_params *regamma_params)
+{
+       if (output_tf == NULL || regamma_params == NULL)
+               return false;
+
+       struct gamma_curve *arr_curve_points = regamma_params->arr_curve_points;
+       struct curve_points *arr_points = regamma_params->arr_points;
+       struct pwl_result_data *rgb_resulted = regamma_params->rgb_resulted;
+       struct fixed31_32 y_r;
+       struct fixed31_32 y_g;
+       struct fixed31_32 y_b;
+       struct fixed31_32 y1_min;
+       struct fixed31_32 y3_max;
+
+       int32_t segment_start, segment_end;
+       uint32_t hw_points, start_index;
+       uint32_t i, j;
+
+       memset(regamma_params, 0, sizeof(struct pwl_params));
+
+       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+               /* 16 segments x 16 points
+                * segments are from 2^-11 to 2^5
+                */
+               segment_start = -11;
+               segment_end = 5;
+
+       } else {
+               /* 10 segments x 16 points
+                * segment is from 2^-10 to 2^0
+                */
+               segment_start = -10;
+               segment_end = 0;
+       }
+
+       hw_points = (segment_end - segment_start) * 16;
+       j = 0;
+       /* (segment + 25) * 32, every 2nd point */
+       start_index = (segment_start + 25) * 32;
+       for (i = start_index; i <= 1025; i += 2) {
+               if (j > hw_points)
+                       break;
+               rgb_resulted[j].red = output_tf->tf_pts.red[i];
+               rgb_resulted[j].green = output_tf->tf_pts.green[i];
+               rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+               j++;
+       }
+
+       arr_points[0].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+                       dal_fixed31_32_from_int(segment_start));
+       arr_points[1].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+                       dal_fixed31_32_from_int(segment_end));
+       arr_points[2].x = dal_fixed31_32_pow(dal_fixed31_32_from_int(2),
+                       dal_fixed31_32_from_int(segment_end));
+
+       y_r = rgb_resulted[0].red;
+       y_g = rgb_resulted[0].green;
+       y_b = rgb_resulted[0].blue;
+
+       y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
+
+       arr_points[0].y = y1_min;
+       arr_points[0].slope = dal_fixed31_32_div(
+                                       arr_points[0].y,
+                                       arr_points[0].x);
+
+       y_r = rgb_resulted[hw_points - 1].red;
+       y_g = rgb_resulted[hw_points - 1].green;
+       y_b = rgb_resulted[hw_points - 1].blue;
+
+       /* see comment above, m_arrPoints[1].y should be the Y value for the
+        * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1)
+        */
+       y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
+
+       arr_points[1].y = y3_max;
+       arr_points[2].y = y3_max;
+
+       arr_points[1].slope = dal_fixed31_32_zero;
+       arr_points[2].slope = dal_fixed31_32_zero;
+
+       if (output_tf->tf == TRANSFER_FUNCTION_PQ) {
+               /* for PQ, we want to have a straight line from last HW X point,
+                * and the slope to be such that we hit 1.0 at 10000 nits.
+                */
+               const struct fixed31_32 end_value =
+                               dal_fixed31_32_from_int(125);
+
+               arr_points[1].slope = dal_fixed31_32_div(
+                       dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
+                       dal_fixed31_32_sub(end_value, arr_points[1].x));
+               arr_points[2].slope = dal_fixed31_32_div(
+                       dal_fixed31_32_sub(dal_fixed31_32_one, arr_points[1].y),
+                       dal_fixed31_32_sub(end_value, arr_points[1].x));
+       }
+
+       regamma_params->hw_points_num = hw_points;
+
+       for (i = 0; i < segment_end - segment_start; i++) {
+               regamma_params->arr_curve_points[i].offset = i * 16;
+               regamma_params->arr_curve_points[i].segments_num = 4;
+       }
+
+       struct pwl_result_data *rgb = rgb_resulted;
+       struct pwl_result_data *rgb_plus_1 = rgb_resulted + 1;
+
+       i = 1;
+
+       while (i != hw_points + 1) {
+               if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
+                       rgb_plus_1->red = rgb->red;
+               if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
+                       rgb_plus_1->green = rgb->green;
+               if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
+                       rgb_plus_1->blue = rgb->blue;
+
+               rgb->delta_red = dal_fixed31_32_sub(
+                       rgb_plus_1->red,
+                       rgb->red);
+               rgb->delta_green = dal_fixed31_32_sub(
+                       rgb_plus_1->green,
+                       rgb->green);
+               rgb->delta_blue = dal_fixed31_32_sub(
+                       rgb_plus_1->blue,
+                       rgb->blue);
+
+               ++rgb_plus_1;
+               ++rgb;
+               ++i;
+       }
+
+       convert_to_custom_float(rgb_resulted, arr_points, hw_points);
+
+       return true;
+}
+
 static bool dce110_set_output_transfer_func(
        struct pipe_ctx *pipe_ctx,
        const struct core_surface *surface, /* Surface - To be removed */
@@ -308,10 +737,13 @@ static bool dce110_set_output_transfer_func(
        opp->funcs->opp_power_on_regamma_lut(opp, true);
 
        if (stream->public.out_transfer_func &&
-           stream->public.out_transfer_func->type == TF_TYPE_PREDEFINED &&
-           stream->public.out_transfer_func->tf == TRANSFER_FUNCTION_SRGB) {
+                       stream->public.out_transfer_func->type ==
+                       TF_TYPE_PREDEFINED &&
+                       stream->public.out_transfer_func->tf ==
+                       TRANSFER_FUNCTION_SRGB) {
                opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_SRGB);
-       } else if (ramp && calculate_regamma_params(regamma_params, ramp, surface, stream)) {
+       } else if (dce110_translate_regamma_to_hw_format(
+                       stream->public.out_transfer_func, regamma_params)) {
                opp->funcs->opp_program_regamma_pwl(opp, regamma_params);
                opp->funcs->opp_set_regamma_mode(opp, OPP_REGAMMA_USER);
        } else {
diff --git a/drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h
deleted file mode 100644 (file)
index 0712268..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * gamma_calcs.h
- *
- *  Created on: Feb 9, 2016
- *      Author: yonsun
- */
-
-#ifndef DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_GAMMA_CALCS_H_
-#define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_GAMMA_CALCS_H_
-
-#include "opp.h"
-#include "core_types.h"
-#include "dc.h"
-
-bool calculate_regamma_params(struct pwl_params *params,
-               const struct core_gamma *ramp,
-               const struct core_surface *surface,
-               const struct core_stream *stream);
-
-#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_GAMMA_CALCS_H_ */
index a1f31a4..bef5e2c 100644 (file)
@@ -138,9 +138,7 @@ struct custom_float_value {
 
 struct hw_x_point {
        uint32_t custom_float_x;
-       uint32_t custom_float_x_adjusted;
        struct fixed31_32 x;
-       struct fixed31_32 adjusted_x;
        struct fixed31_32 regamma_y_red;
        struct fixed31_32 regamma_y_green;
        struct fixed31_32 regamma_y_blue;
index c28de16..5a4364d 100644 (file)
@@ -192,6 +192,14 @@ struct fixed31_32 dal_fixed31_32_add(
 
 /*
  * @brief
+ * result = arg1 + arg2
+ */
+struct fixed31_32 dal_fixed31_32_add_int(
+       struct fixed31_32 arg1,
+       int32_t arg2);
+
+/*
+ * @brief
  * result = arg1 - arg2
  */
 struct fixed31_32 dal_fixed31_32_sub_int(