[PATCH 02/25] drm/amd/display: Output Transfer Function Regamma Refactor

Harry Wentland harry.wentland at amd.com
Mon Jan 23 14:35:50 UTC 2017


From: Amy Zhang <Amy.Zhang at amd.com>

- Create translation function to translate logical format to hw format
- Refactor to use transfer function in dc instead of input gamma

Change-Id: If7ea756ea206c3776ab328f3b351ce546ae080a0
Signed-off-by: Amy Zhang <Amy.Zhang at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo at amd.com>
---
 drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c |    9 +
 drivers/gpu/drm/amd/display/dc/calcs/Makefile      |    2 +-
 drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c | 1481 --------------------
 drivers/gpu/drm/amd/display/dc/core/dc.c           |   10 +-
 drivers/gpu/drm/amd/display/dc/dc.h                |   11 +-
 .../amd/display/dc/dce110/dce110_hw_sequencer.c    |  440 +++++-
 drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h   |   20 -
 drivers/gpu/drm/amd/display/dc/inc/hw/opp.h        |    2 -
 drivers/gpu/drm/amd/display/include/fixed31_32.h   |    8 +
 9 files changed, 466 insertions(+), 1517 deletions(-)
 delete mode 100644 drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
 delete mode 100644 drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h

diff --git a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
index 5a6e46843502..546ed67c6f83 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/fixpt31_32.c
@@ -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)
diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
index 4001933e7808..4bb08aea6a03 100644
--- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile
@@ -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
index fd300db833c7..000000000000
--- a/drivers/gpu/drm/amd/display/dc/calcs/gamma_calcs.c
+++ /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;
-
-}
-
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 7d4299b9ee1f..948f82a56472 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -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);
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b814e7b76bbc..f53b41339951 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -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 {
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 415b12accd2c..6e70cf7b99ef 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -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
index 0712268856c2..000000000000
--- a/drivers/gpu/drm/amd/display/dc/inc/gamma_calcs.h
+++ /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_ */
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
index a1f31a4410a3..bef5e2cacbe3 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
@@ -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;
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index c28de167250f..5a4364dfd2f7 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -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(
-- 
2.9.3



More information about the amd-gfx mailing list