1/* 2 * Copyright 2020 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26#include "dm_services.h" 27#include "core_types.h" 28#include "reg_helper.h" 29#include "dcn30/dcn30_dpp.h" 30#include "basics/conversion.h" 31#include "dcn30/dcn30_cm_common.h" 32 33#define REG(reg)\ 34 dpp->tf_regs->reg 35 36#define CTX \ 37 dpp->base.ctx 38 39#undef FN 40#define FN(reg_name, field_name) \ 41 dpp->tf_shift->field_name, dpp->tf_mask->field_name 42 43static void dpp3_enable_cm_block( 44 struct dpp *dpp_base) 45{ 46 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 47 48 unsigned int cm_bypass_mode = 0; 49 50 // debug option: put CM in bypass mode 51 if (dpp_base->ctx->dc->debug.cm_in_bypass) 52 cm_bypass_mode = 1; 53 54 REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode); 55} 56 57static enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) 58{ 59 enum dc_lut_mode mode = LUT_BYPASS; 60 uint32_t state_mode; 61 uint32_t lut_mode; 62 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 63 64 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &state_mode); 65 66 if (state_mode == 2) {//Programmable RAM LUT 67 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, &lut_mode); 68 if (lut_mode == 0) 69 mode = LUT_RAM_A; 70 else 71 mode = LUT_RAM_B; 72 } 73 74 return mode; 75} 76 77static void dpp3_program_gammcor_lut( 78 struct dpp *dpp_base, 79 const struct pwl_result_data *rgb, 80 uint32_t num, 81 bool is_ram_a) 82{ 83 uint32_t i; 84 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 85 uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; 86 uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; 87 uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; 88 89 /*fill in the LUT with all base values to be used by pwl module 90 * HW auto increments the LUT index: back-to-back write 91 */ 92 if (is_rgb_equal(rgb, num)) { 93 for (i = 0 ; i < num; i++) 94 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].red_reg); 95 96 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_red); 97 98 } else { 99 REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 100 CM_GAMCOR_LUT_WRITE_COLOR_MASK, 4); 101 for (i = 0 ; i < num; i++) 102 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].red_reg); 103 104 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_red); 105 106 REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 107 108 REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 109 CM_GAMCOR_LUT_WRITE_COLOR_MASK, 2); 110 for (i = 0 ; i < num; i++) 111 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].green_reg); 112 113 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_green); 114 115 REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 116 117 REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 118 CM_GAMCOR_LUT_WRITE_COLOR_MASK, 1); 119 for (i = 0 ; i < num; i++) 120 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, rgb[i].blue_reg); 121 122 REG_SET(CM_GAMCOR_LUT_DATA, 0, CM_GAMCOR_LUT_DATA, last_base_value_blue); 123 } 124} 125 126static void dpp3_power_on_gamcor_lut( 127 struct dpp *dpp_base, 128 bool power_on) 129{ 130 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 131 132 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 133 if (power_on) { 134 REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0); 135 REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); 136 } else { 137 dpp_base->ctx->dc->optimized_required = true; 138 dpp_base->deferred_reg_writes.bits.disable_gamcor = true; 139 } 140 } else 141 REG_SET(CM_MEM_PWR_CTRL, 0, 142 GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); 143} 144 145void dpp3_program_cm_dealpha( 146 struct dpp *dpp_base, 147 uint32_t enable, uint32_t additive_blending) 148{ 149 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 150 151 REG_SET_2(CM_DEALPHA, 0, 152 CM_DEALPHA_EN, enable, 153 CM_DEALPHA_ABLND, additive_blending); 154} 155 156void dpp3_program_cm_bias( 157 struct dpp *dpp_base, 158 struct CM_bias_params *bias_params) 159{ 160 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 161 162 REG_SET(CM_BIAS_CR_R, 0, CM_BIAS_CR_R, bias_params->cm_bias_cr_r); 163 REG_SET_2(CM_BIAS_Y_G_CB_B, 0, 164 CM_BIAS_Y_G, bias_params->cm_bias_y_g, 165 CM_BIAS_CB_B, bias_params->cm_bias_cb_b); 166} 167 168static void dpp3_gamcor_reg_field( 169 struct dcn3_dpp *dpp, 170 struct dcn3_xfer_func_reg *reg) 171{ 172 173 reg->shifts.field_region_start_base = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_BASE_B; 174 reg->masks.field_region_start_base = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_BASE_B; 175 reg->shifts.field_offset = dpp->tf_shift->CM_GAMCOR_RAMA_OFFSET_B; 176 reg->masks.field_offset = dpp->tf_mask->CM_GAMCOR_RAMA_OFFSET_B; 177 178 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET; 179 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION0_LUT_OFFSET; 180 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS; 181 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION0_NUM_SEGMENTS; 182 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET; 183 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION1_LUT_OFFSET; 184 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS; 185 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION1_NUM_SEGMENTS; 186 187 reg->shifts.field_region_end = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_B; 188 reg->masks.field_region_end = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_B; 189 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B; 190 reg->masks.field_region_end_slope = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_SLOPE_B; 191 reg->shifts.field_region_end_base = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_END_BASE_B; 192 reg->masks.field_region_end_base = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_END_BASE_B; 193 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B; 194 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_SLOPE_B; 195 reg->shifts.exp_region_start = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_B; 196 reg->masks.exp_region_start = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_B; 197 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; 198 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_GAMCOR_RAMA_EXP_REGION_START_SEGMENT_B; 199} 200 201static void dpp3_configure_gamcor_lut( 202 struct dpp *dpp_base, 203 bool is_ram_a) 204{ 205 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 206 207 REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 208 CM_GAMCOR_LUT_WRITE_COLOR_MASK, 7); 209 REG_UPDATE(CM_GAMCOR_LUT_CONTROL, 210 CM_GAMCOR_LUT_HOST_SEL, is_ram_a == true ? 0:1); 211 REG_SET(CM_GAMCOR_LUT_INDEX, 0, CM_GAMCOR_LUT_INDEX, 0); 212} 213 214 215bool dpp3_program_gamcor_lut( 216 struct dpp *dpp_base, const struct pwl_params *params) 217{ 218 enum dc_lut_mode current_mode; 219 enum dc_lut_mode next_mode; 220 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 221 struct dcn3_xfer_func_reg gam_regs; 222 223 dpp3_enable_cm_block(dpp_base); 224 225 if (params == NULL) { //bypass if we have no pwl data 226 REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 0); 227 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) 228 dpp3_power_on_gamcor_lut(dpp_base, false); 229 return false; 230 } 231 dpp3_power_on_gamcor_lut(dpp_base, true); 232 REG_SET(CM_GAMCOR_CONTROL, 0, CM_GAMCOR_MODE, 2); 233 234 current_mode = dpp30_get_gamcor_current(dpp_base); 235 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 236 next_mode = LUT_RAM_B; 237 else 238 next_mode = LUT_RAM_A; 239 240 dpp3_power_on_gamcor_lut(dpp_base, true); 241 dpp3_configure_gamcor_lut(dpp_base, next_mode == LUT_RAM_A); 242 243 if (next_mode == LUT_RAM_B) { 244 gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMB_START_CNTL_B); 245 gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMB_START_CNTL_G); 246 gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMB_START_CNTL_R); 247 gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_B); 248 gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_G); 249 gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMB_START_SLOPE_CNTL_R); 250 gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMB_END_CNTL1_B); 251 gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMB_END_CNTL2_B); 252 gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMB_END_CNTL1_G); 253 gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMB_END_CNTL2_G); 254 gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMB_END_CNTL1_R); 255 gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMB_END_CNTL2_R); 256 gam_regs.region_start = REG(CM_GAMCOR_RAMB_REGION_0_1); 257 gam_regs.region_end = REG(CM_GAMCOR_RAMB_REGION_32_33); 258 //New registers in DCN3AG/DCN GAMCOR block 259 gam_regs.offset_b = REG(CM_GAMCOR_RAMB_OFFSET_B); 260 gam_regs.offset_g = REG(CM_GAMCOR_RAMB_OFFSET_G); 261 gam_regs.offset_r = REG(CM_GAMCOR_RAMB_OFFSET_R); 262 gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_B); 263 gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_G); 264 gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMB_START_BASE_CNTL_R); 265 } else { 266 gam_regs.start_cntl_b = REG(CM_GAMCOR_RAMA_START_CNTL_B); 267 gam_regs.start_cntl_g = REG(CM_GAMCOR_RAMA_START_CNTL_G); 268 gam_regs.start_cntl_r = REG(CM_GAMCOR_RAMA_START_CNTL_R); 269 gam_regs.start_slope_cntl_b = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_B); 270 gam_regs.start_slope_cntl_g = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_G); 271 gam_regs.start_slope_cntl_r = REG(CM_GAMCOR_RAMA_START_SLOPE_CNTL_R); 272 gam_regs.start_end_cntl1_b = REG(CM_GAMCOR_RAMA_END_CNTL1_B); 273 gam_regs.start_end_cntl2_b = REG(CM_GAMCOR_RAMA_END_CNTL2_B); 274 gam_regs.start_end_cntl1_g = REG(CM_GAMCOR_RAMA_END_CNTL1_G); 275 gam_regs.start_end_cntl2_g = REG(CM_GAMCOR_RAMA_END_CNTL2_G); 276 gam_regs.start_end_cntl1_r = REG(CM_GAMCOR_RAMA_END_CNTL1_R); 277 gam_regs.start_end_cntl2_r = REG(CM_GAMCOR_RAMA_END_CNTL2_R); 278 gam_regs.region_start = REG(CM_GAMCOR_RAMA_REGION_0_1); 279 gam_regs.region_end = REG(CM_GAMCOR_RAMA_REGION_32_33); 280 //New registers in DCN3AG/DCN GAMCOR block 281 gam_regs.offset_b = REG(CM_GAMCOR_RAMA_OFFSET_B); 282 gam_regs.offset_g = REG(CM_GAMCOR_RAMA_OFFSET_G); 283 gam_regs.offset_r = REG(CM_GAMCOR_RAMA_OFFSET_R); 284 gam_regs.start_base_cntl_b = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_B); 285 gam_regs.start_base_cntl_g = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_G); 286 gam_regs.start_base_cntl_r = REG(CM_GAMCOR_RAMA_START_BASE_CNTL_R); 287 } 288 289 //get register fields 290 dpp3_gamcor_reg_field(dpp, &gam_regs); 291 292 //program register set for LUTA/LUTB 293 cm_helper_program_gamcor_xfer_func(dpp_base->ctx, params, &gam_regs); 294 295 dpp3_program_gammcor_lut(dpp_base, params->rgb_resulted, params->hw_points_num, 296 next_mode == LUT_RAM_A); 297 298 //select Gamma LUT to use for next frame 299 REG_UPDATE(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT, next_mode == LUT_RAM_A ? 0:1); 300 301 return true; 302} 303 304void dpp3_set_hdr_multiplier( 305 struct dpp *dpp_base, 306 uint32_t multiplier) 307{ 308 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 309 310 REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier); 311} 312 313 314static void program_gamut_remap( 315 struct dcn3_dpp *dpp, 316 const uint16_t *regval, 317 int select) 318{ 319 uint16_t selection = 0; 320 struct color_matrices_reg gam_regs; 321 322 if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 323 REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 324 CM_GAMUT_REMAP_MODE, 0); 325 return; 326 } 327 switch (select) { 328 case GAMUT_REMAP_COEFF: 329 selection = 1; 330 break; 331 /*this corresponds to GAMUT_REMAP coefficients set B 332 *we don't have common coefficient sets in dcn3ag/dcn3 333 */ 334 case GAMUT_REMAP_COMA_COEFF: 335 selection = 2; 336 break; 337 default: 338 break; 339 } 340 341 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; 342 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; 343 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; 344 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; 345 346 347 if (select == GAMUT_REMAP_COEFF) { 348 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12); 349 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 350 351 cm_helper_program_color_matrices( 352 dpp->base.ctx, 353 regval, 354 &gam_regs); 355 356 } else if (select == GAMUT_REMAP_COMA_COEFF) { 357 358 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12); 359 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34); 360 361 cm_helper_program_color_matrices( 362 dpp->base.ctx, 363 regval, 364 &gam_regs); 365 366 } 367 //select coefficient set to use 368 REG_SET( 369 CM_GAMUT_REMAP_CONTROL, 0, 370 CM_GAMUT_REMAP_MODE, selection); 371} 372 373void dpp3_cm_set_gamut_remap( 374 struct dpp *dpp_base, 375 const struct dpp_grph_csc_adjustment *adjust) 376{ 377 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 378 int i = 0; 379 int gamut_mode; 380 381 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 382 /* Bypass if type is bypass or hw */ 383 program_gamut_remap(dpp, NULL, GAMUT_REMAP_BYPASS); 384 else { 385 struct fixed31_32 arr_matrix[12]; 386 uint16_t arr_reg_val[12]; 387 388 for (i = 0; i < 12; i++) 389 arr_matrix[i] = adjust->temperature_matrix[i]; 390 391 convert_float_matrix( 392 arr_reg_val, arr_matrix, 12); 393 394 //current coefficient set in use 395 REG_GET(CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE_CURRENT, &gamut_mode); 396 397 if (gamut_mode == 0) 398 gamut_mode = 1; //use coefficient set A 399 else if (gamut_mode == 1) 400 gamut_mode = 2; 401 else 402 gamut_mode = 1; 403 404 //follow dcn2 approach for now - using only coefficient set A 405 program_gamut_remap(dpp, arr_reg_val, gamut_mode); 406 } 407} 408 409static void read_gamut_remap(struct dcn3_dpp *dpp, 410 uint16_t *regval, 411 int *select) 412{ 413 struct color_matrices_reg gam_regs; 414 uint32_t selection; 415 416 //current coefficient set in use 417 REG_GET(CM_GAMUT_REMAP_CONTROL, CM_GAMUT_REMAP_MODE_CURRENT, &selection); 418 419 *select = selection; 420 421 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; 422 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; 423 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; 424 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; 425 426 if (*select == GAMUT_REMAP_COEFF) { 427 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12); 428 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 429 430 cm_helper_read_color_matrices(dpp->base.ctx, 431 regval, 432 &gam_regs); 433 434 } else if (*select == GAMUT_REMAP_COMA_COEFF) { 435 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12); 436 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34); 437 438 cm_helper_read_color_matrices(dpp->base.ctx, 439 regval, 440 &gam_regs); 441 } 442} 443 444void dpp3_cm_get_gamut_remap(struct dpp *dpp_base, 445 struct dpp_grph_csc_adjustment *adjust) 446{ 447 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 448 uint16_t arr_reg_val[12] = {0}; 449 int select; 450 451 read_gamut_remap(dpp, arr_reg_val, &select); 452 453 if (select == GAMUT_REMAP_BYPASS) { 454 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 455 return; 456 } 457 458 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 459 convert_hw_matrix(adjust->temperature_matrix, 460 arr_reg_val, ARRAY_SIZE(arr_reg_val)); 461} 462