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