1/* 2 * Copyright 2016 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 28#include "core_types.h" 29 30#include "reg_helper.h" 31#include "dcn20_dpp.h" 32#include "basics/conversion.h" 33 34#include "dcn10/dcn10_cm_common.h" 35 36#define REG(reg)\ 37 dpp->tf_regs->reg 38 39#define IND_REG(index) \ 40 (index) 41 42#define CTX \ 43 dpp->base.ctx 44 45#undef FN 46#define FN(reg_name, field_name) \ 47 dpp->tf_shift->field_name, dpp->tf_mask->field_name 48 49 50static void dpp2_enable_cm_block( 51 struct dpp *dpp_base) 52{ 53 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 54 55 unsigned int cm_bypass_mode = 0; 56 //Temp, put CM in bypass mode 57 if (dpp_base->ctx->dc->debug.cm_in_bypass) 58 cm_bypass_mode = 1; 59 60 REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode); 61} 62 63 64static bool dpp2_degamma_ram_inuse( 65 struct dpp *dpp_base, 66 bool *ram_a_inuse) 67{ 68 bool ret = false; 69 uint32_t status_reg = 0; 70 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 71 72 REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS, 73 &status_reg); 74 75 if (status_reg == 3) { 76 *ram_a_inuse = true; 77 ret = true; 78 } else if (status_reg == 4) { 79 *ram_a_inuse = false; 80 ret = true; 81 } 82 return ret; 83} 84 85static void dpp2_program_degamma_lut( 86 struct dpp *dpp_base, 87 const struct pwl_result_data *rgb, 88 uint32_t num, 89 bool is_ram_a) 90{ 91 uint32_t i; 92 93 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 94 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, 95 CM_DGAM_LUT_WRITE_EN_MASK, 7); 96 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL, 97 is_ram_a == true ? 0:1); 98 99 REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0); 100 for (i = 0 ; i < num; i++) { 101 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg); 102 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg); 103 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg); 104 105 REG_SET(CM_DGAM_LUT_DATA, 0, 106 CM_DGAM_LUT_DATA, rgb[i].delta_red_reg); 107 REG_SET(CM_DGAM_LUT_DATA, 0, 108 CM_DGAM_LUT_DATA, rgb[i].delta_green_reg); 109 REG_SET(CM_DGAM_LUT_DATA, 0, 110 CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg); 111 112 } 113 114} 115 116void dpp2_set_degamma_pwl( 117 struct dpp *dpp_base, 118 const struct pwl_params *params) 119{ 120 bool is_ram_a = true; 121 122 dpp1_power_on_degamma_lut(dpp_base, true); 123 dpp2_enable_cm_block(dpp_base); 124 dpp2_degamma_ram_inuse(dpp_base, &is_ram_a); 125 if (is_ram_a == true) 126 dpp1_program_degamma_lutb_settings(dpp_base, params); 127 else 128 dpp1_program_degamma_luta_settings(dpp_base, params); 129 130 dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a); 131 dpp1_degamma_ram_select(dpp_base, !is_ram_a); 132} 133 134void dpp2_set_degamma( 135 struct dpp *dpp_base, 136 enum ipp_degamma_mode mode) 137{ 138 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 139 dpp2_enable_cm_block(dpp_base); 140 141 switch (mode) { 142 case IPP_DEGAMMA_MODE_BYPASS: 143 /* Setting de gamma bypass for now */ 144 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0); 145 break; 146 case IPP_DEGAMMA_MODE_HW_sRGB: 147 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1); 148 break; 149 case IPP_DEGAMMA_MODE_HW_xvYCC: 150 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2); 151 break; 152 case IPP_DEGAMMA_MODE_USER_PWL: 153 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3); 154 break; 155 default: 156 BREAK_TO_DEBUGGER(); 157 break; 158 } 159} 160 161static void program_gamut_remap( 162 struct dcn20_dpp *dpp, 163 const uint16_t *regval, 164 enum dcn20_gamut_remap_select select) 165{ 166 uint32_t cur_select = 0; 167 struct color_matrices_reg gam_regs; 168 169 if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) { 170 REG_SET(CM_GAMUT_REMAP_CONTROL, 0, 171 CM_GAMUT_REMAP_MODE, 0); 172 return; 173 } 174 175 /* determine which gamut_remap coefficients (A or B) we are using 176 * currently. select the alternate set to double buffer 177 * the update so gamut_remap is updated on frame boundary 178 */ 179 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, 180 CM_TEST_DEBUG_DATA_STATUS_IDX, 181 CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select); 182 183 /* value stored in dbg reg will be 1 greater than mode we want */ 184 if (cur_select != DCN2_GAMUT_REMAP_COEF_A) 185 select = DCN2_GAMUT_REMAP_COEF_A; 186 else 187 select = DCN2_GAMUT_REMAP_COEF_B; 188 189 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; 190 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; 191 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; 192 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; 193 194 if (select == DCN2_GAMUT_REMAP_COEF_A) { 195 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12); 196 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 197 } else { 198 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12); 199 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34); 200 } 201 202 cm_helper_program_color_matrices( 203 dpp->base.ctx, 204 regval, 205 &gam_regs); 206 207 REG_SET( 208 CM_GAMUT_REMAP_CONTROL, 0, 209 CM_GAMUT_REMAP_MODE, select); 210 211} 212 213void dpp2_cm_set_gamut_remap( 214 struct dpp *dpp_base, 215 const struct dpp_grph_csc_adjustment *adjust) 216{ 217 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 218 int i = 0; 219 220 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 221 /* Bypass if type is bypass or hw */ 222 program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS); 223 else { 224 struct fixed31_32 arr_matrix[12]; 225 uint16_t arr_reg_val[12]; 226 227 for (i = 0; i < 12; i++) 228 arr_matrix[i] = adjust->temperature_matrix[i]; 229 230 convert_float_matrix( 231 arr_reg_val, arr_matrix, 12); 232 233 program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A); 234 } 235} 236 237static void read_gamut_remap(struct dcn20_dpp *dpp, 238 uint16_t *regval, 239 enum dcn20_gamut_remap_select *select) 240{ 241 struct color_matrices_reg gam_regs; 242 uint32_t selection; 243 244 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, 245 CM_TEST_DEBUG_DATA_STATUS_IDX, 246 CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &selection); 247 248 *select = selection; 249 250 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11; 251 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11; 252 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12; 253 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12; 254 255 if (*select == DCN2_GAMUT_REMAP_COEF_A) { 256 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12); 257 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34); 258 259 cm_helper_read_color_matrices(dpp->base.ctx, 260 regval, 261 &gam_regs); 262 263 } else if (*select == DCN2_GAMUT_REMAP_COEF_B) { 264 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12); 265 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34); 266 267 cm_helper_read_color_matrices(dpp->base.ctx, 268 regval, 269 &gam_regs); 270 } 271} 272 273void dpp2_cm_get_gamut_remap(struct dpp *dpp_base, 274 struct dpp_grph_csc_adjustment *adjust) 275{ 276 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 277 uint16_t arr_reg_val[12]; 278 enum dcn20_gamut_remap_select select; 279 280 read_gamut_remap(dpp, arr_reg_val, &select); 281 282 if (select == DCN2_GAMUT_REMAP_BYPASS) { 283 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 284 return; 285 } 286 287 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 288 convert_hw_matrix(adjust->temperature_matrix, 289 arr_reg_val, ARRAY_SIZE(arr_reg_val)); 290} 291 292void dpp2_program_input_csc( 293 struct dpp *dpp_base, 294 enum dc_color_space color_space, 295 enum dcn20_input_csc_select input_select, 296 const struct out_csc_color_matrix *tbl_entry) 297{ 298 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 299 int i; 300 int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix); 301 const uint16_t *regval = NULL; 302 uint32_t cur_select = 0; 303 enum dcn20_input_csc_select select; 304 struct color_matrices_reg icsc_regs; 305 306 if (input_select == DCN2_ICSC_SELECT_BYPASS) { 307 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0); 308 return; 309 } 310 311 if (tbl_entry == NULL) { 312 for (i = 0; i < arr_size; i++) 313 if (dpp_input_csc_matrix[i].color_space == color_space) { 314 regval = dpp_input_csc_matrix[i].regval; 315 break; 316 } 317 318 if (regval == NULL) { 319 BREAK_TO_DEBUGGER(); 320 return; 321 } 322 } else { 323 regval = tbl_entry->regval; 324 } 325 326 /* determine which CSC coefficients (A or B) we are using 327 * currently. select the alternate set to double buffer 328 * the CSC update so CSC is updated on frame boundary 329 */ 330 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, 331 CM_TEST_DEBUG_DATA_STATUS_IDX, 332 CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select); 333 334 if (cur_select != DCN2_ICSC_SELECT_ICSC_A) 335 select = DCN2_ICSC_SELECT_ICSC_A; 336 else 337 select = DCN2_ICSC_SELECT_ICSC_B; 338 339 icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11; 340 icsc_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11; 341 icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12; 342 icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12; 343 344 if (select == DCN2_ICSC_SELECT_ICSC_A) { 345 346 icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12); 347 icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34); 348 349 } else { 350 351 icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12); 352 icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34); 353 354 } 355 356 cm_helper_program_color_matrices( 357 dpp->base.ctx, 358 regval, 359 &icsc_regs); 360 361 REG_SET(CM_ICSC_CONTROL, 0, 362 CM_ICSC_MODE, select); 363} 364 365static void dpp20_power_on_blnd_lut( 366 struct dpp *dpp_base, 367 bool power_on) 368{ 369 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 370 371 REG_SET(CM_MEM_PWR_CTRL, 0, 372 BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 373 374} 375 376static void dpp20_configure_blnd_lut( 377 struct dpp *dpp_base, 378 bool is_ram_a) 379{ 380 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 381 382 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK, 383 CM_BLNDGAM_LUT_WRITE_EN_MASK, 7); 384 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK, 385 CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 386 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 387} 388 389static void dpp20_program_blnd_pwl( 390 struct dpp *dpp_base, 391 const struct pwl_result_data *rgb, 392 uint32_t num) 393{ 394 uint32_t i; 395 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 396 397 for (i = 0 ; i < num; i++) { 398 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg); 399 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg); 400 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg); 401 402 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 403 CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg); 404 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 405 CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg); 406 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 407 CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg); 408 409 } 410 411} 412 413static void dcn20_dpp_cm_get_reg_field( 414 struct dcn20_dpp *dpp, 415 struct xfer_func_reg *reg) 416{ 417 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 418 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 419 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 420 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 421 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 422 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 423 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 424 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 425 426 reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 427 reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 428 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 429 reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 430 reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 431 reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 432 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; 433 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; 434 reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 435 reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 436 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 437 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 438} 439 440/*program blnd lut RAM A*/ 441static void dpp20_program_blnd_luta_settings( 442 struct dpp *dpp_base, 443 const struct pwl_params *params) 444{ 445 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 446 struct xfer_func_reg gam_regs; 447 448 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs); 449 450 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B); 451 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G); 452 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R); 453 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B); 454 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G); 455 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R); 456 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B); 457 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B); 458 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G); 459 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G); 460 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R); 461 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R); 462 gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1); 463 gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33); 464 465 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); 466} 467 468/*program blnd lut RAM B*/ 469static void dpp20_program_blnd_lutb_settings( 470 struct dpp *dpp_base, 471 const struct pwl_params *params) 472{ 473 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 474 struct xfer_func_reg gam_regs; 475 476 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs); 477 478 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B); 479 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G); 480 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R); 481 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B); 482 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G); 483 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R); 484 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B); 485 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B); 486 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G); 487 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G); 488 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R); 489 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R); 490 gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1); 491 gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33); 492 493 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); 494} 495 496static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base) 497{ 498 enum dc_lut_mode mode; 499 uint32_t state_mode; 500 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 501 502 REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK, CM_BLNDGAM_CONFIG_STATUS, &state_mode); 503 504 switch (state_mode) { 505 case 0: 506 mode = LUT_BYPASS; 507 break; 508 case 1: 509 mode = LUT_RAM_A; 510 break; 511 case 2: 512 mode = LUT_RAM_B; 513 break; 514 default: 515 mode = LUT_BYPASS; 516 break; 517 } 518 519 return mode; 520} 521 522bool dpp20_program_blnd_lut( 523 struct dpp *dpp_base, const struct pwl_params *params) 524{ 525 enum dc_lut_mode current_mode; 526 enum dc_lut_mode next_mode; 527 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 528 529 if (params == NULL) { 530 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0); 531 return false; 532 } 533 current_mode = dpp20_get_blndgam_current(dpp_base); 534 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 535 next_mode = LUT_RAM_B; 536 else 537 next_mode = LUT_RAM_A; 538 539 dpp20_power_on_blnd_lut(dpp_base, true); 540 dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A); 541 542 if (next_mode == LUT_RAM_A) 543 dpp20_program_blnd_luta_settings(dpp_base, params); 544 else 545 dpp20_program_blnd_lutb_settings(dpp_base, params); 546 547 dpp20_program_blnd_pwl( 548 dpp_base, params->rgb_resulted, params->hw_points_num); 549 550 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 551 next_mode == LUT_RAM_A ? 1:2); 552 553 return true; 554} 555 556 557static void dpp20_program_shaper_lut( 558 struct dpp *dpp_base, 559 const struct pwl_result_data *rgb, 560 uint32_t num) 561{ 562 uint32_t i, red, green, blue; 563 uint32_t red_delta, green_delta, blue_delta; 564 uint32_t red_value, green_value, blue_value; 565 566 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 567 568 for (i = 0 ; i < num; i++) { 569 570 red = rgb[i].red_reg; 571 green = rgb[i].green_reg; 572 blue = rgb[i].blue_reg; 573 574 red_delta = rgb[i].delta_red_reg; 575 green_delta = rgb[i].delta_green_reg; 576 blue_delta = rgb[i].delta_blue_reg; 577 578 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff); 579 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff); 580 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff); 581 582 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value); 583 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value); 584 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value); 585 } 586 587} 588 589static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base) 590{ 591 enum dc_lut_mode mode; 592 uint32_t state_mode; 593 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 594 595 REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK, CM_SHAPER_CONFIG_STATUS, &state_mode); 596 597 switch (state_mode) { 598 case 0: 599 mode = LUT_BYPASS; 600 break; 601 case 1: 602 mode = LUT_RAM_A; 603 break; 604 case 2: 605 mode = LUT_RAM_B; 606 break; 607 default: 608 mode = LUT_BYPASS; 609 break; 610 } 611 612 return mode; 613} 614 615static void dpp20_configure_shaper_lut( 616 struct dpp *dpp_base, 617 bool is_ram_a) 618{ 619 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 620 621 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 622 CM_SHAPER_LUT_WRITE_EN_MASK, 7); 623 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 624 CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 625 REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0); 626} 627 628/*program shaper RAM A*/ 629 630static void dpp20_program_shaper_luta_settings( 631 struct dpp *dpp_base, 632 const struct pwl_params *params) 633{ 634 const struct gamma_curve *curve; 635 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 636 637 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0, 638 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 639 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 640 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0, 641 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 642 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0); 643 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0, 644 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 645 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0); 646 647 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0, 648 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 649 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 650 651 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0, 652 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 653 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 654 655 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0, 656 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 657 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 658 659 curve = params->arr_curve_points; 660 REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0, 661 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 662 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 663 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 664 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 665 666 curve += 2; 667 REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0, 668 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 669 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 670 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 671 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 672 673 curve += 2; 674 REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0, 675 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 676 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 677 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 678 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 679 680 curve += 2; 681 REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0, 682 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 683 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 684 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 685 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 686 687 curve += 2; 688 REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0, 689 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 690 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 691 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 692 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 693 694 curve += 2; 695 REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0, 696 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 697 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 698 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 699 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 700 701 curve += 2; 702 REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0, 703 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 704 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 705 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 706 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 707 708 curve += 2; 709 REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0, 710 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 711 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 712 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 713 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 714 715 curve += 2; 716 REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0, 717 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset, 718 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 719 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset, 720 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 721 722 curve += 2; 723 REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0, 724 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset, 725 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 726 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset, 727 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 728 729 curve += 2; 730 REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0, 731 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset, 732 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 733 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset, 734 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 735 736 curve += 2; 737 REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0, 738 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset, 739 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 740 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset, 741 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 742 743 curve += 2; 744 REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0, 745 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset, 746 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 747 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset, 748 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 749 750 curve += 2; 751 REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0, 752 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset, 753 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 754 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset, 755 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 756 757 curve += 2; 758 REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0, 759 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset, 760 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 761 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset, 762 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 763 764 curve += 2; 765 REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0, 766 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset, 767 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 768 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset, 769 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 770 771 curve += 2; 772 REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0, 773 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset, 774 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 775 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset, 776 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 777} 778 779/*program shaper RAM B*/ 780static void dpp20_program_shaper_lutb_settings( 781 struct dpp *dpp_base, 782 const struct pwl_params *params) 783{ 784 const struct gamma_curve *curve; 785 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 786 787 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0, 788 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 789 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0); 790 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0, 791 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 792 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0); 793 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0, 794 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 795 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0); 796 797 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0, 798 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 799 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 800 801 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0, 802 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 803 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 804 805 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0, 806 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 807 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 808 809 curve = params->arr_curve_points; 810 REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0, 811 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 812 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 813 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 814 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 815 816 curve += 2; 817 REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0, 818 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 819 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 820 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 821 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 822 823 curve += 2; 824 REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0, 825 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 826 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 827 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 828 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 829 830 curve += 2; 831 REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0, 832 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 833 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 834 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 835 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 836 837 curve += 2; 838 REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0, 839 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 840 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 841 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 842 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 843 844 curve += 2; 845 REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0, 846 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 847 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 848 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 849 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 850 851 curve += 2; 852 REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0, 853 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 854 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 855 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 856 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 857 858 curve += 2; 859 REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0, 860 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 861 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 862 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 863 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 864 865 curve += 2; 866 REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0, 867 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset, 868 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 869 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset, 870 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 871 872 curve += 2; 873 REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0, 874 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset, 875 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 876 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset, 877 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 878 879 curve += 2; 880 REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0, 881 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset, 882 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 883 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset, 884 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 885 886 curve += 2; 887 REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0, 888 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset, 889 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 890 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset, 891 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 892 893 curve += 2; 894 REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0, 895 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset, 896 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 897 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset, 898 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 899 900 curve += 2; 901 REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0, 902 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset, 903 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 904 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset, 905 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 906 907 curve += 2; 908 REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0, 909 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset, 910 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 911 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset, 912 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 913 914 curve += 2; 915 REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0, 916 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset, 917 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 918 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset, 919 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 920 921 curve += 2; 922 REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0, 923 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset, 924 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 925 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset, 926 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 927 928} 929 930 931bool dpp20_program_shaper( 932 struct dpp *dpp_base, 933 const struct pwl_params *params) 934{ 935 enum dc_lut_mode current_mode; 936 enum dc_lut_mode next_mode; 937 938 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 939 940 if (params == NULL) { 941 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0); 942 return false; 943 } 944 current_mode = dpp20_get_shaper_current(dpp_base); 945 946 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 947 next_mode = LUT_RAM_B; 948 else 949 next_mode = LUT_RAM_A; 950 951 dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A); 952 953 if (next_mode == LUT_RAM_A) 954 dpp20_program_shaper_luta_settings(dpp_base, params); 955 else 956 dpp20_program_shaper_lutb_settings(dpp_base, params); 957 958 dpp20_program_shaper_lut( 959 dpp_base, params->rgb_resulted, params->hw_points_num); 960 961 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2); 962 963 return true; 964 965} 966 967static enum dc_lut_mode get3dlut_config( 968 struct dpp *dpp_base, 969 bool *is_17x17x17, 970 bool *is_12bits_color_channel) 971{ 972 uint32_t i_mode, i_enable_10bits, lut_size; 973 enum dc_lut_mode mode; 974 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 975 976 REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL, 977 CM_3DLUT_CONFIG_STATUS, &i_mode, 978 CM_3DLUT_30BIT_EN, &i_enable_10bits); 979 980 switch (i_mode) { 981 case 0: 982 mode = LUT_BYPASS; 983 break; 984 case 1: 985 mode = LUT_RAM_A; 986 break; 987 case 2: 988 mode = LUT_RAM_B; 989 break; 990 default: 991 mode = LUT_BYPASS; 992 break; 993 } 994 if (i_enable_10bits > 0) 995 *is_12bits_color_channel = false; 996 else 997 *is_12bits_color_channel = true; 998 999 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size); 1000 1001 if (lut_size == 0) 1002 *is_17x17x17 = true; 1003 else 1004 *is_17x17x17 = false; 1005 1006 return mode; 1007} 1008/* 1009 * select ramA or ramB, or bypass 1010 * select color channel size 10 or 12 bits 1011 * select 3dlut size 17x17x17 or 9x9x9 1012 */ 1013static void dpp20_set_3dlut_mode( 1014 struct dpp *dpp_base, 1015 enum dc_lut_mode mode, 1016 bool is_color_channel_12bits, 1017 bool is_lut_size17x17x17) 1018{ 1019 uint32_t lut_mode; 1020 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1021 1022 if (mode == LUT_BYPASS) 1023 lut_mode = 0; 1024 else if (mode == LUT_RAM_A) 1025 lut_mode = 1; 1026 else 1027 lut_mode = 2; 1028 1029 REG_UPDATE_2(CM_3DLUT_MODE, 1030 CM_3DLUT_MODE, lut_mode, 1031 CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1); 1032} 1033 1034static void dpp20_select_3dlut_ram( 1035 struct dpp *dpp_base, 1036 enum dc_lut_mode mode, 1037 bool is_color_channel_12bits) 1038{ 1039 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1040 1041 REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL, 1042 CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, 1043 CM_3DLUT_30BIT_EN, 1044 is_color_channel_12bits == true ? 0:1); 1045} 1046 1047 1048 1049static void dpp20_set3dlut_ram12( 1050 struct dpp *dpp_base, 1051 const struct dc_rgb *lut, 1052 uint32_t entries) 1053{ 1054 uint32_t i, red, green, blue, red1, green1, blue1; 1055 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1056 1057 for (i = 0 ; i < entries; i += 2) { 1058 red = lut[i].red<<4; 1059 green = lut[i].green<<4; 1060 blue = lut[i].blue<<4; 1061 red1 = lut[i+1].red<<4; 1062 green1 = lut[i+1].green<<4; 1063 blue1 = lut[i+1].blue<<4; 1064 1065 REG_SET_2(CM_3DLUT_DATA, 0, 1066 CM_3DLUT_DATA0, red, 1067 CM_3DLUT_DATA1, red1); 1068 1069 REG_SET_2(CM_3DLUT_DATA, 0, 1070 CM_3DLUT_DATA0, green, 1071 CM_3DLUT_DATA1, green1); 1072 1073 REG_SET_2(CM_3DLUT_DATA, 0, 1074 CM_3DLUT_DATA0, blue, 1075 CM_3DLUT_DATA1, blue1); 1076 1077 } 1078} 1079 1080/* 1081 * load selected lut with 10 bits color channels 1082 */ 1083static void dpp20_set3dlut_ram10( 1084 struct dpp *dpp_base, 1085 const struct dc_rgb *lut, 1086 uint32_t entries) 1087{ 1088 uint32_t i, red, green, blue, value; 1089 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1090 1091 for (i = 0; i < entries; i++) { 1092 red = lut[i].red; 1093 green = lut[i].green; 1094 blue = lut[i].blue; 1095 1096 value = (red<<20) | (green<<10) | blue; 1097 1098 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value); 1099 } 1100 1101} 1102 1103 1104static void dpp20_select_3dlut_ram_mask( 1105 struct dpp *dpp_base, 1106 uint32_t ram_selection_mask) 1107{ 1108 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1109 1110 REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK, 1111 ram_selection_mask); 1112 REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0); 1113} 1114 1115bool dpp20_program_3dlut( 1116 struct dpp *dpp_base, 1117 struct tetrahedral_params *params) 1118{ 1119 enum dc_lut_mode mode; 1120 bool is_17x17x17; 1121 bool is_12bits_color_channel; 1122 struct dc_rgb *lut0; 1123 struct dc_rgb *lut1; 1124 struct dc_rgb *lut2; 1125 struct dc_rgb *lut3; 1126 int lut_size0; 1127 int lut_size; 1128 1129 if (params == NULL) { 1130 dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false); 1131 return false; 1132 } 1133 mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel); 1134 1135 if (mode == LUT_BYPASS || mode == LUT_RAM_B) 1136 mode = LUT_RAM_A; 1137 else 1138 mode = LUT_RAM_B; 1139 1140 is_17x17x17 = !params->use_tetrahedral_9; 1141 is_12bits_color_channel = params->use_12bits; 1142 if (is_17x17x17) { 1143 lut0 = params->tetrahedral_17.lut0; 1144 lut1 = params->tetrahedral_17.lut1; 1145 lut2 = params->tetrahedral_17.lut2; 1146 lut3 = params->tetrahedral_17.lut3; 1147 lut_size0 = sizeof(params->tetrahedral_17.lut0)/ 1148 sizeof(params->tetrahedral_17.lut0[0]); 1149 lut_size = sizeof(params->tetrahedral_17.lut1)/ 1150 sizeof(params->tetrahedral_17.lut1[0]); 1151 } else { 1152 lut0 = params->tetrahedral_9.lut0; 1153 lut1 = params->tetrahedral_9.lut1; 1154 lut2 = params->tetrahedral_9.lut2; 1155 lut3 = params->tetrahedral_9.lut3; 1156 lut_size0 = sizeof(params->tetrahedral_9.lut0)/ 1157 sizeof(params->tetrahedral_9.lut0[0]); 1158 lut_size = sizeof(params->tetrahedral_9.lut1)/ 1159 sizeof(params->tetrahedral_9.lut1[0]); 1160 } 1161 1162 dpp20_select_3dlut_ram(dpp_base, mode, 1163 is_12bits_color_channel); 1164 dpp20_select_3dlut_ram_mask(dpp_base, 0x1); 1165 if (is_12bits_color_channel) 1166 dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0); 1167 else 1168 dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0); 1169 1170 dpp20_select_3dlut_ram_mask(dpp_base, 0x2); 1171 if (is_12bits_color_channel) 1172 dpp20_set3dlut_ram12(dpp_base, lut1, lut_size); 1173 else 1174 dpp20_set3dlut_ram10(dpp_base, lut1, lut_size); 1175 1176 dpp20_select_3dlut_ram_mask(dpp_base, 0x4); 1177 if (is_12bits_color_channel) 1178 dpp20_set3dlut_ram12(dpp_base, lut2, lut_size); 1179 else 1180 dpp20_set3dlut_ram10(dpp_base, lut2, lut_size); 1181 1182 dpp20_select_3dlut_ram_mask(dpp_base, 0x8); 1183 if (is_12bits_color_channel) 1184 dpp20_set3dlut_ram12(dpp_base, lut3, lut_size); 1185 else 1186 dpp20_set3dlut_ram10(dpp_base, lut3, lut_size); 1187 1188 1189 dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel, 1190 is_17x17x17); 1191 1192 return true; 1193} 1194 1195void dpp2_set_hdr_multiplier( 1196 struct dpp *dpp_base, 1197 uint32_t multiplier) 1198{ 1199 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1200 1201 REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier); 1202} 1203