diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0142-drm-amd-display-Output-Transfer-Function-Regamma-Ref.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0142-drm-amd-display-Output-Transfer-Function-Regamma-Ref.patch | 2131 |
1 files changed, 0 insertions, 2131 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0142-drm-amd-display-Output-Transfer-Function-Regamma-Ref.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0142-drm-amd-display-Output-Transfer-Function-Regamma-Ref.patch deleted file mode 100644 index 8b4922e1..00000000 --- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0142-drm-amd-display-Output-Transfer-Function-Regamma-Ref.patch +++ /dev/null @@ -1,2131 +0,0 @@ -From 7bca50c9ad6a913eaabf9b7b23e7347d9673f62c Mon Sep 17 00:00:00 2001 -From: Amy Zhang <Amy.Zhang@amd.com> -Date: Thu, 5 Jan 2017 17:12:20 -0500 -Subject: [PATCH 0142/4131] drm/amd/display: Output Transfer Function Regamma - Refactor - -- 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 | 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 5a6e4684..546ed67 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 4001933..4bb08ae 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 fd300db..0000000 ---- 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, -- ¶ms->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, -- ¶ms->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 7d4299b..948f82a 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 b814e7b..f53b413 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 415b12a..6e70cf7 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 0712268..0000000 ---- 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 a1f31a4..bef5e2c 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 c28de16..5a4364d 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.7.4 - |