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 "reg_helper.h" 27#include "dcn30_mpc.h" 28#include "dcn30_cm_common.h" 29#include "basics/conversion.h" 30#include "dcn10/dcn10_cm_common.h" 31#include "dc.h" 32 33#define REG(reg)\ 34 mpc30->mpc_regs->reg 35 36#define CTX \ 37 mpc30->base.ctx 38 39#undef FN 40#define FN(reg_name, field_name) \ 41 mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name 42 43 44#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) 45 46 47bool mpc3_is_dwb_idle( 48 struct mpc *mpc, 49 int dwb_id) 50{ 51 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 52 unsigned int status; 53 54 REG_GET(DWB_MUX[dwb_id], MPC_DWB0_MUX_STATUS, &status); 55 56 if (status == 0xf) 57 return true; 58 else 59 return false; 60} 61 62void mpc3_set_dwb_mux( 63 struct mpc *mpc, 64 int dwb_id, 65 int mpcc_id) 66{ 67 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 68 69 REG_SET(DWB_MUX[dwb_id], 0, 70 MPC_DWB0_MUX, mpcc_id); 71} 72 73void mpc3_disable_dwb_mux( 74 struct mpc *mpc, 75 int dwb_id) 76{ 77 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 78 79 REG_SET(DWB_MUX[dwb_id], 0, 80 MPC_DWB0_MUX, 0xf); 81} 82 83void mpc3_set_out_rate_control( 84 struct mpc *mpc, 85 int opp_id, 86 bool enable, 87 bool rate_2x_mode, 88 struct mpc_dwb_flow_control *flow_control) 89{ 90 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 91 92 REG_UPDATE_2(MUX[opp_id], 93 MPC_OUT_RATE_CONTROL_DISABLE, !enable, 94 MPC_OUT_RATE_CONTROL, rate_2x_mode); 95 96 if (flow_control) 97 REG_UPDATE_2(MUX[opp_id], 98 MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode, 99 MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1); 100} 101 102enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id) 103{ 104 /*Contrary to DCN2 and DCN1 wherein a single status register field holds this info; 105 *in DCN3/3AG, we need to read two separate fields to retrieve the same info 106 */ 107 enum dc_lut_mode mode; 108 uint32_t state_mode; 109 uint32_t state_ram_lut_in_use; 110 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 111 112 REG_GET_2(MPCC_OGAM_CONTROL[mpcc_id], MPCC_OGAM_MODE_CURRENT, &state_mode, 113 MPCC_OGAM_SELECT_CURRENT, &state_ram_lut_in_use); 114 115 switch (state_mode) { 116 case 0: 117 mode = LUT_BYPASS; 118 break; 119 case 2: 120 switch (state_ram_lut_in_use) { 121 case 0: 122 mode = LUT_RAM_A; 123 break; 124 case 1: 125 mode = LUT_RAM_B; 126 break; 127 default: 128 mode = LUT_BYPASS; 129 break; 130 } 131 break; 132 default: 133 mode = LUT_BYPASS; 134 break; 135 } 136 137 return mode; 138} 139 140void mpc3_power_on_ogam_lut( 141 struct mpc *mpc, int mpcc_id, 142 bool power_on) 143{ 144 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 145 146 /* 147 * Powering on: force memory active so the LUT can be updated. 148 * Powering off: allow entering memory low power mode 149 * 150 * Memory low power mode is controlled during MPC OGAM LUT init. 151 */ 152 REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], 153 MPCC_OGAM_MEM_PWR_DIS, power_on != 0); 154 155 /* Wait for memory to be powered on - we won't be able to write to it otherwise. */ 156 if (power_on) 157 REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10); 158} 159 160static void mpc3_configure_ogam_lut( 161 struct mpc *mpc, int mpcc_id, 162 bool is_ram_a) 163{ 164 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 165 166 REG_UPDATE_2(MPCC_OGAM_LUT_CONTROL[mpcc_id], 167 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 7, 168 MPCC_OGAM_LUT_HOST_SEL, is_ram_a == true ? 0:1); 169 170 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0); 171} 172 173static void mpc3_ogam_get_reg_field( 174 struct mpc *mpc, 175 struct dcn3_xfer_func_reg *reg) 176{ 177 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 178 179 reg->shifts.field_region_start_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B; 180 reg->masks.field_region_start_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B; 181 reg->shifts.field_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_OFFSET_B; 182 reg->masks.field_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_OFFSET_B; 183 184 reg->shifts.exp_region0_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; 185 reg->masks.exp_region0_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET; 186 reg->shifts.exp_region0_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 187 reg->masks.exp_region0_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS; 188 reg->shifts.exp_region1_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET; 189 reg->masks.exp_region1_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET; 190 reg->shifts.exp_region1_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 191 reg->masks.exp_region1_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS; 192 193 reg->shifts.field_region_end = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_B; 194 reg->masks.field_region_end = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_B; 195 reg->shifts.field_region_end_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B; 196 reg->masks.field_region_end_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B; 197 reg->shifts.field_region_end_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B; 198 reg->masks.field_region_end_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B; 199 reg->shifts.field_region_linear_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B; 200 reg->masks.field_region_linear_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B; 201 reg->shifts.exp_region_start = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_B; 202 reg->masks.exp_region_start = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_B; 203 reg->shifts.exp_resion_start_segment = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B; 204 reg->masks.exp_resion_start_segment = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B; 205} 206 207static void mpc3_program_luta(struct mpc *mpc, int mpcc_id, 208 const struct pwl_params *params) 209{ 210 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 211 struct dcn3_xfer_func_reg gam_regs; 212 213 mpc3_ogam_get_reg_field(mpc, &gam_regs); 214 215 gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMA_START_CNTL_B[mpcc_id]); 216 gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMA_START_CNTL_G[mpcc_id]); 217 gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMA_START_CNTL_R[mpcc_id]); 218 gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_B[mpcc_id]); 219 gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_G[mpcc_id]); 220 gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_R[mpcc_id]); 221 gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMA_END_CNTL1_B[mpcc_id]); 222 gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMA_END_CNTL2_B[mpcc_id]); 223 gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMA_END_CNTL1_G[mpcc_id]); 224 gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMA_END_CNTL2_G[mpcc_id]); 225 gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMA_END_CNTL1_R[mpcc_id]); 226 gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMA_END_CNTL2_R[mpcc_id]); 227 gam_regs.region_start = REG(MPCC_OGAM_RAMA_REGION_0_1[mpcc_id]); 228 gam_regs.region_end = REG(MPCC_OGAM_RAMA_REGION_32_33[mpcc_id]); 229 //New registers in DCN3AG/DCN OGAM block 230 gam_regs.offset_b = REG(MPCC_OGAM_RAMA_OFFSET_B[mpcc_id]); 231 gam_regs.offset_g = REG(MPCC_OGAM_RAMA_OFFSET_G[mpcc_id]); 232 gam_regs.offset_r = REG(MPCC_OGAM_RAMA_OFFSET_R[mpcc_id]); 233 gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_B[mpcc_id]); 234 gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_G[mpcc_id]); 235 gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_R[mpcc_id]); 236 237 cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs); 238} 239 240static void mpc3_program_lutb(struct mpc *mpc, int mpcc_id, 241 const struct pwl_params *params) 242{ 243 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 244 struct dcn3_xfer_func_reg gam_regs; 245 246 mpc3_ogam_get_reg_field(mpc, &gam_regs); 247 248 gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMB_START_CNTL_B[mpcc_id]); 249 gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMB_START_CNTL_G[mpcc_id]); 250 gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMB_START_CNTL_R[mpcc_id]); 251 gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_B[mpcc_id]); 252 gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_G[mpcc_id]); 253 gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_R[mpcc_id]); 254 gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMB_END_CNTL1_B[mpcc_id]); 255 gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMB_END_CNTL2_B[mpcc_id]); 256 gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMB_END_CNTL1_G[mpcc_id]); 257 gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMB_END_CNTL2_G[mpcc_id]); 258 gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMB_END_CNTL1_R[mpcc_id]); 259 gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMB_END_CNTL2_R[mpcc_id]); 260 gam_regs.region_start = REG(MPCC_OGAM_RAMB_REGION_0_1[mpcc_id]); 261 gam_regs.region_end = REG(MPCC_OGAM_RAMB_REGION_32_33[mpcc_id]); 262 //New registers in DCN3AG/DCN OGAM block 263 gam_regs.offset_b = REG(MPCC_OGAM_RAMB_OFFSET_B[mpcc_id]); 264 gam_regs.offset_g = REG(MPCC_OGAM_RAMB_OFFSET_G[mpcc_id]); 265 gam_regs.offset_r = REG(MPCC_OGAM_RAMB_OFFSET_R[mpcc_id]); 266 gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_B[mpcc_id]); 267 gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_G[mpcc_id]); 268 gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_R[mpcc_id]); 269 270 cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs); 271} 272 273 274static void mpc3_program_ogam_pwl( 275 struct mpc *mpc, int mpcc_id, 276 const struct pwl_result_data *rgb, 277 uint32_t num) 278{ 279 uint32_t i; 280 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 281 282 if (is_rgb_equal(rgb, num)) { 283 for (i = 0 ; i < num; i++) 284 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg); 285 } else { 286 287 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 288 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 4); 289 290 for (i = 0 ; i < num; i++) 291 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg); 292 293 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0); 294 295 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 296 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 2); 297 298 for (i = 0 ; i < num; i++) 299 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg); 300 301 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0); 302 303 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 304 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 1); 305 306 for (i = 0 ; i < num; i++) 307 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg); 308 309 } 310 311} 312 313void mpc3_set_output_gamma( 314 struct mpc *mpc, 315 int mpcc_id, 316 const struct pwl_params *params) 317{ 318 enum dc_lut_mode current_mode; 319 enum dc_lut_mode next_mode; 320 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 321 322 if (mpc->ctx->dc->debug.cm_in_bypass) { 323 REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0); 324 return; 325 } 326 327 if (params == NULL) { //disable OGAM 328 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 0); 329 return; 330 } 331 //enable OGAM 332 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 2); 333 334 current_mode = mpc3_get_ogam_current(mpc, mpcc_id); 335 if (current_mode == LUT_BYPASS) 336 next_mode = LUT_RAM_A; 337 else if (current_mode == LUT_RAM_A) 338 next_mode = LUT_RAM_B; 339 else 340 next_mode = LUT_RAM_A; 341 342 mpc3_power_on_ogam_lut(mpc, mpcc_id, true); 343 mpc3_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A); 344 345 if (next_mode == LUT_RAM_A) 346 mpc3_program_luta(mpc, mpcc_id, params); 347 else 348 mpc3_program_lutb(mpc, mpcc_id, params); 349 350 mpc3_program_ogam_pwl( 351 mpc, mpcc_id, params->rgb_resulted, params->hw_points_num); 352 353 /*we need to program 2 fields here as apposed to 1*/ 354 REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id], 355 MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1); 356 357 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 358 mpc3_power_on_ogam_lut(mpc, mpcc_id, false); 359} 360 361void mpc3_set_denorm( 362 struct mpc *mpc, 363 int opp_id, 364 enum dc_color_depth output_depth) 365{ 366 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 367 /* De-normalize Fixed U1.13 color data to different target bit depths. 0 is bypass*/ 368 int denorm_mode = 0; 369 370 switch (output_depth) { 371 case COLOR_DEPTH_666: 372 denorm_mode = 1; 373 break; 374 case COLOR_DEPTH_888: 375 denorm_mode = 2; 376 break; 377 case COLOR_DEPTH_999: 378 denorm_mode = 3; 379 break; 380 case COLOR_DEPTH_101010: 381 denorm_mode = 4; 382 break; 383 case COLOR_DEPTH_111111: 384 denorm_mode = 5; 385 break; 386 case COLOR_DEPTH_121212: 387 denorm_mode = 6; 388 break; 389 case COLOR_DEPTH_141414: 390 case COLOR_DEPTH_161616: 391 default: 392 /* not valid used case! */ 393 break; 394 } 395 396 REG_UPDATE(DENORM_CONTROL[opp_id], 397 MPC_OUT_DENORM_MODE, denorm_mode); 398} 399 400void mpc3_set_denorm_clamp( 401 struct mpc *mpc, 402 int opp_id, 403 struct mpc_denorm_clamp denorm_clamp) 404{ 405 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 406 407 /*program min and max clamp values for the pixel components*/ 408 REG_UPDATE_2(DENORM_CONTROL[opp_id], 409 MPC_OUT_DENORM_CLAMP_MAX_R_CR, denorm_clamp.clamp_max_r_cr, 410 MPC_OUT_DENORM_CLAMP_MIN_R_CR, denorm_clamp.clamp_min_r_cr); 411 REG_UPDATE_2(DENORM_CLAMP_G_Y[opp_id], 412 MPC_OUT_DENORM_CLAMP_MAX_G_Y, denorm_clamp.clamp_max_g_y, 413 MPC_OUT_DENORM_CLAMP_MIN_G_Y, denorm_clamp.clamp_min_g_y); 414 REG_UPDATE_2(DENORM_CLAMP_B_CB[opp_id], 415 MPC_OUT_DENORM_CLAMP_MAX_B_CB, denorm_clamp.clamp_max_b_cb, 416 MPC_OUT_DENORM_CLAMP_MIN_B_CB, denorm_clamp.clamp_min_b_cb); 417} 418 419static enum dc_lut_mode mpc3_get_shaper_current(struct mpc *mpc, uint32_t rmu_idx) 420{ 421 enum dc_lut_mode mode; 422 uint32_t state_mode; 423 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 424 425 REG_GET(SHAPER_CONTROL[rmu_idx], MPC_RMU_SHAPER_LUT_MODE_CURRENT, &state_mode); 426 427 switch (state_mode) { 428 case 0: 429 mode = LUT_BYPASS; 430 break; 431 case 1: 432 mode = LUT_RAM_A; 433 break; 434 case 2: 435 mode = LUT_RAM_B; 436 break; 437 default: 438 mode = LUT_BYPASS; 439 break; 440 } 441 442 return mode; 443} 444 445static void mpc3_configure_shaper_lut( 446 struct mpc *mpc, 447 bool is_ram_a, 448 uint32_t rmu_idx) 449{ 450 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 451 452 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx], 453 MPC_RMU_SHAPER_LUT_WRITE_EN_MASK, 7); 454 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx], 455 MPC_RMU_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 456 REG_SET(SHAPER_LUT_INDEX[rmu_idx], 0, MPC_RMU_SHAPER_LUT_INDEX, 0); 457} 458 459static void mpc3_program_shaper_luta_settings( 460 struct mpc *mpc, 461 const struct pwl_params *params, 462 uint32_t rmu_idx) 463{ 464 const struct gamma_curve *curve; 465 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 466 467 REG_SET_2(SHAPER_RAMA_START_CNTL_B[rmu_idx], 0, 468 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 469 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 470 REG_SET_2(SHAPER_RAMA_START_CNTL_G[rmu_idx], 0, 471 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x, 472 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 473 REG_SET_2(SHAPER_RAMA_START_CNTL_R[rmu_idx], 0, 474 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x, 475 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 476 477 REG_SET_2(SHAPER_RAMA_END_CNTL_B[rmu_idx], 0, 478 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 479 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 480 REG_SET_2(SHAPER_RAMA_END_CNTL_G[rmu_idx], 0, 481 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x, 482 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y); 483 REG_SET_2(SHAPER_RAMA_END_CNTL_R[rmu_idx], 0, 484 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x, 485 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y); 486 487 curve = params->arr_curve_points; 488 REG_SET_4(SHAPER_RAMA_REGION_0_1[rmu_idx], 0, 489 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 490 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 491 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 492 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 493 494 curve += 2; 495 REG_SET_4(SHAPER_RAMA_REGION_2_3[rmu_idx], 0, 496 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 497 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 498 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 499 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 500 501 curve += 2; 502 REG_SET_4(SHAPER_RAMA_REGION_4_5[rmu_idx], 0, 503 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 504 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 505 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 506 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 507 508 curve += 2; 509 REG_SET_4(SHAPER_RAMA_REGION_6_7[rmu_idx], 0, 510 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 511 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 512 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 513 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 514 515 curve += 2; 516 REG_SET_4(SHAPER_RAMA_REGION_8_9[rmu_idx], 0, 517 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 518 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 519 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 520 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 521 522 curve += 2; 523 REG_SET_4(SHAPER_RAMA_REGION_10_11[rmu_idx], 0, 524 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 525 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 526 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 527 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 528 529 curve += 2; 530 REG_SET_4(SHAPER_RAMA_REGION_12_13[rmu_idx], 0, 531 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 532 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 533 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 534 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 535 536 curve += 2; 537 REG_SET_4(SHAPER_RAMA_REGION_14_15[rmu_idx], 0, 538 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 539 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 540 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 541 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 542 543 544 curve += 2; 545 REG_SET_4(SHAPER_RAMA_REGION_16_17[rmu_idx], 0, 546 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 547 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 548 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 549 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 550 551 curve += 2; 552 REG_SET_4(SHAPER_RAMA_REGION_18_19[rmu_idx], 0, 553 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 554 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 555 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 556 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 557 558 curve += 2; 559 REG_SET_4(SHAPER_RAMA_REGION_20_21[rmu_idx], 0, 560 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 561 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 562 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 563 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 564 565 curve += 2; 566 REG_SET_4(SHAPER_RAMA_REGION_22_23[rmu_idx], 0, 567 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 568 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 569 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 570 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 571 572 curve += 2; 573 REG_SET_4(SHAPER_RAMA_REGION_24_25[rmu_idx], 0, 574 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 575 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 576 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 577 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 578 579 curve += 2; 580 REG_SET_4(SHAPER_RAMA_REGION_26_27[rmu_idx], 0, 581 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 582 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 583 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 584 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 585 586 curve += 2; 587 REG_SET_4(SHAPER_RAMA_REGION_28_29[rmu_idx], 0, 588 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 589 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 590 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 591 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 592 593 curve += 2; 594 REG_SET_4(SHAPER_RAMA_REGION_30_31[rmu_idx], 0, 595 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 596 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 597 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 598 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 599 600 curve += 2; 601 REG_SET_4(SHAPER_RAMA_REGION_32_33[rmu_idx], 0, 602 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 603 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 604 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 605 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 606} 607 608static void mpc3_program_shaper_lutb_settings( 609 struct mpc *mpc, 610 const struct pwl_params *params, 611 uint32_t rmu_idx) 612{ 613 const struct gamma_curve *curve; 614 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 615 616 REG_SET_2(SHAPER_RAMB_START_CNTL_B[rmu_idx], 0, 617 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 618 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 619 REG_SET_2(SHAPER_RAMB_START_CNTL_G[rmu_idx], 0, 620 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x, 621 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 622 REG_SET_2(SHAPER_RAMB_START_CNTL_R[rmu_idx], 0, 623 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x, 624 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 625 626 REG_SET_2(SHAPER_RAMB_END_CNTL_B[rmu_idx], 0, 627 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 628 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 629 REG_SET_2(SHAPER_RAMB_END_CNTL_G[rmu_idx], 0, 630 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x, 631 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y); 632 REG_SET_2(SHAPER_RAMB_END_CNTL_R[rmu_idx], 0, 633 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x, 634 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y); 635 636 curve = params->arr_curve_points; 637 REG_SET_4(SHAPER_RAMB_REGION_0_1[rmu_idx], 0, 638 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 639 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 640 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 641 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 642 643 curve += 2; 644 REG_SET_4(SHAPER_RAMB_REGION_2_3[rmu_idx], 0, 645 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 646 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 647 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 648 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 649 650 651 curve += 2; 652 REG_SET_4(SHAPER_RAMB_REGION_4_5[rmu_idx], 0, 653 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 654 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 655 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 656 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 657 658 curve += 2; 659 REG_SET_4(SHAPER_RAMB_REGION_6_7[rmu_idx], 0, 660 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 661 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 662 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 663 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 664 665 curve += 2; 666 REG_SET_4(SHAPER_RAMB_REGION_8_9[rmu_idx], 0, 667 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 668 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 669 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 670 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 671 672 curve += 2; 673 REG_SET_4(SHAPER_RAMB_REGION_10_11[rmu_idx], 0, 674 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 675 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 676 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 677 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 678 679 curve += 2; 680 REG_SET_4(SHAPER_RAMB_REGION_12_13[rmu_idx], 0, 681 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 682 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 683 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 684 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 685 686 curve += 2; 687 REG_SET_4(SHAPER_RAMB_REGION_14_15[rmu_idx], 0, 688 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 689 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 690 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 691 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 692 693 694 curve += 2; 695 REG_SET_4(SHAPER_RAMB_REGION_16_17[rmu_idx], 0, 696 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 697 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 698 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 699 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 700 701 curve += 2; 702 REG_SET_4(SHAPER_RAMB_REGION_18_19[rmu_idx], 0, 703 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 704 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 705 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 706 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 707 708 curve += 2; 709 REG_SET_4(SHAPER_RAMB_REGION_20_21[rmu_idx], 0, 710 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 711 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 712 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 713 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 714 715 curve += 2; 716 REG_SET_4(SHAPER_RAMB_REGION_22_23[rmu_idx], 0, 717 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 718 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 719 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 720 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 721 722 curve += 2; 723 REG_SET_4(SHAPER_RAMB_REGION_24_25[rmu_idx], 0, 724 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 725 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 726 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 727 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 728 729 curve += 2; 730 REG_SET_4(SHAPER_RAMB_REGION_26_27[rmu_idx], 0, 731 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 732 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 733 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 734 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 735 736 curve += 2; 737 REG_SET_4(SHAPER_RAMB_REGION_28_29[rmu_idx], 0, 738 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 739 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 740 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 741 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 742 743 curve += 2; 744 REG_SET_4(SHAPER_RAMB_REGION_30_31[rmu_idx], 0, 745 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 746 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 747 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 748 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 749 750 curve += 2; 751 REG_SET_4(SHAPER_RAMB_REGION_32_33[rmu_idx], 0, 752 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 753 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 754 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 755 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 756} 757 758 759static void mpc3_program_shaper_lut( 760 struct mpc *mpc, 761 const struct pwl_result_data *rgb, 762 uint32_t num, 763 uint32_t rmu_idx) 764{ 765 uint32_t i, red, green, blue; 766 uint32_t red_delta, green_delta, blue_delta; 767 uint32_t red_value, green_value, blue_value; 768 769 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 770 771 for (i = 0 ; i < num; i++) { 772 773 red = rgb[i].red_reg; 774 green = rgb[i].green_reg; 775 blue = rgb[i].blue_reg; 776 777 red_delta = rgb[i].delta_red_reg; 778 green_delta = rgb[i].delta_green_reg; 779 blue_delta = rgb[i].delta_blue_reg; 780 781 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff); 782 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff); 783 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff); 784 785 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, red_value); 786 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, green_value); 787 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, blue_value); 788 } 789 790} 791 792static void mpc3_power_on_shaper_3dlut( 793 struct mpc *mpc, 794 uint32_t rmu_idx, 795 bool power_on) 796{ 797 uint32_t power_status_shaper = 2; 798 uint32_t power_status_3dlut = 2; 799 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 800 int max_retries = 10; 801 802 if (rmu_idx == 0) { 803 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, 804 MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0); 805 /* wait for memory to fully power up */ 806 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 807 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); 808 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); 809 } 810 811 /*read status is not mandatory, it is just for debugging*/ 812 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper); 813 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut); 814 } else if (rmu_idx == 1) { 815 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, 816 MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0); 817 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 818 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); 819 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); 820 } 821 822 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper); 823 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut); 824 } 825 /*TODO Add rmu_idx == 2 for SIENNA_CICHLID */ 826 if (power_status_shaper != 0 && power_on == true) 827 BREAK_TO_DEBUGGER(); 828 829 if (power_status_3dlut != 0 && power_on == true) 830 BREAK_TO_DEBUGGER(); 831} 832 833 834 835bool mpc3_program_shaper( 836 struct mpc *mpc, 837 const struct pwl_params *params, 838 uint32_t rmu_idx) 839{ 840 enum dc_lut_mode current_mode; 841 enum dc_lut_mode next_mode; 842 843 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 844 845 if (params == NULL) { 846 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0); 847 return false; 848 } 849 850 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 851 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); 852 853 current_mode = mpc3_get_shaper_current(mpc, rmu_idx); 854 855 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 856 next_mode = LUT_RAM_B; 857 else 858 next_mode = LUT_RAM_A; 859 860 mpc3_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, rmu_idx); 861 862 if (next_mode == LUT_RAM_A) 863 mpc3_program_shaper_luta_settings(mpc, params, rmu_idx); 864 else 865 mpc3_program_shaper_lutb_settings(mpc, params, rmu_idx); 866 867 mpc3_program_shaper_lut( 868 mpc, params->rgb_resulted, params->hw_points_num, rmu_idx); 869 870 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2); 871 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); 872 873 return true; 874} 875 876static void mpc3_set_3dlut_mode( 877 struct mpc *mpc, 878 enum dc_lut_mode mode, 879 bool is_color_channel_12bits, 880 bool is_lut_size17x17x17, 881 uint32_t rmu_idx) 882{ 883 uint32_t lut_mode; 884 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 885 886 if (mode == LUT_BYPASS) 887 lut_mode = 0; 888 else if (mode == LUT_RAM_A) 889 lut_mode = 1; 890 else 891 lut_mode = 2; 892 893 REG_UPDATE_2(RMU_3DLUT_MODE[rmu_idx], 894 MPC_RMU_3DLUT_MODE, lut_mode, 895 MPC_RMU_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1); 896} 897 898static enum dc_lut_mode get3dlut_config( 899 struct mpc *mpc, 900 bool *is_17x17x17, 901 bool *is_12bits_color_channel, 902 int rmu_idx) 903{ 904 uint32_t i_mode, i_enable_10bits, lut_size; 905 enum dc_lut_mode mode; 906 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 907 908 REG_GET(RMU_3DLUT_MODE[rmu_idx], 909 MPC_RMU_3DLUT_MODE_CURRENT, &i_mode); 910 911 REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], 912 MPC_RMU_3DLUT_30BIT_EN, &i_enable_10bits); 913 914 switch (i_mode) { 915 case 0: 916 mode = LUT_BYPASS; 917 break; 918 case 1: 919 mode = LUT_RAM_A; 920 break; 921 case 2: 922 mode = LUT_RAM_B; 923 break; 924 default: 925 mode = LUT_BYPASS; 926 break; 927 } 928 if (i_enable_10bits > 0) 929 *is_12bits_color_channel = false; 930 else 931 *is_12bits_color_channel = true; 932 933 REG_GET(RMU_3DLUT_MODE[rmu_idx], MPC_RMU_3DLUT_SIZE, &lut_size); 934 935 if (lut_size == 0) 936 *is_17x17x17 = true; 937 else 938 *is_17x17x17 = false; 939 940 return mode; 941} 942 943static void mpc3_select_3dlut_ram( 944 struct mpc *mpc, 945 enum dc_lut_mode mode, 946 bool is_color_channel_12bits, 947 uint32_t rmu_idx) 948{ 949 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 950 951 REG_UPDATE_2(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], 952 MPC_RMU_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, 953 MPC_RMU_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1); 954} 955 956static void mpc3_select_3dlut_ram_mask( 957 struct mpc *mpc, 958 uint32_t ram_selection_mask, 959 uint32_t rmu_idx) 960{ 961 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 962 963 REG_UPDATE(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], MPC_RMU_3DLUT_WRITE_EN_MASK, 964 ram_selection_mask); 965 REG_SET(RMU_3DLUT_INDEX[rmu_idx], 0, MPC_RMU_3DLUT_INDEX, 0); 966} 967 968static void mpc3_set3dlut_ram12( 969 struct mpc *mpc, 970 const struct dc_rgb *lut, 971 uint32_t entries, 972 uint32_t rmu_idx) 973{ 974 uint32_t i, red, green, blue, red1, green1, blue1; 975 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 976 977 for (i = 0 ; i < entries; i += 2) { 978 red = lut[i].red<<4; 979 green = lut[i].green<<4; 980 blue = lut[i].blue<<4; 981 red1 = lut[i+1].red<<4; 982 green1 = lut[i+1].green<<4; 983 blue1 = lut[i+1].blue<<4; 984 985 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 986 MPC_RMU_3DLUT_DATA0, red, 987 MPC_RMU_3DLUT_DATA1, red1); 988 989 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 990 MPC_RMU_3DLUT_DATA0, green, 991 MPC_RMU_3DLUT_DATA1, green1); 992 993 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 994 MPC_RMU_3DLUT_DATA0, blue, 995 MPC_RMU_3DLUT_DATA1, blue1); 996 } 997} 998 999static void mpc3_set3dlut_ram10( 1000 struct mpc *mpc, 1001 const struct dc_rgb *lut, 1002 uint32_t entries, 1003 uint32_t rmu_idx) 1004{ 1005 uint32_t i, red, green, blue, value; 1006 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1007 1008 for (i = 0; i < entries; i++) { 1009 red = lut[i].red; 1010 green = lut[i].green; 1011 blue = lut[i].blue; 1012 //should we shift red 22bit and green 12? ask Nvenko 1013 value = (red<<20) | (green<<10) | blue; 1014 1015 REG_SET(RMU_3DLUT_DATA_30BIT[rmu_idx], 0, MPC_RMU_3DLUT_DATA_30BIT, value); 1016 } 1017 1018} 1019 1020 1021void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst) 1022{ 1023 mpcc->mpcc_id = mpcc_inst; 1024 mpcc->dpp_id = 0xf; 1025 mpcc->mpcc_bot = NULL; 1026 mpcc->blnd_cfg.overlap_only = false; 1027 mpcc->blnd_cfg.global_alpha = 0xff; 1028 mpcc->blnd_cfg.global_gain = 0xff; 1029 mpcc->blnd_cfg.background_color_bpc = 4; 1030 mpcc->blnd_cfg.bottom_gain_mode = 0; 1031 mpcc->blnd_cfg.top_gain = 0x1f000; 1032 mpcc->blnd_cfg.bottom_inside_gain = 0x1f000; 1033 mpcc->blnd_cfg.bottom_outside_gain = 0x1f000; 1034 mpcc->sm_cfg.enable = false; 1035 mpcc->shared_bottom = false; 1036} 1037 1038static void program_gamut_remap( 1039 struct dcn30_mpc *mpc30, 1040 int mpcc_id, 1041 const uint16_t *regval, 1042 int select) 1043{ 1044 uint16_t selection = 0; 1045 struct color_matrices_reg gam_regs; 1046 1047 if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 1048 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, 1049 MPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS); 1050 return; 1051 } 1052 switch (select) { 1053 case GAMUT_REMAP_COEFF: 1054 selection = 1; 1055 break; 1056 /*this corresponds to GAMUT_REMAP coefficients set B 1057 * we don't have common coefficient sets in dcn3ag/dcn3 1058 */ 1059 case GAMUT_REMAP_COMA_COEFF: 1060 selection = 2; 1061 break; 1062 default: 1063 break; 1064 } 1065 1066 gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 1067 gam_regs.masks.csc_c11 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 1068 gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 1069 gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 1070 1071 1072 if (select == GAMUT_REMAP_COEFF) { 1073 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]); 1074 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]); 1075 1076 cm_helper_program_color_matrices( 1077 mpc30->base.ctx, 1078 regval, 1079 &gam_regs); 1080 1081 } else if (select == GAMUT_REMAP_COMA_COEFF) { 1082 1083 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]); 1084 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]); 1085 1086 cm_helper_program_color_matrices( 1087 mpc30->base.ctx, 1088 regval, 1089 &gam_regs); 1090 1091 } 1092 //select coefficient set to use 1093 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, 1094 MPCC_GAMUT_REMAP_MODE, selection); 1095} 1096 1097void mpc3_set_gamut_remap( 1098 struct mpc *mpc, 1099 int mpcc_id, 1100 const struct mpc_grph_gamut_adjustment *adjust) 1101{ 1102 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1103 int i = 0; 1104 int gamut_mode; 1105 1106 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 1107 program_gamut_remap(mpc30, mpcc_id, NULL, GAMUT_REMAP_BYPASS); 1108 else { 1109 struct fixed31_32 arr_matrix[12]; 1110 uint16_t arr_reg_val[12]; 1111 1112 for (i = 0; i < 12; i++) 1113 arr_matrix[i] = adjust->temperature_matrix[i]; 1114 1115 convert_float_matrix( 1116 arr_reg_val, arr_matrix, 12); 1117 1118 //current coefficient set in use 1119 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, &gamut_mode); 1120 1121 if (gamut_mode == 0) 1122 gamut_mode = 1; //use coefficient set A 1123 else if (gamut_mode == 1) 1124 gamut_mode = 2; 1125 else 1126 gamut_mode = 1; 1127 1128 program_gamut_remap(mpc30, mpcc_id, arr_reg_val, gamut_mode); 1129 } 1130} 1131 1132static void read_gamut_remap(struct dcn30_mpc *mpc30, 1133 int mpcc_id, 1134 uint16_t *regval, 1135 uint32_t *select) 1136{ 1137 struct color_matrices_reg gam_regs; 1138 1139 //current coefficient set in use 1140 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, select); 1141 1142 gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 1143 gam_regs.masks.csc_c11 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 1144 gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 1145 gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 1146 1147 if (*select == GAMUT_REMAP_COEFF) { 1148 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]); 1149 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]); 1150 1151 cm_helper_read_color_matrices( 1152 mpc30->base.ctx, 1153 regval, 1154 &gam_regs); 1155 1156 } else if (*select == GAMUT_REMAP_COMA_COEFF) { 1157 1158 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]); 1159 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]); 1160 1161 cm_helper_read_color_matrices( 1162 mpc30->base.ctx, 1163 regval, 1164 &gam_regs); 1165 1166 } 1167 1168} 1169 1170void mpc3_get_gamut_remap(struct mpc *mpc, 1171 int mpcc_id, 1172 struct mpc_grph_gamut_adjustment *adjust) 1173{ 1174 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1175 uint16_t arr_reg_val[12]; 1176 int select; 1177 1178 read_gamut_remap(mpc30, mpcc_id, arr_reg_val, &select); 1179 1180 if (select == GAMUT_REMAP_BYPASS) { 1181 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 1182 return; 1183 } 1184 1185 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 1186 convert_hw_matrix(adjust->temperature_matrix, 1187 arr_reg_val, ARRAY_SIZE(arr_reg_val)); 1188} 1189 1190bool mpc3_program_3dlut( 1191 struct mpc *mpc, 1192 const struct tetrahedral_params *params, 1193 int rmu_idx) 1194{ 1195 enum dc_lut_mode mode; 1196 bool is_17x17x17; 1197 bool is_12bits_color_channel; 1198 const struct dc_rgb *lut0; 1199 const struct dc_rgb *lut1; 1200 const struct dc_rgb *lut2; 1201 const struct dc_rgb *lut3; 1202 int lut_size0; 1203 int lut_size; 1204 1205 if (params == NULL) { 1206 mpc3_set_3dlut_mode(mpc, LUT_BYPASS, false, false, rmu_idx); 1207 return false; 1208 } 1209 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); 1210 1211 mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, rmu_idx); 1212 1213 if (mode == LUT_BYPASS || mode == LUT_RAM_B) 1214 mode = LUT_RAM_A; 1215 else 1216 mode = LUT_RAM_B; 1217 1218 is_17x17x17 = !params->use_tetrahedral_9; 1219 is_12bits_color_channel = params->use_12bits; 1220 if (is_17x17x17) { 1221 lut0 = params->tetrahedral_17.lut0; 1222 lut1 = params->tetrahedral_17.lut1; 1223 lut2 = params->tetrahedral_17.lut2; 1224 lut3 = params->tetrahedral_17.lut3; 1225 lut_size0 = sizeof(params->tetrahedral_17.lut0)/ 1226 sizeof(params->tetrahedral_17.lut0[0]); 1227 lut_size = sizeof(params->tetrahedral_17.lut1)/ 1228 sizeof(params->tetrahedral_17.lut1[0]); 1229 } else { 1230 lut0 = params->tetrahedral_9.lut0; 1231 lut1 = params->tetrahedral_9.lut1; 1232 lut2 = params->tetrahedral_9.lut2; 1233 lut3 = params->tetrahedral_9.lut3; 1234 lut_size0 = sizeof(params->tetrahedral_9.lut0)/ 1235 sizeof(params->tetrahedral_9.lut0[0]); 1236 lut_size = sizeof(params->tetrahedral_9.lut1)/ 1237 sizeof(params->tetrahedral_9.lut1[0]); 1238 } 1239 1240 mpc3_select_3dlut_ram(mpc, mode, 1241 is_12bits_color_channel, rmu_idx); 1242 mpc3_select_3dlut_ram_mask(mpc, 0x1, rmu_idx); 1243 if (is_12bits_color_channel) 1244 mpc3_set3dlut_ram12(mpc, lut0, lut_size0, rmu_idx); 1245 else 1246 mpc3_set3dlut_ram10(mpc, lut0, lut_size0, rmu_idx); 1247 1248 mpc3_select_3dlut_ram_mask(mpc, 0x2, rmu_idx); 1249 if (is_12bits_color_channel) 1250 mpc3_set3dlut_ram12(mpc, lut1, lut_size, rmu_idx); 1251 else 1252 mpc3_set3dlut_ram10(mpc, lut1, lut_size, rmu_idx); 1253 1254 mpc3_select_3dlut_ram_mask(mpc, 0x4, rmu_idx); 1255 if (is_12bits_color_channel) 1256 mpc3_set3dlut_ram12(mpc, lut2, lut_size, rmu_idx); 1257 else 1258 mpc3_set3dlut_ram10(mpc, lut2, lut_size, rmu_idx); 1259 1260 mpc3_select_3dlut_ram_mask(mpc, 0x8, rmu_idx); 1261 if (is_12bits_color_channel) 1262 mpc3_set3dlut_ram12(mpc, lut3, lut_size, rmu_idx); 1263 else 1264 mpc3_set3dlut_ram10(mpc, lut3, lut_size, rmu_idx); 1265 1266 mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel, 1267 is_17x17x17, rmu_idx); 1268 1269 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 1270 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); 1271 1272 return true; 1273} 1274 1275void mpc3_set_output_csc( 1276 struct mpc *mpc, 1277 int opp_id, 1278 const uint16_t *regval, 1279 enum mpc_output_csc_mode ocsc_mode) 1280{ 1281 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1282 struct color_matrices_reg ocsc_regs; 1283 1284 REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0); 1285 1286 REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); 1287 1288 if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) 1289 return; 1290 1291 if (regval == NULL) { 1292 BREAK_TO_DEBUGGER(); 1293 return; 1294 } 1295 1296 ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A; 1297 ocsc_regs.masks.csc_c11 = mpc30->mpc_mask->MPC_OCSC_C11_A; 1298 ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A; 1299 ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A; 1300 1301 if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) { 1302 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]); 1303 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]); 1304 } else { 1305 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]); 1306 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]); 1307 } 1308 cm_helper_program_color_matrices( 1309 mpc30->base.ctx, 1310 regval, 1311 &ocsc_regs); 1312} 1313 1314void mpc3_set_ocsc_default( 1315 struct mpc *mpc, 1316 int opp_id, 1317 enum dc_color_space color_space, 1318 enum mpc_output_csc_mode ocsc_mode) 1319{ 1320 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1321 uint32_t arr_size; 1322 struct color_matrices_reg ocsc_regs; 1323 const uint16_t *regval = NULL; 1324 1325 REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0); 1326 1327 REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); 1328 if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) 1329 return; 1330 1331 regval = find_color_matrix(color_space, &arr_size); 1332 1333 if (regval == NULL) { 1334 BREAK_TO_DEBUGGER(); 1335 return; 1336 } 1337 1338 ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A; 1339 ocsc_regs.masks.csc_c11 = mpc30->mpc_mask->MPC_OCSC_C11_A; 1340 ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A; 1341 ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A; 1342 1343 1344 if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) { 1345 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]); 1346 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]); 1347 } else { 1348 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]); 1349 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]); 1350 } 1351 1352 cm_helper_program_color_matrices( 1353 mpc30->base.ctx, 1354 regval, 1355 &ocsc_regs); 1356} 1357 1358void mpc3_set_rmu_mux( 1359 struct mpc *mpc, 1360 int rmu_idx, 1361 int value) 1362{ 1363 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1364 1365 if (rmu_idx == 0) 1366 REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU0_MUX, value); 1367 else if (rmu_idx == 1) 1368 REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU1_MUX, value); 1369 1370} 1371 1372uint32_t mpc3_get_rmu_mux_status( 1373 struct mpc *mpc, 1374 int rmu_idx) 1375{ 1376 uint32_t status = 0xf; 1377 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1378 1379 if (rmu_idx == 0) 1380 REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &status); 1381 else if (rmu_idx == 1) 1382 REG_GET(MPC_RMU_CONTROL, MPC_RMU1_MUX_STATUS, &status); 1383 1384 return status; 1385} 1386 1387uint32_t mpcc3_acquire_rmu(struct mpc *mpc, int mpcc_id, int rmu_idx) 1388{ 1389 uint32_t rmu_status; 1390 1391 //determine if this mpcc is already multiplexed to an RMU unit 1392 rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx); 1393 if (rmu_status == mpcc_id) 1394 //return rmu_idx of pre_acquired rmu unit 1395 return rmu_idx; 1396 1397 if (rmu_status == 0xf) {//rmu unit is disabled 1398 mpc3_set_rmu_mux(mpc, rmu_idx, mpcc_id); 1399 return rmu_idx; 1400 } 1401 1402 //no vacant RMU units or invalid parameters acquire_post_bldn_3dlut 1403 return -1; 1404} 1405 1406static int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) 1407{ 1408 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1409 int rmu_idx; 1410 uint32_t rmu_status; 1411 int released_rmu = -1; 1412 1413 for (rmu_idx = 0; rmu_idx < mpc30->num_rmu; rmu_idx++) { 1414 rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx); 1415 if (rmu_status == mpcc_id) { 1416 mpc3_set_rmu_mux(mpc, rmu_idx, 0xf); 1417 released_rmu = rmu_idx; 1418 break; 1419 } 1420 } 1421 return released_rmu; 1422 1423} 1424 1425static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc) 1426{ 1427 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1428 int mpcc_id; 1429 1430 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 1431 if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) { 1432 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3); 1433 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, 3); 1434 } 1435 1436 if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) { 1437 for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++) 1438 REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3); 1439 } 1440 } 1441} 1442 1443static void mpc3_read_mpcc_state( 1444 struct mpc *mpc, 1445 int mpcc_inst, 1446 struct mpcc_state *s) 1447{ 1448 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1449 uint32_t rmu_status = 0xf; 1450 1451 REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, &s->opp_id); 1452 REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, &s->dpp_id); 1453 REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, &s->bot_mpcc_id); 1454 REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, &s->mode, 1455 MPCC_ALPHA_BLND_MODE, &s->alpha_mode, 1456 MPCC_ALPHA_MULTIPLIED_MODE, &s->pre_multiplied_alpha, 1457 MPCC_BLND_ACTIVE_OVERLAP_ONLY, &s->overlap_only); 1458 REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, &s->idle, 1459 MPCC_BUSY, &s->busy); 1460 1461 /* Color blocks state */ 1462 REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &rmu_status); 1463 1464 if (rmu_status == mpcc_inst) { 1465 REG_GET(SHAPER_CONTROL[0], 1466 MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode); 1467 REG_GET(RMU_3DLUT_MODE[0], 1468 MPC_RMU_3DLUT_MODE_CURRENT, &s->lut3d_mode); 1469 REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[0], 1470 MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth); 1471 REG_GET(RMU_3DLUT_MODE[0], 1472 MPC_RMU_3DLUT_SIZE, &s->lut3d_size); 1473 } else { 1474 REG_GET(SHAPER_CONTROL[1], 1475 MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode); 1476 REG_GET(RMU_3DLUT_MODE[1], 1477 MPC_RMU_3DLUT_MODE_CURRENT, &s->lut3d_mode); 1478 REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[1], 1479 MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth); 1480 REG_GET(RMU_3DLUT_MODE[1], 1481 MPC_RMU_3DLUT_SIZE, &s->lut3d_size); 1482 } 1483 1484 REG_GET_2(MPCC_OGAM_CONTROL[mpcc_inst], 1485 MPCC_OGAM_MODE_CURRENT, &s->rgam_mode, 1486 MPCC_OGAM_SELECT_CURRENT, &s->rgam_lut); 1487} 1488 1489static const struct mpc_funcs dcn30_mpc_funcs = { 1490 .read_mpcc_state = mpc3_read_mpcc_state, 1491 .insert_plane = mpc1_insert_plane, 1492 .remove_mpcc = mpc1_remove_mpcc, 1493 .mpc_init = mpc1_mpc_init, 1494 .mpc_init_single_inst = mpc1_mpc_init_single_inst, 1495 .update_blending = mpc2_update_blending, 1496 .cursor_lock = mpc1_cursor_lock, 1497 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, 1498 .wait_for_idle = mpc2_assert_idle_mpcc, 1499 .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, 1500 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, 1501 .set_denorm = mpc3_set_denorm, 1502 .set_denorm_clamp = mpc3_set_denorm_clamp, 1503 .set_output_csc = mpc3_set_output_csc, 1504 .set_ocsc_default = mpc3_set_ocsc_default, 1505 .set_output_gamma = mpc3_set_output_gamma, 1506 .insert_plane_to_secondary = NULL, 1507 .remove_mpcc_from_secondary = NULL, 1508 .set_dwb_mux = mpc3_set_dwb_mux, 1509 .disable_dwb_mux = mpc3_disable_dwb_mux, 1510 .is_dwb_idle = mpc3_is_dwb_idle, 1511 .set_out_rate_control = mpc3_set_out_rate_control, 1512 .set_gamut_remap = mpc3_set_gamut_remap, 1513 .program_shaper = mpc3_program_shaper, 1514 .acquire_rmu = mpcc3_acquire_rmu, 1515 .program_3dlut = mpc3_program_3dlut, 1516 .release_rmu = mpcc3_release_rmu, 1517 .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut, 1518 .get_mpc_out_mux = mpc1_get_mpc_out_mux, 1519 .set_bg_color = mpc1_set_bg_color, 1520 .set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode, 1521}; 1522 1523void dcn30_mpc_construct(struct dcn30_mpc *mpc30, 1524 struct dc_context *ctx, 1525 const struct dcn30_mpc_registers *mpc_regs, 1526 const struct dcn30_mpc_shift *mpc_shift, 1527 const struct dcn30_mpc_mask *mpc_mask, 1528 int num_mpcc, 1529 int num_rmu) 1530{ 1531 int i; 1532 1533 mpc30->base.ctx = ctx; 1534 1535 mpc30->base.funcs = &dcn30_mpc_funcs; 1536 1537 mpc30->mpc_regs = mpc_regs; 1538 mpc30->mpc_shift = mpc_shift; 1539 mpc30->mpc_mask = mpc_mask; 1540 1541 mpc30->mpcc_in_use_mask = 0; 1542 mpc30->num_mpcc = num_mpcc; 1543 mpc30->num_rmu = num_rmu; 1544 1545 for (i = 0; i < MAX_MPCC; i++) 1546 mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i); 1547} 1548 1549