FILE
dcn30_dpp.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c
1/* 2 * Copyright 2020 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26#include "dm_services.h" 27#include "core_types.h" 28#include "reg_helper.h" 29#include "dcn30/dcn30_dpp.h" 30#include "basics/conversion.h" 31#include "dcn30/dcn30_cm_common.h" 32 33#define REG(reg)\ 34 dpp->tf_regs->reg 35 36#define CTX \ 37 dpp->base.ctx 38 39#undef FN 40#define FN(reg_name, field_name) \ 41 dpp->tf_shift->field_name, dpp->tf_mask->field_name 42 43 44void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s) 45{ 46 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 47 uint32_t gamcor_lut_mode, rgam_lut_mode; 48 49 REG_GET(DPP_CONTROL, 50 DPP_CLOCK_ENABLE, &s->is_enabled); 51 52 // Pre-degamma (ROM) 53 REG_GET_2(PRE_DEGAM, 54 PRE_DEGAM_MODE, &s->pre_dgam_mode, 55 PRE_DEGAM_SELECT, &s->pre_dgam_select); 56 57 // Gamma Correction (RAM) 58 REG_GET(CM_GAMCOR_CONTROL, 59 CM_GAMCOR_MODE_CURRENT, &s->gamcor_mode); 60 if (s->gamcor_mode) { 61 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, &gamcor_lut_mode); 62 if (!gamcor_lut_mode) 63 s->gamcor_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B 64 } 65 66 // Shaper LUT (RAM), 3D LUT (mode, bit-depth, size) 67 if (REG(CM_SHAPER_CONTROL)) 68 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_LUT_MODE, &s->shaper_lut_mode); 69 if (REG(CM_3DLUT_MODE)) 70 REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &s->lut3d_mode); 71 if (REG(CM_3DLUT_READ_WRITE_CONTROL)) 72 REG_GET(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_30BIT_EN, &s->lut3d_bit_depth); 73 if (REG(CM_3DLUT_MODE)) 74 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &s->lut3d_size); 75 76 // Blend/Out Gamma (RAM) 77 if (REG(CM_BLNDGAM_CONTROL)) { 78 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &s->rgam_lut_mode); 79 if (s->rgam_lut_mode) { 80 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &rgam_lut_mode); 81 if (!rgam_lut_mode) 82 s->rgam_lut_mode = LUT_RAM_A; // Otherwise, LUT_RAM_B 83 } 84 } 85} 86 87void dpp30_read_reg_state(struct dpp *dpp_base, struct dcn_dpp_reg_state *dpp_reg_state) 88{ 89 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 90 91 dpp_reg_state->recout_start = REG_READ(RECOUT_START); 92 dpp_reg_state->recout_size = REG_READ(RECOUT_SIZE); 93 dpp_reg_state->scl_horz_filter_scale_ratio = REG_READ(SCL_HORZ_FILTER_SCALE_RATIO); 94 dpp_reg_state->scl_vert_filter_scale_ratio = REG_READ(SCL_VERT_FILTER_SCALE_RATIO); 95 dpp_reg_state->scl_mode = REG_READ(SCL_MODE); 96 dpp_reg_state->cm_control = REG_READ(CM_CONTROL); 97 dpp_reg_state->dpp_control = REG_READ(DPP_CONTROL); 98 dpp_reg_state->dscl_control = REG_READ(DSCL_CONTROL); 99 dpp_reg_state->obuf_control = REG_READ(OBUF_CONTROL); 100 dpp_reg_state->mpc_size = REG_READ(MPC_SIZE); 101} 102 103/*program post scaler scs block in dpp CM*/ 104void dpp3_program_post_csc( 105 struct dpp *dpp_base, 106 enum dc_color_space color_space, 107 enum dcn10_input_csc_select input_select, 108 const struct out_csc_color_matrix *tbl_entry) 109{ 110 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 111 int i; 112 int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix); 113 const uint16_t *regval = NULL; 114 uint32_t cur_select = 0; 115 enum dcn10_input_csc_select select; 116 struct color_matrices_reg gam_regs; 117 118 if (input_select == INPUT_CSC_SELECT_BYPASS) { 119 REG_SET(CM_POST_CSC_CONTROL, 0, CM_POST_CSC_MODE, 0); 120 return; 121 } 122 123 if (tbl_entry == NULL) { 124 for (i = 0; i < arr_size; i++) 125 if (dpp_input_csc_matrix[i].color_space == color_space) { 126 regval = dpp_input_csc_matrix[i].regval; 127 break; 128 } 129 130 if (regval == NULL) { 131 BREAK_TO_DEBUGGER(); 132 return; 133 } 134 } else { 135 regval = tbl_entry->regval; 136 } 137 138 /* determine which CSC matrix (icsc or coma) we are using 139 * currently. select the alternate set to double buffer 140 * the CSC update so CSC is updated on frame boundary 141 */ 142 REG_GET(CM_POST_CSC_CONTROL, 143 CM_POST_CSC_MODE_CURRENT, &cur_select); 144 145 if (cur_select != INPUT_CSC_SELECT_ICSC) 146 select = INPUT_CSC_SELECT_ICSC; 147 else 148 select = INPUT_CSC_SELECT_COMA; 149 150 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_POST_CSC_C11; 151 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_POST_CSC_C11; 152 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_POST_CSC_C12; 153 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_POST_CSC_C12; 154 155 if (select == INPUT_CSC_SELECT_ICSC) { 156 157 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_C11_C12); 158 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_C33_C34); 159 160 } else { 161 162 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_B_C11_C12); 163 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_B_C33_C34); 164 165 } 166 167 cm_helper_program_color_matrices( 168 dpp->base.ctx, 169 regval, 170 &gam_regs); 171 172 REG_SET(CM_POST_CSC_CONTROL, 0, 173 CM_POST_CSC_MODE, select); 174} 175 176 177/*CNVC degam unit has read only LUTs*/ 178void dpp3_set_pre_degam(struct dpp *dpp_base, enum dc_transfer_func_predefined tr) 179{ 180 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 181 int pre_degam_en = 1; 182 int degamma_lut_selection = 0; 183 184 switch (tr) { 185 case TRANSFER_FUNCTION_LINEAR: 186 case TRANSFER_FUNCTION_UNITY: 187 pre_degam_en = 0; //bypass 188 break; 189 case TRANSFER_FUNCTION_SRGB: 190 degamma_lut_selection = 0; 191 break; 192 case TRANSFER_FUNCTION_BT709: 193 degamma_lut_selection = 4; 194 break; 195 case TRANSFER_FUNCTION_PQ: 196 degamma_lut_selection = 5; 197 break; 198 case TRANSFER_FUNCTION_HLG: 199 degamma_lut_selection = 6; 200 break; 201 case TRANSFER_FUNCTION_GAMMA22: 202 degamma_lut_selection = 1; 203 break; 204 case TRANSFER_FUNCTION_GAMMA24: 205 degamma_lut_selection = 2; 206 break; 207 case TRANSFER_FUNCTION_GAMMA26: 208 degamma_lut_selection = 3; 209 break; 210 default: 211 pre_degam_en = 0; 212 break; 213 } 214 215 REG_SET_2(PRE_DEGAM, 0, 216 PRE_DEGAM_MODE, pre_degam_en, 217 PRE_DEGAM_SELECT, degamma_lut_selection); 218} 219 220void dpp3_cnv_setup ( 221 struct dpp *dpp_base, 222 enum surface_pixel_format format, 223 enum expansion_mode mode, 224 struct dc_csc_transform input_csc_color_matrix, 225 enum dc_color_space input_color_space, 226 struct cnv_alpha_2bit_lut *alpha_2bit_lut) 227{ 228 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 229 uint32_t pixel_format = 0; 230 uint32_t alpha_en = 1; 231 enum dc_color_space color_space = COLOR_SPACE_SRGB; 232 enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS; 233 bool force_disable_cursor = false; 234 uint32_t is_2bit = 0; 235 uint32_t alpha_plane_enable = 0; 236 uint32_t dealpha_en = 0, dealpha_ablnd_en = 0; 237 uint32_t realpha_en = 0, realpha_ablnd_en = 0; 238 struct out_csc_color_matrix tbl_entry; 239 int i; 240 241 REG_SET_2(FORMAT_CONTROL, 0, 242 CNVC_BYPASS, 0, 243 FORMAT_EXPANSION_MODE, mode); 244 245 REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0); 246 REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0); 247 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0); 248 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0); 249 250 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0); 251 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1); 252 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2); 253 254 switch (format) { 255 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 256 pixel_format = 1; 257 break; 258 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 259 pixel_format = 3; 260 alpha_en = 0; 261 break; 262 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 263 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 264 pixel_format = 8; 265 break; 266 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 267 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 268 pixel_format = 10; 269 is_2bit = 1; 270 break; 271 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 272 force_disable_cursor = false; 273 pixel_format = 65; 274 color_space = COLOR_SPACE_YCBCR709; 275 select = INPUT_CSC_SELECT_ICSC; 276 break; 277 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 278 force_disable_cursor = true; 279 pixel_format = 64; 280 color_space = COLOR_SPACE_YCBCR709; 281 select = INPUT_CSC_SELECT_ICSC; 282 break; 283 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: 284 force_disable_cursor = true; 285 pixel_format = 67; 286 color_space = COLOR_SPACE_YCBCR709; 287 select = INPUT_CSC_SELECT_ICSC; 288 break; 289 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: 290 force_disable_cursor = true; 291 pixel_format = 66; 292 color_space = COLOR_SPACE_YCBCR709; 293 select = INPUT_CSC_SELECT_ICSC; 294 break; 295 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 296 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: 297 pixel_format = 26; /* ARGB16161616_UNORM */ 298 break; 299 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 300 pixel_format = 24; 301 break; 302 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 303 pixel_format = 25; 304 break; 305 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888: 306 pixel_format = 12; 307 color_space = COLOR_SPACE_YCBCR709; 308 select = INPUT_CSC_SELECT_ICSC; 309 break; 310 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: 311 pixel_format = 112; 312 alpha_en = 0; 313 break; 314 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: 315 pixel_format = 113; 316 alpha_en = 0; 317 break; 318 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: 319 pixel_format = 114; 320 color_space = COLOR_SPACE_YCBCR709; 321 select = INPUT_CSC_SELECT_ICSC; 322 is_2bit = 1; 323 break; 324 case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102: 325 pixel_format = 115; 326 color_space = COLOR_SPACE_YCBCR709; 327 select = INPUT_CSC_SELECT_ICSC; 328 is_2bit = 1; 329 break; 330 case SURFACE_PIXEL_FORMAT_GRPH_RGBE: 331 pixel_format = 116; 332 alpha_plane_enable = 0; 333 break; 334 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: 335 pixel_format = 116; 336 alpha_plane_enable = 1; 337 break; 338 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: 339 pixel_format = 118; 340 alpha_en = 0; 341 break; 342 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: 343 pixel_format = 119; 344 alpha_en = 0; 345 break; 346 default: 347 break; 348 } 349 350 /* Set default color space based on format if none is given. */ 351 color_space = input_color_space ? input_color_space : color_space; 352 353 if (is_2bit == 1 && alpha_2bit_lut != NULL) { 354 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); 355 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); 356 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2); 357 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3); 358 } 359 360 REG_SET_2(CNVC_SURFACE_PIXEL_FORMAT, 0, 361 CNVC_SURFACE_PIXEL_FORMAT, pixel_format, 362 CNVC_ALPHA_PLANE_ENABLE, alpha_plane_enable); 363 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); 364 365 REG_SET_2(PRE_DEALPHA, 0, 366 PRE_DEALPHA_EN, dealpha_en, 367 PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en); 368 REG_SET_2(PRE_REALPHA, 0, 369 PRE_REALPHA_EN, realpha_en, 370 PRE_REALPHA_ABLND_EN, realpha_ablnd_en); 371 372 /* If input adjustment exists, program the ICSC with those values. */ 373 if (input_csc_color_matrix.enable_adjustment == true) { 374 for (i = 0; i < 12; i++) 375 tbl_entry.regval[i] = input_csc_color_matrix.matrix[i]; 376 377 tbl_entry.color_space = input_color_space; 378 379 if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) 380 select = INPUT_CSC_SELECT_BYPASS; 381 else 382 select = INPUT_CSC_SELECT_ICSC; 383 384 dpp3_program_post_csc(dpp_base, color_space, select, 385 &tbl_entry); 386 } else { 387 dpp3_program_post_csc(dpp_base, color_space, select, NULL); 388 } 389 390 if (force_disable_cursor) { 391 REG_UPDATE(CURSOR_CONTROL, 392 CURSOR_ENABLE, 0); 393 REG_UPDATE(CURSOR0_CONTROL, 394 CUR0_ENABLE, 0); 395 } 396} 397 398#define IDENTITY_RATIO(ratio) (dc_fixpt_u3d19(ratio) == (1 << 19)) 399 400void dpp3_set_cursor_attributes( 401 struct dpp *dpp_base, 402 struct dc_cursor_attributes *cursor_attributes) 403{ 404 enum dc_cursor_color_format color_format = cursor_attributes->color_format; 405 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 406 int cur_rom_en = 0; 407 408 if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA || 409 color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA) { 410 if (cursor_attributes->attribute_flags.bits.ENABLE_CURSOR_DEGAMMA) { 411 cur_rom_en = 1; 412 } 413 } 414 415 if (!dpp_base->cursor_offload) 416 REG_UPDATE_3(CURSOR0_CONTROL, 417 CUR0_MODE, color_format, 418 CUR0_EXPANSION_MODE, 0, 419 CUR0_ROM_EN, cur_rom_en); 420 421 if (color_format == CURSOR_MODE_MONO) { 422 /* todo: clarify what to program these to */ 423 424 if (!dpp_base->cursor_offload) { 425 REG_UPDATE(CURSOR0_COLOR0, 426 CUR0_COLOR0, 0x00000000); 427 REG_UPDATE(CURSOR0_COLOR1, 428 CUR0_COLOR1, 0xFFFFFFFF); 429 } 430 } 431 432 dpp_base->att.cur0_ctl.bits.expansion_mode = 0; 433 dpp_base->att.cur0_ctl.bits.cur0_rom_en = cur_rom_en; 434 dpp_base->att.cur0_ctl.bits.mode = color_format; 435} 436 437 438bool dpp3_get_optimal_number_of_taps( 439 struct dpp *dpp, 440 struct scaler_data *scl_data, 441 const struct scaling_taps *in_taps) 442{ 443 int num_part_y, num_part_c; 444 int max_taps_y, max_taps_c; 445 int min_taps_y, min_taps_c; 446 enum lb_memory_config lb_config; 447 448 /* 449 * Set default taps if none are provided 450 * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling 451 * taps = 4 for upscaling 452 */ 453 if (in_taps->h_taps == 0) { 454 if (dc_fixpt_ceil(scl_data->ratios.horz) > 1) 455 scl_data->taps.h_taps = min(2 * dc_fixpt_ceil(scl_data->ratios.horz), 8); 456 else 457 scl_data->taps.h_taps = 4; 458 } else 459 scl_data->taps.h_taps = in_taps->h_taps; 460 if (in_taps->v_taps == 0) { 461 if (dc_fixpt_ceil(scl_data->ratios.vert) > 1) 462 scl_data->taps.v_taps = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert, 2)), 8); 463 else 464 scl_data->taps.v_taps = 4; 465 } else 466 scl_data->taps.v_taps = in_taps->v_taps; 467 if (in_taps->v_taps_c == 0) { 468 if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 1) 469 scl_data->taps.v_taps_c = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert_c, 2)), 8); 470 else 471 scl_data->taps.v_taps_c = 4; 472 } else 473 scl_data->taps.v_taps_c = in_taps->v_taps_c; 474 if (in_taps->h_taps_c == 0) { 475 if (dc_fixpt_ceil(scl_data->ratios.horz_c) > 1) 476 scl_data->taps.h_taps_c = min(2 * dc_fixpt_ceil(scl_data->ratios.horz_c), 8); 477 else 478 scl_data->taps.h_taps_c = 4; 479 } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1) 480 /* Only 1 and even h_taps_c are supported by hw */ 481 scl_data->taps.h_taps_c = in_taps->h_taps_c - 1; 482 else 483 scl_data->taps.h_taps_c = in_taps->h_taps_c; 484 485 // Avoid null data in the scl data with this early return, proceed non-adaptive calcualtion first 486 if (scl_data->viewport.width > scl_data->h_active && 487 dpp->ctx->dc->debug.max_downscale_src_width != 0 && 488 scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width) 489 return false; 490 491 /*Ensure we can support the requested number of vtaps*/ 492 min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert); 493 min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c); 494 495 /* Use LB_MEMORY_CONFIG_3 for 4:2:0 */ 496 if ((scl_data->format == PIXEL_FORMAT_420BPP8) || (scl_data->format == PIXEL_FORMAT_420BPP10)) 497 lb_config = LB_MEMORY_CONFIG_3; 498 else 499 lb_config = LB_MEMORY_CONFIG_0; 500 501 dpp->caps->dscl_calc_lb_num_partitions( 502 scl_data, lb_config, &num_part_y, &num_part_c); 503 504 /* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */ 505 if (dc_fixpt_ceil(scl_data->ratios.vert) > 2) 506 max_taps_y = num_part_y - (dc_fixpt_ceil(scl_data->ratios.vert) - 2); 507 else 508 max_taps_y = num_part_y; 509 510 if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 2) 511 max_taps_c = num_part_c - (dc_fixpt_ceil(scl_data->ratios.vert_c) - 2); 512 else 513 max_taps_c = num_part_c; 514 515 if (max_taps_y < min_taps_y) 516 return false; 517 else if (max_taps_c < min_taps_c) 518 return false; 519 520 if (scl_data->taps.v_taps > max_taps_y) 521 scl_data->taps.v_taps = max_taps_y; 522 523 if (scl_data->taps.v_taps_c > max_taps_c) 524 scl_data->taps.v_taps_c = max_taps_c; 525 526 if (!dpp->ctx->dc->debug.always_scale) { 527 if (IDENTITY_RATIO(scl_data->ratios.horz)) 528 scl_data->taps.h_taps = 1; 529 if (IDENTITY_RATIO(scl_data->ratios.vert)) 530 scl_data->taps.v_taps = 1; 531 if (IDENTITY_RATIO(scl_data->ratios.horz_c)) 532 scl_data->taps.h_taps_c = 1; 533 if (IDENTITY_RATIO(scl_data->ratios.vert_c)) 534 scl_data->taps.v_taps_c = 1; 535 } 536 537 return true; 538} 539 540static void dpp3_deferred_update(struct dpp *dpp_base) 541{ 542 int bypass_state; 543 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 544 545 if (dpp_base->deferred_reg_writes.bits.disable_dscl) { 546 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); 547 dpp_base->deferred_reg_writes.bits.disable_dscl = false; 548 } 549 550 if (dpp_base->deferred_reg_writes.bits.disable_gamcor) { 551 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state); 552 if (bypass_state == 0) { // only program if bypass was latched 553 REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3); 554 } else 555 ASSERT(0); // LUT select was updated again before vupdate 556 dpp_base->deferred_reg_writes.bits.disable_gamcor = false; 557 } 558 559 if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) { 560 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state); 561 if (bypass_state == 0) { // only program if bypass was latched 562 REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3); 563 } else 564 ASSERT(0); // LUT select was updated again before vupdate 565 dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false; 566 } 567 568 if (dpp_base->deferred_reg_writes.bits.disable_3dlut) { 569 REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state); 570 if (bypass_state == 0) { // only program if bypass was latched 571 REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3); 572 } else 573 ASSERT(0); // LUT select was updated again before vupdate 574 dpp_base->deferred_reg_writes.bits.disable_3dlut = false; 575 } 576 577 if (dpp_base->deferred_reg_writes.bits.disable_shaper) { 578 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state); 579 if (bypass_state == 0) { // only program if bypass was latched 580 REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3); 581 } else 582 ASSERT(0); // LUT select was updated again before vupdate 583 dpp_base->deferred_reg_writes.bits.disable_shaper = false; 584 } 585} 586 587static void dpp3_power_on_blnd_lut( 588 struct dpp *dpp_base, 589 bool power_on) 590{ 591 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 592 593 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 594 if (power_on) { 595 REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0); 596 REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5); 597 } else { 598 dpp_base->ctx->dc->optimized_required = true; 599 dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true; 600 } 601 } 602} 603 604static void dpp3_power_on_hdr3dlut( 605 struct dpp *dpp_base, 606 bool power_on) 607{ 608 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 609 610 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 611 if (power_on) { 612 REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0); 613 REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5); 614 } else { 615 dpp_base->ctx->dc->optimized_required = true; 616 dpp_base->deferred_reg_writes.bits.disable_3dlut = true; 617 } 618 } 619} 620 621static void dpp3_power_on_shaper( 622 struct dpp *dpp_base, 623 bool power_on) 624{ 625 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 626 627 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { 628 if (power_on) { 629 REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0); 630 REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5); 631 } else { 632 dpp_base->ctx->dc->optimized_required = true; 633 dpp_base->deferred_reg_writes.bits.disable_shaper = true; 634 } 635 } 636} 637 638static void dpp3_configure_blnd_lut( 639 struct dpp *dpp_base, 640 bool is_ram_a) 641{ 642 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 643 644 REG_UPDATE_2(CM_BLNDGAM_LUT_CONTROL, 645 CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 7, 646 CM_BLNDGAM_LUT_HOST_SEL, is_ram_a == true ? 0 : 1); 647 648 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 649} 650 651static void dpp3_program_blnd_pwl( 652 struct dpp *dpp_base, 653 const struct pwl_result_data *rgb, 654 uint32_t num) 655{ 656 uint32_t i; 657 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 658 uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; 659 uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; 660 uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; 661 662 if (is_rgb_equal(rgb, num)) { 663 for (i = 0 ; i < num; i++) 664 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg); 665 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red); 666 } else { 667 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 668 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 4); 669 for (i = 0 ; i < num; i++) 670 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg); 671 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red); 672 673 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 674 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 2); 675 for (i = 0 ; i < num; i++) 676 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg); 677 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_green); 678 679 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0); 680 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 1); 681 for (i = 0 ; i < num; i++) 682 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg); 683 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_blue); 684 } 685} 686 687static void dcn3_dpp_cm_get_reg_field( 688 struct dcn3_dpp *dpp, 689 struct dcn3_xfer_func_reg *reg) 690{ 691 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 692 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET; 693 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 694 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 695 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 696 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET; 697 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 698 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 699 700 reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 701 reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B; 702 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 703 reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B; 704 reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 705 reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B; 706 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B; 707 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B; 708 reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 709 reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B; 710 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 711 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B; 712} 713 714/*program blnd lut RAM A*/ 715static void dpp3_program_blnd_luta_settings( 716 struct dpp *dpp_base, 717 const struct pwl_params *params) 718{ 719 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 720 struct dcn3_xfer_func_reg gam_regs; 721 722 dcn3_dpp_cm_get_reg_field(dpp, &gam_regs); 723 724 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B); 725 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G); 726 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R); 727 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B); 728 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G); 729 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R); 730 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B); 731 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B); 732 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G); 733 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G); 734 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R); 735 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R); 736 gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1); 737 gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33); 738 739 cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs); 740} 741 742/*program blnd lut RAM B*/ 743static void dpp3_program_blnd_lutb_settings( 744 struct dpp *dpp_base, 745 const struct pwl_params *params) 746{ 747 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 748 struct dcn3_xfer_func_reg gam_regs; 749 750 dcn3_dpp_cm_get_reg_field(dpp, &gam_regs); 751 752 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B); 753 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G); 754 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R); 755 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B); 756 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G); 757 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R); 758 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B); 759 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B); 760 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G); 761 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G); 762 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R); 763 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R); 764 gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1); 765 gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33); 766 767 cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs); 768} 769 770static enum dc_lut_mode dpp3_get_blndgam_current(struct dpp *dpp_base) 771{ 772 enum dc_lut_mode mode; 773 uint32_t mode_current = 0; 774 uint32_t in_use = 0; 775 776 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 777 778 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &mode_current); 779 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &in_use); 780 781 switch (mode_current) { 782 case 0: 783 case 1: 784 mode = LUT_BYPASS; 785 break; 786 787 case 2: 788 if (in_use == 0) 789 mode = LUT_RAM_A; 790 else 791 mode = LUT_RAM_B; 792 break; 793 default: 794 mode = LUT_BYPASS; 795 break; 796 } 797 798 return mode; 799} 800 801static bool dpp3_program_blnd_lut(struct dpp *dpp_base, 802 const struct pwl_params *params) 803{ 804 enum dc_lut_mode current_mode; 805 enum dc_lut_mode next_mode; 806 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 807 808 if (params == NULL) { 809 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_MODE, 0); 810 dpp3_power_on_blnd_lut(dpp_base, false); 811 return false; 812 } 813 814 current_mode = dpp3_get_blndgam_current(dpp_base); 815 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_B) 816 next_mode = LUT_RAM_A; 817 else 818 next_mode = LUT_RAM_B; 819 820 dpp3_power_on_blnd_lut(dpp_base, true); 821 dpp3_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A); 822 823 if (next_mode == LUT_RAM_A) 824 dpp3_program_blnd_luta_settings(dpp_base, params); 825 else 826 dpp3_program_blnd_lutb_settings(dpp_base, params); 827 828 dpp3_program_blnd_pwl( 829 dpp_base, params->rgb_resulted, params->hw_points_num); 830 831 REG_UPDATE_2(CM_BLNDGAM_CONTROL, 832 CM_BLNDGAM_MODE, 2, 833 CM_BLNDGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1); 834 835 return true; 836} 837 838 839static void dpp3_program_shaper_lut( 840 struct dpp *dpp_base, 841 const struct pwl_result_data *rgb, 842 uint32_t num) 843{ 844 uint32_t i, red, green, blue; 845 uint32_t red_delta, green_delta, blue_delta; 846 uint32_t red_value, green_value, blue_value; 847 848 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 849 850 for (i = 0 ; i < num; i++) { 851 852 red = rgb[i].red_reg; 853 green = rgb[i].green_reg; 854 blue = rgb[i].blue_reg; 855 856 red_delta = rgb[i].delta_red_reg; 857 green_delta = rgb[i].delta_green_reg; 858 blue_delta = rgb[i].delta_blue_reg; 859 860 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff); 861 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff); 862 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff); 863 864 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value); 865 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value); 866 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value); 867 } 868 869} 870 871static enum dc_lut_mode dpp3_get_shaper_current(struct dpp *dpp_base) 872{ 873 enum dc_lut_mode mode; 874 uint32_t state_mode; 875 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 876 877 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &state_mode); 878 879 switch (state_mode) { 880 case 0: 881 mode = LUT_BYPASS; 882 break; 883 case 1: 884 mode = LUT_RAM_A; 885 break; 886 case 2: 887 mode = LUT_RAM_B; 888 break; 889 default: 890 mode = LUT_BYPASS; 891 break; 892 } 893 894 return mode; 895} 896 897static void dpp3_configure_shaper_lut( 898 struct dpp *dpp_base, 899 bool is_ram_a) 900{ 901 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 902 903 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 904 CM_SHAPER_LUT_WRITE_EN_MASK, 7); 905 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK, 906 CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 907 REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0); 908} 909 910/*program shaper RAM A*/ 911 912static void dpp3_program_shaper_luta_settings( 913 struct dpp *dpp_base, 914 const struct pwl_params *params) 915{ 916 const struct gamma_curve *curve; 917 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 918 919 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0, 920 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 921 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 922 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0, 923 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 924 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0); 925 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0, 926 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 927 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0); 928 929 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0, 930 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 931 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 932 933 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0, 934 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 935 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 936 937 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0, 938 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 939 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 940 941 curve = params->arr_curve_points; 942 REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0, 943 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 944 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 945 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 946 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 947 948 curve += 2; 949 REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0, 950 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset, 951 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 952 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset, 953 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 954 955 curve += 2; 956 REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0, 957 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset, 958 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 959 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset, 960 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 961 962 curve += 2; 963 REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0, 964 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset, 965 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 966 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset, 967 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 968 969 curve += 2; 970 REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0, 971 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset, 972 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 973 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset, 974 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 975 976 curve += 2; 977 REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0, 978 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset, 979 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 980 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset, 981 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 982 983 curve += 2; 984 REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0, 985 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset, 986 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 987 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset, 988 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 989 990 curve += 2; 991 REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0, 992 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset, 993 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 994 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset, 995 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 996 997 curve += 2; 998 REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0, 999 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset, 1000 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 1001 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset, 1002 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 1003 1004 curve += 2; 1005 REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0, 1006 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset, 1007 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 1008 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset, 1009 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 1010 1011 curve += 2; 1012 REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0, 1013 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset, 1014 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 1015 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset, 1016 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 1017 1018 curve += 2; 1019 REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0, 1020 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset, 1021 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 1022 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset, 1023 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 1024 1025 curve += 2; 1026 REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0, 1027 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset, 1028 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 1029 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset, 1030 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 1031 1032 curve += 2; 1033 REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0, 1034 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset, 1035 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 1036 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset, 1037 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 1038 1039 curve += 2; 1040 REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0, 1041 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset, 1042 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 1043 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset, 1044 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 1045 1046 curve += 2; 1047 REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0, 1048 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset, 1049 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 1050 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset, 1051 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 1052 1053 curve += 2; 1054 REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0, 1055 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset, 1056 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 1057 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset, 1058 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 1059} 1060 1061/*program shaper RAM B*/ 1062static void dpp3_program_shaper_lutb_settings( 1063 struct dpp *dpp_base, 1064 const struct pwl_params *params) 1065{ 1066 const struct gamma_curve *curve; 1067 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1068 1069 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0, 1070 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 1071 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0); 1072 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0, 1073 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x, 1074 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0); 1075 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0, 1076 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x, 1077 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0); 1078 1079 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0, 1080 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 1081 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 1082 1083 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0, 1084 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x, 1085 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y); 1086 1087 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0, 1088 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x, 1089 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y); 1090 1091 curve = params->arr_curve_points; 1092 REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0, 1093 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset, 1094 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 1095 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset, 1096 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 1097 1098 curve += 2; 1099 REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0, 1100 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset, 1101 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num, 1102 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset, 1103 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num); 1104 1105 curve += 2; 1106 REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0, 1107 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset, 1108 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num, 1109 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset, 1110 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num); 1111 1112 curve += 2; 1113 REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0, 1114 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset, 1115 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num, 1116 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset, 1117 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num); 1118 1119 curve += 2; 1120 REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0, 1121 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset, 1122 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num, 1123 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset, 1124 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num); 1125 1126 curve += 2; 1127 REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0, 1128 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset, 1129 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num, 1130 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset, 1131 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num); 1132 1133 curve += 2; 1134 REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0, 1135 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset, 1136 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num, 1137 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset, 1138 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num); 1139 1140 curve += 2; 1141 REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0, 1142 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset, 1143 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num, 1144 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset, 1145 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num); 1146 1147 curve += 2; 1148 REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0, 1149 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset, 1150 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num, 1151 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset, 1152 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num); 1153 1154 curve += 2; 1155 REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0, 1156 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset, 1157 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num, 1158 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset, 1159 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num); 1160 1161 curve += 2; 1162 REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0, 1163 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset, 1164 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num, 1165 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset, 1166 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num); 1167 1168 curve += 2; 1169 REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0, 1170 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset, 1171 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num, 1172 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset, 1173 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num); 1174 1175 curve += 2; 1176 REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0, 1177 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset, 1178 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num, 1179 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset, 1180 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num); 1181 1182 curve += 2; 1183 REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0, 1184 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset, 1185 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num, 1186 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset, 1187 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num); 1188 1189 curve += 2; 1190 REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0, 1191 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset, 1192 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num, 1193 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset, 1194 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num); 1195 1196 curve += 2; 1197 REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0, 1198 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset, 1199 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num, 1200 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset, 1201 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num); 1202 1203 curve += 2; 1204 REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0, 1205 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset, 1206 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num, 1207 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset, 1208 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num); 1209 1210} 1211 1212 1213static bool dpp3_program_shaper(struct dpp *dpp_base, 1214 const struct pwl_params *params) 1215{ 1216 enum dc_lut_mode current_mode; 1217 enum dc_lut_mode next_mode; 1218 1219 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1220 1221 if (params == NULL) { 1222 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0); 1223 dpp3_power_on_shaper(dpp_base, false); 1224 return false; 1225 } 1226 1227 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) 1228 dpp3_power_on_shaper(dpp_base, true); 1229 1230 current_mode = dpp3_get_shaper_current(dpp_base); 1231 1232 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 1233 next_mode = LUT_RAM_B; 1234 else 1235 next_mode = LUT_RAM_A; 1236 1237 dpp3_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A); 1238 1239 if (next_mode == LUT_RAM_A) 1240 dpp3_program_shaper_luta_settings(dpp_base, params); 1241 else 1242 dpp3_program_shaper_lutb_settings(dpp_base, params); 1243 1244 dpp3_program_shaper_lut( 1245 dpp_base, params->rgb_resulted, params->hw_points_num); 1246 1247 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2); 1248 1249 return true; 1250 1251} 1252 1253static enum dc_lut_mode get3dlut_config( 1254 struct dpp *dpp_base, 1255 bool *is_17x17x17, 1256 bool *is_12bits_color_channel) 1257{ 1258 uint32_t i_mode, i_enable_10bits, lut_size; 1259 enum dc_lut_mode mode; 1260 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1261 1262 REG_GET(CM_3DLUT_READ_WRITE_CONTROL, 1263 CM_3DLUT_30BIT_EN, &i_enable_10bits); 1264 REG_GET(CM_3DLUT_MODE, 1265 CM_3DLUT_MODE_CURRENT, &i_mode); 1266 1267 switch (i_mode) { 1268 case 0: 1269 mode = LUT_BYPASS; 1270 break; 1271 case 1: 1272 mode = LUT_RAM_A; 1273 break; 1274 case 2: 1275 mode = LUT_RAM_B; 1276 break; 1277 default: 1278 mode = LUT_BYPASS; 1279 break; 1280 } 1281 if (i_enable_10bits > 0) 1282 *is_12bits_color_channel = false; 1283 else 1284 *is_12bits_color_channel = true; 1285 1286 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size); 1287 1288 if (lut_size == 0) 1289 *is_17x17x17 = true; 1290 else 1291 *is_17x17x17 = false; 1292 1293 return mode; 1294} 1295/* 1296 * select ramA or ramB, or bypass 1297 * select color channel size 10 or 12 bits 1298 * select 3dlut size 17x17x17 or 9x9x9 1299 */ 1300static void dpp3_set_3dlut_mode( 1301 struct dpp *dpp_base, 1302 enum dc_lut_mode mode, 1303 bool is_color_channel_12bits, 1304 bool is_lut_size17x17x17) 1305{ 1306 uint32_t lut_mode; 1307 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1308 1309 if (mode == LUT_BYPASS) 1310 lut_mode = 0; 1311 else if (mode == LUT_RAM_A) 1312 lut_mode = 1; 1313 else 1314 lut_mode = 2; 1315 1316 REG_UPDATE_2(CM_3DLUT_MODE, 1317 CM_3DLUT_MODE, lut_mode, 1318 CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1); 1319} 1320 1321static void dpp3_select_3dlut_ram( 1322 struct dpp *dpp_base, 1323 enum dc_lut_mode mode, 1324 bool is_color_channel_12bits) 1325{ 1326 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1327 1328 REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL, 1329 CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, 1330 CM_3DLUT_30BIT_EN, 1331 is_color_channel_12bits == true ? 0:1); 1332} 1333 1334 1335 1336static void dpp3_set3dlut_ram12( 1337 struct dpp *dpp_base, 1338 const struct dc_rgb *lut, 1339 uint32_t entries) 1340{ 1341 uint32_t i, red, green, blue, red1, green1, blue1; 1342 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1343 1344 for (i = 0 ; i < entries; i += 2) { 1345 red = lut[i].red<<4; 1346 green = lut[i].green<<4; 1347 blue = lut[i].blue<<4; 1348 red1 = lut[i+1].red<<4; 1349 green1 = lut[i+1].green<<4; 1350 blue1 = lut[i+1].blue<<4; 1351 1352 REG_SET_2(CM_3DLUT_DATA, 0, 1353 CM_3DLUT_DATA0, red, 1354 CM_3DLUT_DATA1, red1); 1355 1356 REG_SET_2(CM_3DLUT_DATA, 0, 1357 CM_3DLUT_DATA0, green, 1358 CM_3DLUT_DATA1, green1); 1359 1360 REG_SET_2(CM_3DLUT_DATA, 0, 1361 CM_3DLUT_DATA0, blue, 1362 CM_3DLUT_DATA1, blue1); 1363 1364 } 1365} 1366 1367/* 1368 * load selected lut with 10 bits color channels 1369 */ 1370static void dpp3_set3dlut_ram10( 1371 struct dpp *dpp_base, 1372 const struct dc_rgb *lut, 1373 uint32_t entries) 1374{ 1375 uint32_t i, red, green, blue, value; 1376 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1377 1378 for (i = 0; i < entries; i++) { 1379 red = lut[i].red; 1380 green = lut[i].green; 1381 blue = lut[i].blue; 1382 1383 value = (red<<20) | (green<<10) | blue; 1384 1385 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value); 1386 } 1387 1388} 1389 1390 1391static void dpp3_select_3dlut_ram_mask( 1392 struct dpp *dpp_base, 1393 uint32_t ram_selection_mask) 1394{ 1395 struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); 1396 1397 REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK, 1398 ram_selection_mask); 1399 REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0); 1400} 1401 1402static bool dpp3_program_3dlut(struct dpp *dpp_base, 1403 const struct tetrahedral_params *params) 1404{ 1405 enum dc_lut_mode mode; 1406 bool is_17x17x17; 1407 bool is_12bits_color_channel; 1408 const struct dc_rgb *lut0; 1409 const struct dc_rgb *lut1; 1410 const struct dc_rgb *lut2; 1411 const struct dc_rgb *lut3; 1412 int lut_size0; 1413 int lut_size; 1414 1415 if (params == NULL) { 1416 dpp3_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false); 1417 dpp3_power_on_hdr3dlut(dpp_base, false); 1418 return false; 1419 } 1420 1421 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) 1422 dpp3_power_on_hdr3dlut(dpp_base, true); 1423 1424 mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel); 1425 1426 if (mode == LUT_BYPASS || mode == LUT_RAM_B) 1427 mode = LUT_RAM_A; 1428 else 1429 mode = LUT_RAM_B; 1430 1431 is_17x17x17 = !params->use_tetrahedral_9; 1432 is_12bits_color_channel = params->use_12bits; 1433 if (is_17x17x17) { 1434 lut0 = params->tetrahedral_17.lut0; 1435 lut1 = params->tetrahedral_17.lut1; 1436 lut2 = params->tetrahedral_17.lut2; 1437 lut3 = params->tetrahedral_17.lut3; 1438 lut_size0 = sizeof(params->tetrahedral_17.lut0)/ 1439 sizeof(params->tetrahedral_17.lut0[0]); 1440 lut_size = sizeof(params->tetrahedral_17.lut1)/ 1441 sizeof(params->tetrahedral_17.lut1[0]); 1442 } else { 1443 lut0 = params->tetrahedral_9.lut0; 1444 lut1 = params->tetrahedral_9.lut1; 1445 lut2 = params->tetrahedral_9.lut2; 1446 lut3 = params->tetrahedral_9.lut3; 1447 lut_size0 = sizeof(params->tetrahedral_9.lut0)/ 1448 sizeof(params->tetrahedral_9.lut0[0]); 1449 lut_size = sizeof(params->tetrahedral_9.lut1)/ 1450 sizeof(params->tetrahedral_9.lut1[0]); 1451 } 1452 1453 dpp3_select_3dlut_ram(dpp_base, mode, 1454 is_12bits_color_channel); 1455 dpp3_select_3dlut_ram_mask(dpp_base, 0x1); 1456 if (is_12bits_color_channel) 1457 dpp3_set3dlut_ram12(dpp_base, lut0, lut_size0); 1458 else 1459 dpp3_set3dlut_ram10(dpp_base, lut0, lut_size0); 1460 1461 dpp3_select_3dlut_ram_mask(dpp_base, 0x2); 1462 if (is_12bits_color_channel) 1463 dpp3_set3dlut_ram12(dpp_base, lut1, lut_size); 1464 else 1465 dpp3_set3dlut_ram10(dpp_base, lut1, lut_size); 1466 1467 dpp3_select_3dlut_ram_mask(dpp_base, 0x4); 1468 if (is_12bits_color_channel) 1469 dpp3_set3dlut_ram12(dpp_base, lut2, lut_size); 1470 else 1471 dpp3_set3dlut_ram10(dpp_base, lut2, lut_size); 1472 1473 dpp3_select_3dlut_ram_mask(dpp_base, 0x8); 1474 if (is_12bits_color_channel) 1475 dpp3_set3dlut_ram12(dpp_base, lut3, lut_size); 1476 else 1477 dpp3_set3dlut_ram10(dpp_base, lut3, lut_size); 1478 1479 1480 dpp3_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel, 1481 is_17x17x17); 1482 1483 return true; 1484} 1485static struct dpp_funcs dcn30_dpp_funcs = { 1486 .dpp_program_gamcor_lut = dpp3_program_gamcor_lut, 1487 .dpp_read_state = dpp30_read_state, 1488 .dpp_reset = dpp_reset, 1489 .dpp_set_scaler = dpp1_dscl_set_scaler_manual_scale, 1490 .dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps, 1491 .dpp_set_gamut_remap = dpp3_cm_set_gamut_remap, 1492 .dpp_set_csc_adjustment = NULL, 1493 .dpp_set_csc_default = NULL, 1494 .dpp_program_regamma_pwl = NULL, 1495 .dpp_set_pre_degam = dpp3_set_pre_degam, 1496 .dpp_program_input_lut = NULL, 1497 .dpp_full_bypass = dpp1_full_bypass, 1498 .dpp_setup = dpp3_cnv_setup, 1499 .dpp_program_degamma_pwl = NULL, 1500 .dpp_program_cm_dealpha = dpp3_program_cm_dealpha, 1501 .dpp_program_cm_bias = dpp3_program_cm_bias, 1502 .dpp_program_blnd_lut = dpp3_program_blnd_lut, 1503 .dpp_program_shaper_lut = dpp3_program_shaper, 1504 .dpp_program_3dlut = dpp3_program_3dlut, 1505 .dpp_deferred_update = dpp3_deferred_update, 1506 .dpp_program_bias_and_scale = NULL, 1507 .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, 1508 .set_cursor_attributes = dpp3_set_cursor_attributes, 1509 .set_cursor_position = dpp1_set_cursor_position, 1510 .set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes, 1511 .dpp_dppclk_control = dpp1_dppclk_control, 1512 .dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier, 1513 .dpp_get_gamut_remap = dpp3_cm_get_gamut_remap, 1514 .dpp_force_disable_cursor = dpp_force_disable_cursor, 1515}; 1516 1517 1518static struct dpp_caps dcn30_dpp_cap = { 1519 .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT, 1520 .dscl_calc_lb_num_partitions = dscl2_calc_lb_num_partitions, 1521}; 1522 1523bool dpp3_construct( 1524 struct dcn3_dpp *dpp, 1525 struct dc_context *ctx, 1526 uint32_t inst, 1527 const struct dcn3_dpp_registers *tf_regs, 1528 const struct dcn3_dpp_shift *tf_shift, 1529 const struct dcn3_dpp_mask *tf_mask) 1530{ 1531 dpp->base.ctx = ctx; 1532 1533 dpp->base.inst = inst; 1534 dpp->base.funcs = &dcn30_dpp_funcs; 1535 dpp->base.caps = &dcn30_dpp_cap; 1536 1537 dpp->tf_regs = tf_regs; 1538 dpp->tf_shift = tf_shift; 1539 dpp->tf_mask = tf_mask; 1540 1541 return true; 1542} 1543 1544bool dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space) 1545{ 1546 switch (dc_color_space) { 1547 case COLOR_SPACE_UNKNOWN: 1548 case COLOR_SPACE_SRGB: 1549 case COLOR_SPACE_XR_RGB: 1550 case COLOR_SPACE_SRGB_LIMITED: 1551 case COLOR_SPACE_MSREF_SCRGB: 1552 case COLOR_SPACE_2020_RGB_FULLRANGE: 1553 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 1554 return true; 1555 default: 1556 return false; 1557 } 1558}
~/
Read-only file preview.