dcn20_dpp_cm.c (36787B)
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 237void dpp2_program_input_csc( 238 struct dpp *dpp_base, 239 enum dc_color_space color_space, 240 enum dcn20_input_csc_select input_select, 241 const struct out_csc_color_matrix *tbl_entry) 242{ 243 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 244 int i; 245 int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix); 246 const uint16_t *regval = NULL; 247 uint32_t cur_select = 0; 248 enum dcn20_input_csc_select select; 249 struct color_matrices_reg icsc_regs; 250 251 if (input_select == DCN2_ICSC_SELECT_BYPASS) { 252 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0); 253 return; 254 } 255 256 if (tbl_entry == NULL) { 257 for (i = 0; i < arr_size; i++) 258 if (dpp_input_csc_matrix[i].color_space == color_space) { 259 regval = dpp_input_csc_matrix[i].regval; 260 break; 261 } 262 263 if (regval == NULL) { 264 BREAK_TO_DEBUGGER(); 265 return; 266 } 267 } else { 268 regval = tbl_entry->regval; 269 } 270 271 /* determine which CSC coefficients (A or B) we are using 272 * currently. select the alternate set to double buffer 273 * the CSC update so CSC is updated on frame boundary 274 */ 275 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA, 276 CM_TEST_DEBUG_DATA_STATUS_IDX, 277 CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select); 278 279 if (cur_select != DCN2_ICSC_SELECT_ICSC_A) 280 select = DCN2_ICSC_SELECT_ICSC_A; 281 else 282 select = DCN2_ICSC_SELECT_ICSC_B; 283 284 icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11; 285 icsc_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11; 286 icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12; 287 icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12; 288 289 if (select == DCN2_ICSC_SELECT_ICSC_A) { 290 291 icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12); 292 icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34); 293 294 } else { 295 296 icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12); 297 icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34); 298 299 } 300 301 cm_helper_program_color_matrices( 302 dpp->base.ctx, 303 regval, 304 &icsc_regs); 305 306 REG_SET(CM_ICSC_CONTROL, 0, 307 CM_ICSC_MODE, select); 308} 309 310static void dpp20_power_on_blnd_lut( 311 struct dpp *dpp_base, 312 bool power_on) 313{ 314 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 315 316 REG_SET(CM_MEM_PWR_CTRL, 0, 317 BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 318 319} 320 321static void dpp20_configure_blnd_lut( 322 struct dpp *dpp_base, 323 bool is_ram_a) 324{ 325 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 326 327 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK, 328 CM_BLNDGAM_LUT_WRITE_EN_MASK, 7); 329 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK, 330 CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 331 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 332} 333 334static void dpp20_program_blnd_pwl( 335 struct dpp *dpp_base, 336 const struct pwl_result_data *rgb, 337 uint32_t num) 338{ 339 uint32_t i; 340 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 341 342 for (i = 0 ; i < num; i++) { 343 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg); 344 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg); 345 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg); 346 347 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 348 CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg); 349 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 350 CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg); 351 REG_SET(CM_BLNDGAM_LUT_DATA, 0, 352 CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg); 353 354 } 355 356} 357 358static void dcn20_dpp_cm_get_reg_field( 359 struct dcn20_dpp *dpp, 360 struct xfer_func_reg *reg) 361{ 362 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 363 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 364 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 365 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 366 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 367 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 368 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 369 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 370 371 reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 372 reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 373 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 374 reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 375 reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 376 reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 377 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; 378 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B; 379 reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 380 reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 381 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 382 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 383} 384 385/*program blnd lut RAM A*/ 386static void dpp20_program_blnd_luta_settings( 387 struct dpp *dpp_base, 388 const struct pwl_params *params) 389{ 390 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 391 struct xfer_func_reg gam_regs; 392 393 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs); 394 395 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B); 396 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G); 397 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R); 398 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B); 399 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G); 400 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R); 401 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B); 402 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B); 403 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G); 404 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G); 405 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R); 406 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R); 407 gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1); 408 gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33); 409 410 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); 411} 412 413/*program blnd lut RAM B*/ 414static void dpp20_program_blnd_lutb_settings( 415 struct dpp *dpp_base, 416 const struct pwl_params *params) 417{ 418 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 419 struct xfer_func_reg gam_regs; 420 421 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs); 422 423 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B); 424 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G); 425 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R); 426 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B); 427 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G); 428 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R); 429 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B); 430 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B); 431 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G); 432 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G); 433 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R); 434 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R); 435 gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1); 436 gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33); 437 438 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs); 439} 440 441static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base) 442{ 443 enum dc_lut_mode mode; 444 uint32_t state_mode; 445 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 446 447 REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK, 448 CM_BLNDGAM_CONFIG_STATUS, &state_mode); 449 450 switch (state_mode) { 451 case 0: 452 mode = LUT_BYPASS; 453 break; 454 case 1: 455 mode = LUT_RAM_A; 456 break; 457 case 2: 458 mode = LUT_RAM_B; 459 break; 460 default: 461 mode = LUT_BYPASS; 462 break; 463 } 464 return mode; 465} 466 467bool dpp20_program_blnd_lut( 468 struct dpp *dpp_base, const struct pwl_params *params) 469{ 470 enum dc_lut_mode current_mode; 471 enum dc_lut_mode next_mode; 472 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 473 474 if (params == NULL) { 475 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0); 476 return false; 477 } 478 current_mode = dpp20_get_blndgam_current(dpp_base); 479 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 480 next_mode = LUT_RAM_B; 481 else 482 next_mode = LUT_RAM_A; 483 484 dpp20_power_on_blnd_lut(dpp_base, true); 485 dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A); 486 487 if (next_mode == LUT_RAM_A) 488 dpp20_program_blnd_luta_settings(dpp_base, params); 489 else 490 dpp20_program_blnd_lutb_settings(dpp_base, params); 491 492 dpp20_program_blnd_pwl( 493 dpp_base, params->rgb_resulted, params->hw_points_num); 494 495 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 496 next_mode == LUT_RAM_A ? 1:2); 497 498 return true; 499} 500 501 502static void dpp20_program_shaper_lut( 503 struct dpp *dpp_base, 504 const struct pwl_result_data *rgb, 505 uint32_t num) 506{ 507 uint32_t i, red, green, blue; 508 uint32_t red_delta, green_delta, blue_delta; 509 uint32_t red_value, green_value, blue_value; 510 511 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 512 513 for (i = 0 ; i < num; i++) { 514 515 red = rgb[i].red_reg; 516 green = rgb[i].green_reg; 517 blue = rgb[i].blue_reg; 518 519 red_delta = rgb[i].delta_red_reg; 520 green_delta = rgb[i].delta_green_reg; 521 blue_delta = rgb[i].delta_blue_reg; 522 523 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff); 524 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff); 525 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff); 526 527 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value); 528 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value); 529 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value); 530 } 531 532} 533 534static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base) 535{ 536 enum dc_lut_mode mode; 537 uint32_t state_mode; 538 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 539 540 REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK, 541 CM_SHAPER_CONFIG_STATUS, &state_mode); 542 543 switch (state_mode) { 544 case 0: 545 mode = LUT_BYPASS; 546 break; 547 case 1: 548 mode = LUT_RAM_A; 549 break; 550 case 2: 551 mode = LUT_RAM_B; 552 break; 553 default: 554 mode = LUT_BYPASS; 555 break; 556 } 557 return mode; 558} 559 560static void dpp20_configure_shaper_lut( 561 struct dpp *dpp_base, 562 bool is_ram_a) 563{ 564 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 565 566 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 567 CM_SHAPER_LUT_WRITE_EN_MASK, 7); 568 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 569 CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 570 REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0); 571} 572 573/*program shaper RAM A*/ 574 575static void dpp20_program_shaper_luta_settings( 576 struct dpp *dpp_base, 577 const struct pwl_params *params) 578{ 579 const struct gamma_curve *curve; 580 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 581 582 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0, 583 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 584 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 585 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0, 586 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 587 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0); 588 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0, 589 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 590 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0); 591 592 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0, 593 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 594 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 595 596 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0, 597 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 598 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 599 600 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0, 601 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 602 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 603 604 curve = params->arr_curve_points; 605 REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0, 606 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 607 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 608 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 609 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 610 611 curve += 2; 612 REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0, 613 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 614 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 615 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 616 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 617 618 curve += 2; 619 REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0, 620 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 621 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 622 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 623 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 624 625 curve += 2; 626 REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0, 627 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 628 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 629 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 630 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 631 632 curve += 2; 633 REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0, 634 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 635 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 636 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 637 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 638 639 curve += 2; 640 REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0, 641 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 642 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 643 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 644 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 645 646 curve += 2; 647 REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0, 648 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 649 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 650 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 651 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 652 653 curve += 2; 654 REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0, 655 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 656 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 657 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 658 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 659 660 curve += 2; 661 REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0, 662 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset, 663 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 664 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset, 665 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 666 667 curve += 2; 668 REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0, 669 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset, 670 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 671 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset, 672 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 673 674 curve += 2; 675 REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0, 676 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset, 677 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 678 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset, 679 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 680 681 curve += 2; 682 REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0, 683 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset, 684 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 685 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset, 686 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 687 688 curve += 2; 689 REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0, 690 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset, 691 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 692 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset, 693 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 694 695 curve += 2; 696 REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0, 697 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset, 698 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 699 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset, 700 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 701 702 curve += 2; 703 REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0, 704 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset, 705 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 706 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset, 707 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 708 709 curve += 2; 710 REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0, 711 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset, 712 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 713 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset, 714 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 715 716 curve += 2; 717 REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0, 718 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset, 719 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 720 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset, 721 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 722} 723 724/*program shaper RAM B*/ 725static void dpp20_program_shaper_lutb_settings( 726 struct dpp *dpp_base, 727 const struct pwl_params *params) 728{ 729 const struct gamma_curve *curve; 730 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 731 732 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0, 733 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 734 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0); 735 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0, 736 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 737 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0); 738 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0, 739 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 740 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0); 741 742 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0, 743 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 744 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 745 746 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0, 747 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 748 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 749 750 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0, 751 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 752 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 753 754 curve = params->arr_curve_points; 755 REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0, 756 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 757 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 758 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 759 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 760 761 curve += 2; 762 REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0, 763 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 764 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 765 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 766 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 767 768 curve += 2; 769 REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0, 770 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 771 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 772 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 773 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 774 775 curve += 2; 776 REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0, 777 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 778 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 779 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 780 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 781 782 curve += 2; 783 REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0, 784 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 785 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 786 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 787 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 788 789 curve += 2; 790 REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0, 791 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 792 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 793 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 794 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 795 796 curve += 2; 797 REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0, 798 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 799 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 800 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 801 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 802 803 curve += 2; 804 REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0, 805 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 806 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 807 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 808 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 809 810 curve += 2; 811 REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0, 812 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset, 813 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 814 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset, 815 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 816 817 curve += 2; 818 REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0, 819 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset, 820 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 821 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset, 822 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 823 824 curve += 2; 825 REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0, 826 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset, 827 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 828 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset, 829 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 830 831 curve += 2; 832 REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0, 833 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset, 834 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 835 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset, 836 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 837 838 curve += 2; 839 REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0, 840 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset, 841 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 842 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset, 843 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 844 845 curve += 2; 846 REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0, 847 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset, 848 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 849 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset, 850 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 851 852 curve += 2; 853 REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0, 854 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset, 855 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 856 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset, 857 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 858 859 curve += 2; 860 REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0, 861 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset, 862 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 863 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset, 864 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 865 866 curve += 2; 867 REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0, 868 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset, 869 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 870 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset, 871 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 872 873} 874 875 876bool dpp20_program_shaper( 877 struct dpp *dpp_base, 878 const struct pwl_params *params) 879{ 880 enum dc_lut_mode current_mode; 881 enum dc_lut_mode next_mode; 882 883 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 884 885 if (params == NULL) { 886 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0); 887 return false; 888 } 889 current_mode = dpp20_get_shaper_current(dpp_base); 890 891 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 892 next_mode = LUT_RAM_B; 893 else 894 next_mode = LUT_RAM_A; 895 896 dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A); 897 898 if (next_mode == LUT_RAM_A) 899 dpp20_program_shaper_luta_settings(dpp_base, params); 900 else 901 dpp20_program_shaper_lutb_settings(dpp_base, params); 902 903 dpp20_program_shaper_lut( 904 dpp_base, params->rgb_resulted, params->hw_points_num); 905 906 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2); 907 908 return true; 909 910} 911 912static enum dc_lut_mode get3dlut_config( 913 struct dpp *dpp_base, 914 bool *is_17x17x17, 915 bool *is_12bits_color_channel) 916{ 917 uint32_t i_mode, i_enable_10bits, lut_size; 918 enum dc_lut_mode mode; 919 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 920 921 REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL, 922 CM_3DLUT_CONFIG_STATUS, &i_mode, 923 CM_3DLUT_30BIT_EN, &i_enable_10bits); 924 925 switch (i_mode) { 926 case 0: 927 mode = LUT_BYPASS; 928 break; 929 case 1: 930 mode = LUT_RAM_A; 931 break; 932 case 2: 933 mode = LUT_RAM_B; 934 break; 935 default: 936 mode = LUT_BYPASS; 937 break; 938 } 939 if (i_enable_10bits > 0) 940 *is_12bits_color_channel = false; 941 else 942 *is_12bits_color_channel = true; 943 944 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size); 945 946 if (lut_size == 0) 947 *is_17x17x17 = true; 948 else 949 *is_17x17x17 = false; 950 951 return mode; 952} 953/* 954 * select ramA or ramB, or bypass 955 * select color channel size 10 or 12 bits 956 * select 3dlut size 17x17x17 or 9x9x9 957 */ 958static void dpp20_set_3dlut_mode( 959 struct dpp *dpp_base, 960 enum dc_lut_mode mode, 961 bool is_color_channel_12bits, 962 bool is_lut_size17x17x17) 963{ 964 uint32_t lut_mode; 965 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 966 967 if (mode == LUT_BYPASS) 968 lut_mode = 0; 969 else if (mode == LUT_RAM_A) 970 lut_mode = 1; 971 else 972 lut_mode = 2; 973 974 REG_UPDATE_2(CM_3DLUT_MODE, 975 CM_3DLUT_MODE, lut_mode, 976 CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1); 977} 978 979static void dpp20_select_3dlut_ram( 980 struct dpp *dpp_base, 981 enum dc_lut_mode mode, 982 bool is_color_channel_12bits) 983{ 984 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 985 986 REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL, 987 CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, 988 CM_3DLUT_30BIT_EN, 989 is_color_channel_12bits == true ? 0:1); 990} 991 992 993 994static void dpp20_set3dlut_ram12( 995 struct dpp *dpp_base, 996 const struct dc_rgb *lut, 997 uint32_t entries) 998{ 999 uint32_t i, red, green, blue, red1, green1, blue1; 1000 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1001 1002 for (i = 0 ; i < entries; i += 2) { 1003 red = lut[i].red<<4; 1004 green = lut[i].green<<4; 1005 blue = lut[i].blue<<4; 1006 red1 = lut[i+1].red<<4; 1007 green1 = lut[i+1].green<<4; 1008 blue1 = lut[i+1].blue<<4; 1009 1010 REG_SET_2(CM_3DLUT_DATA, 0, 1011 CM_3DLUT_DATA0, red, 1012 CM_3DLUT_DATA1, red1); 1013 1014 REG_SET_2(CM_3DLUT_DATA, 0, 1015 CM_3DLUT_DATA0, green, 1016 CM_3DLUT_DATA1, green1); 1017 1018 REG_SET_2(CM_3DLUT_DATA, 0, 1019 CM_3DLUT_DATA0, blue, 1020 CM_3DLUT_DATA1, blue1); 1021 1022 } 1023} 1024 1025/* 1026 * load selected lut with 10 bits color channels 1027 */ 1028static void dpp20_set3dlut_ram10( 1029 struct dpp *dpp_base, 1030 const struct dc_rgb *lut, 1031 uint32_t entries) 1032{ 1033 uint32_t i, red, green, blue, value; 1034 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1035 1036 for (i = 0; i < entries; i++) { 1037 red = lut[i].red; 1038 green = lut[i].green; 1039 blue = lut[i].blue; 1040 1041 value = (red<<20) | (green<<10) | blue; 1042 1043 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value); 1044 } 1045 1046} 1047 1048 1049static void dpp20_select_3dlut_ram_mask( 1050 struct dpp *dpp_base, 1051 uint32_t ram_selection_mask) 1052{ 1053 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1054 1055 REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK, 1056 ram_selection_mask); 1057 REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0); 1058} 1059 1060bool dpp20_program_3dlut( 1061 struct dpp *dpp_base, 1062 struct tetrahedral_params *params) 1063{ 1064 enum dc_lut_mode mode; 1065 bool is_17x17x17; 1066 bool is_12bits_color_channel; 1067 struct dc_rgb *lut0; 1068 struct dc_rgb *lut1; 1069 struct dc_rgb *lut2; 1070 struct dc_rgb *lut3; 1071 int lut_size0; 1072 int lut_size; 1073 1074 if (params == NULL) { 1075 dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false); 1076 return false; 1077 } 1078 mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel); 1079 1080 if (mode == LUT_BYPASS || mode == LUT_RAM_B) 1081 mode = LUT_RAM_A; 1082 else 1083 mode = LUT_RAM_B; 1084 1085 is_17x17x17 = !params->use_tetrahedral_9; 1086 is_12bits_color_channel = params->use_12bits; 1087 if (is_17x17x17) { 1088 lut0 = params->tetrahedral_17.lut0; 1089 lut1 = params->tetrahedral_17.lut1; 1090 lut2 = params->tetrahedral_17.lut2; 1091 lut3 = params->tetrahedral_17.lut3; 1092 lut_size0 = sizeof(params->tetrahedral_17.lut0)/ 1093 sizeof(params->tetrahedral_17.lut0[0]); 1094 lut_size = sizeof(params->tetrahedral_17.lut1)/ 1095 sizeof(params->tetrahedral_17.lut1[0]); 1096 } else { 1097 lut0 = params->tetrahedral_9.lut0; 1098 lut1 = params->tetrahedral_9.lut1; 1099 lut2 = params->tetrahedral_9.lut2; 1100 lut3 = params->tetrahedral_9.lut3; 1101 lut_size0 = sizeof(params->tetrahedral_9.lut0)/ 1102 sizeof(params->tetrahedral_9.lut0[0]); 1103 lut_size = sizeof(params->tetrahedral_9.lut1)/ 1104 sizeof(params->tetrahedral_9.lut1[0]); 1105 } 1106 1107 dpp20_select_3dlut_ram(dpp_base, mode, 1108 is_12bits_color_channel); 1109 dpp20_select_3dlut_ram_mask(dpp_base, 0x1); 1110 if (is_12bits_color_channel) 1111 dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0); 1112 else 1113 dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0); 1114 1115 dpp20_select_3dlut_ram_mask(dpp_base, 0x2); 1116 if (is_12bits_color_channel) 1117 dpp20_set3dlut_ram12(dpp_base, lut1, lut_size); 1118 else 1119 dpp20_set3dlut_ram10(dpp_base, lut1, lut_size); 1120 1121 dpp20_select_3dlut_ram_mask(dpp_base, 0x4); 1122 if (is_12bits_color_channel) 1123 dpp20_set3dlut_ram12(dpp_base, lut2, lut_size); 1124 else 1125 dpp20_set3dlut_ram10(dpp_base, lut2, lut_size); 1126 1127 dpp20_select_3dlut_ram_mask(dpp_base, 0x8); 1128 if (is_12bits_color_channel) 1129 dpp20_set3dlut_ram12(dpp_base, lut3, lut_size); 1130 else 1131 dpp20_set3dlut_ram10(dpp_base, lut3, lut_size); 1132 1133 1134 dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel, 1135 is_17x17x17); 1136 1137 return true; 1138} 1139 1140void dpp2_set_hdr_multiplier( 1141 struct dpp *dpp_base, 1142 uint32_t multiplier) 1143{ 1144 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 1145 1146 REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier); 1147}