0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "reg_helper.h"
0027 #include "dcn30_mpc.h"
0028 #include "dcn30_cm_common.h"
0029 #include "basics/conversion.h"
0030 #include "dcn10/dcn10_cm_common.h"
0031 #include "dc.h"
0032
0033 #define REG(reg)\
0034 mpc30->mpc_regs->reg
0035
0036 #define CTX \
0037 mpc30->base.ctx
0038
0039 #undef FN
0040 #define FN(reg_name, field_name) \
0041 mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name
0042
0043
0044 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
0045
0046
0047 bool mpc3_is_dwb_idle(
0048 struct mpc *mpc,
0049 int dwb_id)
0050 {
0051 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0052 unsigned int status;
0053
0054 REG_GET(DWB_MUX[dwb_id], MPC_DWB0_MUX_STATUS, &status);
0055
0056 if (status == 0xf)
0057 return true;
0058 else
0059 return false;
0060 }
0061
0062 void mpc3_set_dwb_mux(
0063 struct mpc *mpc,
0064 int dwb_id,
0065 int mpcc_id)
0066 {
0067 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0068
0069 REG_SET(DWB_MUX[dwb_id], 0,
0070 MPC_DWB0_MUX, mpcc_id);
0071 }
0072
0073 void mpc3_disable_dwb_mux(
0074 struct mpc *mpc,
0075 int dwb_id)
0076 {
0077 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0078
0079 REG_SET(DWB_MUX[dwb_id], 0,
0080 MPC_DWB0_MUX, 0xf);
0081 }
0082
0083 void mpc3_set_out_rate_control(
0084 struct mpc *mpc,
0085 int opp_id,
0086 bool enable,
0087 bool rate_2x_mode,
0088 struct mpc_dwb_flow_control *flow_control)
0089 {
0090 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0091
0092 REG_UPDATE_2(MUX[opp_id],
0093 MPC_OUT_RATE_CONTROL_DISABLE, !enable,
0094 MPC_OUT_RATE_CONTROL, rate_2x_mode);
0095
0096 if (flow_control)
0097 REG_UPDATE_2(MUX[opp_id],
0098 MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode,
0099 MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1);
0100 }
0101
0102 enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
0103 {
0104
0105
0106
0107 enum dc_lut_mode mode;
0108 uint32_t state_mode;
0109 uint32_t state_ram_lut_in_use;
0110 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0111
0112 REG_GET_2(MPCC_OGAM_CONTROL[mpcc_id], MPCC_OGAM_MODE_CURRENT, &state_mode,
0113 MPCC_OGAM_SELECT_CURRENT, &state_ram_lut_in_use);
0114
0115 switch (state_mode) {
0116 case 0:
0117 mode = LUT_BYPASS;
0118 break;
0119 case 2:
0120 switch (state_ram_lut_in_use) {
0121 case 0:
0122 mode = LUT_RAM_A;
0123 break;
0124 case 1:
0125 mode = LUT_RAM_B;
0126 break;
0127 default:
0128 mode = LUT_BYPASS;
0129 break;
0130 }
0131 break;
0132 default:
0133 mode = LUT_BYPASS;
0134 break;
0135 }
0136
0137 return mode;
0138 }
0139
0140 void mpc3_power_on_ogam_lut(
0141 struct mpc *mpc, int mpcc_id,
0142 bool power_on)
0143 {
0144 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0145
0146
0147
0148
0149
0150
0151
0152 REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id],
0153 MPCC_OGAM_MEM_PWR_DIS, power_on != 0);
0154
0155
0156 if (power_on)
0157 REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
0158 }
0159
0160 static void mpc3_configure_ogam_lut(
0161 struct mpc *mpc, int mpcc_id,
0162 bool is_ram_a)
0163 {
0164 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0165
0166 REG_UPDATE_2(MPCC_OGAM_LUT_CONTROL[mpcc_id],
0167 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 7,
0168 MPCC_OGAM_LUT_HOST_SEL, is_ram_a == true ? 0:1);
0169
0170 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
0171 }
0172
0173 static void mpc3_ogam_get_reg_field(
0174 struct mpc *mpc,
0175 struct dcn3_xfer_func_reg *reg)
0176 {
0177 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0178
0179 reg->shifts.field_region_start_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
0180 reg->masks.field_region_start_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
0181 reg->shifts.field_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_OFFSET_B;
0182 reg->masks.field_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_OFFSET_B;
0183
0184 reg->shifts.exp_region0_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
0185 reg->masks.exp_region0_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
0186 reg->shifts.exp_region0_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
0187 reg->masks.exp_region0_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
0188 reg->shifts.exp_region1_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
0189 reg->masks.exp_region1_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
0190 reg->shifts.exp_region1_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
0191 reg->masks.exp_region1_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
0192
0193 reg->shifts.field_region_end = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_B;
0194 reg->masks.field_region_end = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_B;
0195 reg->shifts.field_region_end_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
0196 reg->masks.field_region_end_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
0197 reg->shifts.field_region_end_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
0198 reg->masks.field_region_end_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
0199 reg->shifts.field_region_linear_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
0200 reg->masks.field_region_linear_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
0201 reg->shifts.exp_region_start = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_B;
0202 reg->masks.exp_region_start = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_B;
0203 reg->shifts.exp_resion_start_segment = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
0204 reg->masks.exp_resion_start_segment = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
0205 }
0206
0207 static void mpc3_program_luta(struct mpc *mpc, int mpcc_id,
0208 const struct pwl_params *params)
0209 {
0210 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0211 struct dcn3_xfer_func_reg gam_regs;
0212
0213 mpc3_ogam_get_reg_field(mpc, &gam_regs);
0214
0215 gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMA_START_CNTL_B[mpcc_id]);
0216 gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMA_START_CNTL_G[mpcc_id]);
0217 gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMA_START_CNTL_R[mpcc_id]);
0218 gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_B[mpcc_id]);
0219 gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_G[mpcc_id]);
0220 gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_R[mpcc_id]);
0221 gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMA_END_CNTL1_B[mpcc_id]);
0222 gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMA_END_CNTL2_B[mpcc_id]);
0223 gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMA_END_CNTL1_G[mpcc_id]);
0224 gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMA_END_CNTL2_G[mpcc_id]);
0225 gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMA_END_CNTL1_R[mpcc_id]);
0226 gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMA_END_CNTL2_R[mpcc_id]);
0227 gam_regs.region_start = REG(MPCC_OGAM_RAMA_REGION_0_1[mpcc_id]);
0228 gam_regs.region_end = REG(MPCC_OGAM_RAMA_REGION_32_33[mpcc_id]);
0229
0230 gam_regs.offset_b = REG(MPCC_OGAM_RAMA_OFFSET_B[mpcc_id]);
0231 gam_regs.offset_g = REG(MPCC_OGAM_RAMA_OFFSET_G[mpcc_id]);
0232 gam_regs.offset_r = REG(MPCC_OGAM_RAMA_OFFSET_R[mpcc_id]);
0233 gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_B[mpcc_id]);
0234 gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_G[mpcc_id]);
0235 gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_R[mpcc_id]);
0236
0237 cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
0238 }
0239
0240 static void mpc3_program_lutb(struct mpc *mpc, int mpcc_id,
0241 const struct pwl_params *params)
0242 {
0243 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0244 struct dcn3_xfer_func_reg gam_regs;
0245
0246 mpc3_ogam_get_reg_field(mpc, &gam_regs);
0247
0248 gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMB_START_CNTL_B[mpcc_id]);
0249 gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMB_START_CNTL_G[mpcc_id]);
0250 gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMB_START_CNTL_R[mpcc_id]);
0251 gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_B[mpcc_id]);
0252 gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_G[mpcc_id]);
0253 gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_R[mpcc_id]);
0254 gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMB_END_CNTL1_B[mpcc_id]);
0255 gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMB_END_CNTL2_B[mpcc_id]);
0256 gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMB_END_CNTL1_G[mpcc_id]);
0257 gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMB_END_CNTL2_G[mpcc_id]);
0258 gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMB_END_CNTL1_R[mpcc_id]);
0259 gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMB_END_CNTL2_R[mpcc_id]);
0260 gam_regs.region_start = REG(MPCC_OGAM_RAMB_REGION_0_1[mpcc_id]);
0261 gam_regs.region_end = REG(MPCC_OGAM_RAMB_REGION_32_33[mpcc_id]);
0262
0263 gam_regs.offset_b = REG(MPCC_OGAM_RAMB_OFFSET_B[mpcc_id]);
0264 gam_regs.offset_g = REG(MPCC_OGAM_RAMB_OFFSET_G[mpcc_id]);
0265 gam_regs.offset_r = REG(MPCC_OGAM_RAMB_OFFSET_R[mpcc_id]);
0266 gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_B[mpcc_id]);
0267 gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_G[mpcc_id]);
0268 gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_R[mpcc_id]);
0269
0270 cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
0271 }
0272
0273
0274 static void mpc3_program_ogam_pwl(
0275 struct mpc *mpc, int mpcc_id,
0276 const struct pwl_result_data *rgb,
0277 uint32_t num)
0278 {
0279 uint32_t i;
0280 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0281 uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
0282 uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
0283 uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
0284
0285
0286
0287
0288
0289
0290
0291 if (is_rgb_equal(rgb, num)) {
0292 for (i = 0 ; i < num; i++)
0293 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
0294
0295 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
0296
0297 } else {
0298
0299 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
0300 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 4);
0301
0302 for (i = 0 ; i < num; i++)
0303 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
0304
0305 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_red);
0306
0307 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
0308
0309 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
0310 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 2);
0311
0312 for (i = 0 ; i < num; i++)
0313 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg);
0314
0315 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_green);
0316
0317 REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
0318
0319 REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
0320 MPCC_OGAM_LUT_WRITE_COLOR_MASK, 1);
0321
0322 for (i = 0 ; i < num; i++)
0323 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg);
0324
0325 REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, last_base_value_blue);
0326 }
0327
0328 }
0329
0330 void mpc3_set_output_gamma(
0331 struct mpc *mpc,
0332 int mpcc_id,
0333 const struct pwl_params *params)
0334 {
0335 enum dc_lut_mode current_mode;
0336 enum dc_lut_mode next_mode;
0337 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0338
0339 if (mpc->ctx->dc->debug.cm_in_bypass) {
0340 REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
0341 return;
0342 }
0343
0344 if (params == NULL) {
0345 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 0);
0346 return;
0347 }
0348
0349 REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 2);
0350
0351 current_mode = mpc3_get_ogam_current(mpc, mpcc_id);
0352 if (current_mode == LUT_BYPASS)
0353 next_mode = LUT_RAM_A;
0354 else if (current_mode == LUT_RAM_A)
0355 next_mode = LUT_RAM_B;
0356 else
0357 next_mode = LUT_RAM_A;
0358
0359 mpc3_power_on_ogam_lut(mpc, mpcc_id, true);
0360 mpc3_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A);
0361
0362 if (next_mode == LUT_RAM_A)
0363 mpc3_program_luta(mpc, mpcc_id, params);
0364 else
0365 mpc3_program_lutb(mpc, mpcc_id, params);
0366
0367 mpc3_program_ogam_pwl(
0368 mpc, mpcc_id, params->rgb_resulted, params->hw_points_num);
0369
0370
0371 REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id],
0372 MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1);
0373
0374 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
0375 mpc3_power_on_ogam_lut(mpc, mpcc_id, false);
0376 }
0377
0378 void mpc3_set_denorm(
0379 struct mpc *mpc,
0380 int opp_id,
0381 enum dc_color_depth output_depth)
0382 {
0383 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0384
0385 int denorm_mode = 0;
0386
0387 switch (output_depth) {
0388 case COLOR_DEPTH_666:
0389 denorm_mode = 1;
0390 break;
0391 case COLOR_DEPTH_888:
0392 denorm_mode = 2;
0393 break;
0394 case COLOR_DEPTH_999:
0395 denorm_mode = 3;
0396 break;
0397 case COLOR_DEPTH_101010:
0398 denorm_mode = 4;
0399 break;
0400 case COLOR_DEPTH_111111:
0401 denorm_mode = 5;
0402 break;
0403 case COLOR_DEPTH_121212:
0404 denorm_mode = 6;
0405 break;
0406 case COLOR_DEPTH_141414:
0407 case COLOR_DEPTH_161616:
0408 default:
0409
0410 break;
0411 }
0412
0413 REG_UPDATE(DENORM_CONTROL[opp_id],
0414 MPC_OUT_DENORM_MODE, denorm_mode);
0415 }
0416
0417 void mpc3_set_denorm_clamp(
0418 struct mpc *mpc,
0419 int opp_id,
0420 struct mpc_denorm_clamp denorm_clamp)
0421 {
0422 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0423
0424
0425 REG_UPDATE_2(DENORM_CONTROL[opp_id],
0426 MPC_OUT_DENORM_CLAMP_MAX_R_CR, denorm_clamp.clamp_max_r_cr,
0427 MPC_OUT_DENORM_CLAMP_MIN_R_CR, denorm_clamp.clamp_min_r_cr);
0428 REG_UPDATE_2(DENORM_CLAMP_G_Y[opp_id],
0429 MPC_OUT_DENORM_CLAMP_MAX_G_Y, denorm_clamp.clamp_max_g_y,
0430 MPC_OUT_DENORM_CLAMP_MIN_G_Y, denorm_clamp.clamp_min_g_y);
0431 REG_UPDATE_2(DENORM_CLAMP_B_CB[opp_id],
0432 MPC_OUT_DENORM_CLAMP_MAX_B_CB, denorm_clamp.clamp_max_b_cb,
0433 MPC_OUT_DENORM_CLAMP_MIN_B_CB, denorm_clamp.clamp_min_b_cb);
0434 }
0435
0436 static enum dc_lut_mode mpc3_get_shaper_current(struct mpc *mpc, uint32_t rmu_idx)
0437 {
0438 enum dc_lut_mode mode;
0439 uint32_t state_mode;
0440 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0441
0442 REG_GET(SHAPER_CONTROL[rmu_idx], MPC_RMU_SHAPER_LUT_MODE_CURRENT, &state_mode);
0443
0444 switch (state_mode) {
0445 case 0:
0446 mode = LUT_BYPASS;
0447 break;
0448 case 1:
0449 mode = LUT_RAM_A;
0450 break;
0451 case 2:
0452 mode = LUT_RAM_B;
0453 break;
0454 default:
0455 mode = LUT_BYPASS;
0456 break;
0457 }
0458
0459 return mode;
0460 }
0461
0462 static void mpc3_configure_shaper_lut(
0463 struct mpc *mpc,
0464 bool is_ram_a,
0465 uint32_t rmu_idx)
0466 {
0467 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0468
0469 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
0470 MPC_RMU_SHAPER_LUT_WRITE_EN_MASK, 7);
0471 REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
0472 MPC_RMU_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
0473 REG_SET(SHAPER_LUT_INDEX[rmu_idx], 0, MPC_RMU_SHAPER_LUT_INDEX, 0);
0474 }
0475
0476 static void mpc3_program_shaper_luta_settings(
0477 struct mpc *mpc,
0478 const struct pwl_params *params,
0479 uint32_t rmu_idx)
0480 {
0481 const struct gamma_curve *curve;
0482 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0483
0484 REG_SET_2(SHAPER_RAMA_START_CNTL_B[rmu_idx], 0,
0485 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
0486 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0487 REG_SET_2(SHAPER_RAMA_START_CNTL_G[rmu_idx], 0,
0488 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
0489 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0490 REG_SET_2(SHAPER_RAMA_START_CNTL_R[rmu_idx], 0,
0491 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
0492 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0493
0494 REG_SET_2(SHAPER_RAMA_END_CNTL_B[rmu_idx], 0,
0495 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
0496 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
0497 REG_SET_2(SHAPER_RAMA_END_CNTL_G[rmu_idx], 0,
0498 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
0499 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
0500 REG_SET_2(SHAPER_RAMA_END_CNTL_R[rmu_idx], 0,
0501 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
0502 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
0503
0504 curve = params->arr_curve_points;
0505 REG_SET_4(SHAPER_RAMA_REGION_0_1[rmu_idx], 0,
0506 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0507 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0508 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0509 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0510
0511 curve += 2;
0512 REG_SET_4(SHAPER_RAMA_REGION_2_3[rmu_idx], 0,
0513 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0514 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0515 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0516 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0517
0518 curve += 2;
0519 REG_SET_4(SHAPER_RAMA_REGION_4_5[rmu_idx], 0,
0520 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0521 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0522 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0523 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0524
0525 curve += 2;
0526 REG_SET_4(SHAPER_RAMA_REGION_6_7[rmu_idx], 0,
0527 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0528 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0529 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0530 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0531
0532 curve += 2;
0533 REG_SET_4(SHAPER_RAMA_REGION_8_9[rmu_idx], 0,
0534 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0535 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0536 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0537 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0538
0539 curve += 2;
0540 REG_SET_4(SHAPER_RAMA_REGION_10_11[rmu_idx], 0,
0541 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0542 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0543 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0544 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0545
0546 curve += 2;
0547 REG_SET_4(SHAPER_RAMA_REGION_12_13[rmu_idx], 0,
0548 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0549 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0550 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0551 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0552
0553 curve += 2;
0554 REG_SET_4(SHAPER_RAMA_REGION_14_15[rmu_idx], 0,
0555 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0556 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0557 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0558 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0559
0560
0561 curve += 2;
0562 REG_SET_4(SHAPER_RAMA_REGION_16_17[rmu_idx], 0,
0563 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0564 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0565 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0566 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0567
0568 curve += 2;
0569 REG_SET_4(SHAPER_RAMA_REGION_18_19[rmu_idx], 0,
0570 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0571 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0572 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0573 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0574
0575 curve += 2;
0576 REG_SET_4(SHAPER_RAMA_REGION_20_21[rmu_idx], 0,
0577 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0578 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0579 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0580 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0581
0582 curve += 2;
0583 REG_SET_4(SHAPER_RAMA_REGION_22_23[rmu_idx], 0,
0584 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0585 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0586 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0587 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0588
0589 curve += 2;
0590 REG_SET_4(SHAPER_RAMA_REGION_24_25[rmu_idx], 0,
0591 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0592 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0593 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0594 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0595
0596 curve += 2;
0597 REG_SET_4(SHAPER_RAMA_REGION_26_27[rmu_idx], 0,
0598 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0599 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0600 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0601 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0602
0603 curve += 2;
0604 REG_SET_4(SHAPER_RAMA_REGION_28_29[rmu_idx], 0,
0605 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0606 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0607 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0608 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0609
0610 curve += 2;
0611 REG_SET_4(SHAPER_RAMA_REGION_30_31[rmu_idx], 0,
0612 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0613 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0614 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0615 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0616
0617 curve += 2;
0618 REG_SET_4(SHAPER_RAMA_REGION_32_33[rmu_idx], 0,
0619 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0620 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0621 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0622 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0623 }
0624
0625 static void mpc3_program_shaper_lutb_settings(
0626 struct mpc *mpc,
0627 const struct pwl_params *params,
0628 uint32_t rmu_idx)
0629 {
0630 const struct gamma_curve *curve;
0631 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0632
0633 REG_SET_2(SHAPER_RAMB_START_CNTL_B[rmu_idx], 0,
0634 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
0635 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0636 REG_SET_2(SHAPER_RAMB_START_CNTL_G[rmu_idx], 0,
0637 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
0638 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0639 REG_SET_2(SHAPER_RAMB_START_CNTL_R[rmu_idx], 0,
0640 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
0641 MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0642
0643 REG_SET_2(SHAPER_RAMB_END_CNTL_B[rmu_idx], 0,
0644 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
0645 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
0646 REG_SET_2(SHAPER_RAMB_END_CNTL_G[rmu_idx], 0,
0647 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
0648 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
0649 REG_SET_2(SHAPER_RAMB_END_CNTL_R[rmu_idx], 0,
0650 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
0651 MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
0652
0653 curve = params->arr_curve_points;
0654 REG_SET_4(SHAPER_RAMB_REGION_0_1[rmu_idx], 0,
0655 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0656 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0657 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0658 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0659
0660 curve += 2;
0661 REG_SET_4(SHAPER_RAMB_REGION_2_3[rmu_idx], 0,
0662 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0663 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0664 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0665 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0666
0667
0668 curve += 2;
0669 REG_SET_4(SHAPER_RAMB_REGION_4_5[rmu_idx], 0,
0670 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0671 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0672 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0673 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0674
0675 curve += 2;
0676 REG_SET_4(SHAPER_RAMB_REGION_6_7[rmu_idx], 0,
0677 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0678 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0679 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0680 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0681
0682 curve += 2;
0683 REG_SET_4(SHAPER_RAMB_REGION_8_9[rmu_idx], 0,
0684 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0685 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0686 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0687 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0688
0689 curve += 2;
0690 REG_SET_4(SHAPER_RAMB_REGION_10_11[rmu_idx], 0,
0691 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0692 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0693 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0694 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0695
0696 curve += 2;
0697 REG_SET_4(SHAPER_RAMB_REGION_12_13[rmu_idx], 0,
0698 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0699 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0700 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0701 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0702
0703 curve += 2;
0704 REG_SET_4(SHAPER_RAMB_REGION_14_15[rmu_idx], 0,
0705 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0706 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0707 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0708 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0709
0710
0711 curve += 2;
0712 REG_SET_4(SHAPER_RAMB_REGION_16_17[rmu_idx], 0,
0713 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0714 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0715 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0716 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0717
0718 curve += 2;
0719 REG_SET_4(SHAPER_RAMB_REGION_18_19[rmu_idx], 0,
0720 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0721 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0722 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0723 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0724
0725 curve += 2;
0726 REG_SET_4(SHAPER_RAMB_REGION_20_21[rmu_idx], 0,
0727 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0728 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0729 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0730 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0731
0732 curve += 2;
0733 REG_SET_4(SHAPER_RAMB_REGION_22_23[rmu_idx], 0,
0734 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0735 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0736 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0737 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0738
0739 curve += 2;
0740 REG_SET_4(SHAPER_RAMB_REGION_24_25[rmu_idx], 0,
0741 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0742 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0743 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0744 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0745
0746 curve += 2;
0747 REG_SET_4(SHAPER_RAMB_REGION_26_27[rmu_idx], 0,
0748 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0749 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0750 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0751 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0752
0753 curve += 2;
0754 REG_SET_4(SHAPER_RAMB_REGION_28_29[rmu_idx], 0,
0755 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0756 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0757 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0758 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0759
0760 curve += 2;
0761 REG_SET_4(SHAPER_RAMB_REGION_30_31[rmu_idx], 0,
0762 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0763 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0764 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0765 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0766
0767 curve += 2;
0768 REG_SET_4(SHAPER_RAMB_REGION_32_33[rmu_idx], 0,
0769 MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0770 MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0771 MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0772 MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0773 }
0774
0775
0776 static void mpc3_program_shaper_lut(
0777 struct mpc *mpc,
0778 const struct pwl_result_data *rgb,
0779 uint32_t num,
0780 uint32_t rmu_idx)
0781 {
0782 uint32_t i, red, green, blue;
0783 uint32_t red_delta, green_delta, blue_delta;
0784 uint32_t red_value, green_value, blue_value;
0785
0786 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0787
0788 for (i = 0 ; i < num; i++) {
0789
0790 red = rgb[i].red_reg;
0791 green = rgb[i].green_reg;
0792 blue = rgb[i].blue_reg;
0793
0794 red_delta = rgb[i].delta_red_reg;
0795 green_delta = rgb[i].delta_green_reg;
0796 blue_delta = rgb[i].delta_blue_reg;
0797
0798 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
0799 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
0800 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
0801
0802 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, red_value);
0803 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, green_value);
0804 REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, blue_value);
0805 }
0806
0807 }
0808
0809 static void mpc3_power_on_shaper_3dlut(
0810 struct mpc *mpc,
0811 uint32_t rmu_idx,
0812 bool power_on)
0813 {
0814 uint32_t power_status_shaper = 2;
0815 uint32_t power_status_3dlut = 2;
0816 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0817 int max_retries = 10;
0818
0819 if (rmu_idx == 0) {
0820 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
0821 MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0);
0822
0823 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
0824 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
0825 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
0826 }
0827
0828
0829 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper);
0830 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
0831 } else if (rmu_idx == 1) {
0832 REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
0833 MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0);
0834 if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
0835 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
0836 REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
0837 }
0838
0839 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper);
0840 REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
0841 }
0842
0843 if (power_status_shaper != 0 && power_on == true)
0844 BREAK_TO_DEBUGGER();
0845
0846 if (power_status_3dlut != 0 && power_on == true)
0847 BREAK_TO_DEBUGGER();
0848 }
0849
0850
0851
0852 bool mpc3_program_shaper(
0853 struct mpc *mpc,
0854 const struct pwl_params *params,
0855 uint32_t rmu_idx)
0856 {
0857 enum dc_lut_mode current_mode;
0858 enum dc_lut_mode next_mode;
0859
0860 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0861
0862 if (params == NULL) {
0863 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0);
0864 return false;
0865 }
0866
0867 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
0868 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true);
0869
0870 current_mode = mpc3_get_shaper_current(mpc, rmu_idx);
0871
0872 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
0873 next_mode = LUT_RAM_B;
0874 else
0875 next_mode = LUT_RAM_A;
0876
0877 mpc3_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, rmu_idx);
0878
0879 if (next_mode == LUT_RAM_A)
0880 mpc3_program_shaper_luta_settings(mpc, params, rmu_idx);
0881 else
0882 mpc3_program_shaper_lutb_settings(mpc, params, rmu_idx);
0883
0884 mpc3_program_shaper_lut(
0885 mpc, params->rgb_resulted, params->hw_points_num, rmu_idx);
0886
0887 REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
0888 mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false);
0889
0890 return true;
0891 }
0892
0893 static void mpc3_set_3dlut_mode(
0894 struct mpc *mpc,
0895 enum dc_lut_mode mode,
0896 bool is_color_channel_12bits,
0897 bool is_lut_size17x17x17,
0898 uint32_t rmu_idx)
0899 {
0900 uint32_t lut_mode;
0901 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0902
0903 if (mode == LUT_BYPASS)
0904 lut_mode = 0;
0905 else if (mode == LUT_RAM_A)
0906 lut_mode = 1;
0907 else
0908 lut_mode = 2;
0909
0910 REG_UPDATE_2(RMU_3DLUT_MODE[rmu_idx],
0911 MPC_RMU_3DLUT_MODE, lut_mode,
0912 MPC_RMU_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
0913 }
0914
0915 static enum dc_lut_mode get3dlut_config(
0916 struct mpc *mpc,
0917 bool *is_17x17x17,
0918 bool *is_12bits_color_channel,
0919 int rmu_idx)
0920 {
0921 uint32_t i_mode, i_enable_10bits, lut_size;
0922 enum dc_lut_mode mode;
0923 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0924
0925 REG_GET(RMU_3DLUT_MODE[rmu_idx],
0926 MPC_RMU_3DLUT_MODE_CURRENT, &i_mode);
0927
0928 REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
0929 MPC_RMU_3DLUT_30BIT_EN, &i_enable_10bits);
0930
0931 switch (i_mode) {
0932 case 0:
0933 mode = LUT_BYPASS;
0934 break;
0935 case 1:
0936 mode = LUT_RAM_A;
0937 break;
0938 case 2:
0939 mode = LUT_RAM_B;
0940 break;
0941 default:
0942 mode = LUT_BYPASS;
0943 break;
0944 }
0945 if (i_enable_10bits > 0)
0946 *is_12bits_color_channel = false;
0947 else
0948 *is_12bits_color_channel = true;
0949
0950 REG_GET(RMU_3DLUT_MODE[rmu_idx], MPC_RMU_3DLUT_SIZE, &lut_size);
0951
0952 if (lut_size == 0)
0953 *is_17x17x17 = true;
0954 else
0955 *is_17x17x17 = false;
0956
0957 return mode;
0958 }
0959
0960 static void mpc3_select_3dlut_ram(
0961 struct mpc *mpc,
0962 enum dc_lut_mode mode,
0963 bool is_color_channel_12bits,
0964 uint32_t rmu_idx)
0965 {
0966 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0967
0968 REG_UPDATE_2(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
0969 MPC_RMU_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
0970 MPC_RMU_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1);
0971 }
0972
0973 static void mpc3_select_3dlut_ram_mask(
0974 struct mpc *mpc,
0975 uint32_t ram_selection_mask,
0976 uint32_t rmu_idx)
0977 {
0978 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0979
0980 REG_UPDATE(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], MPC_RMU_3DLUT_WRITE_EN_MASK,
0981 ram_selection_mask);
0982 REG_SET(RMU_3DLUT_INDEX[rmu_idx], 0, MPC_RMU_3DLUT_INDEX, 0);
0983 }
0984
0985 static void mpc3_set3dlut_ram12(
0986 struct mpc *mpc,
0987 const struct dc_rgb *lut,
0988 uint32_t entries,
0989 uint32_t rmu_idx)
0990 {
0991 uint32_t i, red, green, blue, red1, green1, blue1;
0992 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
0993
0994 for (i = 0 ; i < entries; i += 2) {
0995 red = lut[i].red<<4;
0996 green = lut[i].green<<4;
0997 blue = lut[i].blue<<4;
0998 red1 = lut[i+1].red<<4;
0999 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
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 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
1074
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
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
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;
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
1351 rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx);
1352 if (rmu_status == mpcc_id)
1353
1354 return rmu_idx;
1355
1356 if (rmu_status == 0xf) {
1357 mpc3_set_rmu_mux(mpc, rmu_idx, mpcc_id);
1358 return rmu_idx;
1359 }
1360
1361
1362 return -1;
1363 }
1364
1365 static 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_set_mpc_mem_lp_mode(struct mpc *mpc)
1385 {
1386 struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1387 int mpcc_id;
1388
1389 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
1390 if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) {
1391 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3);
1392 REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, 3);
1393 }
1394
1395 if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) {
1396 for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++)
1397 REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3);
1398 }
1399 }
1400 }
1401
1402 const struct mpc_funcs dcn30_mpc_funcs = {
1403 .read_mpcc_state = mpc1_read_mpcc_state,
1404 .insert_plane = mpc1_insert_plane,
1405 .remove_mpcc = mpc1_remove_mpcc,
1406 .mpc_init = mpc1_mpc_init,
1407 .mpc_init_single_inst = mpc1_mpc_init_single_inst,
1408 .update_blending = mpc2_update_blending,
1409 .cursor_lock = mpc1_cursor_lock,
1410 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
1411 .wait_for_idle = mpc2_assert_idle_mpcc,
1412 .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
1413 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
1414 .set_denorm = mpc3_set_denorm,
1415 .set_denorm_clamp = mpc3_set_denorm_clamp,
1416 .set_output_csc = mpc3_set_output_csc,
1417 .set_ocsc_default = mpc3_set_ocsc_default,
1418 .set_output_gamma = mpc3_set_output_gamma,
1419 .insert_plane_to_secondary = NULL,
1420 .remove_mpcc_from_secondary = NULL,
1421 .set_dwb_mux = mpc3_set_dwb_mux,
1422 .disable_dwb_mux = mpc3_disable_dwb_mux,
1423 .is_dwb_idle = mpc3_is_dwb_idle,
1424 .set_out_rate_control = mpc3_set_out_rate_control,
1425 .set_gamut_remap = mpc3_set_gamut_remap,
1426 .program_shaper = mpc3_program_shaper,
1427 .acquire_rmu = mpcc3_acquire_rmu,
1428 .program_3dlut = mpc3_program_3dlut,
1429 .release_rmu = mpcc3_release_rmu,
1430 .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
1431 .get_mpc_out_mux = mpc1_get_mpc_out_mux,
1432 .set_bg_color = mpc1_set_bg_color,
1433 .set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode,
1434 };
1435
1436 void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
1437 struct dc_context *ctx,
1438 const struct dcn30_mpc_registers *mpc_regs,
1439 const struct dcn30_mpc_shift *mpc_shift,
1440 const struct dcn30_mpc_mask *mpc_mask,
1441 int num_mpcc,
1442 int num_rmu)
1443 {
1444 int i;
1445
1446 mpc30->base.ctx = ctx;
1447
1448 mpc30->base.funcs = &dcn30_mpc_funcs;
1449
1450 mpc30->mpc_regs = mpc_regs;
1451 mpc30->mpc_shift = mpc_shift;
1452 mpc30->mpc_mask = mpc_mask;
1453
1454 mpc30->mpcc_in_use_mask = 0;
1455 mpc30->num_mpcc = num_mpcc;
1456 mpc30->num_rmu = num_rmu;
1457
1458 for (i = 0; i < MAX_MPCC; i++)
1459 mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i);
1460 }
1461