1 /* 2 * Copyright 2023 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 "reg_helper.h" 27 #include "dc.h" 28 #include "dcn401_mpc.h" 29 #include "dcn10/dcn10_cm_common.h" 30 #include "basics/conversion.h" 31 #include "mpc.h" 32 33 #define REG(reg)\ 34 mpc401->mpc_regs->reg 35 36 #define CTX \ 37 mpc401->base.ctx 38 39 #undef FN 40 #define FN(reg_name, field_name) \ 41 mpc401->mpc_shift->field_name, mpc401->mpc_mask->field_name 42 43 void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx) 44 { 45 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 46 47 REG_SET(MPCC_MCM_3DLUT_FAST_LOAD_SELECT[mpcc_id], 0, MPCC_MCM_3DLUT_FL_SEL, hubp_idx); 48 } 49 50 void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow) 51 { 52 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 53 54 REG_GET_3(MPCC_MCM_3DLUT_FAST_LOAD_STATUS[mpcc_id], 55 MPCC_MCM_3DLUT_FL_DONE, done, 56 MPCC_MCM_3DLUT_FL_SOFT_UNDERFLOW, soft_underflow, 57 MPCC_MCM_3DLUT_FL_HARD_UNDERFLOW, hard_underflow); 58 } 59 60 void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id) 61 { 62 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 63 64 switch (location) { 65 case MPCC_MOVABLE_CM_LOCATION_BEFORE: 66 REG_UPDATE(MPCC_MOVABLE_CM_LOCATION_CONTROL[mpcc_id], 67 MPCC_MOVABLE_CM_LOCATION_CNTL, 0); 68 break; 69 case MPCC_MOVABLE_CM_LOCATION_AFTER: 70 REG_UPDATE(MPCC_MOVABLE_CM_LOCATION_CONTROL[mpcc_id], 71 MPCC_MOVABLE_CM_LOCATION_CNTL, 1); 72 break; 73 } 74 } 75 76 static enum dc_lut_mode get3dlut_config( 77 struct mpc *mpc, 78 bool *is_17x17x17, 79 bool *is_12bits_color_channel, 80 int mpcc_id) 81 { 82 uint32_t i_mode, i_enable_10bits, lut_size; 83 enum dc_lut_mode mode; 84 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 85 86 REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], 87 MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode); 88 89 REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], 90 MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits); 91 92 switch (i_mode) { 93 case 0: 94 mode = LUT_BYPASS; 95 break; 96 case 1: 97 mode = LUT_RAM_A; 98 break; 99 case 2: 100 mode = LUT_RAM_B; 101 break; 102 default: 103 mode = LUT_BYPASS; 104 break; 105 } 106 if (i_enable_10bits > 0) 107 *is_12bits_color_channel = false; 108 else 109 *is_12bits_color_channel = true; 110 111 REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size); 112 113 if (lut_size == 0) 114 *is_17x17x17 = true; 115 else 116 *is_17x17x17 = false; 117 118 return mode; 119 } 120 121 void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id) 122 { 123 const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B; 124 const struct pwl_params *lut1d = params.pwl; 125 const struct pwl_params *lut_shaper = params.pwl; 126 bool is_17x17x17; 127 bool is_12bits_color_channel; 128 const struct dc_rgb *lut0; 129 const struct dc_rgb *lut1; 130 const struct dc_rgb *lut2; 131 const struct dc_rgb *lut3; 132 int lut_size0; 133 int lut_size; 134 const struct tetrahedral_params *lut3d = params.lut3d; 135 136 switch (id) { 137 case MCM_LUT_1DLUT: 138 if (lut1d == NULL) 139 return; 140 141 mpc32_power_on_blnd_lut(mpc, mpcc_id, true); 142 mpc32_configure_post1dlut(mpc, mpcc_id, next_mode == LUT_RAM_A); 143 144 if (next_mode == LUT_RAM_A) 145 mpc32_program_post1dluta_settings(mpc, mpcc_id, lut1d); 146 else 147 mpc32_program_post1dlutb_settings(mpc, mpcc_id, lut1d); 148 149 mpc32_program_post1dlut_pwl( 150 mpc, mpcc_id, lut1d->rgb_resulted, lut1d->hw_points_num); 151 152 break; 153 case MCM_LUT_SHAPER: 154 if (lut_shaper == NULL) 155 return; 156 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 157 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); 158 159 mpc32_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id); 160 161 if (next_mode == LUT_RAM_A) 162 mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id); 163 else 164 mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id); 165 166 mpc32_program_shaper_lut( 167 mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id); 168 169 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false); 170 break; 171 case MCM_LUT_3DLUT: 172 if (lut3d == NULL) 173 return; 174 175 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); 176 177 get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id); 178 179 is_17x17x17 = !lut3d->use_tetrahedral_9; 180 is_12bits_color_channel = lut3d->use_12bits; 181 if (is_17x17x17) { 182 lut0 = lut3d->tetrahedral_17.lut0; 183 lut1 = lut3d->tetrahedral_17.lut1; 184 lut2 = lut3d->tetrahedral_17.lut2; 185 lut3 = lut3d->tetrahedral_17.lut3; 186 lut_size0 = sizeof(lut3d->tetrahedral_17.lut0)/ 187 sizeof(lut3d->tetrahedral_17.lut0[0]); 188 lut_size = sizeof(lut3d->tetrahedral_17.lut1)/ 189 sizeof(lut3d->tetrahedral_17.lut1[0]); 190 } else { 191 lut0 = lut3d->tetrahedral_9.lut0; 192 lut1 = lut3d->tetrahedral_9.lut1; 193 lut2 = lut3d->tetrahedral_9.lut2; 194 lut3 = lut3d->tetrahedral_9.lut3; 195 lut_size0 = sizeof(lut3d->tetrahedral_9.lut0)/ 196 sizeof(lut3d->tetrahedral_9.lut0[0]); 197 lut_size = sizeof(lut3d->tetrahedral_9.lut1)/ 198 sizeof(lut3d->tetrahedral_9.lut1[0]); 199 } 200 201 mpc32_select_3dlut_ram(mpc, next_mode, 202 is_12bits_color_channel, mpcc_id); 203 mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id); 204 if (is_12bits_color_channel) 205 mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id); 206 else 207 mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id); 208 209 mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id); 210 if (is_12bits_color_channel) 211 mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id); 212 else 213 mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id); 214 215 mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id); 216 if (is_12bits_color_channel) 217 mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id); 218 else 219 mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id); 220 221 mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id); 222 if (is_12bits_color_channel) 223 mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id); 224 else 225 mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id); 226 227 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 228 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false); 229 230 break; 231 } 232 233 } 234 235 void mpc401_program_lut_mode( 236 struct mpc *mpc, 237 const enum MCM_LUT_ID id, 238 const enum MCM_LUT_XABLE xable, 239 bool lut_bank_a, 240 int mpcc_id) 241 { 242 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 243 244 switch (id) { 245 case MCM_LUT_3DLUT: 246 switch (xable) { 247 case MCM_LUT_DISABLE: 248 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0); 249 break; 250 case MCM_LUT_ENABLE: 251 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2); 252 break; 253 } 254 break; 255 case MCM_LUT_SHAPER: 256 switch (xable) { 257 case MCM_LUT_DISABLE: 258 REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0); 259 break; 260 case MCM_LUT_ENABLE: 261 REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2); 262 break; 263 } 264 break; 265 case MCM_LUT_1DLUT: 266 switch (xable) { 267 case MCM_LUT_DISABLE: 268 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 269 MPCC_MCM_1DLUT_MODE, 0); 270 break; 271 case MCM_LUT_ENABLE: 272 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 273 MPCC_MCM_1DLUT_MODE, 2); 274 break; 275 } 276 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 277 MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1); 278 break; 279 } 280 } 281 282 void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id) 283 { 284 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 285 286 switch (id) { 287 case MCM_LUT_3DLUT: 288 mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id); 289 REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1); 290 break; 291 case MCM_LUT_SHAPER: 292 mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id); 293 break; 294 case MCM_LUT_1DLUT: 295 mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id); 296 break; 297 } 298 } 299 300 void mpc401_program_3dlut_size(struct mpc *mpc, bool is_17x17x17, int mpcc_id) 301 { 302 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 303 304 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, is_17x17x17 ? 0 : 1); 305 } 306 307 static void program_gamut_remap( 308 struct mpc *mpc, 309 unsigned int mpcc_id, 310 const uint16_t *regval, 311 enum mpcc_gamut_remap_id gamut_remap_block_id, 312 enum mpcc_gamut_remap_mode_select mode_select) 313 { 314 struct color_matrices_reg gamut_regs; 315 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 316 317 switch (gamut_remap_block_id) { 318 case MPCC_OGAM_GAMUT_REMAP: 319 320 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 321 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, 322 MPCC_GAMUT_REMAP_MODE, mode_select); 323 return; 324 } 325 326 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 327 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 328 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 329 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 330 331 switch (mode_select) { 332 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 333 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]); 334 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]); 335 break; 336 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 337 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]); 338 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]); 339 break; 340 default: 341 break; 342 } 343 344 cm_helper_program_color_matrices( 345 mpc->ctx, 346 regval, 347 &gamut_regs); 348 349 //select coefficient set to use, set A (MODE_1) or set B (MODE_2) 350 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, MPCC_GAMUT_REMAP_MODE, mode_select); 351 break; 352 353 case MPCC_MCM_FIRST_GAMUT_REMAP: 354 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 355 REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0, 356 MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select); 357 return; 358 } 359 360 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A; 361 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A; 362 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A; 363 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A; 364 365 switch (mode_select) { 366 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 367 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]); 368 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]); 369 break; 370 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 371 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]); 372 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]); 373 break; 374 default: 375 break; 376 } 377 378 cm_helper_program_color_matrices( 379 mpc->ctx, 380 regval, 381 &gamut_regs); 382 383 //select coefficient set to use, set A (MODE_1) or set B (MODE_2) 384 REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0, 385 MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select); 386 break; 387 388 case MPCC_MCM_SECOND_GAMUT_REMAP: 389 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 390 REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0, 391 MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select); 392 return; 393 } 394 395 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A; 396 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A; 397 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A; 398 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A; 399 400 switch (mode_select) { 401 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 402 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]); 403 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]); 404 break; 405 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 406 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]); 407 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]); 408 break; 409 default: 410 break; 411 } 412 413 cm_helper_program_color_matrices( 414 mpc->ctx, 415 regval, 416 &gamut_regs); 417 418 //select coefficient set to use, set A (MODE_1) or set B (MODE_2) 419 REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0, 420 MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select); 421 break; 422 423 default: 424 break; 425 } 426 } 427 428 void mpc401_set_gamut_remap( 429 struct mpc *mpc, 430 int mpcc_id, 431 const struct mpc_grph_gamut_adjustment *adjust) 432 { 433 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 434 unsigned int i = 0; 435 uint32_t mode_select = 0; 436 437 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) { 438 /* Bypass / Disable if type is bypass or hw */ 439 program_gamut_remap(mpc, mpcc_id, NULL, 440 adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0); 441 } else { 442 struct fixed31_32 arr_matrix[12]; 443 uint16_t arr_reg_val[12]; 444 445 for (i = 0; i < 12; i++) 446 arr_matrix[i] = adjust->temperature_matrix[i]; 447 448 convert_float_matrix(arr_reg_val, arr_matrix, 12); 449 450 switch (adjust->mpcc_gamut_remap_block_id) { 451 case MPCC_OGAM_GAMUT_REMAP: 452 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 453 MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select); 454 break; 455 case MPCC_MCM_FIRST_GAMUT_REMAP: 456 REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 457 MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, &mode_select); 458 break; 459 case MPCC_MCM_SECOND_GAMUT_REMAP: 460 REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 461 MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, &mode_select); 462 break; 463 default: 464 break; 465 } 466 467 //If current set in use not set A (MODE_1), then use set A, otherwise use set B 468 if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1) 469 mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1; 470 else 471 mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2; 472 473 program_gamut_remap(mpc, mpcc_id, arr_reg_val, 474 adjust->mpcc_gamut_remap_block_id, mode_select); 475 } 476 } 477 478 static void read_gamut_remap(struct mpc *mpc, 479 int mpcc_id, 480 uint16_t *regval, 481 enum mpcc_gamut_remap_id gamut_remap_block_id, 482 uint32_t *mode_select) 483 { 484 struct color_matrices_reg gamut_regs = {0}; 485 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc); 486 487 switch (gamut_remap_block_id) { 488 case MPCC_OGAM_GAMUT_REMAP: 489 //current coefficient set in use 490 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, mode_select); 491 492 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 493 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 494 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 495 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 496 497 switch (*mode_select) { 498 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 499 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]); 500 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]); 501 break; 502 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 503 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]); 504 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]); 505 break; 506 default: 507 break; 508 } 509 break; 510 511 case MPCC_MCM_FIRST_GAMUT_REMAP: 512 REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 513 MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, mode_select); 514 515 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A; 516 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A; 517 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A; 518 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A; 519 520 switch (*mode_select) { 521 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 522 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]); 523 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]); 524 break; 525 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 526 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]); 527 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]); 528 break; 529 default: 530 break; 531 } 532 break; 533 534 case MPCC_MCM_SECOND_GAMUT_REMAP: 535 REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 536 MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, mode_select); 537 538 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A; 539 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A; 540 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A; 541 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A; 542 543 switch (*mode_select) { 544 case MPCC_GAMUT_REMAP_MODE_SELECT_1: 545 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]); 546 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]); 547 break; 548 case MPCC_GAMUT_REMAP_MODE_SELECT_2: 549 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]); 550 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]); 551 break; 552 default: 553 break; 554 } 555 break; 556 557 default: 558 break; 559 } 560 561 if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) { 562 cm_helper_read_color_matrices( 563 mpc401->base.ctx, 564 regval, 565 &gamut_regs); 566 } 567 } 568 569 void mpc401_get_gamut_remap(struct mpc *mpc, 570 int mpcc_id, 571 struct mpc_grph_gamut_adjustment *adjust) 572 { 573 uint16_t arr_reg_val[12] = {0}; 574 uint32_t mode_select; 575 576 read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select); 577 578 if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) { 579 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 580 return; 581 } 582 583 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 584 convert_hw_matrix(adjust->temperature_matrix, 585 arr_reg_val, ARRAY_SIZE(arr_reg_val)); 586 } 587 588 static const struct mpc_funcs dcn401_mpc_funcs = { 589 .read_mpcc_state = mpc1_read_mpcc_state, 590 .insert_plane = mpc1_insert_plane, 591 .remove_mpcc = mpc1_remove_mpcc, 592 .mpc_init = mpc32_mpc_init, 593 .mpc_init_single_inst = mpc3_mpc_init_single_inst, 594 .update_blending = mpc2_update_blending, 595 .cursor_lock = mpc1_cursor_lock, 596 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, 597 .wait_for_idle = mpc2_assert_idle_mpcc, 598 .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, 599 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, 600 .set_denorm = mpc3_set_denorm, 601 .set_denorm_clamp = mpc3_set_denorm_clamp, 602 .set_output_csc = mpc3_set_output_csc, 603 .set_ocsc_default = mpc3_set_ocsc_default, 604 .set_output_gamma = mpc3_set_output_gamma, 605 .insert_plane_to_secondary = NULL, 606 .remove_mpcc_from_secondary = NULL, 607 .set_dwb_mux = mpc3_set_dwb_mux, 608 .disable_dwb_mux = mpc3_disable_dwb_mux, 609 .is_dwb_idle = mpc3_is_dwb_idle, 610 .set_gamut_remap = mpc401_set_gamut_remap, 611 .program_shaper = mpc32_program_shaper, 612 .program_3dlut = mpc32_program_3dlut, 613 .program_1dlut = mpc32_program_post1dlut, 614 .acquire_rmu = NULL, 615 .release_rmu = NULL, 616 .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut, 617 .get_mpc_out_mux = mpc1_get_mpc_out_mux, 618 .set_bg_color = mpc1_set_bg_color, 619 .set_movable_cm_location = mpc401_set_movable_cm_location, 620 .update_3dlut_fast_load_select = mpc401_update_3dlut_fast_load_select, 621 .get_3dlut_fast_load_status = mpc401_get_3dlut_fast_load_status, 622 .populate_lut = mpc401_populate_lut, 623 .program_lut_read_write_control = mpc401_program_lut_read_write_control, 624 .program_lut_mode = mpc401_program_lut_mode, 625 .program_3dlut_size = mpc401_program_3dlut_size, 626 }; 627 628 629 void dcn401_mpc_construct(struct dcn401_mpc *mpc401, 630 struct dc_context *ctx, 631 const struct dcn401_mpc_registers *mpc_regs, 632 const struct dcn401_mpc_shift *mpc_shift, 633 const struct dcn401_mpc_mask *mpc_mask, 634 int num_mpcc, 635 int num_rmu) 636 { 637 int i; 638 639 mpc401->base.ctx = ctx; 640 641 mpc401->base.funcs = &dcn401_mpc_funcs; 642 643 mpc401->mpc_regs = mpc_regs; 644 mpc401->mpc_shift = mpc_shift; 645 mpc401->mpc_mask = mpc_mask; 646 647 mpc401->mpcc_in_use_mask = 0; 648 mpc401->num_mpcc = num_mpcc; 649 mpc401->num_rmu = num_rmu; 650 651 for (i = 0; i < MAX_MPCC; i++) 652 mpc3_init_mpcc(&mpc401->base.mpcc_array[i], i); 653 } 654