diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0112-drm-amd-display-Remove-unused-color-and-power-module.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0112-drm-amd-display-Remove-unused-color-and-power-module.patch | 4338 |
1 files changed, 4338 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0112-drm-amd-display-Remove-unused-color-and-power-module.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0112-drm-amd-display-Remove-unused-color-and-power-module.patch new file mode 100644 index 00000000..c96dc808 --- /dev/null +++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0112-drm-amd-display-Remove-unused-color-and-power-module.patch @@ -0,0 +1,4338 @@ +From 741d4e5c6cddb30650c71b85b959860dbaece8dc Mon Sep 17 00:00:00 2001 +From: Harry Wentland <harry.wentland@amd.com> +Date: Thu, 29 Dec 2016 15:27:07 -0500 +Subject: [PATCH 0112/4131] drm/amd/display: Remove unused color and power + modules + +Signed-off-by: Harry Wentland <harry.wentland@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/modules/color/color.c | 2825 -------------------- + .../drm/amd/display/modules/color/color_helper.c | 210 -- + .../drm/amd/display/modules/color/color_helper.h | 62 - + .../gpu/drm/amd/display/modules/inc/mod_color.h | 282 -- + .../gpu/drm/amd/display/modules/inc/mod_power.h | 112 - + drivers/gpu/drm/amd/display/modules/power/power.c | 784 ------ + 6 files changed, 4275 deletions(-) + delete mode 100644 drivers/gpu/drm/amd/display/modules/color/color.c + delete mode 100644 drivers/gpu/drm/amd/display/modules/color/color_helper.c + delete mode 100644 drivers/gpu/drm/amd/display/modules/color/color_helper.h + delete mode 100644 drivers/gpu/drm/amd/display/modules/inc/mod_color.h + delete mode 100644 drivers/gpu/drm/amd/display/modules/inc/mod_power.h + delete mode 100644 drivers/gpu/drm/amd/display/modules/power/power.c + +diff --git a/drivers/gpu/drm/amd/display/modules/color/color.c b/drivers/gpu/drm/amd/display/modules/color/color.c +deleted file mode 100644 +index 74298c8..0000000 +--- a/drivers/gpu/drm/amd/display/modules/color/color.c ++++ /dev/null +@@ -1,2825 +0,0 @@ +-/* +- * Copyright 2016 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 "dc.h" +-#include "mod_color.h" +-#include "core_types.h" +-#include "fixed31_32.h" +-#include "core_dc.h" +- +-#define MOD_COLOR_MAX_CONCURRENT_SINKS 32 +-#define DIVIDER 10000 +-/* S2D13 value in [-3.00...0.9999] */ +-#define S2D13_MIN (-3 * DIVIDER) +-#define S2D13_MAX (3 * DIVIDER) +-#define S0D13_MIN (-1 * DIVIDER) +-#define S0D13_MAX (1 * DIVIDER) +- +-struct sink_caps { +- const struct dc_sink *sink; +-}; +- +-struct gamut_calculation_matrix { +- struct fixed31_32 MTransposed[9]; +- struct fixed31_32 XYZtoRGB_Custom[9]; +- struct fixed31_32 XYZtoRGB_Ref[9]; +- struct fixed31_32 RGBtoXYZ_Final[9]; +- +- struct fixed31_32 MResult[9]; +- struct fixed31_32 fXYZofWhiteRef[9]; +- struct fixed31_32 fXYZofRGBRef[9]; +-}; +- +-struct gamut_src_dst_matrix { +- struct fixed31_32 rgbCoeffDst[9]; +- struct fixed31_32 whiteCoeffDst[3]; +- struct fixed31_32 rgbCoeffSrc[9]; +- struct fixed31_32 whiteCoeffSrc[3]; +-}; +- +-struct color_state { +- bool user_enable_color_temperature; +- int custom_color_temperature; +- struct color_range contrast; +- struct color_range saturation; +- struct color_range brightness; +- struct color_range hue; +- struct dc_gamma *gamma; +- enum dc_quantization_range preferred_quantization_range; +- +- struct color_gamut_data source_gamut; +- struct color_gamut_data destination_gamut; +- enum color_transfer_func input_transfer_function; +- enum color_transfer_func output_transfer_function; +- struct dc_hdr_static_metadata mastering_info; +-}; +- +-struct core_color { +- struct mod_color public; +- struct dc *dc; +- int num_sinks; +- struct sink_caps *caps; +- struct color_state *state; +- struct color_edid_caps *edid_caps; +-}; +- +-#define MOD_COLOR_TO_CORE(mod_color)\ +- container_of(mod_color, struct core_color, public) +- +-#define COLOR_REGISTRY_NAME "color_v1" +- +-/*Matrix Calculation Functions*/ +-/** +- ***************************************************************************** +- * Function: transposeMatrix +- * +- * @brief +- * rotate the matrix 90 degrees clockwise +- * rows become a columns and columns to rows +- * @param [ in ] M - source matrix +- * @param [ in ] Rows - num of Rows of the original matrix +- * @param [ in ] Cols - num of Cols of the original matrix +- * @param [ out] MTransposed - result matrix +- * @return void +- * +- ***************************************************************************** +- */ +-static void transpose_matrix(const struct fixed31_32 *M, unsigned int Rows, +- unsigned int Cols, struct fixed31_32 *MTransposed) +-{ +- unsigned int i, j; +- +- for (i = 0; i < Rows; i++) { +- for (j = 0; j < Cols; j++) +- MTransposed[(j*Rows)+i] = M[(i*Cols)+j]; +- } +-} +- +-/** +- ***************************************************************************** +- * Function: multiplyMatrices +- * +- * @brief +- * multiplies produce of two matrices: M = M1[ulRows1 x ulCols1] * +- * M2[ulCols1 x ulCols2]. +- * +- * @param [ in ] M1 - first Matrix. +- * @param [ in ] M2 - second Matrix. +- * @param [ in ] Rows1 - num of Rows of the first Matrix +- * @param [ in ] Cols1 - num of Cols of the first Matrix/Num of Rows +- * of the second Matrix +- * @param [ in ] Cols2 - num of Cols of the second Matrix +- * @param [out ] mResult - resulting matrix. +- * @return void +- * +- ***************************************************************************** +- */ +-static void multiply_matrices(struct fixed31_32 *mResult, +- const struct fixed31_32 *M1, +- const struct fixed31_32 *M2, unsigned int Rows1, +- unsigned int Cols1, unsigned int Cols2) +-{ +- unsigned int i, j, k; +- +- for (i = 0; i < Rows1; i++) { +- for (j = 0; j < Cols2; j++) { +- mResult[(i * Cols2) + j] = dal_fixed31_32_zero; +- for (k = 0; k < Cols1; k++) +- mResult[(i * Cols2) + j] = +- dal_fixed31_32_add +- (mResult[(i * Cols2) + j], +- dal_fixed31_32_mul(M1[(i * Cols1) + k], +- M2[(k * Cols2) + j])); +- } +- } +-} +- +-/** +- ***************************************************************************** +- * Function: cFind3X3Det +- * +- * @brief +- * finds determinant of given 3x3 matrix +- * +- * @param [ in ] m - matrix +- * @return determinate whioch could not be zero +- * +- ***************************************************************************** +- */ +-static struct fixed31_32 find_3X3_det(const struct fixed31_32 *m) +-{ +- struct fixed31_32 det, A1, A2, A3; +- +- A1 = dal_fixed31_32_mul(m[0], +- dal_fixed31_32_sub(dal_fixed31_32_mul(m[4], m[8]), +- dal_fixed31_32_mul(m[5], m[7]))); +- A2 = dal_fixed31_32_mul(m[1], +- dal_fixed31_32_sub(dal_fixed31_32_mul(m[3], m[8]), +- dal_fixed31_32_mul(m[5], m[6]))); +- A3 = dal_fixed31_32_mul(m[2], +- dal_fixed31_32_sub(dal_fixed31_32_mul(m[3], m[7]), +- dal_fixed31_32_mul(m[4], m[6]))); +- det = dal_fixed31_32_add(dal_fixed31_32_sub(A1, A2), A3); +- return det; +-} +- +- +-/** +- ***************************************************************************** +- * Function: computeInverseMatrix_3x3 +- * +- * @brief +- * builds inverse matrix +- * +- * @param [ in ] m - matrix +- * @param [ out ] im - result matrix +- * @return true if success +- * +- ***************************************************************************** +- */ +-static bool compute_inverse_matrix_3x3(const struct fixed31_32 *m, +- struct fixed31_32 *im) +-{ +- struct fixed31_32 determinant = find_3X3_det(m); +- +- if (dal_fixed31_32_eq(determinant, dal_fixed31_32_zero) == false) { +- im[0] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[4], m[8]), +- dal_fixed31_32_mul(m[5], m[7])), determinant); +- im[1] = dal_fixed31_32_neg(dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[1], m[8]), +- dal_fixed31_32_mul(m[2], m[7])), determinant)); +- im[2] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[1], m[5]), +- dal_fixed31_32_mul(m[2], m[4])), determinant); +- im[3] = dal_fixed31_32_neg(dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[3], m[8]), +- dal_fixed31_32_mul(m[5], m[6])), determinant)); +- im[4] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[0], m[8]), +- dal_fixed31_32_mul(m[2], m[6])), determinant); +- im[5] = dal_fixed31_32_neg(dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[0], m[5]), +- dal_fixed31_32_mul(m[2], m[3])), determinant)); +- im[6] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[3], m[7]), +- dal_fixed31_32_mul(m[4], m[6])), determinant); +- im[7] = dal_fixed31_32_neg(dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[0], m[7]), +- dal_fixed31_32_mul(m[1], m[6])), determinant)); +- im[8] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_mul(m[0], m[4]), +- dal_fixed31_32_mul(m[1], m[3])), determinant); +- return true; +- } +- return false; +-} +- +-/** +- ***************************************************************************** +- * Function: calculateXYZtoRGB_M3x3 +- * +- * @brief +- * Calculates transformation matrix from XYZ coordinates to RBG +- * +- * @param [ in ] XYZofRGB - primaries XYZ +- * @param [ in ] XYZofWhite - white point. +- * @param [ out ] XYZtoRGB - RGB primires +- * @return true if success +- * +- ***************************************************************************** +- */ +-static bool calculate_XYZ_to_RGB_3x3(const struct fixed31_32 *XYZofRGB, +- const struct fixed31_32 *XYZofWhite, +- struct fixed31_32 *XYZtoRGB) +-{ +- +- struct fixed31_32 MInversed[9]; +- struct fixed31_32 SVector[3]; +- +- /*1. Find Inverse matrix 3x3 of MTransposed*/ +- if (!compute_inverse_matrix_3x3(XYZofRGB, MInversed)) +- return false; +- +- /*2. Calculate vector: |Sr Sg Sb| = [MInversed] * |Wx Wy Wz|*/ +- multiply_matrices(SVector, MInversed, XYZofWhite, 3, 3, 1); +- +- /*3. Calculate matrix XYZtoRGB 3x3*/ +- XYZtoRGB[0] = dal_fixed31_32_mul(XYZofRGB[0], SVector[0]); +- XYZtoRGB[1] = dal_fixed31_32_mul(XYZofRGB[1], SVector[1]); +- XYZtoRGB[2] = dal_fixed31_32_mul(XYZofRGB[2], SVector[2]); +- +- XYZtoRGB[3] = dal_fixed31_32_mul(XYZofRGB[3], SVector[0]); +- XYZtoRGB[4] = dal_fixed31_32_mul(XYZofRGB[4], SVector[1]); +- XYZtoRGB[5] = dal_fixed31_32_mul(XYZofRGB[5], SVector[2]); +- +- XYZtoRGB[6] = dal_fixed31_32_mul(XYZofRGB[6], SVector[0]); +- XYZtoRGB[7] = dal_fixed31_32_mul(XYZofRGB[7], SVector[1]); +- XYZtoRGB[8] = dal_fixed31_32_mul(XYZofRGB[8], SVector[2]); +- +- return true; +-} +- +-static bool gamut_to_color_matrix( +- const struct fixed31_32 *pXYZofRGB,/*destination gamut*/ +- const struct fixed31_32 *pXYZofWhite,/*destination of white point*/ +- const struct fixed31_32 *pRefXYZofRGB,/*source gamut*/ +- const struct fixed31_32 *pRefXYZofWhite,/*source of white point*/ +- bool invert, +- struct fixed31_32 *tempMatrix3X3) +-{ +- int i = 0; +- struct gamut_calculation_matrix *matrix = +- dm_alloc(sizeof(struct gamut_calculation_matrix)); +- +- struct fixed31_32 *pXYZtoRGB_Temp; +- struct fixed31_32 *pXYZtoRGB_Final; +- +- matrix->fXYZofWhiteRef[0] = pRefXYZofWhite[0]; +- matrix->fXYZofWhiteRef[1] = pRefXYZofWhite[1]; +- matrix->fXYZofWhiteRef[2] = pRefXYZofWhite[2]; +- +- +- matrix->fXYZofRGBRef[0] = pRefXYZofRGB[0]; +- matrix->fXYZofRGBRef[1] = pRefXYZofRGB[1]; +- matrix->fXYZofRGBRef[2] = pRefXYZofRGB[2]; +- +- matrix->fXYZofRGBRef[3] = pRefXYZofRGB[3]; +- matrix->fXYZofRGBRef[4] = pRefXYZofRGB[4]; +- matrix->fXYZofRGBRef[5] = pRefXYZofRGB[5]; +- +- matrix->fXYZofRGBRef[6] = pRefXYZofRGB[6]; +- matrix->fXYZofRGBRef[7] = pRefXYZofRGB[7]; +- matrix->fXYZofRGBRef[8] = pRefXYZofRGB[8]; +- +- /*default values - unity matrix*/ +- while (i < 9) { +- if (i == 0 || i == 4 || i == 8) +- tempMatrix3X3[i] = dal_fixed31_32_one; +- else +- tempMatrix3X3[i] = dal_fixed31_32_zero; +- i++; +- } +- +- /*1. Decide about the order of calculation. +- * bInvert == FALSE --> RGBtoXYZ_Ref * XYZtoRGB_Custom +- * bInvert == TRUE --> RGBtoXYZ_Custom * XYZtoRGB_Ref */ +- if (invert) { +- pXYZtoRGB_Temp = matrix->XYZtoRGB_Custom; +- pXYZtoRGB_Final = matrix->XYZtoRGB_Ref; +- } else { +- pXYZtoRGB_Temp = matrix->XYZtoRGB_Ref; +- pXYZtoRGB_Final = matrix->XYZtoRGB_Custom; +- } +- +- /*2. Calculate XYZtoRGB_Ref*/ +- transpose_matrix(matrix->fXYZofRGBRef, 3, 3, matrix->MTransposed); +- +- if (!calculate_XYZ_to_RGB_3x3( +- matrix->MTransposed, +- matrix->fXYZofWhiteRef, +- matrix->XYZtoRGB_Ref)) +- goto function_fail; +- +- /*3. Calculate XYZtoRGB_Custom*/ +- transpose_matrix(pXYZofRGB, 3, 3, matrix->MTransposed); +- +- if (!calculate_XYZ_to_RGB_3x3( +- matrix->MTransposed, +- pXYZofWhite, +- matrix->XYZtoRGB_Custom)) +- goto function_fail; +- +- /*4. Calculate RGBtoXYZ - +- * inverse matrix 3x3 of XYZtoRGB_Ref or XYZtoRGB_Custom*/ +- if (!compute_inverse_matrix_3x3(pXYZtoRGB_Temp, matrix->RGBtoXYZ_Final)) +- goto function_fail; +- +- /*5. Calculate M(3x3) = RGBtoXYZ * XYZtoRGB*/ +- multiply_matrices(matrix->MResult, matrix->RGBtoXYZ_Final, +- pXYZtoRGB_Final, 3, 3, 3); +- +- for (i = 0; i < 9; i++) +- tempMatrix3X3[i] = matrix->MResult[i]; +- +- dm_free(matrix); +- +- return true; +- +-function_fail: +- dm_free(matrix); +- return false; +-} +- +-static bool build_gamut_remap_matrix +- (struct color_space_coordinates gamut_description, +- struct fixed31_32 *rgb_matrix, +- struct fixed31_32 *white_point_matrix) +-{ +- struct fixed31_32 fixed_blueX = dal_fixed31_32_from_fraction +- (gamut_description.blueX, DIVIDER); +- struct fixed31_32 fixed_blueY = dal_fixed31_32_from_fraction +- (gamut_description.blueY, DIVIDER); +- struct fixed31_32 fixed_greenX = dal_fixed31_32_from_fraction +- (gamut_description.greenX, DIVIDER); +- struct fixed31_32 fixed_greenY = dal_fixed31_32_from_fraction +- (gamut_description.greenY, DIVIDER); +- struct fixed31_32 fixed_redX = dal_fixed31_32_from_fraction +- (gamut_description.redX, DIVIDER); +- struct fixed31_32 fixed_redY = dal_fixed31_32_from_fraction +- (gamut_description.redY, DIVIDER); +- struct fixed31_32 fixed_whiteX = dal_fixed31_32_from_fraction +- (gamut_description.whiteX, DIVIDER); +- struct fixed31_32 fixed_whiteY = dal_fixed31_32_from_fraction +- (gamut_description.whiteY, DIVIDER); +- +- rgb_matrix[0] = dal_fixed31_32_div(fixed_redX, fixed_redY); +- rgb_matrix[1] = dal_fixed31_32_one; +- rgb_matrix[2] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_sub(dal_fixed31_32_one, fixed_redX), +- fixed_redY), fixed_redY); +- +- rgb_matrix[3] = dal_fixed31_32_div(fixed_greenX, fixed_greenY); +- rgb_matrix[4] = dal_fixed31_32_one; +- rgb_matrix[5] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_sub(dal_fixed31_32_one, fixed_greenX), +- fixed_greenY), fixed_greenY); +- +- rgb_matrix[6] = dal_fixed31_32_div(fixed_blueX, fixed_blueY); +- rgb_matrix[7] = dal_fixed31_32_one; +- rgb_matrix[8] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_sub(dal_fixed31_32_one, fixed_blueX), +- fixed_blueY), fixed_blueY); +- +- white_point_matrix[0] = dal_fixed31_32_div(fixed_whiteX, fixed_whiteY); +- white_point_matrix[1] = dal_fixed31_32_one; +- white_point_matrix[2] = dal_fixed31_32_div(dal_fixed31_32_sub +- (dal_fixed31_32_sub(dal_fixed31_32_one, fixed_whiteX), +- fixed_whiteY), fixed_whiteY); +- +- return true; +-} +- +-static bool check_dc_support(const struct dc *dc) +-{ +- if (dc->stream_funcs.set_gamut_remap == NULL) +- return false; +- +- return true; +-} +- +-static uint16_t fixed_point_to_int_frac( +- struct fixed31_32 arg, +- uint8_t integer_bits, +- uint8_t fractional_bits) +-{ +- int32_t numerator; +- int32_t divisor = 1 << fractional_bits; +- +- uint16_t result; +- +- uint16_t d = (uint16_t)dal_fixed31_32_floor( +- dal_fixed31_32_abs( +- arg)); +- +- if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor)) +- numerator = (uint16_t)dal_fixed31_32_floor( +- dal_fixed31_32_mul_int( +- arg, +- divisor)); +- else { +- numerator = dal_fixed31_32_floor( +- dal_fixed31_32_sub( +- dal_fixed31_32_from_int( +- 1LL << integer_bits), +- dal_fixed31_32_recip( +- dal_fixed31_32_from_int( +- divisor)))); +- } +- +- if (numerator >= 0) +- result = (uint16_t)numerator; +- else +- result = (uint16_t)( +- (1 << (integer_bits + fractional_bits + 1)) + numerator); +- +- if ((result != 0) && dal_fixed31_32_lt( +- arg, dal_fixed31_32_zero)) +- result |= 1 << (integer_bits + fractional_bits); +- +- return result; +-} +- +-/** +-* convert_float_matrix +-* This converts a double into HW register spec defined format S2D13. +-* @param : +-* @return None +-*/ +- +-static void convert_float_matrix_legacy( +- uint16_t *matrix, +- struct fixed31_32 *flt, +- uint32_t buffer_size) +-{ +- const struct fixed31_32 min_2_13 = +- dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER); +- const struct fixed31_32 max_2_13 = +- dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER); +- uint32_t i; +- +- for (i = 0; i < buffer_size; ++i) { +- uint32_t reg_value = +- fixed_point_to_int_frac( +- dal_fixed31_32_clamp( +- flt[i], +- min_2_13, +- max_2_13), +- 2, +- 13); +- +- matrix[i] = (uint16_t)reg_value; +- } +-} +- +-static void convert_float_matrix( +- uint16_t *matrix, +- struct fixed31_32 *flt, +- uint32_t buffer_size) +-{ +- const struct fixed31_32 min_0_13 = +- dal_fixed31_32_from_fraction(S0D13_MIN, DIVIDER); +- const struct fixed31_32 max_0_13 = +- dal_fixed31_32_from_fraction(S0D13_MAX, DIVIDER); +- const struct fixed31_32 min_2_13 = +- dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER); +- const struct fixed31_32 max_2_13 = +- dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER); +- uint32_t i; +- uint16_t temp_matrix[12]; +- +- for (i = 0; i < buffer_size; ++i) { +- if (i == 3 || i == 7 || i == 11) { +- uint32_t reg_value = +- fixed_point_to_int_frac( +- dal_fixed31_32_clamp( +- flt[i], +- min_0_13, +- max_0_13), +- 2, +- 13); +- +- temp_matrix[i] = (uint16_t)reg_value; +- } else { +- uint32_t reg_value = +- fixed_point_to_int_frac( +- dal_fixed31_32_clamp( +- flt[i], +- min_2_13, +- max_2_13), +- 2, +- 13); +- +- temp_matrix[i] = (uint16_t)reg_value; +- } +- } +- +- matrix[4] = temp_matrix[0]; +- matrix[5] = temp_matrix[1]; +- matrix[6] = temp_matrix[2]; +- matrix[7] = temp_matrix[3]; +- +- matrix[8] = temp_matrix[4]; +- matrix[9] = temp_matrix[5]; +- matrix[10] = temp_matrix[6]; +- matrix[11] = temp_matrix[7]; +- +- matrix[0] = temp_matrix[8]; +- matrix[1] = temp_matrix[9]; +- matrix[2] = temp_matrix[10]; +- matrix[3] = temp_matrix[11]; +-} +- +-static int get_hw_value_from_sw_value(int swVal, int swMin, +- int swMax, int hwMin, int hwMax) +-{ +- int dSW = swMax - swMin; /*software adjustment range size*/ +- int dHW = hwMax - hwMin; /*hardware adjustment range size*/ +- int hwVal; /*HW adjustment value*/ +- +- /* error case, I preserve the behavior from the predecessor +- *getHwStepFromSwHwMinMaxValue (removed in Feb 2013) +- *which was the FP version that only computed SCLF (i.e. dHW/dSW). +- *it would return 0 in this case so +- *hwVal = hwMin from the formula given in @brief +- */ +- if (dSW == 0) +- return hwMin; +- +- /*it's quite often that ranges match, +- *e.g. for overlay colors currently (Feb 2013) +- *only brightness has a different +- *HW range, and in this case no multiplication or division is needed, +- *and if minimums match, no calculation at all +- */ +- if (dSW != dHW) { +- hwVal = (swVal - swMin)*dHW/dSW + hwMin; +- } else { +- hwVal = swVal; +- if (swMin != hwMin) +- hwVal += (hwMin - swMin); +- } +- +- return hwVal; +-} +- +-static void initialize_fix_point_color_values( +- struct core_color *core_color, +- unsigned int sink_index, +- struct fixed31_32 *grph_cont, +- struct fixed31_32 *grph_sat, +- struct fixed31_32 *grph_bright, +- struct fixed31_32 *sin_grph_hue, +- struct fixed31_32 *cos_grph_hue) +-{ +- /* Hue adjustment could be negative. -45 ~ +45 */ +- struct fixed31_32 hue = +- dal_fixed31_32_mul( +- dal_fixed31_32_from_fraction +- (get_hw_value_from_sw_value +- (core_color->state[sink_index].hue.current, +- core_color->state[sink_index].hue.min, +- core_color->state[sink_index].hue.max, +- -30, 30), 180), +- dal_fixed31_32_pi); +- +- *sin_grph_hue = dal_fixed31_32_sin(hue); +- *cos_grph_hue = dal_fixed31_32_cos(hue); +- +- *grph_cont = +- dal_fixed31_32_from_fraction(get_hw_value_from_sw_value +- (core_color->state[sink_index].contrast.current, +- core_color->state[sink_index].contrast.min, +- core_color->state[sink_index].contrast.max, +- 50, 150), 100); +- *grph_sat = +- dal_fixed31_32_from_fraction(get_hw_value_from_sw_value +- (core_color->state[sink_index].saturation.current, +- core_color->state[sink_index].saturation.min, +- core_color->state[sink_index].saturation.max, +- 0, 200), 100); +- *grph_bright = +- dal_fixed31_32_from_fraction(get_hw_value_from_sw_value +- (core_color->state[sink_index].brightness.current, +- core_color->state[sink_index].brightness.min, +- core_color->state[sink_index].brightness.max, +- -25, 25), 100); +-} +- +- +-/* Given a specific dc_sink* this function finds its equivalent +- * on the dc_sink array and returns the corresponding index +- */ +-static int sink_index_from_sink(struct core_color *core_color, +- const struct dc_sink *sink) +-{ +- int index = 0; +- +- for (index = 0; index < core_color->num_sinks; index++) +- if (core_color->caps[index].sink == sink) +- return index; +- +- /* Could not find sink requested */ +- ASSERT(false); +- return -1; +-} +- +-static void calculate_rgb_matrix_legacy(struct core_color *core_color, +- unsigned int sink_index, +- struct fixed31_32 *rgb_matrix) +-{ +- const struct fixed31_32 k1 = +- dal_fixed31_32_from_fraction(701000, 1000000); +- const struct fixed31_32 k2 = +- dal_fixed31_32_from_fraction(236568, 1000000); +- const struct fixed31_32 k3 = +- dal_fixed31_32_from_fraction(-587000, 1000000); +- const struct fixed31_32 k4 = +- dal_fixed31_32_from_fraction(464432, 1000000); +- const struct fixed31_32 k5 = +- dal_fixed31_32_from_fraction(-114000, 1000000); +- const struct fixed31_32 k6 = +- dal_fixed31_32_from_fraction(-701000, 1000000); +- const struct fixed31_32 k7 = +- dal_fixed31_32_from_fraction(-299000, 1000000); +- const struct fixed31_32 k8 = +- dal_fixed31_32_from_fraction(-292569, 1000000); +- const struct fixed31_32 k9 = +- dal_fixed31_32_from_fraction(413000, 1000000); +- const struct fixed31_32 k10 = +- dal_fixed31_32_from_fraction(-92482, 1000000); +- const struct fixed31_32 k11 = +- dal_fixed31_32_from_fraction(-114000, 1000000); +- const struct fixed31_32 k12 = +- dal_fixed31_32_from_fraction(385051, 1000000); +- const struct fixed31_32 k13 = +- dal_fixed31_32_from_fraction(-299000, 1000000); +- const struct fixed31_32 k14 = +- dal_fixed31_32_from_fraction(886000, 1000000); +- const struct fixed31_32 k15 = +- dal_fixed31_32_from_fraction(-587000, 1000000); +- const struct fixed31_32 k16 = +- dal_fixed31_32_from_fraction(-741914, 1000000); +- const struct fixed31_32 k17 = +- dal_fixed31_32_from_fraction(886000, 1000000); +- const struct fixed31_32 k18 = +- dal_fixed31_32_from_fraction(-144086, 1000000); +- +- const struct fixed31_32 luma_r = +- dal_fixed31_32_from_fraction(299, 1000); +- const struct fixed31_32 luma_g = +- dal_fixed31_32_from_fraction(587, 1000); +- const struct fixed31_32 luma_b = +- dal_fixed31_32_from_fraction(114, 1000); +- +- struct fixed31_32 grph_cont; +- struct fixed31_32 grph_sat; +- struct fixed31_32 grph_bright; +- struct fixed31_32 sin_grph_hue; +- struct fixed31_32 cos_grph_hue; +- +- initialize_fix_point_color_values( +- core_color, sink_index, &grph_cont, &grph_sat, +- &grph_bright, &sin_grph_hue, &cos_grph_hue); +- +- /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/ +- /* Sin(GrphHue) * K2))*/ +- /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/ +- rgb_matrix[0] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k1), +- dal_fixed31_32_mul(sin_grph_hue, k2)); +- /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */ +- rgb_matrix[0] = dal_fixed31_32_mul(grph_sat, rgb_matrix[0]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/ +- rgb_matrix[0] = dal_fixed31_32_add(luma_r, rgb_matrix[0]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/ +- /* K2))*/ +- rgb_matrix[0] = dal_fixed31_32_mul(grph_cont, rgb_matrix[0]); +- +- /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/ +- /* Sin(GrphHue) * K4))*/ +- /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/ +- rgb_matrix[1] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k3), +- dal_fixed31_32_mul(sin_grph_hue, k4)); +- /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/ +- rgb_matrix[1] = dal_fixed31_32_mul(grph_sat, rgb_matrix[1]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/ +- rgb_matrix[1] = dal_fixed31_32_add(luma_g, rgb_matrix[1]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/ +- /* K4))*/ +- rgb_matrix[1] = dal_fixed31_32_mul(grph_cont, rgb_matrix[1]); +- +- /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/ +- /* Sin(GrphHue) * K6))*/ +- /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k5), +- dal_fixed31_32_mul(sin_grph_hue, k6)); +- /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = dal_fixed31_32_mul(grph_sat, rgb_matrix[2]); +- /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = dal_fixed31_32_add(luma_b, rgb_matrix[2]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/ +- /* K6))*/ +- rgb_matrix[2] = dal_fixed31_32_mul(grph_cont, rgb_matrix[2]); +- +- /* COEF_1_4 = GrphBright*/ +- rgb_matrix[3] = grph_bright; +- +- /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/ +- /* Sin(GrphHue) * K8))*/ +- /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/ +- rgb_matrix[4] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k7), +- dal_fixed31_32_mul(sin_grph_hue, k8)); +- /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/ +- rgb_matrix[4] = dal_fixed31_32_mul(grph_sat, rgb_matrix[4]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/ +- rgb_matrix[4] = dal_fixed31_32_add(luma_r, rgb_matrix[4]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/ +- /* K8))*/ +- rgb_matrix[4] = dal_fixed31_32_mul(grph_cont, rgb_matrix[4]); +- +- /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/ +- /* Sin(GrphHue) * K10))*/ +- /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k9), +- dal_fixed31_32_mul(sin_grph_hue, k10)); +- /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = dal_fixed31_32_mul(grph_sat, rgb_matrix[5]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = dal_fixed31_32_add(luma_g, rgb_matrix[5]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/ +- /* K10))*/ +- rgb_matrix[5] = dal_fixed31_32_mul(grph_cont, rgb_matrix[5]); +- +- /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/ +- /* Sin(GrphHue) * K12))*/ +- /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k11), +- dal_fixed31_32_mul(sin_grph_hue, k12)); +- /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = dal_fixed31_32_mul(grph_sat, rgb_matrix[6]); +- /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = dal_fixed31_32_add(luma_b, rgb_matrix[6]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/ +- /* K12))*/ +- rgb_matrix[6] = dal_fixed31_32_mul(grph_cont, rgb_matrix[6]); +- +- /* COEF_2_4 = GrphBright*/ +- rgb_matrix[7] = grph_bright; +- +- /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/ +- /* Sin(GrphHue) * K14))*/ +- /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k13), +- dal_fixed31_32_mul(sin_grph_hue, k14)); +- /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = dal_fixed31_32_mul(grph_sat, rgb_matrix[8]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = dal_fixed31_32_add(luma_r, rgb_matrix[8]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/ +- /* K14)) */ +- rgb_matrix[8] = dal_fixed31_32_mul(grph_cont, rgb_matrix[8]); +- +- /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/ +- /* Sin(GrphHue) * K16)) */ +- /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */ +- rgb_matrix[9] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k15), +- dal_fixed31_32_mul(sin_grph_hue, k16)); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */ +- rgb_matrix[9] = dal_fixed31_32_mul(grph_sat, rgb_matrix[9]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */ +- rgb_matrix[9] = dal_fixed31_32_add(luma_g, rgb_matrix[9]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/ +- /* K16)) */ +- rgb_matrix[9] = dal_fixed31_32_mul(grph_cont, rgb_matrix[9]); +- +- /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/ +- /* Sin(GrphHue) * K18)) */ +- /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k17), +- dal_fixed31_32_mul(sin_grph_hue, k18)); +- /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = dal_fixed31_32_mul(grph_sat, rgb_matrix[10]); +- /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = dal_fixed31_32_add(luma_b, rgb_matrix[10]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/ +- /* K18)) */ +- rgb_matrix[10] = dal_fixed31_32_mul(grph_cont, rgb_matrix[10]); +- +- /* COEF_3_4 = GrphBright */ +- rgb_matrix[11] = grph_bright; +-} +- +-static void calculate_rgb_limited_range_matrix_legacy( +- struct core_color *core_color, unsigned int sink_index, +- struct fixed31_32 *rgb_matrix) +-{ +- const struct fixed31_32 k1 = +- dal_fixed31_32_from_fraction(701000, 1000000); +- const struct fixed31_32 k2 = +- dal_fixed31_32_from_fraction(236568, 1000000); +- const struct fixed31_32 k3 = +- dal_fixed31_32_from_fraction(-587000, 1000000); +- const struct fixed31_32 k4 = +- dal_fixed31_32_from_fraction(464432, 1000000); +- const struct fixed31_32 k5 = +- dal_fixed31_32_from_fraction(-114000, 1000000); +- const struct fixed31_32 k6 = +- dal_fixed31_32_from_fraction(-701000, 1000000); +- const struct fixed31_32 k7 = +- dal_fixed31_32_from_fraction(-299000, 1000000); +- const struct fixed31_32 k8 = +- dal_fixed31_32_from_fraction(-292569, 1000000); +- const struct fixed31_32 k9 = +- dal_fixed31_32_from_fraction(413000, 1000000); +- const struct fixed31_32 k10 = +- dal_fixed31_32_from_fraction(-92482, 1000000); +- const struct fixed31_32 k11 = +- dal_fixed31_32_from_fraction(-114000, 1000000); +- const struct fixed31_32 k12 = +- dal_fixed31_32_from_fraction(385051, 1000000); +- const struct fixed31_32 k13 = +- dal_fixed31_32_from_fraction(-299000, 1000000); +- const struct fixed31_32 k14 = +- dal_fixed31_32_from_fraction(886000, 1000000); +- const struct fixed31_32 k15 = +- dal_fixed31_32_from_fraction(-587000, 1000000); +- const struct fixed31_32 k16 = +- dal_fixed31_32_from_fraction(-741914, 1000000); +- const struct fixed31_32 k17 = +- dal_fixed31_32_from_fraction(886000, 1000000); +- const struct fixed31_32 k18 = +- dal_fixed31_32_from_fraction(-144086, 1000000); +- +- const struct fixed31_32 luma_r = +- dal_fixed31_32_from_fraction(299, 1000); +- const struct fixed31_32 luma_g = +- dal_fixed31_32_from_fraction(587, 1000); +- const struct fixed31_32 luma_b = +- dal_fixed31_32_from_fraction(114, 1000); +- const struct fixed31_32 luma_scale = +- dal_fixed31_32_from_fraction(875855, 1000000); +- +- const struct fixed31_32 rgb_scale = +- dal_fixed31_32_from_fraction(85546875, 100000000); +- const struct fixed31_32 rgb_bias = +- dal_fixed31_32_from_fraction(625, 10000); +- +- struct fixed31_32 grph_cont; +- struct fixed31_32 grph_sat; +- struct fixed31_32 grph_bright; +- struct fixed31_32 sin_grph_hue; +- struct fixed31_32 cos_grph_hue; +- +- initialize_fix_point_color_values( +- core_color, sink_index, &grph_cont, &grph_sat, +- &grph_bright, &sin_grph_hue, &cos_grph_hue); +- +- /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/ +- /* Sin(GrphHue) * K2))*/ +- /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/ +- rgb_matrix[0] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k1), +- dal_fixed31_32_mul(sin_grph_hue, k2)); +- /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */ +- rgb_matrix[0] = dal_fixed31_32_mul(grph_sat, rgb_matrix[0]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/ +- rgb_matrix[0] = dal_fixed31_32_add(luma_r, rgb_matrix[0]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/ +- /* K2))*/ +- rgb_matrix[0] = dal_fixed31_32_mul(grph_cont, rgb_matrix[0]); +- /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + */ +- /* Sin(GrphHue) * K2))*/ +- rgb_matrix[0] = dal_fixed31_32_mul(luma_scale, rgb_matrix[0]); +- +- /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/ +- /* Sin(GrphHue) * K4))*/ +- /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/ +- rgb_matrix[1] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k3), +- dal_fixed31_32_mul(sin_grph_hue, k4)); +- /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/ +- rgb_matrix[1] = dal_fixed31_32_mul(grph_sat, rgb_matrix[1]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/ +- rgb_matrix[1] = dal_fixed31_32_add(luma_g, rgb_matrix[1]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/ +- /* K4))*/ +- rgb_matrix[1] = dal_fixed31_32_mul(grph_cont, rgb_matrix[1]); +- /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K3 + */ +- /* Sin(GrphHue) * K4))*/ +- rgb_matrix[1] = dal_fixed31_32_mul(luma_scale, rgb_matrix[1]); +- +- /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/ +- /* Sin(GrphHue) * K6))*/ +- /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k5), +- dal_fixed31_32_mul(sin_grph_hue, k6)); +- /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = dal_fixed31_32_mul(grph_sat, rgb_matrix[2]); +- /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/ +- rgb_matrix[2] = dal_fixed31_32_add(luma_b, rgb_matrix[2]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/ +- /* K6))*/ +- rgb_matrix[2] = dal_fixed31_32_mul(grph_cont, rgb_matrix[2]); +- /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K5 + */ +- /* Sin(GrphHue) * K6))*/ +- rgb_matrix[2] = dal_fixed31_32_mul(luma_scale, rgb_matrix[2]); +- +- /* COEF_1_4 = RGBBias + RGBScale * GrphBright*/ +- rgb_matrix[3] = dal_fixed31_32_add( +- rgb_bias, +- dal_fixed31_32_mul(rgb_scale, grph_bright)); +- +- /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/ +- /* Sin(GrphHue) * K8))*/ +- /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/ +- rgb_matrix[4] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k7), +- dal_fixed31_32_mul(sin_grph_hue, k8)); +- /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/ +- rgb_matrix[4] = dal_fixed31_32_mul(grph_sat, rgb_matrix[4]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/ +- rgb_matrix[4] = dal_fixed31_32_add(luma_r, rgb_matrix[4]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/ +- /* K8))*/ +- rgb_matrix[4] = dal_fixed31_32_mul(grph_cont, rgb_matrix[4]); +- /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + */ +- /* Sin(GrphHue) * K8))*/ +- rgb_matrix[4] = dal_fixed31_32_mul(luma_scale, rgb_matrix[4]); +- +- /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/ +- /* Sin(GrphHue) * K10))*/ +- /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k9), +- dal_fixed31_32_mul(sin_grph_hue, k10)); +- /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = dal_fixed31_32_mul(grph_sat, rgb_matrix[5]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = dal_fixed31_32_add(luma_g, rgb_matrix[5]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/ +- /* K10))*/ +- rgb_matrix[5] = dal_fixed31_32_mul(grph_cont, rgb_matrix[5]); +- /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K9 + */ +- /* Sin(GrphHue) * K10))*/ +- rgb_matrix[5] = dal_fixed31_32_mul(luma_scale, rgb_matrix[5]); +- +- /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/ +- /* Sin(GrphHue) * K12))*/ +- /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k11), +- dal_fixed31_32_mul(sin_grph_hue, k12)); +- /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = dal_fixed31_32_mul(grph_sat, rgb_matrix[6]); +- /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/ +- rgb_matrix[6] = dal_fixed31_32_add(luma_b, rgb_matrix[6]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/ +- /* K12))*/ +- rgb_matrix[6] = dal_fixed31_32_mul(grph_cont, rgb_matrix[6]); +- /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * K11 +*/ +- /* Sin(GrphHue) * K12)) */ +- rgb_matrix[6] = dal_fixed31_32_mul(luma_scale, rgb_matrix[6]); +- +- /* COEF_2_4 = RGBBias + RGBScale * GrphBright*/ +- rgb_matrix[7] = dal_fixed31_32_add( +- rgb_bias, +- dal_fixed31_32_mul(rgb_scale, grph_bright)); +- +- /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/ +- /* Sin(GrphHue) * K14))*/ +- /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k13), +- dal_fixed31_32_mul(sin_grph_hue, k14)); +- /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = dal_fixed31_32_mul(grph_sat, rgb_matrix[8]); +- /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */ +- rgb_matrix[8] = dal_fixed31_32_add(luma_r, rgb_matrix[8]); +- /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/ +- /* K14)) */ +- rgb_matrix[8] = dal_fixed31_32_mul(grph_cont, rgb_matrix[8]); +- /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/ +- /* Sin(GrphHue) * K14))*/ +- rgb_matrix[8] = dal_fixed31_32_mul(luma_scale, rgb_matrix[8]); +- +- /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/ +- /* Sin(GrphHue) * K16)) */ +- /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */ +- rgb_matrix[9] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k15), +- dal_fixed31_32_mul(sin_grph_hue, k16)); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */ +- rgb_matrix[9] = dal_fixed31_32_mul(grph_sat, rgb_matrix[9]); +- /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */ +- rgb_matrix[9] = dal_fixed31_32_add(luma_g, rgb_matrix[9]); +- /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/ +- /* K16)) */ +- rgb_matrix[9] = dal_fixed31_32_mul(grph_cont, rgb_matrix[9]); +- /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K15 + */ +- /* Sin(GrphHue) * K16))*/ +- rgb_matrix[9] = dal_fixed31_32_mul(luma_scale, rgb_matrix[9]); +- +- /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/ +- /* Sin(GrphHue) * K18)) */ +- /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = +- dal_fixed31_32_add( +- dal_fixed31_32_mul(cos_grph_hue, k17), +- dal_fixed31_32_mul(sin_grph_hue, k18)); +- /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = dal_fixed31_32_mul(grph_sat, rgb_matrix[10]); +- /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */ +- rgb_matrix[10] = dal_fixed31_32_add(luma_b, rgb_matrix[10]); +- /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/ +- /* K18)) */ +- rgb_matrix[10] = dal_fixed31_32_mul(grph_cont, rgb_matrix[10]); +- /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * */ +- /* K17 + Sin(GrphHue) * K18))*/ +- rgb_matrix[10] = dal_fixed31_32_mul(luma_scale, rgb_matrix[10]); +- +- /* COEF_3_4 = RGBBias + RGBScale * GrphBright */ +- rgb_matrix[11] = dal_fixed31_32_add( +- rgb_bias, +- dal_fixed31_32_mul(rgb_scale, grph_bright)); +-} +- +-static void calculate_yuv_matrix(struct core_color *core_color, +- unsigned int sink_index, +- enum dc_color_space color_space, +- struct fixed31_32 *yuv_matrix) +-{ +- struct fixed31_32 ideal[12]; +- uint32_t i = 0; +- +- if ((color_space == COLOR_SPACE_YPBPR601) || +- (color_space == COLOR_SPACE_YCBCR601) || +- (color_space == COLOR_SPACE_YCBCR601_LIMITED)) { +- static const int32_t matrix_[] = { +- 25578516, 50216016, 9752344, 6250000, +- -14764391, -28985609, 43750000, 50000000, +- 43750000, -36635164, -7114836, 50000000 +- }; +- do { +- ideal[i] = dal_fixed31_32_from_fraction( +- matrix_[i], +- 100000000); +- ++i; +- } while (i != ARRAY_SIZE(matrix_)); +- } else { +- static const int32_t matrix_[] = { +- 18187266, 61183125, 6176484, 6250000, +- -10025059, -33724941, 43750000, 50000000, +- 43750000, -39738379, -4011621, 50000000 +- }; +- do { +- ideal[i] = dal_fixed31_32_from_fraction( +- matrix_[i], +- 100000000); +- ++i; +- } while (i != ARRAY_SIZE(matrix_)); +- } +- +- struct fixed31_32 grph_cont; +- struct fixed31_32 grph_sat; +- struct fixed31_32 grph_bright; +- struct fixed31_32 sin_grph_hue; +- struct fixed31_32 cos_grph_hue; +- +- initialize_fix_point_color_values( +- core_color, sink_index, &grph_cont, &grph_sat, +- &grph_bright, &sin_grph_hue, &cos_grph_hue); +- +- const struct fixed31_32 multiplier = +- dal_fixed31_32_mul(grph_cont, grph_sat); +- +- yuv_matrix[0] = dal_fixed31_32_mul(ideal[0], grph_cont); +- +- yuv_matrix[1] = dal_fixed31_32_mul(ideal[1], grph_cont); +- +- yuv_matrix[2] = dal_fixed31_32_mul(ideal[2], grph_cont); +- +- yuv_matrix[4] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_add( +- dal_fixed31_32_mul( +- ideal[4], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[8], +- sin_grph_hue))); +- +- yuv_matrix[5] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_add( +- dal_fixed31_32_mul( +- ideal[5], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[9], +- sin_grph_hue))); +- +- yuv_matrix[6] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_add( +- dal_fixed31_32_mul( +- ideal[6], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[10], +- sin_grph_hue))); +- +- yuv_matrix[7] = ideal[7]; +- +- yuv_matrix[8] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_sub( +- dal_fixed31_32_mul( +- ideal[8], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[4], +- sin_grph_hue))); +- +- yuv_matrix[9] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_sub( +- dal_fixed31_32_mul( +- ideal[9], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[5], +- sin_grph_hue))); +- +- yuv_matrix[10] = dal_fixed31_32_mul( +- multiplier, +- dal_fixed31_32_sub( +- dal_fixed31_32_mul( +- ideal[10], +- cos_grph_hue), +- dal_fixed31_32_mul( +- ideal[6], +- sin_grph_hue))); +- +- yuv_matrix[11] = ideal[11]; +- +- if ((color_space == COLOR_SPACE_YCBCR601_LIMITED) || +- (color_space == COLOR_SPACE_YCBCR709_LIMITED)) { +- yuv_matrix[3] = dal_fixed31_32_add(ideal[3], grph_bright); +- } else { +- yuv_matrix[3] = dal_fixed31_32_add( +- ideal[3], +- dal_fixed31_32_mul( +- grph_bright, +- dal_fixed31_32_from_fraction(86, 100))); +- } +-} +- +-static void calculate_csc_matrix(struct core_color *core_color, +- unsigned int sink_index, +- enum dc_color_space color_space, +- uint16_t *csc_matrix) +-{ +- struct fixed31_32 fixed_csc_matrix[12]; +- switch (color_space) { +- case COLOR_SPACE_SRGB: +- calculate_rgb_matrix_legacy +- (core_color, sink_index, fixed_csc_matrix); +- convert_float_matrix_legacy +- (csc_matrix, fixed_csc_matrix, 12); +- break; +- case COLOR_SPACE_SRGB_LIMITED: +- calculate_rgb_limited_range_matrix_legacy( +- core_color, sink_index, fixed_csc_matrix); +- convert_float_matrix_legacy(csc_matrix, fixed_csc_matrix, 12); +- break; +- case COLOR_SPACE_YCBCR601: +- case COLOR_SPACE_YCBCR709: +- case COLOR_SPACE_YCBCR601_LIMITED: +- case COLOR_SPACE_YCBCR709_LIMITED: +- case COLOR_SPACE_YPBPR601: +- case COLOR_SPACE_YPBPR709: +- calculate_yuv_matrix(core_color, sink_index, color_space, +- fixed_csc_matrix); +- convert_float_matrix(csc_matrix, fixed_csc_matrix, 12); +- break; +- default: +- calculate_rgb_matrix_legacy +- (core_color, sink_index, fixed_csc_matrix); +- convert_float_matrix_legacy +- (csc_matrix, fixed_csc_matrix, 12); +- break; +- } +-} +- +-static struct dc_surface *dc_stream_to_surface_from_pipe_ctx( +- struct core_color *core_color, +- const struct dc_stream *stream) +-{ +- int i; +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct core_stream *core_stream = DC_STREAM_TO_CORE(stream); +- struct dc_surface *out_surface = NULL; +- +- for (i = 0; i < MAX_PIPES; i++) { +- if (core_dc->current_context->res_ctx.pipe_ctx[i].stream +- == core_stream) { +- out_surface = &core_dc->current_context->res_ctx. +- pipe_ctx[i].surface->public; +- break; +- } +- } +- return out_surface; +-} +- +-static enum predefined_gamut_type color_space_to_predefined_gamut_types(enum +- color_color_space color_space) +-{ +- switch (color_space) { +- case color_space_bt709: +- case color_space_xv_ycc_bt709: +- return gamut_type_bt709; +- case color_space_bt601: +- case color_space_xv_ycc_bt601: +- return gamut_type_bt601; +- case color_space_adobe: +- return gamut_type_adobe_rgb; +- case color_space_srgb: +- case color_space_sc_rgb_ms_ref: +- return gamut_type_srgb; +- case color_space_bt2020: +- return gamut_type_bt2020; +- case color_space_dci_p3: /* TODO */ +- default: +- return gamut_type_unknown; +- } +-} +- +-static enum predefined_white_point_type white_point_to_predefined_white_point +- (enum color_white_point_type white_point) +-{ +- switch (white_point) { +- case color_white_point_type_5000k_horizon: +- return white_point_type_5000k_horizon; +- case color_white_point_type_6500k_noon: +- return white_point_type_6500k_noon; +- case color_white_point_type_7500k_north_sky: +- return white_point_type_7500k_north_sky; +- case color_white_point_type_9300k: +- return white_point_type_9300k; +- default: +- return white_point_type_unknown; +- } +-} +- +-static bool update_color_gamut_data(struct color_gamut_data *input_data, +- struct color_gamut_data *output_data) +-{ +- bool output_custom_cs = false; +- bool output_custom_wp = false; +- +- if (input_data == NULL || output_data == NULL) +- return false; +- +- if (input_data->color_space == color_space_custom_coordinates) { +- output_data->color_space = input_data->color_space; +- output_data->gamut.redX = input_data->gamut.redX; +- output_data->gamut.redY = input_data->gamut.redY; +- output_data->gamut.greenX = input_data->gamut.greenX; +- output_data->gamut.greenY = input_data->gamut.greenY; +- output_data->gamut.blueX = input_data->gamut.blueX; +- output_data->gamut.blueY = input_data->gamut.blueY; +- } else { +- struct gamut_space_coordinates gamut_coord; +- enum predefined_gamut_type gamut_type = +- color_space_to_predefined_gamut_types +- (input_data->color_space); +- +- /* fall back to original color space if unknown */ +- if (gamut_type == gamut_type_unknown) { +- if (output_data->color_space == +- color_space_custom_coordinates) { +- output_custom_cs = true; +- } else { +- gamut_type = +- color_space_to_predefined_gamut_types +- (output_data->color_space); +- /* fall back to sRGB if both unknown*/ +- if (gamut_type == gamut_type_unknown) { +- output_data->color_space = +- color_space_srgb; +- gamut_type = gamut_type_srgb; +- } +- } +- } else { +- output_data->color_space = input_data->color_space; +- } +- +- if (!output_custom_cs) { +- mod_color_find_predefined_gamut(&gamut_coord, +- gamut_type); +- output_data->gamut.redX = gamut_coord.redX; +- output_data->gamut.redY = gamut_coord.redY; +- output_data->gamut.greenX = gamut_coord.greenX; +- output_data->gamut.greenY = gamut_coord.greenY; +- output_data->gamut.blueX = gamut_coord.blueX; +- output_data->gamut.blueY = gamut_coord.blueY; +- } +- } +- +- if (input_data->white_point == color_space_custom_coordinates) { +- output_data->white_point = input_data->white_point; +- output_data->gamut.whiteX = input_data->gamut.whiteX; +- output_data->gamut.whiteY = input_data->gamut.whiteY; +- } else { +- struct white_point_coodinates white_point_coord; +- enum predefined_white_point_type white_type = +- white_point_to_predefined_white_point +- (input_data->white_point); +- +- /* fall back to original white point if not found */ +- if (white_type == white_point_type_unknown) { +- if (output_data->white_point == +- color_white_point_type_custom_coordinates) { +- output_custom_wp = true; +- } else { +- white_type = +- white_point_to_predefined_white_point +- (output_data->white_point); +- /* fall back to 6500 if both unknown*/ +- if (white_type == white_point_type_unknown) { +- output_data->white_point = +- color_white_point_type_6500k_noon; +- white_type = +- white_point_type_6500k_noon; +- } +- } +- } else { +- output_data->white_point = input_data->white_point; +- } +- +- if (!output_custom_wp) { +- mod_color_find_predefined_white_point( +- &white_point_coord, white_type); +- output_data->gamut.whiteX = white_point_coord.whiteX; +- output_data->gamut.whiteY = white_point_coord.whiteY; +- } +- } +- return true; +-} +- +-void initialize_color_state(struct core_color *core_color, int index) +-{ +- core_color->state[index].user_enable_color_temperature = true; +- +- core_color->state[index].custom_color_temperature = 6500; +- +- core_color->state[index].contrast.current = 100; +- core_color->state[index].contrast.min = 0; +- core_color->state[index].contrast.max = 200; +- +- core_color->state[index].saturation.current = 100; +- core_color->state[index].saturation.min = 0; +- core_color->state[index].saturation.max = 200; +- +- core_color->state[index].brightness.current = 0; +- core_color->state[index].brightness.min = -100; +- core_color->state[index].brightness.max = 100; +- +- core_color->state[index].hue.current = 0; +- core_color->state[index].hue.min = -30; +- core_color->state[index].hue.max = 30; +- +- core_color->state[index].gamma = NULL; +- +- core_color->state[index].preferred_quantization_range = +- QUANTIZATION_RANGE_FULL; +- +- core_color->state[index].source_gamut.color_space = +- color_space_srgb; +- core_color->state[index].source_gamut.white_point = +- color_white_point_type_6500k_noon; +- core_color->state[index].source_gamut.gamut.blueX = 1500; +- core_color->state[index].source_gamut.gamut.blueY = 600; +- core_color->state[index].source_gamut.gamut.greenX = 3000; +- core_color->state[index].source_gamut.gamut.greenY = 6000; +- core_color->state[index].source_gamut.gamut.redX = 6400; +- core_color->state[index].source_gamut.gamut.redY = 3300; +- core_color->state[index].source_gamut.gamut.whiteX = 3127; +- core_color->state[index].source_gamut.gamut.whiteY = 3290; +- +- core_color->state[index].destination_gamut.color_space = +- color_space_srgb; +- core_color->state[index].destination_gamut.white_point = +- color_white_point_type_6500k_noon; +- core_color->state[index].destination_gamut.gamut.blueX = 1500; +- core_color->state[index].destination_gamut.gamut.blueY = 600; +- core_color->state[index].destination_gamut.gamut.greenX = 3000; +- core_color->state[index].destination_gamut.gamut.greenY = 6000; +- core_color->state[index].destination_gamut.gamut.redX = 6400; +- core_color->state[index].destination_gamut.gamut.redY = 3300; +- core_color->state[index].destination_gamut.gamut.whiteX = 3127; +- core_color->state[index].destination_gamut.gamut.whiteY = 3290; +- +- core_color->state[index].input_transfer_function = +- transfer_func_srgb; +- core_color->state[index].output_transfer_function = +- transfer_func_srgb; +-} +- +-struct mod_color *mod_color_create(struct dc *dc) +-{ +- int i = 0; +- struct core_color *core_color = +- dm_alloc(sizeof(struct core_color)); +- struct core_dc *core_dc = DC_TO_CORE(dc); +- struct persistent_data_flag flag; +- +- if (core_color == NULL) +- goto fail_alloc_context; +- +- core_color->caps = dm_alloc(sizeof(struct sink_caps) * +- MOD_COLOR_MAX_CONCURRENT_SINKS); +- +- if (core_color->caps == NULL) +- goto fail_alloc_caps; +- +- for (i = 0; i < MOD_COLOR_MAX_CONCURRENT_SINKS; i++) +- core_color->caps[i].sink = NULL; +- +- core_color->state = dm_alloc(sizeof(struct color_state) * +- MOD_COLOR_MAX_CONCURRENT_SINKS); +- +- /*hardcoded to sRGB with 6500 color temperature*/ +- for (i = 0; i < MOD_COLOR_MAX_CONCURRENT_SINKS; i++) { +- initialize_color_state(core_color, i); +- } +- +- if (core_color->state == NULL) +- goto fail_alloc_state; +- +- core_color->edid_caps = dm_alloc(sizeof(struct color_edid_caps) * +- MOD_COLOR_MAX_CONCURRENT_SINKS); +- +- if (core_color->edid_caps == NULL) +- goto fail_alloc_edid_caps; +- +- core_color->num_sinks = 0; +- +- if (dc == NULL) +- goto fail_construct; +- +- core_color->dc = dc; +- +- if (!check_dc_support(dc)) +- goto fail_construct; +- +- /* Create initial module folder in registry for color adjustment */ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- +- dm_write_persistent_data(core_dc->ctx, NULL, COLOR_REGISTRY_NAME, NULL, +- NULL, 0, &flag); +- +- return &core_color->public; +- +-fail_construct: +- dm_free(core_color->edid_caps); +- +-fail_alloc_edid_caps: +- dm_free(core_color->state); +- +-fail_alloc_state: +- dm_free(core_color->caps); +- +-fail_alloc_caps: +- dm_free(core_color); +- +-fail_alloc_context: +- return NULL; +-} +- +-void mod_color_destroy(struct mod_color *mod_color) +-{ +- if (mod_color != NULL) { +- int i; +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- dm_free(core_color->edid_caps); +- +- for (i = 0; i < core_color->num_sinks; i++) +- if (core_color->state[i].gamma) +- dc_gamma_release(&core_color->state[i].gamma); +- +- dm_free(core_color->state); +- +- for (i = 0; i < core_color->num_sinks; i++) +- dc_sink_release(core_color->caps[i].sink); +- +- dm_free(core_color->caps); +- +- dm_free(core_color); +- } +-} +- +-bool mod_color_add_sink(struct mod_color *mod_color, const struct dc_sink *sink, +- struct color_edid_caps *edid_caps) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- bool persistent_color_temp_enable; +- int persistent_custom_color_temp = 0; +- struct color_space_coordinates persistent_source_gamut; +- struct color_space_coordinates persistent_destination_gamut; +- int persistent_brightness; +- int persistent_contrast; +- int persistent_hue; +- int persistent_saturation; +- enum dc_quantization_range persistent_quantization_range; +- struct persistent_data_flag flag; +- +- if (core_color->num_sinks < MOD_COLOR_MAX_CONCURRENT_SINKS) { +- dc_sink_retain(sink); +- core_color->caps[core_color->num_sinks].sink = sink; +- +- initialize_color_state(core_color, core_color->num_sinks); +- +- core_color->edid_caps[core_color->num_sinks].colorimetry_caps = +- edid_caps->colorimetry_caps; +- core_color->edid_caps[core_color->num_sinks].hdr_caps = +- edid_caps->hdr_caps; +- +- /* get persistent data from registry */ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, +- COLOR_REGISTRY_NAME, +- "enablecolortempadj", +- &persistent_color_temp_enable, +- sizeof(bool), &flag)) +- core_color->state[core_color->num_sinks]. +- user_enable_color_temperature = +- persistent_color_temp_enable; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, +- COLOR_REGISTRY_NAME, +- "customcolortemp", +- &persistent_custom_color_temp, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- custom_color_temperature +- = persistent_custom_color_temp; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, +- COLOR_REGISTRY_NAME, +- "sourcegamut", +- &persistent_source_gamut, +- sizeof(struct color_space_coordinates), +- &flag)) { +- memcpy(&core_color->state[core_color->num_sinks]. +- source_gamut.gamut, &persistent_source_gamut, +- sizeof(struct color_space_coordinates)); +- } +- +- if (dm_read_persistent_data(core_dc->ctx, sink, COLOR_REGISTRY_NAME, +- "destgamut", +- &persistent_destination_gamut, +- sizeof(struct color_space_coordinates), +- &flag)) { +- memcpy(&core_color->state[core_color->num_sinks]. +- destination_gamut.gamut, +- &persistent_destination_gamut, +- sizeof(struct color_space_coordinates)); +- } +- +- if (dm_read_persistent_data(core_dc->ctx, sink, COLOR_REGISTRY_NAME, +- "brightness", +- &persistent_brightness, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- brightness.current = persistent_brightness; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, COLOR_REGISTRY_NAME, +- "contrast", +- &persistent_contrast, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- contrast.current = persistent_contrast; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, COLOR_REGISTRY_NAME, +- "hue", +- &persistent_hue, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- hue.current = persistent_hue; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, COLOR_REGISTRY_NAME, +- "saturation", +- &persistent_saturation, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- saturation.current = persistent_saturation; +- +- if (dm_read_persistent_data(core_dc->ctx, sink, +- COLOR_REGISTRY_NAME, +- "preferred_quantization_range", +- &persistent_quantization_range, +- sizeof(int), &flag)) +- core_color->state[core_color->num_sinks]. +- preferred_quantization_range = +- persistent_quantization_range; +- +- core_color->num_sinks++; +- return true; +- } +- return false; +-} +- +-bool mod_color_remove_sink(struct mod_color *mod_color, +- const struct dc_sink *sink) +-{ +- int i = 0, j = 0; +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- for (i = 0; i < core_color->num_sinks; i++) { +- if (core_color->caps[i].sink == sink) { +- if (core_color->state[i].gamma) { +- dc_gamma_release(&core_color->state[i].gamma); +- } +- memset(&core_color->state[i], 0, +- sizeof(struct color_state)); +- memset(&core_color->edid_caps[i], 0, +- sizeof(struct color_edid_caps)); +- +- /* To remove this sink, shift everything after down */ +- for (j = i; j < core_color->num_sinks - 1; j++) { +- core_color->caps[j].sink = +- core_color->caps[j + 1].sink; +- +- memcpy(&core_color->state[j], +- &core_color->state[j + 1], +- sizeof(struct color_state)); +- +- memcpy(&core_color->edid_caps[j], +- &core_color->edid_caps[j + 1], +- sizeof(struct color_edid_caps)); +- } +- +- memset(&core_color->state[core_color->num_sinks - 1], 0, +- sizeof(struct color_state)); +- memset(&core_color->edid_caps[core_color->num_sinks - 1], 0, +- sizeof(struct color_edid_caps)); +- +- core_color->num_sinks--; +- +- dc_sink_release(sink); +- +- return true; +- } +- } +- +- return false; +-} +- +-bool mod_color_update_gamut_to_stream(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- struct gamut_src_dst_matrix *matrix = +- dm_alloc(sizeof(struct gamut_src_dst_matrix)); +- +- unsigned int stream_index, j; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "sourcegamut", +- &core_color->state[sink_index]. +- source_gamut.gamut, +- sizeof(struct color_space_coordinates), +- &flag); +- +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "destgamut", +- &core_color->state[sink_index]. +- destination_gamut.gamut, +- sizeof(struct color_space_coordinates), +- &flag); +- +- if (!build_gamut_remap_matrix +- (core_color->state[sink_index].source_gamut.gamut, +- matrix->rgbCoeffSrc, +- matrix->whiteCoeffSrc)) +- goto function_fail; +- +- if (!build_gamut_remap_matrix +- (core_color->state[sink_index]. +- destination_gamut.gamut, +- matrix->rgbCoeffDst, matrix->whiteCoeffDst)) +- goto function_fail; +- +- struct fixed31_32 gamut_result[12]; +- struct fixed31_32 temp_matrix[9]; +- +- if (!gamut_to_color_matrix( +- matrix->rgbCoeffDst, +- matrix->whiteCoeffDst, +- matrix->rgbCoeffSrc, +- matrix->whiteCoeffSrc, +- true, +- temp_matrix)) +- goto function_fail; +- +- gamut_result[0] = temp_matrix[0]; +- gamut_result[1] = temp_matrix[1]; +- gamut_result[2] = temp_matrix[2]; +- gamut_result[3] = matrix->whiteCoeffSrc[0]; +- gamut_result[4] = temp_matrix[3]; +- gamut_result[5] = temp_matrix[4]; +- gamut_result[6] = temp_matrix[5]; +- gamut_result[7] = matrix->whiteCoeffSrc[1]; +- gamut_result[8] = temp_matrix[6]; +- gamut_result[9] = temp_matrix[7]; +- gamut_result[10] = temp_matrix[8]; +- gamut_result[11] = matrix->whiteCoeffSrc[2]; +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_stream->public.gamut_remap_matrix.enable_remap = true; +- +- for (j = 0; j < 12; j++) +- core_stream->public. +- gamut_remap_matrix.matrix[j] = +- gamut_result[j]; +- } +- +- dm_free(matrix); +- core_color->dc->stream_funcs.set_gamut_remap +- (core_color->dc, streams, num_streams); +- +- return true; +- +-function_fail: +- dm_free(matrix); +- return false; +-} +- +-bool mod_color_adjust_source_gamut(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- update_color_gamut_data(input_gamut_data, +- &core_color->state[sink_index].source_gamut); +- } +- +- if (!mod_color_update_gamut_info(mod_color, streams, num_streams)) +- return false; +- +- return true; +-} +- +-bool mod_color_adjust_source_gamut_and_tf(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data, +- enum color_transfer_func input_transfer_func) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- update_color_gamut_data(input_gamut_data, +- &core_color->state[sink_index].source_gamut); +- core_color->state[sink_index].input_transfer_function = +- input_transfer_func; +- } +- +- if (!mod_color_update_gamut_info(mod_color, streams, num_streams)) +- return false; +- +- return true; +-} +- +-bool mod_color_adjust_destination_gamut(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- update_color_gamut_data(input_gamut_data, +- &core_color->state[sink_index].destination_gamut); +- } +- +- if (!mod_color_update_gamut_to_stream(mod_color, streams, num_streams)) +- return false; +- +- return true; +-} +- +-bool mod_color_set_white_point(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct white_point_coodinates *white_point) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; +- stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- core_color->state[sink_index].source_gamut.gamut.whiteX = +- white_point->whiteX; +- core_color->state[sink_index].source_gamut.gamut.whiteY = +- white_point->whiteY; +- } +- +- if (!mod_color_update_gamut_to_stream(mod_color, streams, num_streams)) +- return false; +- +- return true; +-} +- +- +-bool mod_color_set_mastering_info(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- const struct dc_hdr_static_metadata *mastering_info) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- memcpy(&core_color->state[sink_index].mastering_info, +- mastering_info, +- sizeof(struct dc_hdr_static_metadata)); +- } +- return true; +-} +- +-bool mod_color_get_mastering_info(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct dc_hdr_static_metadata *mastering_info) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- memcpy(mastering_info, &core_color->state[sink_index].mastering_info, +- sizeof(struct dc_hdr_static_metadata)); +- +- return true; +-} +- +-bool mod_color_set_user_enable(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- bool user_enable) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- core_color->state[sink_index].user_enable_color_temperature +- = user_enable; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "enablecolortempadj", +- &user_enable, +- sizeof(bool), +- &flag); +- } +- return true; +-} +- +-bool mod_color_get_user_enable(struct mod_color *mod_color, +- const struct dc_sink *sink, +- bool *user_enable) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *user_enable = core_color->state[sink_index]. +- user_enable_color_temperature; +- +- return true; +-} +- +-bool mod_color_get_custom_color_temperature(struct mod_color *mod_color, +- const struct dc_sink *sink, +- int *color_temperature) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *color_temperature = core_color->state[sink_index]. +- custom_color_temperature; +- +- return true; +-} +- +-bool mod_color_set_custom_color_temperature(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int color_temperature) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- core_color->state[sink_index].custom_color_temperature +- = color_temperature; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "customcolortemp", +- &color_temperature, +- sizeof(int), +- &flag); +- } +- return true; +-} +- +-bool mod_color_get_color_saturation(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_saturation) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *color_saturation = core_color->state[sink_index].saturation; +- +- return true; +-} +- +-bool mod_color_get_color_contrast(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_contrast) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *color_contrast = core_color->state[sink_index].contrast; +- +- return true; +-} +- +-bool mod_color_get_color_brightness(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_brightness) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *color_brightness = core_color->state[sink_index].brightness; +- +- return true; +-} +- +-bool mod_color_get_color_hue(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_hue) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *color_hue = core_color->state[sink_index].hue; +- +- return true; +-} +- +-bool mod_color_get_source_gamut(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_space_coordinates *source_gamut) +-{ +- struct core_color *core_color = +- MOD_COLOR_TO_CORE(mod_color); +- +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- *source_gamut = core_color->state[sink_index].source_gamut.gamut; +- +- return true; +-} +- +-bool mod_color_notify_mode_change(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- +- struct gamut_src_dst_matrix *matrix = +- dm_alloc(sizeof(struct gamut_src_dst_matrix)); +- +- unsigned int stream_index, j; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- if (!build_gamut_remap_matrix +- (core_color->state[sink_index].source_gamut.gamut, +- matrix->rgbCoeffSrc, +- matrix->whiteCoeffSrc)) +- goto function_fail; +- +- if (!build_gamut_remap_matrix +- (core_color->state[sink_index]. +- destination_gamut.gamut, +- matrix->rgbCoeffDst, matrix->whiteCoeffDst)) +- goto function_fail; +- +- struct fixed31_32 gamut_result[12]; +- struct fixed31_32 temp_matrix[9]; +- +- if (!gamut_to_color_matrix( +- matrix->rgbCoeffDst, +- matrix->whiteCoeffDst, +- matrix->rgbCoeffSrc, +- matrix->whiteCoeffSrc, +- true, +- temp_matrix)) +- goto function_fail; +- +- gamut_result[0] = temp_matrix[0]; +- gamut_result[1] = temp_matrix[1]; +- gamut_result[2] = temp_matrix[2]; +- gamut_result[3] = matrix->whiteCoeffSrc[0]; +- gamut_result[4] = temp_matrix[3]; +- gamut_result[5] = temp_matrix[4]; +- gamut_result[6] = temp_matrix[5]; +- gamut_result[7] = matrix->whiteCoeffSrc[1]; +- gamut_result[8] = temp_matrix[6]; +- gamut_result[9] = temp_matrix[7]; +- gamut_result[10] = temp_matrix[8]; +- gamut_result[11] = matrix->whiteCoeffSrc[2]; +- +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_stream->public.gamut_remap_matrix.enable_remap = true; +- +- for (j = 0; j < 12; j++) +- core_stream->public. +- gamut_remap_matrix.matrix[j] = +- gamut_result[j]; +- +- calculate_csc_matrix(core_color, sink_index, +- core_stream->public.output_color_space, +- core_stream->public.csc_color_matrix.matrix); +- +- core_stream->public.csc_color_matrix.enable_adjustment = true; +- } +- +- dm_free(matrix); +- +- return true; +- +-function_fail: +- dm_free(matrix); +- return false; +-} +- +-bool mod_color_set_brightness(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int brightness_value) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_color->state[sink_index].brightness.current = +- brightness_value; +- +- calculate_csc_matrix(core_color, sink_index, +- core_stream->public.output_color_space, +- core_stream->public.csc_color_matrix.matrix); +- +- core_stream->public.csc_color_matrix.enable_adjustment = true; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "brightness", +- &brightness_value, +- sizeof(int), +- &flag); +- } +- +- core_color->dc->stream_funcs.set_gamut_remap +- (core_color->dc, streams, num_streams); +- +- return true; +-} +- +-bool mod_color_set_contrast(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int contrast_value) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_color->state[sink_index].contrast.current = +- contrast_value; +- +- calculate_csc_matrix(core_color, sink_index, +- core_stream->public.output_color_space, +- core_stream->public.csc_color_matrix.matrix); +- +- core_stream->public.csc_color_matrix.enable_adjustment = true; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "contrast", +- &contrast_value, +- sizeof(int), +- &flag); +- } +- +- core_color->dc->stream_funcs.set_gamut_remap +- (core_color->dc, streams, num_streams); +- +- return true; +-} +- +-bool mod_color_set_hue(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int hue_value) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_color->state[sink_index].hue.current = hue_value; +- +- calculate_csc_matrix(core_color, sink_index, +- core_stream->public.output_color_space, +- core_stream->public.csc_color_matrix.matrix); +- +- core_stream->public.csc_color_matrix.enable_adjustment = true; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "hue", +- &hue_value, +- sizeof(int), +- &flag); +- } +- +- core_color->dc->stream_funcs.set_gamut_remap +- (core_color->dc, streams, num_streams); +- +- return true; +-} +- +-bool mod_color_set_saturation(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int saturation_value) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- struct core_stream *core_stream = +- DC_STREAM_TO_CORE +- (streams[stream_index]); +- +- core_color->state[sink_index].saturation.current = +- saturation_value; +- +- calculate_csc_matrix(core_color, sink_index, +- core_stream->public.output_color_space, +- core_stream->public.csc_color_matrix.matrix); +- +- core_stream->public.csc_color_matrix.enable_adjustment = true; +- +- /* Write persistent data in registry*/ +- flag.save_per_edid = true; +- flag.save_per_link = false; +- dm_write_persistent_data(core_dc->ctx, +- streams[stream_index]->sink, +- COLOR_REGISTRY_NAME, +- "saturation", +- &saturation_value, +- sizeof(int), +- &flag); +- } +- +- core_color->dc->stream_funcs.set_gamut_remap +- (core_color->dc, streams, num_streams); +- +- return true; +-} +- +-bool mod_color_set_input_gamma_correction(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct dc_gamma *gamma) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- unsigned int stream_index; +- int sink_index; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- +- struct dc_surface *surface = +- dc_stream_to_surface_from_pipe_ctx(core_color, +- streams[stream_index]); +- +- if (surface != NULL) { +- struct dc_transfer_func *input_tf = +- dc_create_transfer_func(); +- struct dc_surface_update updates = {0}; +- +- if (input_tf != NULL) { +- input_tf->type = TF_TYPE_PREDEFINED; +- input_tf->tf = TRANSFER_FUNCTION_SRGB; +- } +- +- if (core_color->state[sink_index].gamma != gamma) { +- if (core_color->state[sink_index].gamma) +- dc_gamma_release( +- &core_color->state[sink_index].gamma); +- +- dc_gamma_retain(gamma); +- core_color->state[sink_index].gamma = gamma; +- } +- +- updates.surface = surface; +- updates.gamma = gamma; +- updates.in_transfer_func = input_tf; +- dc_update_surfaces_for_target(core_color->dc, &updates, +- 1, NULL); +- +- if (input_tf != NULL) +- dc_transfer_func_release(input_tf); +- } +- } +- +- return true; +-} +- +-bool mod_color_persist_user_preferred_quantization_range( +- struct mod_color *mod_color, +- const struct dc_sink *sink, +- enum dc_quantization_range quantization_range) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- struct core_dc *core_dc = DC_TO_CORE(core_color->dc); +- struct persistent_data_flag flag; +- int sink_index; +- +- sink_index = sink_index_from_sink(core_color, sink); +- if (sink_index == -1) +- return false; +- +- if (core_color->state[sink_index]. +- preferred_quantization_range != quantization_range) { +- core_color->state[sink_index].preferred_quantization_range = +- quantization_range; +- flag.save_per_edid = true; +- flag.save_per_link = false; +- dm_write_persistent_data(core_dc->ctx, +- sink, +- COLOR_REGISTRY_NAME, +- "quantization_range", +- &quantization_range, +- sizeof(int), +- &flag); +- } +- +- return true; +-} +- +-bool mod_color_get_preferred_quantization_range(struct mod_color *mod_color, +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing, +- enum dc_quantization_range *quantization_range) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- int sink_index = sink_index_from_sink(core_color, sink); +- +- if (sink_index == -1) +- return false; +- +- enum dc_quantization_range user_preferred_quantization_range = +- core_color->state[sink_index]. +- preferred_quantization_range; +- bool rgb_full_range_supported = +- mod_color_is_rgb_full_range_supported_for_timing( +- sink, timing); +- bool rgb_limited_range_supported = +- mod_color_is_rgb_limited_range_supported_for_timing( +- sink, timing); +- +- if (rgb_full_range_supported && rgb_limited_range_supported) +- *quantization_range = user_preferred_quantization_range; +- else if (rgb_full_range_supported && !rgb_limited_range_supported) +- *quantization_range = QUANTIZATION_RANGE_FULL; +- else if (!rgb_full_range_supported && rgb_limited_range_supported) +- *quantization_range = QUANTIZATION_RANGE_LIMITED; +- else +- *quantization_range = QUANTIZATION_RANGE_UNKNOWN; +- +- return true; +-} +- +-bool mod_color_is_rgb_full_range_supported_for_timing( +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing) +-{ +- bool result = false; +- +- if (!sink || !timing) +- return result; +- +- if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) +- if (timing->vic || timing->hdmi_vic) +- if (timing->h_addressable == 640 && +- timing->v_addressable == 480 && +- (timing->pix_clk_khz == 25200 || +- timing->pix_clk_khz == 25170 || +- timing->pix_clk_khz == 25175)) +- result = true; +- else +- /* don't support full range rgb */ +- /* for HDMI CEA861 timings except VGA mode */ +- result = false; +- else +- result = true; +- else +- result = true; +- +- return result; +-} +- +-bool mod_color_is_rgb_limited_range_supported_for_timing( +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing) +-{ +- bool result = false; +- +- if (!sink || !timing) +- return result; +- +- if (sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) +- if (timing->vic || timing->hdmi_vic) +- if (timing->h_addressable == 640 && +- timing->v_addressable == 480 && +- (timing->pix_clk_khz == 25200 || +- timing->pix_clk_khz == 25170 || +- timing->pix_clk_khz == 25175)) +- /* don't support rgb limited for */ +- /* HDMI CEA VGA mode */ +- result = false; +- else +- /* support rgb limited for non VGA CEA timing */ +- result = true; +- else +- /* support rgb limited for non CEA HDMI timing */ +- result = true; +- else +- /* don't support rgb limited for non HDMI signal */ +- result = false; +- +- return result; +-} +- +-bool mod_color_set_regamma(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams) +-{ +- /*TODO*/ +- return true; +-} +- +-bool mod_color_set_degamma(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- enum color_transfer_func transfer_function) +-{ +- /*TODO*/ +- return true; +-} +- +-bool mod_color_update_gamut_info(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams) +-{ +- struct core_color *core_color = MOD_COLOR_TO_CORE(mod_color); +- unsigned int stream_index; +- int sink_index; +- bool should_defer = false; +- bool is_hdr = false; +- enum color_color_space source_color_space; +- enum color_transfer_func input_transfer_function; +- struct color_gamut_data new_gamut_source; +- struct color_gamut_data new_gamut_destination; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- sink_index = sink_index_from_sink(core_color, +- streams[stream_index]->sink); +- if (sink_index == -1) +- continue; +- source_color_space = +- core_color->state[sink_index].source_gamut.color_space; +- input_transfer_function = +- core_color->state[sink_index].input_transfer_function; +- new_gamut_source.color_space = source_color_space; +- new_gamut_destination.color_space = +- core_color->state[sink_index]. +- destination_gamut.color_space; +- +- struct dc_surface *surface = +- dc_stream_to_surface_from_pipe_ctx(core_color, +- streams[stream_index]); +- if (surface == NULL) +- return false; +- +- if (surface->format == SURFACE_PIXEL_FORMAT_GRPH_ARGB8888 || +- surface->format == +- SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010) { +- +- if (input_transfer_function == +- transfer_func_pq2084 || +- input_transfer_function == +- transfer_func_pq2084_interim) { +- /* For PQ and PQ interim, we bypass degamma+ +- * remap+regamma, application needs to also +- * handle gamut remapping +- */ +- /* TODO */ +- is_hdr = true; +- } else if (input_transfer_function == +- transfer_func_linear_0_1 || +- input_transfer_function == +- transfer_func_linear_0_125) { +- /* TF not supported in current surface format, +- * but may be deferred to a later flip +- */ +- should_defer = true; +- } else { +- new_gamut_destination.color_space = +- color_space_srgb; +- } +- } else if (surface->format == +- SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F || +- surface->format == +- SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F || +- surface->format == +- SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616) { +- if (input_transfer_function == +- transfer_func_linear_0_125) { +- /* Regamma PQ for HDR supported displays and +- * 0-125 source +- */ +- if ((core_color->edid_caps[sink_index]. +- hdr_caps) & smpte_st2084) +- is_hdr = true; +- +- /* override for BT.2020 whenever PQ */ +- if (core_color->state[sink_index]. +- destination_gamut.color_space != +- color_space_bt2020) { +- if (streams[stream_index]->timing. +- pixel_encoding == +- PIXEL_ENCODING_RGB) { +- if ((core_color-> +- edid_caps[sink_index]. +- colorimetry_caps) & bt_2020_rgb) +- new_gamut_destination. +- color_space = +- color_space_bt2020; +- } else { +- if ((core_color-> +- edid_caps[sink_index]. +- colorimetry_caps) & bt_2020_ycc) +- new_gamut_destination. +- color_space = +- color_space_bt2020; +- } +- } +- } else if (input_transfer_function == +- transfer_func_linear_0_1) { +- new_gamut_destination.color_space = +- color_space_srgb; +- } else { +- /* TF not supported in current surface format, +- * but may be deferred to a later flip +- */ +- should_defer = true; +- } +- } +- +- /* 0. ---- CHECK DEFERRED ---- */ +- if (should_defer) +- return true; +- +- /* 1. ---- SET GAMUT SOURCE ---- */ +- new_gamut_source.white_point = core_color->state[sink_index]. +- source_gamut.white_point; +- update_color_gamut_data(&new_gamut_source, +- &core_color->state[sink_index].source_gamut); +- +- /* 2. ---- SET GAMUT DESTINATION ---- */ +- new_gamut_destination.white_point = +- core_color->state[sink_index]. +- destination_gamut.white_point; +- update_color_gamut_data(&new_gamut_destination, +- &core_color->state[sink_index].destination_gamut); +- +- /* 3. ---- SET DEGAMMA ---- */ +- struct dc_transfer_func *input_tf = NULL; +- +- input_tf = dc_create_transfer_func(); +- +- if (input_tf != NULL) { +- input_tf->type = TF_TYPE_PREDEFINED; +- +- switch (input_transfer_function) { +- case transfer_func_srgb: +- input_tf->tf = TRANSFER_FUNCTION_SRGB; +- break; +- case transfer_func_linear_0_1: +- case transfer_func_linear_0_125: +- input_tf->tf = TRANSFER_FUNCTION_LINEAR; +- break; +- default: +- dc_transfer_func_release(input_tf); +- input_tf = NULL; +- break; +- } +- } +- +- /* 4. ---- SET REGAMMA ---- */ +- struct dc_transfer_func *output_tf = NULL; +- +- output_tf = dc_create_transfer_func(); +- +- if (output_tf != NULL) { +- output_tf->type = TF_TYPE_PREDEFINED; +- if (is_hdr) +- output_tf->tf = TRANSFER_FUNCTION_PQ; +- else +- output_tf->tf = TRANSFER_FUNCTION_SRGB; +- } +- /* 5. ---- POPULATE HDR METADATA ---- */ +- core_color->state[sink_index].mastering_info.is_hdr = is_hdr; +- +- /* 6. ---- TODO: UPDATE INFOPACKETS ---- */ +- +- if (!mod_color_update_gamut_to_stream( +- mod_color, streams, num_streams)) +- return false; +- +- struct dc_surface_update updates[4] = {0}; +- +- updates[0].surface = surface; +- updates[0].gamma = core_color->state[sink_index].gamma; +- updates[0].in_transfer_func = input_tf; +- updates[0].out_transfer_func = output_tf; +- updates[0].hdr_static_metadata = +- &core_color->state[sink_index].mastering_info; +- +- dc_update_surfaces_for_target(core_color->dc, updates, 1, NULL); +- +- if (input_tf != NULL) +- dc_transfer_func_release(input_tf); +- +- if (output_tf != NULL) +- dc_transfer_func_release(output_tf); +- } +- return true; +-} +diff --git a/drivers/gpu/drm/amd/display/modules/color/color_helper.c b/drivers/gpu/drm/amd/display/modules/color/color_helper.c +deleted file mode 100644 +index ff6779c..0000000 +--- a/drivers/gpu/drm/amd/display/modules/color/color_helper.c ++++ /dev/null +@@ -1,210 +0,0 @@ +-/* +- * Copyright 2016 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 "dc.h" +-#include "mod_color.h" +-#include "color_helper.h" +- +-const struct gamut_space_entry predefined_gamuts[] = { +- /* x_red y_red x_gr y_gr x_blue y_blue a0 a1 a2 a3 gamma */ +- [gamut_type_bt709] = {6400, 3300, 3000, 6000, 1500, 600, 180000, 4500, 99, 99, 2200}, +- [gamut_type_bt601] = {6400, 3300, 2900, 6000, 1500, 600, 180000, 4500, 99, 99, 2200}, +- [gamut_type_adobe_rgb] = {6400, 3300, 2100, 7100, 1500, 600, 180000, 4500, 99, 99, 2200}, +- [gamut_type_srgb] = {6400, 3300, 3000, 6000, 1500, 600, 31308, 12920, 55, 55, 2400}, +- [gamut_type_bt2020] = {7080, 2920, 1700, 7970, 1310, 460, 180000, 4500, 99, 99, 2200} +-}; +- +-const struct white_point_coodinates_entry predefined_white_points[] = { +- [white_point_type_5000k_horizon] = {5000, 3473, 3561}, +- [white_point_type_6500k_noon] = {6500, 3127, 3290}, +- [white_point_type_7500k_north_sky] = {7500, 3022, 3129}, +- [white_point_type_9300k] = {9300, 2866, 2950} +-}; +- +-const unsigned int white_point_entries = 91; +- +-const struct white_point_coodinates_entry white_point_temps[] = { +- /*001*/{1000, 6499, 3474}, +- /*002*/{1100, 6361, 3594}, +- /*003*/{1200, 6226, 3703}, +- /*004*/{1300, 6095, 3801}, +- /*005*/{1400, 5966, 3887}, +- /*006*/{1500, 5841, 3962}, +- /*007*/{1600, 5720, 4025}, +- /*008*/{1700, 5601, 4076}, +- /*009*/{1800, 5486, 4118}, +- /*010*/{1900, 5375, 4150}, +- /*011*/{2000, 5267, 4173}, +- /*012*/{2100, 5162, 4188}, +- /*013*/{2200, 5062, 4196}, +- /*014*/{2300, 4965, 4198}, +- /*015*/{2400, 4872, 4194}, +- /*016*/{2500, 4782, 4186}, +- /*017*/{2600, 4696, 4173}, +- /*018*/{2700, 4614, 4158}, +- /*019*/{2800, 4535, 4139}, +- /*020*/{2900, 4460, 4118}, +- /*021*/{3000, 4388, 4095}, +- /*022*/{3100, 4320, 4070}, +- /*023*/{3200, 4254, 4044}, +- /*024*/{3300, 4192, 4018}, +- /*025*/{3400, 4132, 3990}, +- /*026*/{3500, 4075, 3962}, +- /*027*/{3600, 4021, 3934}, +- /*028*/{3700, 3969, 3905}, +- /*029*/{3800, 3919, 3877}, +- /*030*/{3900, 3872, 3849}, +- /*031*/{4000, 3827, 3820}, +- /*032*/{4100, 3784, 3793}, +- /*033*/{4200, 3743, 3765}, +- /*034*/{4300, 3704, 3738}, +- /*035*/{4400, 3666, 3711}, +- /*036*/{4500, 3631, 3685}, +- /*037*/{4600, 3596, 3659}, +- /*038*/{4700, 3563, 3634}, +- /*039*/{4800, 3532, 3609}, +- /*040*/{4900, 3502, 3585}, +- /*041*/{5000, 3473, 3561}, +- /*042*/{5100, 3446, 3538}, +- /*043*/{5200, 3419, 3516}, +- /*044*/{5300, 3394, 3494}, +- /*045*/{5400, 3369, 3472}, +- /*046*/{5500, 3346, 3451}, +- /*047*/{5600, 3323, 3431}, +- /*048*/{5700, 3302, 3411}, +- /*049*/{5800, 3281, 3392}, +- /*050*/{5900, 3261, 3373}, +- /*051*/{6000, 3242, 3355}, +- /*052*/{6100, 3223, 3337}, +- /*053*/{6200, 3205, 3319}, +- /*054*/{6300, 3188, 3302}, +- /*055*/{6400, 3161, 3296}, +- /*056*/{6500, 3127, 3290}, /* This is the real white point sRGB */ +- /*057*/{6600, 3126, 3264}, +- /*058*/{6700, 3125, 3238}, +- /*059*/{6800, 3110, 3224}, +- /*060*/{6900, 3097, 3209}, +- /*061*/{7000, 3083, 3195}, +- /*062*/{7100, 3070, 3181}, +- /*063*/{7200, 3058, 3168}, +- /*064*/{7300, 3045, 3154}, +- /*065*/{7400, 3034, 3142}, +- /*066*/{7500, 3022, 3129}, +- /*067*/{7600, 3011, 3117}, +- /*068*/{7700, 3000, 3105}, +- /*069*/{7800, 2990, 3094}, +- /*070*/{7900, 2980, 3082}, +- /*071*/{8000, 2970, 3071}, +- /*072*/{8100, 2961, 3061}, +- /*073*/{8200, 2952, 3050}, +- /*074*/{8300, 2943, 3040}, +- /*075*/{8400, 2934, 3030}, +- /*076*/{8500, 2926, 3020}, +- /*077*/{8600, 2917, 3011}, +- /*078*/{8700, 2910, 3001}, +- /*079*/{8800, 2902, 2992}, +- /*080*/{8900, 2894, 2983}, +- /*081*/{9000, 2887, 2975}, +- /*082*/{9100, 2880, 2966}, +- /*083*/{9200, 2873, 2958}, +- /*084*/{9300, 2866, 2950}, +- /*085*/{9400, 2860, 2942}, +- /*086*/{9500, 2853, 2934}, +- /*087*/{9600, 2847, 2927}, +- /*088*/{9700, 2841, 2919}, +- /*089*/{9800, 2835, 2912}, +- /*090*/{9900, 2829, 2905}, +- /*091*/{10000, 2824, 2898} +-}; +- +-bool mod_color_find_predefined_gamut( +- struct gamut_space_coordinates *out_gamut, +- enum predefined_gamut_type type) +-{ +- out_gamut->redX = predefined_gamuts[type].redX; +- out_gamut->redY = predefined_gamuts[type].redY; +- out_gamut->greenX = predefined_gamuts[type].greenX; +- out_gamut->greenY = predefined_gamuts[type].greenY; +- out_gamut->blueX = predefined_gamuts[type].blueX; +- out_gamut->blueY = predefined_gamuts[type].blueY; +- +- return true; +-} +- +-bool mod_color_find_predefined_white_point( +- struct white_point_coodinates *out_white_point, +- enum predefined_white_point_type type) +-{ +- out_white_point->whiteX = predefined_white_points[type].whiteX; +- out_white_point->whiteY = predefined_white_points[type].whiteY; +- +- return true; +-} +- +-bool mod_color_find_white_point_from_temperature( +- struct white_point_coodinates *out_white_point, +- unsigned int temperature) +-{ +- int i; +- unsigned int found = false; +- struct white_point_coodinates_entry temp_white_point = +- white_point_temps[55]; +- +- if (temperature < 1000 || temperature > 10000) +- return false; +- +- for (i = 0; i < white_point_entries; i++) { +- if (temperature == white_point_temps[i].temperature) { +- temp_white_point = white_point_temps[i]; +- found = true; +- break; +- } +- } +- +- out_white_point->whiteX = temp_white_point.whiteX; +- out_white_point->whiteY = temp_white_point.whiteY; +- +- return found; +-} +- +-bool mod_color_find_temperature_from_white_point( +- struct white_point_coodinates *in_white_point, +- unsigned int *out_temperature) +-{ +- unsigned int i; +- *out_temperature = 6500; +- +- for (i = 0; i < white_point_entries; i++) { +- if (in_white_point->whiteX == white_point_temps[i].whiteX && +- in_white_point->whiteY == white_point_temps[i].whiteY) { +- *out_temperature = white_point_temps[i].temperature; +- return true; +- } +- } +- +- return false; +-} +- +diff --git a/drivers/gpu/drm/amd/display/modules/color/color_helper.h b/drivers/gpu/drm/amd/display/modules/color/color_helper.h +deleted file mode 100644 +index 76575c1..0000000 +--- a/drivers/gpu/drm/amd/display/modules/color/color_helper.h ++++ /dev/null +@@ -1,62 +0,0 @@ +-/* +- * Copyright 2016 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 +- * +- */ +- +-#ifndef COLOR_MOD_COLOR_HELPER_H_ +-#define COLOR_MOD_COLOR_HELPER_H_ +- +-enum predefined_gamut_type { +- gamut_type_bt709, +- gamut_type_bt601, +- gamut_type_adobe_rgb, +- gamut_type_srgb, +- gamut_type_bt2020, +- gamut_type_unknown, +-}; +- +-enum predefined_white_point_type { +- white_point_type_5000k_horizon, +- white_point_type_6500k_noon, +- white_point_type_7500k_north_sky, +- white_point_type_9300k, +- white_point_type_unknown, +-}; +- +-bool mod_color_find_predefined_gamut( +- struct gamut_space_coordinates *out_gamut, +- enum predefined_gamut_type type); +- +-bool mod_color_find_predefined_white_point( +- struct white_point_coodinates *out_white_point, +- enum predefined_white_point_type type); +- +-bool mod_color_find_white_point_from_temperature( +- struct white_point_coodinates *out_white_point, +- unsigned int temperature); +- +-bool mod_color_find_temperature_from_white_point( +- struct white_point_coodinates *in_white_point, +- unsigned int *out_temperature); +- +-#endif /* COLOR_MOD_COLOR_HELPER_H_ */ +diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h b/drivers/gpu/drm/amd/display/modules/inc/mod_color.h +deleted file mode 100644 +index 70349a8..0000000 +--- a/drivers/gpu/drm/amd/display/modules/inc/mod_color.h ++++ /dev/null +@@ -1,282 +0,0 @@ +-/* +- * Copyright 2016 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 +- * +- */ +- +- +-#ifndef MOD_COLOR_H_ +-#define MOD_COLOR_H_ +- +-#include "dm_services.h" +-#include "color_helper.h" +- +-enum color_transfer_func { +- transfer_func_unknown, +- transfer_func_srgb, +- transfer_func_bt709, +- transfer_func_pq2084, +- transfer_func_pq2084_interim, +- transfer_func_linear_0_1, +- transfer_func_linear_0_125, +- transfer_func_dolbyvision, +- transfer_func_gamma_22, +- transfer_func_gamma_26 +-}; +- +-enum color_color_space { +- color_space_unsupported, +- color_space_srgb, +- color_space_bt601, +- color_space_bt709, +- color_space_xv_ycc_bt601, +- color_space_xv_ycc_bt709, +- color_space_xr_rgb, +- color_space_bt2020, +- color_space_adobe, +- color_space_dci_p3, +- color_space_sc_rgb_ms_ref, +- color_space_display_native, +- color_space_app_ctrl, +- color_space_dolby_vision, +- color_space_custom_coordinates +-}; +- +-enum color_white_point_type { +- color_white_point_type_unknown, +- color_white_point_type_5000k_horizon, +- color_white_point_type_6500k_noon, +- color_white_point_type_7500k_north_sky, +- color_white_point_type_9300k, +- color_white_point_type_custom_coordinates +-}; +- +-enum colorimetry_support_flag { +- xv_ycc_bt601 = 0x01, +- xv_ycc_bt709 = 0x02, +- s_ycc_601 = 0x04, +- adobe_ycc_601 = 0x08, +- adobe_rgb = 0x10, +- bt_2020_c_ycc = 0x20, +- bt_2020_ycc = 0x40, +- bt_2020_rgb = 0x80 +-}; +- +-enum hdr_tf_support_flag { +- traditional_gamma_sdr = 0x01, +- traditional_gamma_hdr = 0x02, +- smpte_st2084 = 0x04 +-}; +- +-struct mod_color { +- int dummy; +-}; +- +-struct color_space_coordinates { +- unsigned int redX; +- unsigned int redY; +- unsigned int greenX; +- unsigned int greenY; +- unsigned int blueX; +- unsigned int blueY; +- unsigned int whiteX; +- unsigned int whiteY; +-}; +- +-struct gamut_space_coordinates { +- unsigned int redX; +- unsigned int redY; +- unsigned int greenX; +- unsigned int greenY; +- unsigned int blueX; +- unsigned int blueY; +-}; +- +-struct gamut_space_entry { +- unsigned int redX; +- unsigned int redY; +- unsigned int greenX; +- unsigned int greenY; +- unsigned int blueX; +- unsigned int blueY; +- +- int a0; +- int a1; +- int a2; +- int a3; +- int gamma; +-}; +- +-struct white_point_coodinates { +- unsigned int whiteX; +- unsigned int whiteY; +-}; +- +-struct white_point_coodinates_entry { +- unsigned int temperature; +- unsigned int whiteX; +- unsigned int whiteY; +-}; +- +-struct color_range { +- int current; +- int min; +- int max; +-}; +- +-struct color_gamut_data { +- enum color_color_space color_space; +- enum color_white_point_type white_point; +- struct color_space_coordinates gamut; +-}; +- +-struct color_edid_caps { +- unsigned int colorimetry_caps; +- unsigned int hdr_caps; +-}; +- +-struct mod_color *mod_color_create(struct dc *dc); +- +-void mod_color_destroy(struct mod_color *mod_color); +- +-bool mod_color_add_sink(struct mod_color *mod_color, +- const struct dc_sink *sink, struct color_edid_caps *edid_caps); +- +-bool mod_color_remove_sink(struct mod_color *mod_color, +- const struct dc_sink *sink); +- +-bool mod_color_update_gamut_to_stream(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams); +- +-bool mod_color_set_white_point(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct white_point_coodinates *white_point); +- +-bool mod_color_adjust_source_gamut(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data); +- +-bool mod_color_adjust_destination_gamut(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data); +- +-bool mod_color_adjust_source_gamut_and_tf(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct color_gamut_data *input_gamut_data, +- enum color_transfer_func input_transfer_func); +- +-bool mod_color_get_user_enable(struct mod_color *mod_color, +- const struct dc_sink *sink, +- bool *user_enable); +- +-bool mod_color_set_mastering_info(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- const struct dc_hdr_static_metadata *mastering_info); +- +-bool mod_color_get_mastering_info(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct dc_hdr_static_metadata *mastering_info); +- +-bool mod_color_set_user_enable(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- bool user_enable); +- +-bool mod_color_get_custom_color_temperature(struct mod_color *mod_color, +- const struct dc_sink *sink, +- int *color_temperature); +- +-bool mod_color_set_custom_color_temperature(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int color_temperature); +- +-bool mod_color_get_color_saturation(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_saturation); +- +-bool mod_color_get_color_contrast(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_contrast); +- +-bool mod_color_get_color_brightness(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_brightness); +- +-bool mod_color_get_color_hue(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_range *color_hue); +- +-bool mod_color_get_source_gamut(struct mod_color *mod_color, +- const struct dc_sink *sink, +- struct color_space_coordinates *source_gamut); +- +-bool mod_color_notify_mode_change(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams); +- +-bool mod_color_set_brightness(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int brightness_value); +- +-bool mod_color_set_contrast(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int contrast_value); +- +-bool mod_color_set_hue(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int hue_value); +- +-bool mod_color_set_saturation(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- int saturation_value); +- +-bool mod_color_set_input_gamma_correction(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- struct dc_gamma *gamma); +- +-bool mod_color_persist_user_preferred_quantization_range( +- struct mod_color *mod_color, +- const struct dc_sink *sink, +- enum dc_quantization_range quantization_range); +- +-bool mod_color_get_preferred_quantization_range(struct mod_color *mod_color, +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing, +- enum dc_quantization_range *quantization_range); +- +-bool mod_color_is_rgb_full_range_supported_for_timing( +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing); +- +-bool mod_color_is_rgb_limited_range_supported_for_timing( +- const struct dc_sink *sink, +- const struct dc_crtc_timing *timing); +- +-bool mod_color_set_regamma(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams); +- +-bool mod_color_set_degamma(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams, +- enum color_transfer_func transfer_function); +- +-bool mod_color_update_gamut_info(struct mod_color *mod_color, +- const struct dc_stream **streams, int num_streams); +- +-#endif /* MOD_COLOR_H_ */ +diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h b/drivers/gpu/drm/amd/display/modules/inc/mod_power.h +deleted file mode 100644 +index a204e8d..0000000 +--- a/drivers/gpu/drm/amd/display/modules/inc/mod_power.h ++++ /dev/null +@@ -1,112 +0,0 @@ +-/* +- * Copyright 2016 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 +- * +- */ +- +-#ifndef MODULES_INC_MOD_POWER_H_ +-#define MODULES_INC_MOD_POWER_H_ +- +-#include "dm_services.h" +- +-struct mod_power { +- int dummy; +-}; +- +-/* VariBright related commands */ +-enum varibright_command { +- VariBright_Cmd__SetVBLevel = 0, +- VariBright_Cmd__UserEnable, +- VariBright_Cmd__PreDisplayConfigChange, +- VariBright_Cmd__PostDisplayConfigChange, +- VariBright_Cmd__SuspendABM, +- VariBright_Cmd__ResumeABM, +- +- VariBright_Cmd__Unknown, +-}; +- +-/* VariBright settings structure */ +-struct varibright_info { +- enum varibright_command cmd; +- +- unsigned int level; +- bool enable; +- bool activate; +-}; +- +-enum dmcu_block_psr_reason { +- /* This is a bitfield mask */ +- dmcu_block_psr_reason_invalid = 0x0, +- dmcu_block_psr_reason_vsync_int = 0x1, +- dmcu_block_psr_reason_shared_primary = 0x2, +- dmcu_block_psr_reason_unsupported_link_rate = 0x4 +-}; +- +-struct mod_power *mod_power_create(struct dc *dc); +- +-void mod_power_destroy(struct mod_power *mod_power); +- +-bool mod_power_add_sink(struct mod_power *mod_power, +- const struct dc_sink *sink); +- +-bool mod_power_remove_sink(struct mod_power *mod_power, +- const struct dc_sink *sink); +- +-bool mod_power_set_backlight(struct mod_power *mod_power, +- const struct dc_stream **streams, int num_streams, +- unsigned int backlight_8bit); +- +-bool mod_power_get_backlight(struct mod_power *mod_power, +- const struct dc_sink *sink, +- unsigned int *backlight_8bit); +- +-void mod_power_initialize_backlight_caps +- (struct mod_power *mod_power); +- +-unsigned int mod_power_backlight_level_percentage_to_signal +- (struct mod_power *mod_power, unsigned int percentage); +- +-unsigned int mod_power_backlight_level_signal_to_percentage +- (struct mod_power *mod_power, unsigned int signalLevel8bit); +- +-bool mod_power_get_panel_backlight_boundaries +- (struct mod_power *mod_power, +- unsigned int *min_backlight, +- unsigned int *max_backlight, +- unsigned int *output_ac_level_percentage, +- unsigned int *output_dc_level_percentage); +- +-bool mod_power_set_smooth_brightness(struct mod_power *mod_power, +- const struct dc_sink *sink, bool enable_brightness); +- +-bool mod_power_notify_mode_change(struct mod_power *mod_power, +- const struct dc_stream *stream); +- +-bool mod_power_varibright_control(struct mod_power *mod_power, +- struct varibright_info *input_varibright_info); +- +-bool mod_power_block_psr(bool block_enable, enum dmcu_block_psr_reason reason); +- +-bool mod_power_set_psr_enable(struct mod_power *mod_power, +- bool psr_enable); +- +-#endif /* MODULES_INC_MOD_POWER_H_ */ +diff --git a/drivers/gpu/drm/amd/display/modules/power/power.c b/drivers/gpu/drm/amd/display/modules/power/power.c +deleted file mode 100644 +index ea07e84..0000000 +--- a/drivers/gpu/drm/amd/display/modules/power/power.c ++++ /dev/null +@@ -1,784 +0,0 @@ +-/* +- * Copyright 2016 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 "mod_power.h" +-#include "dm_services.h" +-#include "dc.h" +-#include "core_types.h" +-#include "core_dc.h" +- +-#define MOD_POWER_MAX_CONCURRENT_SINKS 32 +-#define SMOOTH_BRIGHTNESS_ADJUSTMENT_TIME_IN_MS 500 +- +-struct sink_caps { +- const struct dc_sink *sink; +-}; +- +-struct backlight_state { +- unsigned int backlight; +- unsigned int frame_ramp; +- bool smooth_brightness_enabled; +-}; +- +-struct core_power { +- struct mod_power public; +- struct dc *dc; +- int num_sinks; +- struct sink_caps *caps; +- struct backlight_state *state; +-}; +- +-union dmcu_abm_set_bl_params { +- struct { +- unsigned int gradual_change : 1; /* [0:0] */ +- unsigned int reserved : 15; /* [15:1] */ +- unsigned int frame_ramp : 16; /* [31:16] */ +- } bits; +- unsigned int u32All; +-}; +- +-/* Backlight cached properties */ +-static unsigned int backlight_8bit_lut_array[101]; +-static unsigned int ac_level_percentage; +-static unsigned int dc_level_percentage; +-static bool backlight_caps_valid; +-/* we use lazy initialization of backlight capabilities cache */ +-static bool backlight_caps_initialized; +-/* AC/DC levels initialized later in separate context */ +-static bool backlight_def_levels_valid; +- +-/* ABM cached properties */ +-static unsigned int abm_level; +-static bool abm_user_enable; +-static bool abm_active; +- +-/*PSR cached properties*/ +-static unsigned int block_psr; +- +-/* Defines default backlight curve F(x) = A(x*x) + Bx + C. +- * +- * Backlight curve should always satisfy F(0) = min, F(100) = max, +- * so polynom coefficients are: +- * A is 0.0255 - B/100 - min/10000 - (255-max)/10000 = (max - min)/10000 - B/100 +- * B is adjustable factor to modify the curve. +- * Bigger B results in less concave curve. B range is [0..(max-min)/100] +- * C is backlight minimum +- */ +-static const unsigned int backlight_curve_coeff_a_factor = 10000; +-static const unsigned int backlight_curve_coeff_b = 100; +-static const unsigned int backlight_curve_coeff_b_factor = 100; +- +-/* Minimum and maximum backlight input signal levels */ +-static const unsigned int default_min_backlight = 12; +-static const unsigned int default_max_backlight = 255; +- +-/* Other backlight constants */ +-static const unsigned int absolute_backlight_max = 255; +- +-#define MOD_POWER_TO_CORE(mod_power)\ +- container_of(mod_power, struct core_power, public) +- +-static bool check_dc_support(const struct dc *dc) +-{ +- if (dc->stream_funcs.set_backlight == NULL) +- return false; +- +- return true; +-} +- +-/* Given a specific dc_sink* this function finds its equivalent +- * on the dc_sink array and returns the corresponding index +- */ +-static unsigned int sink_index_from_sink(struct core_power *core_power, +- const struct dc_sink *sink) +-{ +- unsigned int index = 0; +- +- for (index = 0; index < core_power->num_sinks; index++) +- if (core_power->caps[index].sink == sink) +- return index; +- +- /* Could not find sink requested */ +- ASSERT(false); +- return index; +-} +- +-static unsigned int convertBL8to17(unsigned int backlight_8bit) +-{ +- unsigned int temp_ulong = backlight_8bit * 0x10101; +- unsigned char temp_uchar = +- (unsigned char)(((temp_ulong & 0x80) >> 7) & 1); +- +- temp_ulong = (temp_ulong >> 8) + temp_uchar; +- +- return temp_ulong; +-} +- +-static uint16_t convertBL8to16(unsigned int backlight_8bit) +-{ +- return (uint16_t)((backlight_8bit * 0x10101) >> 8); +-} +- +-/*This is used when OS wants to retrieve the current BL. +- * We return the 8bit value to OS. +- */ +-static unsigned int convertBL17to8(unsigned int backlight_17bit) +-{ +- if (backlight_17bit & 0x10000) +- return default_max_backlight; +- else +- return (backlight_17bit >> 8); +-} +- +-struct mod_power *mod_power_create(struct dc *dc) +-{ +- struct core_power *core_power = +- dm_alloc(sizeof(struct core_power)); +- +- struct core_dc *core_dc = DC_TO_CORE(dc); +- +- int i = 0; +- +- if (core_power == NULL) +- goto fail_alloc_context; +- +- core_power->caps = dm_alloc(sizeof(struct sink_caps) * +- MOD_POWER_MAX_CONCURRENT_SINKS); +- +- if (core_power->caps == NULL) +- goto fail_alloc_caps; +- +- for (i = 0; i < MOD_POWER_MAX_CONCURRENT_SINKS; i++) +- core_power->caps[i].sink = NULL; +- +- core_power->state = dm_alloc(sizeof(struct backlight_state) * +- MOD_POWER_MAX_CONCURRENT_SINKS); +- +- if (core_power->state == NULL) +- goto fail_alloc_state; +- +- core_power->num_sinks = 0; +- backlight_caps_valid = false; +- +- if (dc == NULL) +- goto fail_construct; +- +- core_power->dc = dc; +- +- if (!check_dc_support(dc)) +- goto fail_construct; +- +- abm_user_enable = false; +- abm_active = false; +- +- return &core_power->public; +- +-fail_construct: +- dm_free(core_power->state); +- +-fail_alloc_state: +- dm_free(core_power->caps); +- +-fail_alloc_caps: +- dm_free(core_power); +- +-fail_alloc_context: +- return NULL; +-} +- +- +-void mod_power_destroy(struct mod_power *mod_power) +-{ +- if (mod_power != NULL) { +- int i; +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- dm_free(core_power->state); +- +- for (i = 0; i < core_power->num_sinks; i++) +- dc_sink_release(core_power->caps[i].sink); +- +- dm_free(core_power->caps); +- +- dm_free(core_power); +- } +-} +- +-bool mod_power_add_sink(struct mod_power *mod_power, +- const struct dc_sink *sink) +-{ +- if (sink->sink_signal == SIGNAL_TYPE_VIRTUAL) +- return false; +- +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- struct core_dc *core_dc = DC_TO_CORE(core_power->dc); +- +- if (core_power->num_sinks < MOD_POWER_MAX_CONCURRENT_SINKS) { +- dc_sink_retain(sink); +- core_power->caps[core_power->num_sinks].sink = sink; +- core_power->state[core_power->num_sinks]. +- smooth_brightness_enabled = false; +- core_power->state[core_power->num_sinks]. +- backlight = 100; +- core_power->num_sinks++; +- return true; +- } +- +- return false; +-} +- +-bool mod_power_remove_sink(struct mod_power *mod_power, +- const struct dc_sink *sink) +-{ +- int i = 0, j = 0; +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- for (i = 0; i < core_power->num_sinks; i++) { +- if (core_power->caps[i].sink == sink) { +- /* To remove this sink, shift everything after down */ +- for (j = i; j < core_power->num_sinks - 1; j++) { +- core_power->caps[j].sink = +- core_power->caps[j + 1].sink; +- +- memcpy(&core_power->state[j], +- &core_power->state[j + 1], +- sizeof(struct backlight_state)); +- } +- core_power->num_sinks--; +- dc_sink_release(sink); +- return true; +- } +- } +- return false; +-} +- +-bool mod_power_set_backlight(struct mod_power *mod_power, +- const struct dc_stream **streams, int num_streams, +- unsigned int backlight_8bit) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- unsigned int frame_ramp = 0; +- +- unsigned int stream_index, sink_index, vsync_rate_hz; +- +- union dmcu_abm_set_bl_params params; +- +- for (stream_index = 0; stream_index < num_streams; stream_index++) { +- if (streams[stream_index]->sink->sink_signal == SIGNAL_TYPE_VIRTUAL) { +- core_power->state[sink_index].backlight = 0; +- core_power->state[sink_index].frame_ramp = 0; +- core_power->state[sink_index].smooth_brightness_enabled = false; +- continue; +- } +- +- sink_index = sink_index_from_sink(core_power, +- streams[stream_index]->sink); +- +- vsync_rate_hz = div64_u64(div64_u64((streams[stream_index]-> +- timing.pix_clk_khz * 1000), +- streams[stream_index]->timing.v_total), +- streams[stream_index]->timing.h_total); +- +- core_power->state[sink_index].backlight = backlight_8bit; +- +- if (core_power->state[sink_index].smooth_brightness_enabled) +- frame_ramp = ((vsync_rate_hz * +- SMOOTH_BRIGHTNESS_ADJUSTMENT_TIME_IN_MS) + 500) +- / 1000; +- else +- frame_ramp = 0; +- +- core_power->state[sink_index].frame_ramp = frame_ramp; +- } +- +- params.u32All = 0; +- params.bits.gradual_change = (frame_ramp > 0); +- params.bits.frame_ramp = frame_ramp; +- +- core_power->dc->stream_funcs.set_backlight +- (core_power->dc, backlight_8bit, params.u32All, streams[0]); +- +- return true; +-} +- +-bool mod_power_get_backlight(struct mod_power *mod_power, +- const struct dc_sink *sink, +- unsigned int *backlight_8bit) +-{ +- if (sink->sink_signal == SIGNAL_TYPE_VIRTUAL) +- return false; +- +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- unsigned int sink_index = sink_index_from_sink(core_power, sink); +- +- *backlight_8bit = core_power->state[sink_index].backlight; +- +- return true; +-} +- +-/* hard coded to default backlight curve. */ +-void mod_power_initialize_backlight_caps(struct mod_power +- *mod_power) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- struct core_dc *core_dc = DC_TO_CORE(core_power->dc); +- unsigned int i; +- +- backlight_caps_initialized = true; +- +- struct dm_acpi_atif_backlight_caps *pExtCaps = NULL; +- bool customCurvePresent = false; +- bool customMinMaxPresent = false; +- bool customDefLevelsPresent = false; +- +- /* Allocate memory for ATIF output +- * (do not want to use 256 bytes on the stack) +- */ +- pExtCaps = (struct dm_acpi_atif_backlight_caps *) +- (dm_alloc(sizeof(struct dm_acpi_atif_backlight_caps))); +- if (pExtCaps == NULL) +- return; +- +- /* Retrieve ACPI extended brightness caps */ +- if (dm_query_extended_brightness_caps +- (core_dc->ctx, AcpiDisplayType_LCD1, pExtCaps)) { +- ac_level_percentage = pExtCaps->acLevelPercentage; +- dc_level_percentage = pExtCaps->dcLevelPercentage; +- customMinMaxPresent = true; +- customDefLevelsPresent = true; +- customCurvePresent = (pExtCaps->numOfDataPoints > 0); +- +- ASSERT(pExtCaps->numOfDataPoints <= 99); +- } else { +- dm_free(pExtCaps); +- return; +- } +- +- if (customMinMaxPresent) +- backlight_8bit_lut_array[0] = pExtCaps->minInputSignal; +- else +- backlight_8bit_lut_array[0] = default_min_backlight; +- +- if (customMinMaxPresent) +- backlight_8bit_lut_array[100] = pExtCaps->maxInputSignal; +- else +- backlight_8bit_lut_array[100] = default_max_backlight; +- +- ASSERT(backlight_8bit_lut_array[100] <= absolute_backlight_max); +- ASSERT(backlight_8bit_lut_array[0] <= +- backlight_8bit_lut_array[100]); +- +- /* Just to make sure we use valid values */ +- if (backlight_8bit_lut_array[100] > absolute_backlight_max) +- backlight_8bit_lut_array[100] = absolute_backlight_max; +- if (backlight_8bit_lut_array[0] > backlight_8bit_lut_array[100]) { +- unsigned int swap; +- +- swap = backlight_8bit_lut_array[0]; +- backlight_8bit_lut_array[0] = backlight_8bit_lut_array[100]; +- backlight_8bit_lut_array[100] = swap; +- } +- +- /* Build backlight translation table for custom curve */ +- if (customCurvePresent) { +- unsigned int index = 1; +- unsigned int numOfDataPoints = +- (pExtCaps->numOfDataPoints <= 99 ? +- pExtCaps->numOfDataPoints : 99); +- +- /* Filling translation table from data points - +- * between every two provided data points we +- * lineary interpolate missing values +- */ +- for (i = 0; i < numOfDataPoints; i++) { +- /* Clamp signal level between min and max +- * (since min and max might come other +- * soruce like registry) +- */ +- unsigned int luminance = +- pExtCaps->dataPoints[i].luminance; +- unsigned int signalLevel = +- pExtCaps->dataPoints[i].signalLevel; +- +- if (signalLevel < backlight_8bit_lut_array[0]) +- signalLevel = backlight_8bit_lut_array[0]; +- if (signalLevel > backlight_8bit_lut_array[100]) +- signalLevel = backlight_8bit_lut_array[100]; +- +- /* Lineary interpolate missing values */ +- if (index < luminance) { +- unsigned int baseValue = +- backlight_8bit_lut_array[index-1]; +- unsigned int deltaSignal = +- signalLevel - baseValue; +- unsigned int deltaLuma = +- luminance - index + 1; +- unsigned int step = deltaSignal; +- +- for (; index < luminance; index++) { +- backlight_8bit_lut_array[index] = +- baseValue + (step / deltaLuma); +- step += deltaSignal; +- } +- } +- +- /* Now [index == luminance], +- * so we can add data point to the translation table +- */ +- backlight_8bit_lut_array[index++] = signalLevel; +- } +- +- /* Complete the final segment of interpolation - +- * between last datapoint and maximum value +- */ +- if (index < 100) { +- unsigned int baseValue = +- backlight_8bit_lut_array[index-1]; +- unsigned int deltaSignal = +- backlight_8bit_lut_array[100] - +- baseValue; +- unsigned int deltaLuma = 100 - index + 1; +- unsigned int step = deltaSignal; +- +- for (; index < 100; index++) { +- backlight_8bit_lut_array[index] = +- baseValue + (step / deltaLuma); +- step += deltaSignal; +- } +- } +- /* Build backlight translation table based on default curve */ +- } else { +- unsigned int delta = +- backlight_8bit_lut_array[100] - +- backlight_8bit_lut_array[0]; +- unsigned int coeffC = backlight_8bit_lut_array[0]; +- unsigned int coeffB = +- (backlight_curve_coeff_b < delta ? +- backlight_curve_coeff_b : delta); +- unsigned int coeffA = delta - coeffB; /* coeffB is B*100 */ +- +- for (i = 1; i < 100; i++) { +- backlight_8bit_lut_array[i] = +- (coeffA * i * i) / +- backlight_curve_coeff_a_factor + +- (coeffB * i) / +- backlight_curve_coeff_b_factor + +- coeffC; +- } +- } +- +- if (pExtCaps != NULL) +- dm_free(pExtCaps); +- +- /* Successfully initialized */ +- backlight_caps_valid = true; +- backlight_def_levels_valid = customDefLevelsPresent; +-} +- +-unsigned int mod_power_backlight_level_percentage_to_signal( +- struct mod_power *mod_power, unsigned int percentage) +-{ +- /* Do lazy initialization of backlight capabilities*/ +- if (!backlight_caps_initialized) +- mod_power_initialize_backlight_caps(mod_power); +- +- /* Since the translation table is indexed by percentage, +- * we simply return backlight value at given percent +- */ +- if (backlight_caps_valid && percentage <= 100) +- return backlight_8bit_lut_array[percentage]; +- +- return -1; +-} +- +-unsigned int mod_power_backlight_level_signal_to_percentage( +- struct mod_power *mod_power, +- unsigned int signalLevel8bit) +-{ +- unsigned int invalid_backlight = (unsigned int)(-1); +- /* Do lazy initialization of backlight capabilities */ +- if (!backlight_caps_initialized) +- mod_power_initialize_backlight_caps(mod_power); +- +- /* If customer curve cannot convert to differentiated value near min +- * it is important to report 0 for min signal to pass setting "Dimmed" +- * setting in HCK brightness2 tests. +- */ +- if (signalLevel8bit <= backlight_8bit_lut_array[0]) +- return 0; +- +- /* Since the translation table is indexed by percentage +- * we need to do a binary search over the array +- * Another option would be to guess entry based on linear distribution +- * and then do linear search in correct direction +- */ +- if (backlight_caps_valid && signalLevel8bit <= +- absolute_backlight_max) { +- unsigned int min = 0; +- unsigned int max = 100; +- unsigned int mid = invalid_backlight; +- +- while (max >= min) { +- mid = (min + max) / 2; /* floor of half range */ +- +- if (backlight_8bit_lut_array[mid] < signalLevel8bit) +- min = mid + 1; +- else if (backlight_8bit_lut_array[mid] > +- signalLevel8bit) +- max = mid - 1; +- else +- break; +- +- if (max == 0 || max == 1) +- return invalid_backlight; +- } +- return mid; +- } +- +- return invalid_backlight; +-} +- +- +-bool mod_power_get_panel_backlight_boundaries( +- struct mod_power *mod_power, +- unsigned int *min_backlight, +- unsigned int *max_backlight, +- unsigned int *output_ac_level_percentage, +- unsigned int *output_dc_level_percentage) +-{ +- /* Do lazy initialization of backlight capabilities */ +- if (!backlight_caps_initialized) +- mod_power_initialize_backlight_caps(mod_power); +- +- /* If cache was successfully updated, +- * copy the values to output structure and return success +- */ +- if (backlight_caps_valid) { +- *min_backlight = backlight_8bit_lut_array[0]; +- *max_backlight = backlight_8bit_lut_array[100]; +- +- *output_ac_level_percentage = ac_level_percentage; +- *output_dc_level_percentage = dc_level_percentage; +- +- return true; +- } +- +- return false; +-} +- +-bool mod_power_set_smooth_brightness(struct mod_power *mod_power, +- const struct dc_sink *sink, bool enable_brightness) +-{ +- if (sink->sink_signal == SIGNAL_TYPE_VIRTUAL) +- return false; +- +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- unsigned int sink_index = sink_index_from_sink(core_power, sink); +- +- core_power->state[sink_index].smooth_brightness_enabled +- = enable_brightness; +- return true; +-} +- +-bool mod_power_notify_mode_change(struct mod_power *mod_power, +- const struct dc_stream *stream) +-{ +- if (stream->sink->sink_signal == SIGNAL_TYPE_VIRTUAL) +- return false; +- +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- unsigned int sink_index = sink_index_from_sink(core_power, +- stream->sink); +- unsigned int frame_ramp = core_power->state[sink_index].frame_ramp; +- union dmcu_abm_set_bl_params params; +- +- params.u32All = 0; +- params.bits.gradual_change = (frame_ramp > 0); +- params.bits.frame_ramp = frame_ramp; +- +- core_power->dc->stream_funcs.set_backlight +- (core_power->dc, +- core_power->state[sink_index].backlight, +- params.u32All, stream); +- +- core_power->dc->stream_funcs.setup_psr +- (core_power->dc, stream); +- +- return true; +-} +- +- +-static bool mod_power_abm_feature_enable(struct mod_power +- *mod_power, bool enable) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- if (abm_user_enable == enable) +- return true; +- +- abm_user_enable = enable; +- +- if (enable) { +- if (abm_level != 0 && abm_active) +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, abm_level); +- } else { +- if (abm_level != 0 && abm_active) { +- abm_level = 0; +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, abm_level); +- } +- } +- +- return true; +-} +- +-static bool mod_power_abm_activate(struct mod_power +- *mod_power, bool activate) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- if (abm_active == activate) +- return true; +- +- abm_active = activate; +- +- if (activate) { +- if (abm_level != 0 && abm_user_enable) +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, abm_level); +- } else { +- if (abm_level != 0 && abm_user_enable) { +- abm_level = 0; +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, abm_level); +- } +- } +- +- return true; +-} +- +-static bool mod_power_abm_set_level(struct mod_power *mod_power, +- unsigned int level) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- if (abm_level == level) +- return true; +- +- if (abm_active && abm_user_enable && level == 0) +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, 0); +- else if (abm_active && abm_user_enable && level != 0) +- core_power->dc->stream_funcs.set_abm_level +- (core_power->dc, level); +- +- abm_level = level; +- +- return true; +-} +- +-bool mod_power_varibright_control(struct mod_power *mod_power, +- struct varibright_info *input_varibright_info) +-{ +- switch (input_varibright_info->cmd) { +- case VariBright_Cmd__SetVBLevel: +- { +- /* Set VariBright user level. */ +- mod_power_abm_set_level(mod_power, +- input_varibright_info->level); +- } +- break; +- +- case VariBright_Cmd__UserEnable: +- { +- /* Set VariBright user enable state. */ +- mod_power_abm_feature_enable(mod_power, +- input_varibright_info->enable); +- } +- break; +- +- case VariBright_Cmd__PostDisplayConfigChange: +- { +- /* Set VariBright user level. */ +- mod_power_abm_set_level(mod_power, +- input_varibright_info->level); +- +- /* Set VariBright user enable state. */ +- mod_power_abm_feature_enable(mod_power, +- input_varibright_info->enable); +- +- /* Set VariBright activate based on power state. */ +- mod_power_abm_activate(mod_power, +- input_varibright_info->activate); +- } +- break; +- +- default: +- { +- return false; +- } +- break; +- } +- +- return true; +-} +- +-bool mod_power_block_psr(bool block_enable, enum dmcu_block_psr_reason reason) +-{ +- if (block_enable) +- block_psr |= reason; +- else +- block_psr &= ~reason; +- +- return true; +-} +- +- +-bool mod_power_set_psr_enable(struct mod_power *mod_power, +- bool psr_enable) +-{ +- struct core_power *core_power = +- MOD_POWER_TO_CORE(mod_power); +- +- if (block_psr == 0) +- return core_power->dc->stream_funcs.set_psr_enable +- (core_power->dc, psr_enable); +- +- return false; +-} +- +- +-- +2.7.4 + |