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 47 static bool 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 62 static void 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 73 static void 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 83 static void 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 102 static enum 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], 113 MPCC_OGAM_MODE_CURRENT, &state_mode, 114 MPCC_OGAM_SELECT_CURRENT, &state_ram_lut_in_use); 115 116 switch (state_mode) { 117 case 0: 118 mode = LUT_BYPASS; 119 break; 120 case 2: 121 switch (state_ram_lut_in_use) { 122 case 0: 123 mode = LUT_RAM_A; 124 break; 125 case 1: 126 mode = LUT_RAM_B; 127 break; 128 default: 129 mode = LUT_BYPASS; 130 break; 131 } 132 break; 133 default: 134 mode = LUT_BYPASS; 135 break; 136 } 137 return mode; 138 } 139 140 static void 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 160 static 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 173 static 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 207 static 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 240 static 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 274 static 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 uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg; 282 uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg; 283 uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg; 284 285 /*the entries of DCN3AG gamma LUTs take 18bit base values as opposed to 286 *38 base+delta values per entry in earlier DCN architectures 287 *last base value for our lut is compute by adding the last base value 288 *in our data + last delta 289 */ 290 291 if (is_rgb_equal(rgb, num)) { 292 for (i = 0 ; i < num; i++) 293 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg); 294 295 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red); 296 297 } else { 298 299 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 300 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 4); 301 302 for (i = 0 ; i < num; i++) 303 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg); 304 305 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red); 306 307 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0); 308 309 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 310 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 2); 311 312 for (i = 0 ; i < num; i++) 313 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg); 314 315 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_green); 316 317 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0); 318 319 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id], 320 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 1); 321 322 for (i = 0 ; i < num; i++) 323 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg); 324 325 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_blue); 326 } 327 328 } 329 330 void mpc3_set_output_gamma( 331 struct mpc *mpc, 332 int mpcc_id, 333 const struct pwl_params *params) 334 { 335 enum dc_lut_mode current_mode; 336 enum dc_lut_mode next_mode; 337 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 338 339 if (mpc->ctx->dc->debug.cm_in_bypass) { 340 REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0); 341 return; 342 } 343 344 if (params == NULL) { //disable OGAM 345 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 0); 346 return; 347 } 348 //enable OGAM 349 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 2); 350 351 current_mode = mpc3_get_ogam_current(mpc, mpcc_id); 352 if (current_mode == LUT_BYPASS) 353 next_mode = LUT_RAM_A; 354 else if (current_mode == LUT_RAM_A) 355 next_mode = LUT_RAM_B; 356 else 357 next_mode = LUT_RAM_A; 358 359 mpc3_power_on_ogam_lut(mpc, mpcc_id, true); 360 mpc3_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A); 361 362 if (next_mode == LUT_RAM_A) 363 mpc3_program_luta(mpc, mpcc_id, params); 364 else 365 mpc3_program_lutb(mpc, mpcc_id, params); 366 367 mpc3_program_ogam_pwl( 368 mpc, mpcc_id, params->rgb_resulted, params->hw_points_num); 369 370 /*we need to program 2 fields here as apposed to 1*/ 371 REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id], 372 MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1); 373 374 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 375 mpc3_power_on_ogam_lut(mpc, mpcc_id, false); 376 } 377 378 void mpc3_set_denorm( 379 struct mpc *mpc, 380 int opp_id, 381 enum dc_color_depth output_depth) 382 { 383 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 384 /* De-normalize Fixed U1.13 color data to different target bit depths. 0 is bypass*/ 385 int denorm_mode = 0; 386 387 switch (output_depth) { 388 case COLOR_DEPTH_666: 389 denorm_mode = 1; 390 break; 391 case COLOR_DEPTH_888: 392 denorm_mode = 2; 393 break; 394 case COLOR_DEPTH_999: 395 denorm_mode = 3; 396 break; 397 case COLOR_DEPTH_101010: 398 denorm_mode = 4; 399 break; 400 case COLOR_DEPTH_111111: 401 denorm_mode = 5; 402 break; 403 case COLOR_DEPTH_121212: 404 denorm_mode = 6; 405 break; 406 case COLOR_DEPTH_141414: 407 case COLOR_DEPTH_161616: 408 default: 409 /* not valid used case! */ 410 break; 411 } 412 413 REG_UPDATE(DENORM_CONTROL[opp_id], 414 MPC_OUT_DENORM_MODE, denorm_mode); 415 } 416 417 void mpc3_set_denorm_clamp( 418 struct mpc *mpc, 419 int opp_id, 420 struct mpc_denorm_clamp denorm_clamp) 421 { 422 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 423 424 /*program min and max clamp values for the pixel components*/ 425 REG_UPDATE_2(DENORM_CONTROL[opp_id], 426 MPC_OUT_DENORM_CLAMP_MAX_R_CR, denorm_clamp.clamp_max_r_cr, 427 MPC_OUT_DENORM_CLAMP_MIN_R_CR, denorm_clamp.clamp_min_r_cr); 428 REG_UPDATE_2(DENORM_CLAMP_G_Y[opp_id], 429 MPC_OUT_DENORM_CLAMP_MAX_G_Y, denorm_clamp.clamp_max_g_y, 430 MPC_OUT_DENORM_CLAMP_MIN_G_Y, denorm_clamp.clamp_min_g_y); 431 REG_UPDATE_2(DENORM_CLAMP_B_CB[opp_id], 432 MPC_OUT_DENORM_CLAMP_MAX_B_CB, denorm_clamp.clamp_max_b_cb, 433 MPC_OUT_DENORM_CLAMP_MIN_B_CB, denorm_clamp.clamp_min_b_cb); 434 } 435 436 static enum dc_lut_mode mpc3_get_shaper_current(struct mpc *mpc, uint32_t rmu_idx) 437 { 438 enum dc_lut_mode mode; 439 uint32_t state_mode; 440 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 441 442 REG_GET(SHAPER_CONTROL[rmu_idx], 443 MPC_RMU_SHAPER_LUT_MODE_CURRENT, &state_mode); 444 445 switch (state_mode) { 446 case 0: 447 mode = LUT_BYPASS; 448 break; 449 case 1: 450 mode = LUT_RAM_A; 451 break; 452 case 2: 453 mode = LUT_RAM_B; 454 break; 455 default: 456 mode = LUT_BYPASS; 457 break; 458 } 459 return mode; 460 } 461 462 static void mpc3_configure_shaper_lut( 463 struct mpc *mpc, 464 bool is_ram_a, 465 uint32_t rmu_idx) 466 { 467 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 468 469 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx], 470 MPC_RMU_SHAPER_LUT_WRITE_EN_MASK, 7); 471 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx], 472 MPC_RMU_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1); 473 REG_SET(SHAPER_LUT_INDEX[rmu_idx], 0, MPC_RMU_SHAPER_LUT_INDEX, 0); 474 } 475 476 static void mpc3_program_shaper_luta_settings( 477 struct mpc *mpc, 478 const struct pwl_params *params, 479 uint32_t rmu_idx) 480 { 481 const struct gamma_curve *curve; 482 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 483 484 REG_SET_2(SHAPER_RAMA_START_CNTL_B[rmu_idx], 0, 485 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 486 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 487 REG_SET_2(SHAPER_RAMA_START_CNTL_G[rmu_idx], 0, 488 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x, 489 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 490 REG_SET_2(SHAPER_RAMA_START_CNTL_R[rmu_idx], 0, 491 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x, 492 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 493 494 REG_SET_2(SHAPER_RAMA_END_CNTL_B[rmu_idx], 0, 495 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 496 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 497 REG_SET_2(SHAPER_RAMA_END_CNTL_G[rmu_idx], 0, 498 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x, 499 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y); 500 REG_SET_2(SHAPER_RAMA_END_CNTL_R[rmu_idx], 0, 501 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x, 502 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y); 503 504 curve = params->arr_curve_points; 505 REG_SET_4(SHAPER_RAMA_REGION_0_1[rmu_idx], 0, 506 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 507 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 508 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 509 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 510 511 curve += 2; 512 REG_SET_4(SHAPER_RAMA_REGION_2_3[rmu_idx], 0, 513 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 514 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 515 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 516 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 517 518 curve += 2; 519 REG_SET_4(SHAPER_RAMA_REGION_4_5[rmu_idx], 0, 520 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 521 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 522 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 523 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 524 525 curve += 2; 526 REG_SET_4(SHAPER_RAMA_REGION_6_7[rmu_idx], 0, 527 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 528 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 529 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 530 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 531 532 curve += 2; 533 REG_SET_4(SHAPER_RAMA_REGION_8_9[rmu_idx], 0, 534 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 535 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 536 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 537 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 538 539 curve += 2; 540 REG_SET_4(SHAPER_RAMA_REGION_10_11[rmu_idx], 0, 541 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 542 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 543 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 544 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 545 546 curve += 2; 547 REG_SET_4(SHAPER_RAMA_REGION_12_13[rmu_idx], 0, 548 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 549 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 550 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 551 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 552 553 curve += 2; 554 REG_SET_4(SHAPER_RAMA_REGION_14_15[rmu_idx], 0, 555 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 556 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 557 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 558 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 559 560 561 curve += 2; 562 REG_SET_4(SHAPER_RAMA_REGION_16_17[rmu_idx], 0, 563 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 564 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 565 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 566 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 567 568 curve += 2; 569 REG_SET_4(SHAPER_RAMA_REGION_18_19[rmu_idx], 0, 570 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 571 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 572 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 573 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 574 575 curve += 2; 576 REG_SET_4(SHAPER_RAMA_REGION_20_21[rmu_idx], 0, 577 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 578 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 579 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 580 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 581 582 curve += 2; 583 REG_SET_4(SHAPER_RAMA_REGION_22_23[rmu_idx], 0, 584 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 585 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 586 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 587 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 588 589 curve += 2; 590 REG_SET_4(SHAPER_RAMA_REGION_24_25[rmu_idx], 0, 591 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 592 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 593 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 594 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 595 596 curve += 2; 597 REG_SET_4(SHAPER_RAMA_REGION_26_27[rmu_idx], 0, 598 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 599 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 600 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 601 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 602 603 curve += 2; 604 REG_SET_4(SHAPER_RAMA_REGION_28_29[rmu_idx], 0, 605 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 606 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 607 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 608 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 609 610 curve += 2; 611 REG_SET_4(SHAPER_RAMA_REGION_30_31[rmu_idx], 0, 612 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 613 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 614 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 615 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 616 617 curve += 2; 618 REG_SET_4(SHAPER_RAMA_REGION_32_33[rmu_idx], 0, 619 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 620 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 621 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 622 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 623 } 624 625 static void mpc3_program_shaper_lutb_settings( 626 struct mpc *mpc, 627 const struct pwl_params *params, 628 uint32_t rmu_idx) 629 { 630 const struct gamma_curve *curve; 631 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 632 633 REG_SET_2(SHAPER_RAMB_START_CNTL_B[rmu_idx], 0, 634 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x, 635 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 636 REG_SET_2(SHAPER_RAMB_START_CNTL_G[rmu_idx], 0, 637 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x, 638 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 639 REG_SET_2(SHAPER_RAMB_START_CNTL_R[rmu_idx], 0, 640 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x, 641 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0); 642 643 REG_SET_2(SHAPER_RAMB_END_CNTL_B[rmu_idx], 0, 644 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x, 645 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y); 646 REG_SET_2(SHAPER_RAMB_END_CNTL_G[rmu_idx], 0, 647 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x, 648 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y); 649 REG_SET_2(SHAPER_RAMB_END_CNTL_R[rmu_idx], 0, 650 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x, 651 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y); 652 653 curve = params->arr_curve_points; 654 REG_SET_4(SHAPER_RAMB_REGION_0_1[rmu_idx], 0, 655 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 656 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 657 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 658 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 659 660 curve += 2; 661 REG_SET_4(SHAPER_RAMB_REGION_2_3[rmu_idx], 0, 662 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 663 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 664 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 665 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 666 667 668 curve += 2; 669 REG_SET_4(SHAPER_RAMB_REGION_4_5[rmu_idx], 0, 670 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 671 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 672 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 673 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 674 675 curve += 2; 676 REG_SET_4(SHAPER_RAMB_REGION_6_7[rmu_idx], 0, 677 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 678 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 679 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 680 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 681 682 curve += 2; 683 REG_SET_4(SHAPER_RAMB_REGION_8_9[rmu_idx], 0, 684 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 685 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 686 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 687 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 688 689 curve += 2; 690 REG_SET_4(SHAPER_RAMB_REGION_10_11[rmu_idx], 0, 691 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 692 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 693 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 694 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 695 696 curve += 2; 697 REG_SET_4(SHAPER_RAMB_REGION_12_13[rmu_idx], 0, 698 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 699 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 700 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 701 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 702 703 curve += 2; 704 REG_SET_4(SHAPER_RAMB_REGION_14_15[rmu_idx], 0, 705 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 706 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 707 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 708 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 709 710 711 curve += 2; 712 REG_SET_4(SHAPER_RAMB_REGION_16_17[rmu_idx], 0, 713 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 714 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 715 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 716 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 717 718 curve += 2; 719 REG_SET_4(SHAPER_RAMB_REGION_18_19[rmu_idx], 0, 720 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 721 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 722 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 723 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 724 725 curve += 2; 726 REG_SET_4(SHAPER_RAMB_REGION_20_21[rmu_idx], 0, 727 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 728 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 729 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 730 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 731 732 curve += 2; 733 REG_SET_4(SHAPER_RAMB_REGION_22_23[rmu_idx], 0, 734 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 735 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 736 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 737 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 738 739 curve += 2; 740 REG_SET_4(SHAPER_RAMB_REGION_24_25[rmu_idx], 0, 741 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 742 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 743 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 744 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 745 746 curve += 2; 747 REG_SET_4(SHAPER_RAMB_REGION_26_27[rmu_idx], 0, 748 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 749 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 750 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 751 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 752 753 curve += 2; 754 REG_SET_4(SHAPER_RAMB_REGION_28_29[rmu_idx], 0, 755 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 756 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 757 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 758 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 759 760 curve += 2; 761 REG_SET_4(SHAPER_RAMB_REGION_30_31[rmu_idx], 0, 762 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 763 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 764 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 765 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 766 767 curve += 2; 768 REG_SET_4(SHAPER_RAMB_REGION_32_33[rmu_idx], 0, 769 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset, 770 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num, 771 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset, 772 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num); 773 } 774 775 776 static void mpc3_program_shaper_lut( 777 struct mpc *mpc, 778 const struct pwl_result_data *rgb, 779 uint32_t num, 780 uint32_t rmu_idx) 781 { 782 uint32_t i, red, green, blue; 783 uint32_t red_delta, green_delta, blue_delta; 784 uint32_t red_value, green_value, blue_value; 785 786 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 787 788 for (i = 0 ; i < num; i++) { 789 790 red = rgb[i].red_reg; 791 green = rgb[i].green_reg; 792 blue = rgb[i].blue_reg; 793 794 red_delta = rgb[i].delta_red_reg; 795 green_delta = rgb[i].delta_green_reg; 796 blue_delta = rgb[i].delta_blue_reg; 797 798 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff); 799 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff); 800 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff); 801 802 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, red_value); 803 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, green_value); 804 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, blue_value); 805 } 806 807 } 808 809 static void mpc3_power_on_shaper_3dlut( 810 struct mpc *mpc, 811 uint32_t rmu_idx, 812 bool power_on) 813 { 814 uint32_t power_status_shaper = 2; 815 uint32_t power_status_3dlut = 2; 816 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 817 int max_retries = 10; 818 819 if (rmu_idx == 0) { 820 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, 821 MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0); 822 /* wait for memory to fully power up */ 823 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 824 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); 825 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); 826 } 827 828 /*read status is not mandatory, it is just for debugging*/ 829 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper); 830 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut); 831 } else if (rmu_idx == 1) { 832 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0, 833 MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0); 834 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 835 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries); 836 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries); 837 } 838 839 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper); 840 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut); 841 } 842 /*TODO Add rmu_idx == 2 for SIENNA_CICHLID */ 843 if (power_status_shaper != 0 && power_on == true) 844 BREAK_TO_DEBUGGER(); 845 846 if (power_status_3dlut != 0 && power_on == true) 847 BREAK_TO_DEBUGGER(); 848 } 849 850 851 852 bool mpc3_program_shaper( 853 struct mpc *mpc, 854 const struct pwl_params *params, 855 uint32_t rmu_idx) 856 { 857 enum dc_lut_mode current_mode; 858 enum dc_lut_mode next_mode; 859 860 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 861 862 if (params == NULL) { 863 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0); 864 return false; 865 } 866 867 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 868 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); 869 870 current_mode = mpc3_get_shaper_current(mpc, rmu_idx); 871 872 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A) 873 next_mode = LUT_RAM_B; 874 else 875 next_mode = LUT_RAM_A; 876 877 mpc3_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, rmu_idx); 878 879 if (next_mode == LUT_RAM_A) 880 mpc3_program_shaper_luta_settings(mpc, params, rmu_idx); 881 else 882 mpc3_program_shaper_lutb_settings(mpc, params, rmu_idx); 883 884 mpc3_program_shaper_lut( 885 mpc, params->rgb_resulted, params->hw_points_num, rmu_idx); 886 887 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2); 888 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); 889 890 return true; 891 } 892 893 static void mpc3_set_3dlut_mode( 894 struct mpc *mpc, 895 enum dc_lut_mode mode, 896 bool is_color_channel_12bits, 897 bool is_lut_size17x17x17, 898 uint32_t rmu_idx) 899 { 900 uint32_t lut_mode; 901 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 902 903 if (mode == LUT_BYPASS) 904 lut_mode = 0; 905 else if (mode == LUT_RAM_A) 906 lut_mode = 1; 907 else 908 lut_mode = 2; 909 910 REG_UPDATE_2(RMU_3DLUT_MODE[rmu_idx], 911 MPC_RMU_3DLUT_MODE, lut_mode, 912 MPC_RMU_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1); 913 } 914 915 static enum dc_lut_mode get3dlut_config( 916 struct mpc *mpc, 917 bool *is_17x17x17, 918 bool *is_12bits_color_channel, 919 int rmu_idx) 920 { 921 uint32_t i_mode, i_enable_10bits, lut_size; 922 enum dc_lut_mode mode; 923 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 924 925 REG_GET(RMU_3DLUT_MODE[rmu_idx], 926 MPC_RMU_3DLUT_MODE_CURRENT, &i_mode); 927 928 REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], 929 MPC_RMU_3DLUT_30BIT_EN, &i_enable_10bits); 930 931 switch (i_mode) { 932 case 0: 933 mode = LUT_BYPASS; 934 break; 935 case 1: 936 mode = LUT_RAM_A; 937 break; 938 case 2: 939 mode = LUT_RAM_B; 940 break; 941 default: 942 mode = LUT_BYPASS; 943 break; 944 } 945 if (i_enable_10bits > 0) 946 *is_12bits_color_channel = false; 947 else 948 *is_12bits_color_channel = true; 949 950 REG_GET(RMU_3DLUT_MODE[rmu_idx], MPC_RMU_3DLUT_SIZE, &lut_size); 951 952 if (lut_size == 0) 953 *is_17x17x17 = true; 954 else 955 *is_17x17x17 = false; 956 957 return mode; 958 } 959 960 static void mpc3_select_3dlut_ram( 961 struct mpc *mpc, 962 enum dc_lut_mode mode, 963 bool is_color_channel_12bits, 964 uint32_t rmu_idx) 965 { 966 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 967 968 REG_UPDATE_2(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], 969 MPC_RMU_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1, 970 MPC_RMU_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1); 971 } 972 973 static void mpc3_select_3dlut_ram_mask( 974 struct mpc *mpc, 975 uint32_t ram_selection_mask, 976 uint32_t rmu_idx) 977 { 978 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 979 980 REG_UPDATE(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], MPC_RMU_3DLUT_WRITE_EN_MASK, 981 ram_selection_mask); 982 REG_SET(RMU_3DLUT_INDEX[rmu_idx], 0, MPC_RMU_3DLUT_INDEX, 0); 983 } 984 985 static void mpc3_set3dlut_ram12( 986 struct mpc *mpc, 987 const struct dc_rgb *lut, 988 uint32_t entries, 989 uint32_t rmu_idx) 990 { 991 uint32_t i, red, green, blue, red1, green1, blue1; 992 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 993 994 for (i = 0 ; i < entries; i += 2) { 995 red = lut[i].red<<4; 996 green = lut[i].green<<4; 997 blue = lut[i].blue<<4; 998 red1 = lut[i+1].red<<4; 999 green1 = lut[i+1].green<<4; 1000 blue1 = lut[i+1].blue<<4; 1001 1002 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 1003 MPC_RMU_3DLUT_DATA0, red, 1004 MPC_RMU_3DLUT_DATA1, red1); 1005 1006 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 1007 MPC_RMU_3DLUT_DATA0, green, 1008 MPC_RMU_3DLUT_DATA1, green1); 1009 1010 REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0, 1011 MPC_RMU_3DLUT_DATA0, blue, 1012 MPC_RMU_3DLUT_DATA1, blue1); 1013 } 1014 } 1015 1016 static void mpc3_set3dlut_ram10( 1017 struct mpc *mpc, 1018 const struct dc_rgb *lut, 1019 uint32_t entries, 1020 uint32_t rmu_idx) 1021 { 1022 uint32_t i, red, green, blue, value; 1023 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1024 1025 for (i = 0; i < entries; i++) { 1026 red = lut[i].red; 1027 green = lut[i].green; 1028 blue = lut[i].blue; 1029 //should we shift red 22bit and green 12? ask Nvenko 1030 value = (red<<20) | (green<<10) | blue; 1031 1032 REG_SET(RMU_3DLUT_DATA_30BIT[rmu_idx], 0, MPC_RMU_3DLUT_DATA_30BIT, value); 1033 } 1034 1035 } 1036 1037 1038 static void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst) 1039 { 1040 mpcc->mpcc_id = mpcc_inst; 1041 mpcc->dpp_id = 0xf; 1042 mpcc->mpcc_bot = NULL; 1043 mpcc->blnd_cfg.overlap_only = false; 1044 mpcc->blnd_cfg.global_alpha = 0xff; 1045 mpcc->blnd_cfg.global_gain = 0xff; 1046 mpcc->blnd_cfg.background_color_bpc = 4; 1047 mpcc->blnd_cfg.bottom_gain_mode = 0; 1048 mpcc->blnd_cfg.top_gain = 0x1f000; 1049 mpcc->blnd_cfg.bottom_inside_gain = 0x1f000; 1050 mpcc->blnd_cfg.bottom_outside_gain = 0x1f000; 1051 mpcc->sm_cfg.enable = false; 1052 mpcc->shared_bottom = false; 1053 } 1054 1055 static void program_gamut_remap( 1056 struct dcn30_mpc *mpc30, 1057 int mpcc_id, 1058 const uint16_t *regval, 1059 int select) 1060 { 1061 uint16_t selection = 0; 1062 struct color_matrices_reg gam_regs; 1063 1064 if (regval == NULL || select == GAMUT_REMAP_BYPASS) { 1065 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, 1066 MPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS); 1067 return; 1068 } 1069 switch (select) { 1070 case GAMUT_REMAP_COEFF: 1071 selection = 1; 1072 break; 1073 /*this corresponds to GAMUT_REMAP coefficients set B 1074 * we don't have common coefficient sets in dcn3ag/dcn3 1075 */ 1076 case GAMUT_REMAP_COMA_COEFF: 1077 selection = 2; 1078 break; 1079 default: 1080 break; 1081 } 1082 1083 gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A; 1084 gam_regs.masks.csc_c11 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A; 1085 gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A; 1086 gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A; 1087 1088 1089 if (select == GAMUT_REMAP_COEFF) { 1090 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]); 1091 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]); 1092 1093 cm_helper_program_color_matrices( 1094 mpc30->base.ctx, 1095 regval, 1096 &gam_regs); 1097 1098 } else if (select == GAMUT_REMAP_COMA_COEFF) { 1099 1100 gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]); 1101 gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]); 1102 1103 cm_helper_program_color_matrices( 1104 mpc30->base.ctx, 1105 regval, 1106 &gam_regs); 1107 1108 } 1109 //select coefficient set to use 1110 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, 1111 MPCC_GAMUT_REMAP_MODE, selection); 1112 } 1113 1114 void mpc3_set_gamut_remap( 1115 struct mpc *mpc, 1116 int mpcc_id, 1117 const struct mpc_grph_gamut_adjustment *adjust) 1118 { 1119 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1120 int i = 0; 1121 int gamut_mode; 1122 1123 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) 1124 program_gamut_remap(mpc30, mpcc_id, NULL, GAMUT_REMAP_BYPASS); 1125 else { 1126 struct fixed31_32 arr_matrix[12]; 1127 uint16_t arr_reg_val[12]; 1128 1129 for (i = 0; i < 12; i++) 1130 arr_matrix[i] = adjust->temperature_matrix[i]; 1131 1132 convert_float_matrix( 1133 arr_reg_val, arr_matrix, 12); 1134 1135 //current coefficient set in use 1136 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, &gamut_mode); 1137 1138 if (gamut_mode == 0) 1139 gamut_mode = 1; //use coefficient set A 1140 else if (gamut_mode == 1) 1141 gamut_mode = 2; 1142 else 1143 gamut_mode = 1; 1144 1145 program_gamut_remap(mpc30, mpcc_id, arr_reg_val, gamut_mode); 1146 } 1147 } 1148 1149 bool mpc3_program_3dlut( 1150 struct mpc *mpc, 1151 const struct tetrahedral_params *params, 1152 int rmu_idx) 1153 { 1154 enum dc_lut_mode mode; 1155 bool is_17x17x17; 1156 bool is_12bits_color_channel; 1157 const struct dc_rgb *lut0; 1158 const struct dc_rgb *lut1; 1159 const struct dc_rgb *lut2; 1160 const struct dc_rgb *lut3; 1161 int lut_size0; 1162 int lut_size; 1163 1164 if (params == NULL) { 1165 mpc3_set_3dlut_mode(mpc, LUT_BYPASS, false, false, rmu_idx); 1166 return false; 1167 } 1168 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true); 1169 1170 mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, rmu_idx); 1171 1172 if (mode == LUT_BYPASS || mode == LUT_RAM_B) 1173 mode = LUT_RAM_A; 1174 else 1175 mode = LUT_RAM_B; 1176 1177 is_17x17x17 = !params->use_tetrahedral_9; 1178 is_12bits_color_channel = params->use_12bits; 1179 if (is_17x17x17) { 1180 lut0 = params->tetrahedral_17.lut0; 1181 lut1 = params->tetrahedral_17.lut1; 1182 lut2 = params->tetrahedral_17.lut2; 1183 lut3 = params->tetrahedral_17.lut3; 1184 lut_size0 = sizeof(params->tetrahedral_17.lut0)/ 1185 sizeof(params->tetrahedral_17.lut0[0]); 1186 lut_size = sizeof(params->tetrahedral_17.lut1)/ 1187 sizeof(params->tetrahedral_17.lut1[0]); 1188 } else { 1189 lut0 = params->tetrahedral_9.lut0; 1190 lut1 = params->tetrahedral_9.lut1; 1191 lut2 = params->tetrahedral_9.lut2; 1192 lut3 = params->tetrahedral_9.lut3; 1193 lut_size0 = sizeof(params->tetrahedral_9.lut0)/ 1194 sizeof(params->tetrahedral_9.lut0[0]); 1195 lut_size = sizeof(params->tetrahedral_9.lut1)/ 1196 sizeof(params->tetrahedral_9.lut1[0]); 1197 } 1198 1199 mpc3_select_3dlut_ram(mpc, mode, 1200 is_12bits_color_channel, rmu_idx); 1201 mpc3_select_3dlut_ram_mask(mpc, 0x1, rmu_idx); 1202 if (is_12bits_color_channel) 1203 mpc3_set3dlut_ram12(mpc, lut0, lut_size0, rmu_idx); 1204 else 1205 mpc3_set3dlut_ram10(mpc, lut0, lut_size0, rmu_idx); 1206 1207 mpc3_select_3dlut_ram_mask(mpc, 0x2, rmu_idx); 1208 if (is_12bits_color_channel) 1209 mpc3_set3dlut_ram12(mpc, lut1, lut_size, rmu_idx); 1210 else 1211 mpc3_set3dlut_ram10(mpc, lut1, lut_size, rmu_idx); 1212 1213 mpc3_select_3dlut_ram_mask(mpc, 0x4, rmu_idx); 1214 if (is_12bits_color_channel) 1215 mpc3_set3dlut_ram12(mpc, lut2, lut_size, rmu_idx); 1216 else 1217 mpc3_set3dlut_ram10(mpc, lut2, lut_size, rmu_idx); 1218 1219 mpc3_select_3dlut_ram_mask(mpc, 0x8, rmu_idx); 1220 if (is_12bits_color_channel) 1221 mpc3_set3dlut_ram12(mpc, lut3, lut_size, rmu_idx); 1222 else 1223 mpc3_set3dlut_ram10(mpc, lut3, lut_size, rmu_idx); 1224 1225 mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel, 1226 is_17x17x17, rmu_idx); 1227 1228 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) 1229 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false); 1230 1231 return true; 1232 } 1233 1234 void mpc3_set_output_csc( 1235 struct mpc *mpc, 1236 int opp_id, 1237 const uint16_t *regval, 1238 enum mpc_output_csc_mode ocsc_mode) 1239 { 1240 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1241 struct color_matrices_reg ocsc_regs; 1242 1243 REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0); 1244 1245 REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode); 1246 1247 if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) 1248 return; 1249 1250 if (regval == NULL) { 1251 BREAK_TO_DEBUGGER(); 1252 return; 1253 } 1254 1255 ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A; 1256 ocsc_regs.masks.csc_c11 = mpc30->mpc_mask->MPC_OCSC_C11_A; 1257 ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A; 1258 ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A; 1259 1260 if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) { 1261 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]); 1262 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]); 1263 } else { 1264 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]); 1265 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]); 1266 } 1267 cm_helper_program_color_matrices( 1268 mpc30->base.ctx, 1269 regval, 1270 &ocsc_regs); 1271 } 1272 1273 void mpc3_set_ocsc_default( 1274 struct mpc *mpc, 1275 int opp_id, 1276 enum dc_color_space color_space, 1277 enum mpc_output_csc_mode ocsc_mode) 1278 { 1279 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1280 uint32_t arr_size; 1281 struct color_matrices_reg ocsc_regs; 1282 const uint16_t *regval = NULL; 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 if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) 1288 return; 1289 1290 regval = find_color_matrix(color_space, &arr_size); 1291 1292 if (regval == NULL) { 1293 BREAK_TO_DEBUGGER(); 1294 return; 1295 } 1296 1297 ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A; 1298 ocsc_regs.masks.csc_c11 = mpc30->mpc_mask->MPC_OCSC_C11_A; 1299 ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A; 1300 ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A; 1301 1302 1303 if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) { 1304 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]); 1305 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]); 1306 } else { 1307 ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]); 1308 ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]); 1309 } 1310 1311 cm_helper_program_color_matrices( 1312 mpc30->base.ctx, 1313 regval, 1314 &ocsc_regs); 1315 } 1316 1317 void mpc3_set_rmu_mux( 1318 struct mpc *mpc, 1319 int rmu_idx, 1320 int value) 1321 { 1322 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1323 1324 if (rmu_idx == 0) 1325 REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU0_MUX, value); 1326 else if (rmu_idx == 1) 1327 REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU1_MUX, value); 1328 1329 } 1330 1331 uint32_t mpc3_get_rmu_mux_status( 1332 struct mpc *mpc, 1333 int rmu_idx) 1334 { 1335 uint32_t status = 0xf; 1336 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1337 1338 if (rmu_idx == 0) 1339 REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &status); 1340 else if (rmu_idx == 1) 1341 REG_GET(MPC_RMU_CONTROL, MPC_RMU1_MUX_STATUS, &status); 1342 1343 return status; 1344 } 1345 1346 uint32_t mpcc3_acquire_rmu(struct mpc *mpc, int mpcc_id, int rmu_idx) 1347 { 1348 uint32_t rmu_status; 1349 1350 //determine if this mpcc is already multiplexed to an RMU unit 1351 rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx); 1352 if (rmu_status == mpcc_id) 1353 //return rmu_idx of pre_acquired rmu unit 1354 return rmu_idx; 1355 1356 if (rmu_status == 0xf) {//rmu unit is disabled 1357 mpc3_set_rmu_mux(mpc, rmu_idx, mpcc_id); 1358 return rmu_idx; 1359 } 1360 1361 //no vacant RMU units or invalid parameters acquire_post_bldn_3dlut 1362 return -1; 1363 } 1364 1365 int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id) 1366 { 1367 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1368 int rmu_idx; 1369 uint32_t rmu_status; 1370 int released_rmu = -1; 1371 1372 for (rmu_idx = 0; rmu_idx < mpc30->num_rmu; rmu_idx++) { 1373 rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx); 1374 if (rmu_status == mpcc_id) { 1375 mpc3_set_rmu_mux(mpc, rmu_idx, 0xf); 1376 released_rmu = rmu_idx; 1377 break; 1378 } 1379 } 1380 return released_rmu; 1381 1382 } 1383 1384 static void mpc3_mpc_init(struct mpc *mpc) 1385 { 1386 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc); 1387 int mpcc_id; 1388 1389 mpc1_mpc_init(mpc); 1390 1391 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) { 1392 if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) { 1393 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3); 1394 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, 3); 1395 } 1396 1397 if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) { 1398 for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++) 1399 REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3); 1400 } 1401 } 1402 } 1403 1404 const struct mpc_funcs dcn30_mpc_funcs = { 1405 .read_mpcc_state = mpc1_read_mpcc_state, 1406 .insert_plane = mpc1_insert_plane, 1407 .remove_mpcc = mpc1_remove_mpcc, 1408 .mpc_init = mpc3_mpc_init, 1409 .mpc_init_single_inst = mpc1_mpc_init_single_inst, 1410 .update_blending = mpc2_update_blending, 1411 .cursor_lock = mpc1_cursor_lock, 1412 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp, 1413 .wait_for_idle = mpc2_assert_idle_mpcc, 1414 .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, 1415 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, 1416 .set_denorm = mpc3_set_denorm, 1417 .set_denorm_clamp = mpc3_set_denorm_clamp, 1418 .set_output_csc = mpc3_set_output_csc, 1419 .set_ocsc_default = mpc3_set_ocsc_default, 1420 .set_output_gamma = mpc3_set_output_gamma, 1421 .insert_plane_to_secondary = NULL, 1422 .remove_mpcc_from_secondary = NULL, 1423 .set_dwb_mux = mpc3_set_dwb_mux, 1424 .disable_dwb_mux = mpc3_disable_dwb_mux, 1425 .is_dwb_idle = mpc3_is_dwb_idle, 1426 .set_out_rate_control = mpc3_set_out_rate_control, 1427 .set_gamut_remap = mpc3_set_gamut_remap, 1428 .program_shaper = mpc3_program_shaper, 1429 .acquire_rmu = mpcc3_acquire_rmu, 1430 .program_3dlut = mpc3_program_3dlut, 1431 .release_rmu = mpcc3_release_rmu, 1432 .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut, 1433 .get_mpc_out_mux = mpc1_get_mpc_out_mux, 1434 1435 }; 1436 1437 void dcn30_mpc_construct(struct dcn30_mpc *mpc30, 1438 struct dc_context *ctx, 1439 const struct dcn30_mpc_registers *mpc_regs, 1440 const struct dcn30_mpc_shift *mpc_shift, 1441 const struct dcn30_mpc_mask *mpc_mask, 1442 int num_mpcc, 1443 int num_rmu) 1444 { 1445 int i; 1446 1447 mpc30->base.ctx = ctx; 1448 1449 mpc30->base.funcs = &dcn30_mpc_funcs; 1450 1451 mpc30->mpc_regs = mpc_regs; 1452 mpc30->mpc_shift = mpc_shift; 1453 mpc30->mpc_mask = mpc_mask; 1454 1455 mpc30->mpcc_in_use_mask = 0; 1456 mpc30->num_mpcc = num_mpcc; 1457 mpc30->num_rmu = num_rmu; 1458 1459 for (i = 0; i < MAX_MPCC; i++) 1460 mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i); 1461 } 1462 1463