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