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 "dm_services.h"
0027
0028 #include "core_types.h"
0029
0030 #include "reg_helper.h"
0031 #include "dcn20_dpp.h"
0032 #include "basics/conversion.h"
0033
0034 #include "dcn10/dcn10_cm_common.h"
0035
0036 #define REG(reg)\
0037 dpp->tf_regs->reg
0038
0039 #define IND_REG(index) \
0040 (index)
0041
0042 #define CTX \
0043 dpp->base.ctx
0044
0045 #undef FN
0046 #define FN(reg_name, field_name) \
0047 dpp->tf_shift->field_name, dpp->tf_mask->field_name
0048
0049
0050 static void dpp2_enable_cm_block(
0051 struct dpp *dpp_base)
0052 {
0053 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0054
0055 unsigned int cm_bypass_mode = 0;
0056
0057 if (dpp_base->ctx->dc->debug.cm_in_bypass)
0058 cm_bypass_mode = 1;
0059
0060 REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
0061 }
0062
0063
0064 static bool dpp2_degamma_ram_inuse(
0065 struct dpp *dpp_base,
0066 bool *ram_a_inuse)
0067 {
0068 bool ret = false;
0069 uint32_t status_reg = 0;
0070 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0071
0072 REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
0073 &status_reg);
0074
0075 if (status_reg == 3) {
0076 *ram_a_inuse = true;
0077 ret = true;
0078 } else if (status_reg == 4) {
0079 *ram_a_inuse = false;
0080 ret = true;
0081 }
0082 return ret;
0083 }
0084
0085 static void dpp2_program_degamma_lut(
0086 struct dpp *dpp_base,
0087 const struct pwl_result_data *rgb,
0088 uint32_t num,
0089 bool is_ram_a)
0090 {
0091 uint32_t i;
0092
0093 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0094 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
0095 CM_DGAM_LUT_WRITE_EN_MASK, 7);
0096 REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
0097 is_ram_a == true ? 0:1);
0098
0099 REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
0100 for (i = 0 ; i < num; i++) {
0101 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
0102 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
0103 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
0104
0105 REG_SET(CM_DGAM_LUT_DATA, 0,
0106 CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
0107 REG_SET(CM_DGAM_LUT_DATA, 0,
0108 CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
0109 REG_SET(CM_DGAM_LUT_DATA, 0,
0110 CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
0111
0112 }
0113
0114 }
0115
0116 void dpp2_set_degamma_pwl(
0117 struct dpp *dpp_base,
0118 const struct pwl_params *params)
0119 {
0120 bool is_ram_a = true;
0121
0122 dpp1_power_on_degamma_lut(dpp_base, true);
0123 dpp2_enable_cm_block(dpp_base);
0124 dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
0125 if (is_ram_a == true)
0126 dpp1_program_degamma_lutb_settings(dpp_base, params);
0127 else
0128 dpp1_program_degamma_luta_settings(dpp_base, params);
0129
0130 dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
0131 dpp1_degamma_ram_select(dpp_base, !is_ram_a);
0132 }
0133
0134 void dpp2_set_degamma(
0135 struct dpp *dpp_base,
0136 enum ipp_degamma_mode mode)
0137 {
0138 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0139 dpp2_enable_cm_block(dpp_base);
0140
0141 switch (mode) {
0142 case IPP_DEGAMMA_MODE_BYPASS:
0143
0144 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
0145 break;
0146 case IPP_DEGAMMA_MODE_HW_sRGB:
0147 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
0148 break;
0149 case IPP_DEGAMMA_MODE_HW_xvYCC:
0150 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
0151 break;
0152 case IPP_DEGAMMA_MODE_USER_PWL:
0153 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
0154 break;
0155 default:
0156 BREAK_TO_DEBUGGER();
0157 break;
0158 }
0159 }
0160
0161 static void program_gamut_remap(
0162 struct dcn20_dpp *dpp,
0163 const uint16_t *regval,
0164 enum dcn20_gamut_remap_select select)
0165 {
0166 uint32_t cur_select = 0;
0167 struct color_matrices_reg gam_regs;
0168
0169 if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
0170 REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
0171 CM_GAMUT_REMAP_MODE, 0);
0172 return;
0173 }
0174
0175
0176
0177
0178
0179 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
0180 CM_TEST_DEBUG_DATA_STATUS_IDX,
0181 CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
0182
0183
0184 if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
0185 select = DCN2_GAMUT_REMAP_COEF_A;
0186 else
0187 select = DCN2_GAMUT_REMAP_COEF_B;
0188
0189 gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
0190 gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
0191 gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
0192 gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
0193
0194 if (select == DCN2_GAMUT_REMAP_COEF_A) {
0195 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
0196 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
0197 } else {
0198 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
0199 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
0200 }
0201
0202 cm_helper_program_color_matrices(
0203 dpp->base.ctx,
0204 regval,
0205 &gam_regs);
0206
0207 REG_SET(
0208 CM_GAMUT_REMAP_CONTROL, 0,
0209 CM_GAMUT_REMAP_MODE, select);
0210
0211 }
0212
0213 void dpp2_cm_set_gamut_remap(
0214 struct dpp *dpp_base,
0215 const struct dpp_grph_csc_adjustment *adjust)
0216 {
0217 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0218 int i = 0;
0219
0220 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
0221
0222 program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
0223 else {
0224 struct fixed31_32 arr_matrix[12];
0225 uint16_t arr_reg_val[12];
0226
0227 for (i = 0; i < 12; i++)
0228 arr_matrix[i] = adjust->temperature_matrix[i];
0229
0230 convert_float_matrix(
0231 arr_reg_val, arr_matrix, 12);
0232
0233 program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
0234 }
0235 }
0236
0237 void dpp2_program_input_csc(
0238 struct dpp *dpp_base,
0239 enum dc_color_space color_space,
0240 enum dcn20_input_csc_select input_select,
0241 const struct out_csc_color_matrix *tbl_entry)
0242 {
0243 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0244 int i;
0245 int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
0246 const uint16_t *regval = NULL;
0247 uint32_t cur_select = 0;
0248 enum dcn20_input_csc_select select;
0249 struct color_matrices_reg icsc_regs;
0250
0251 if (input_select == DCN2_ICSC_SELECT_BYPASS) {
0252 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
0253 return;
0254 }
0255
0256 if (tbl_entry == NULL) {
0257 for (i = 0; i < arr_size; i++)
0258 if (dpp_input_csc_matrix[i].color_space == color_space) {
0259 regval = dpp_input_csc_matrix[i].regval;
0260 break;
0261 }
0262
0263 if (regval == NULL) {
0264 BREAK_TO_DEBUGGER();
0265 return;
0266 }
0267 } else {
0268 regval = tbl_entry->regval;
0269 }
0270
0271
0272
0273
0274
0275 IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
0276 CM_TEST_DEBUG_DATA_STATUS_IDX,
0277 CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
0278
0279 if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
0280 select = DCN2_ICSC_SELECT_ICSC_A;
0281 else
0282 select = DCN2_ICSC_SELECT_ICSC_B;
0283
0284 icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
0285 icsc_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
0286 icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
0287 icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
0288
0289 if (select == DCN2_ICSC_SELECT_ICSC_A) {
0290
0291 icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
0292 icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
0293
0294 } else {
0295
0296 icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
0297 icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
0298
0299 }
0300
0301 cm_helper_program_color_matrices(
0302 dpp->base.ctx,
0303 regval,
0304 &icsc_regs);
0305
0306 REG_SET(CM_ICSC_CONTROL, 0,
0307 CM_ICSC_MODE, select);
0308 }
0309
0310 static void dpp20_power_on_blnd_lut(
0311 struct dpp *dpp_base,
0312 bool power_on)
0313 {
0314 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0315
0316 REG_SET(CM_MEM_PWR_CTRL, 0,
0317 BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
0318
0319 }
0320
0321 static void dpp20_configure_blnd_lut(
0322 struct dpp *dpp_base,
0323 bool is_ram_a)
0324 {
0325 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0326
0327 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
0328 CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
0329 REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
0330 CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
0331 REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
0332 }
0333
0334 static void dpp20_program_blnd_pwl(
0335 struct dpp *dpp_base,
0336 const struct pwl_result_data *rgb,
0337 uint32_t num)
0338 {
0339 uint32_t i;
0340 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0341
0342 for (i = 0 ; i < num; i++) {
0343 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
0344 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
0345 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
0346
0347 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
0348 CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
0349 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
0350 CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
0351 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
0352 CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
0353
0354 }
0355
0356 }
0357
0358 static void dcn20_dpp_cm_get_reg_field(
0359 struct dcn20_dpp *dpp,
0360 struct xfer_func_reg *reg)
0361 {
0362 reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
0363 reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
0364 reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
0365 reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
0366 reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
0367 reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
0368 reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
0369 reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
0370
0371 reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
0372 reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
0373 reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
0374 reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
0375 reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
0376 reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
0377 reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
0378 reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
0379 reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
0380 reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
0381 reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
0382 reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
0383 }
0384
0385
0386 static void dpp20_program_blnd_luta_settings(
0387 struct dpp *dpp_base,
0388 const struct pwl_params *params)
0389 {
0390 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0391 struct xfer_func_reg gam_regs;
0392
0393 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
0394
0395 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
0396 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
0397 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
0398 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
0399 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
0400 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
0401 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
0402 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
0403 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
0404 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
0405 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
0406 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
0407 gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
0408 gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
0409
0410 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
0411 }
0412
0413
0414 static void dpp20_program_blnd_lutb_settings(
0415 struct dpp *dpp_base,
0416 const struct pwl_params *params)
0417 {
0418 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0419 struct xfer_func_reg gam_regs;
0420
0421 dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
0422
0423 gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
0424 gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
0425 gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
0426 gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
0427 gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
0428 gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
0429 gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
0430 gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
0431 gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
0432 gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
0433 gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
0434 gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
0435 gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
0436 gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
0437
0438 cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
0439 }
0440
0441 static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
0442 {
0443 enum dc_lut_mode mode;
0444 uint32_t state_mode;
0445 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0446
0447 REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK, CM_BLNDGAM_CONFIG_STATUS, &state_mode);
0448
0449 switch (state_mode) {
0450 case 0:
0451 mode = LUT_BYPASS;
0452 break;
0453 case 1:
0454 mode = LUT_RAM_A;
0455 break;
0456 case 2:
0457 mode = LUT_RAM_B;
0458 break;
0459 default:
0460 mode = LUT_BYPASS;
0461 break;
0462 }
0463
0464 return mode;
0465 }
0466
0467 bool dpp20_program_blnd_lut(
0468 struct dpp *dpp_base, const struct pwl_params *params)
0469 {
0470 enum dc_lut_mode current_mode;
0471 enum dc_lut_mode next_mode;
0472 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0473
0474 if (params == NULL) {
0475 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
0476 return false;
0477 }
0478 current_mode = dpp20_get_blndgam_current(dpp_base);
0479 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
0480 next_mode = LUT_RAM_B;
0481 else
0482 next_mode = LUT_RAM_A;
0483
0484 dpp20_power_on_blnd_lut(dpp_base, true);
0485 dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
0486
0487 if (next_mode == LUT_RAM_A)
0488 dpp20_program_blnd_luta_settings(dpp_base, params);
0489 else
0490 dpp20_program_blnd_lutb_settings(dpp_base, params);
0491
0492 dpp20_program_blnd_pwl(
0493 dpp_base, params->rgb_resulted, params->hw_points_num);
0494
0495 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
0496 next_mode == LUT_RAM_A ? 1:2);
0497
0498 return true;
0499 }
0500
0501
0502 static void dpp20_program_shaper_lut(
0503 struct dpp *dpp_base,
0504 const struct pwl_result_data *rgb,
0505 uint32_t num)
0506 {
0507 uint32_t i, red, green, blue;
0508 uint32_t red_delta, green_delta, blue_delta;
0509 uint32_t red_value, green_value, blue_value;
0510
0511 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0512
0513 for (i = 0 ; i < num; i++) {
0514
0515 red = rgb[i].red_reg;
0516 green = rgb[i].green_reg;
0517 blue = rgb[i].blue_reg;
0518
0519 red_delta = rgb[i].delta_red_reg;
0520 green_delta = rgb[i].delta_green_reg;
0521 blue_delta = rgb[i].delta_blue_reg;
0522
0523 red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
0524 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
0525 blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
0526
0527 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
0528 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
0529 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
0530 }
0531
0532 }
0533
0534 static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
0535 {
0536 enum dc_lut_mode mode;
0537 uint32_t state_mode;
0538 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0539
0540 REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK, CM_SHAPER_CONFIG_STATUS, &state_mode);
0541
0542 switch (state_mode) {
0543 case 0:
0544 mode = LUT_BYPASS;
0545 break;
0546 case 1:
0547 mode = LUT_RAM_A;
0548 break;
0549 case 2:
0550 mode = LUT_RAM_B;
0551 break;
0552 default:
0553 mode = LUT_BYPASS;
0554 break;
0555 }
0556
0557 return mode;
0558 }
0559
0560 static void dpp20_configure_shaper_lut(
0561 struct dpp *dpp_base,
0562 bool is_ram_a)
0563 {
0564 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0565
0566 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
0567 CM_SHAPER_LUT_WRITE_EN_MASK, 7);
0568 REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
0569 CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
0570 REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
0571 }
0572
0573
0574
0575 static void dpp20_program_shaper_luta_settings(
0576 struct dpp *dpp_base,
0577 const struct pwl_params *params)
0578 {
0579 const struct gamma_curve *curve;
0580 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0581
0582 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
0583 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
0584 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
0585 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
0586 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
0587 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
0588 REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
0589 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
0590 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
0591
0592 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
0593 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
0594 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
0595
0596 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
0597 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
0598 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
0599
0600 REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
0601 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
0602 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
0603
0604 curve = params->arr_curve_points;
0605 REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
0606 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0607 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0608 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0609 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0610
0611 curve += 2;
0612 REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
0613 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
0614 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
0615 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
0616 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
0617
0618 curve += 2;
0619 REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
0620 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
0621 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
0622 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
0623 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
0624
0625 curve += 2;
0626 REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
0627 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
0628 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
0629 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
0630 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
0631
0632 curve += 2;
0633 REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
0634 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
0635 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
0636 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
0637 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
0638
0639 curve += 2;
0640 REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
0641 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
0642 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
0643 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
0644 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
0645
0646 curve += 2;
0647 REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
0648 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
0649 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
0650 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
0651 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
0652
0653 curve += 2;
0654 REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
0655 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
0656 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
0657 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
0658 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
0659
0660 curve += 2;
0661 REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
0662 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
0663 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
0664 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
0665 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
0666
0667 curve += 2;
0668 REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
0669 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
0670 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
0671 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
0672 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
0673
0674 curve += 2;
0675 REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
0676 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
0677 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
0678 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
0679 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
0680
0681 curve += 2;
0682 REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
0683 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
0684 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
0685 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
0686 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
0687
0688 curve += 2;
0689 REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
0690 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
0691 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
0692 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
0693 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
0694
0695 curve += 2;
0696 REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
0697 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
0698 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
0699 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
0700 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
0701
0702 curve += 2;
0703 REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
0704 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
0705 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
0706 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
0707 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
0708
0709 curve += 2;
0710 REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
0711 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
0712 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
0713 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
0714 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
0715
0716 curve += 2;
0717 REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
0718 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
0719 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
0720 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
0721 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
0722 }
0723
0724
0725 static void dpp20_program_shaper_lutb_settings(
0726 struct dpp *dpp_base,
0727 const struct pwl_params *params)
0728 {
0729 const struct gamma_curve *curve;
0730 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0731
0732 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
0733 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
0734 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
0735 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
0736 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
0737 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
0738 REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
0739 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
0740 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
0741
0742 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
0743 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
0744 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
0745
0746 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
0747 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
0748 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
0749
0750 REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
0751 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
0752 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
0753
0754 curve = params->arr_curve_points;
0755 REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
0756 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
0757 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
0758 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
0759 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
0760
0761 curve += 2;
0762 REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
0763 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
0764 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
0765 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
0766 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
0767
0768 curve += 2;
0769 REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
0770 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
0771 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
0772 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
0773 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
0774
0775 curve += 2;
0776 REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
0777 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
0778 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
0779 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
0780 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
0781
0782 curve += 2;
0783 REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
0784 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
0785 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
0786 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
0787 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
0788
0789 curve += 2;
0790 REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
0791 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
0792 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
0793 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
0794 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
0795
0796 curve += 2;
0797 REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
0798 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
0799 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
0800 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
0801 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
0802
0803 curve += 2;
0804 REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
0805 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
0806 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
0807 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
0808 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
0809
0810 curve += 2;
0811 REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
0812 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
0813 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
0814 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
0815 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
0816
0817 curve += 2;
0818 REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
0819 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
0820 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
0821 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
0822 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
0823
0824 curve += 2;
0825 REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
0826 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
0827 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
0828 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
0829 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
0830
0831 curve += 2;
0832 REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
0833 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
0834 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
0835 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
0836 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
0837
0838 curve += 2;
0839 REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
0840 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
0841 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
0842 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
0843 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
0844
0845 curve += 2;
0846 REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
0847 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
0848 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
0849 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
0850 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
0851
0852 curve += 2;
0853 REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
0854 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
0855 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
0856 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
0857 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
0858
0859 curve += 2;
0860 REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
0861 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
0862 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
0863 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
0864 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
0865
0866 curve += 2;
0867 REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
0868 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
0869 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
0870 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
0871 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
0872
0873 }
0874
0875
0876 bool dpp20_program_shaper(
0877 struct dpp *dpp_base,
0878 const struct pwl_params *params)
0879 {
0880 enum dc_lut_mode current_mode;
0881 enum dc_lut_mode next_mode;
0882
0883 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0884
0885 if (params == NULL) {
0886 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
0887 return false;
0888 }
0889 current_mode = dpp20_get_shaper_current(dpp_base);
0890
0891 if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
0892 next_mode = LUT_RAM_B;
0893 else
0894 next_mode = LUT_RAM_A;
0895
0896 dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
0897
0898 if (next_mode == LUT_RAM_A)
0899 dpp20_program_shaper_luta_settings(dpp_base, params);
0900 else
0901 dpp20_program_shaper_lutb_settings(dpp_base, params);
0902
0903 dpp20_program_shaper_lut(
0904 dpp_base, params->rgb_resulted, params->hw_points_num);
0905
0906 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
0907
0908 return true;
0909
0910 }
0911
0912 static enum dc_lut_mode get3dlut_config(
0913 struct dpp *dpp_base,
0914 bool *is_17x17x17,
0915 bool *is_12bits_color_channel)
0916 {
0917 uint32_t i_mode, i_enable_10bits, lut_size;
0918 enum dc_lut_mode mode;
0919 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0920
0921 REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
0922 CM_3DLUT_CONFIG_STATUS, &i_mode,
0923 CM_3DLUT_30BIT_EN, &i_enable_10bits);
0924
0925 switch (i_mode) {
0926 case 0:
0927 mode = LUT_BYPASS;
0928 break;
0929 case 1:
0930 mode = LUT_RAM_A;
0931 break;
0932 case 2:
0933 mode = LUT_RAM_B;
0934 break;
0935 default:
0936 mode = LUT_BYPASS;
0937 break;
0938 }
0939 if (i_enable_10bits > 0)
0940 *is_12bits_color_channel = false;
0941 else
0942 *is_12bits_color_channel = true;
0943
0944 REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
0945
0946 if (lut_size == 0)
0947 *is_17x17x17 = true;
0948 else
0949 *is_17x17x17 = false;
0950
0951 return mode;
0952 }
0953
0954
0955
0956
0957
0958 static void dpp20_set_3dlut_mode(
0959 struct dpp *dpp_base,
0960 enum dc_lut_mode mode,
0961 bool is_color_channel_12bits,
0962 bool is_lut_size17x17x17)
0963 {
0964 uint32_t lut_mode;
0965 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0966
0967 if (mode == LUT_BYPASS)
0968 lut_mode = 0;
0969 else if (mode == LUT_RAM_A)
0970 lut_mode = 1;
0971 else
0972 lut_mode = 2;
0973
0974 REG_UPDATE_2(CM_3DLUT_MODE,
0975 CM_3DLUT_MODE, lut_mode,
0976 CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
0977 }
0978
0979 static void dpp20_select_3dlut_ram(
0980 struct dpp *dpp_base,
0981 enum dc_lut_mode mode,
0982 bool is_color_channel_12bits)
0983 {
0984 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
0985
0986 REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
0987 CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
0988 CM_3DLUT_30BIT_EN,
0989 is_color_channel_12bits == true ? 0:1);
0990 }
0991
0992
0993
0994 static void dpp20_set3dlut_ram12(
0995 struct dpp *dpp_base,
0996 const struct dc_rgb *lut,
0997 uint32_t entries)
0998 {
0999 uint32_t i, red, green, blue, red1, green1, blue1;
1000 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1001
1002 for (i = 0 ; i < entries; i += 2) {
1003 red = lut[i].red<<4;
1004 green = lut[i].green<<4;
1005 blue = lut[i].blue<<4;
1006 red1 = lut[i+1].red<<4;
1007 green1 = lut[i+1].green<<4;
1008 blue1 = lut[i+1].blue<<4;
1009
1010 REG_SET_2(CM_3DLUT_DATA, 0,
1011 CM_3DLUT_DATA0, red,
1012 CM_3DLUT_DATA1, red1);
1013
1014 REG_SET_2(CM_3DLUT_DATA, 0,
1015 CM_3DLUT_DATA0, green,
1016 CM_3DLUT_DATA1, green1);
1017
1018 REG_SET_2(CM_3DLUT_DATA, 0,
1019 CM_3DLUT_DATA0, blue,
1020 CM_3DLUT_DATA1, blue1);
1021
1022 }
1023 }
1024
1025
1026
1027
1028 static void dpp20_set3dlut_ram10(
1029 struct dpp *dpp_base,
1030 const struct dc_rgb *lut,
1031 uint32_t entries)
1032 {
1033 uint32_t i, red, green, blue, value;
1034 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1035
1036 for (i = 0; i < entries; i++) {
1037 red = lut[i].red;
1038 green = lut[i].green;
1039 blue = lut[i].blue;
1040
1041 value = (red<<20) | (green<<10) | blue;
1042
1043 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1044 }
1045
1046 }
1047
1048
1049 static void dpp20_select_3dlut_ram_mask(
1050 struct dpp *dpp_base,
1051 uint32_t ram_selection_mask)
1052 {
1053 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1054
1055 REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1056 ram_selection_mask);
1057 REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1058 }
1059
1060 bool dpp20_program_3dlut(
1061 struct dpp *dpp_base,
1062 struct tetrahedral_params *params)
1063 {
1064 enum dc_lut_mode mode;
1065 bool is_17x17x17;
1066 bool is_12bits_color_channel;
1067 struct dc_rgb *lut0;
1068 struct dc_rgb *lut1;
1069 struct dc_rgb *lut2;
1070 struct dc_rgb *lut3;
1071 int lut_size0;
1072 int lut_size;
1073
1074 if (params == NULL) {
1075 dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1076 return false;
1077 }
1078 mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1079
1080 if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1081 mode = LUT_RAM_A;
1082 else
1083 mode = LUT_RAM_B;
1084
1085 is_17x17x17 = !params->use_tetrahedral_9;
1086 is_12bits_color_channel = params->use_12bits;
1087 if (is_17x17x17) {
1088 lut0 = params->tetrahedral_17.lut0;
1089 lut1 = params->tetrahedral_17.lut1;
1090 lut2 = params->tetrahedral_17.lut2;
1091 lut3 = params->tetrahedral_17.lut3;
1092 lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1093 sizeof(params->tetrahedral_17.lut0[0]);
1094 lut_size = sizeof(params->tetrahedral_17.lut1)/
1095 sizeof(params->tetrahedral_17.lut1[0]);
1096 } else {
1097 lut0 = params->tetrahedral_9.lut0;
1098 lut1 = params->tetrahedral_9.lut1;
1099 lut2 = params->tetrahedral_9.lut2;
1100 lut3 = params->tetrahedral_9.lut3;
1101 lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1102 sizeof(params->tetrahedral_9.lut0[0]);
1103 lut_size = sizeof(params->tetrahedral_9.lut1)/
1104 sizeof(params->tetrahedral_9.lut1[0]);
1105 }
1106
1107 dpp20_select_3dlut_ram(dpp_base, mode,
1108 is_12bits_color_channel);
1109 dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
1110 if (is_12bits_color_channel)
1111 dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
1112 else
1113 dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
1114
1115 dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
1116 if (is_12bits_color_channel)
1117 dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
1118 else
1119 dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
1120
1121 dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
1122 if (is_12bits_color_channel)
1123 dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
1124 else
1125 dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
1126
1127 dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
1128 if (is_12bits_color_channel)
1129 dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
1130 else
1131 dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
1132
1133
1134 dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1135 is_17x17x17);
1136
1137 return true;
1138 }
1139
1140 void dpp2_set_hdr_multiplier(
1141 struct dpp *dpp_base,
1142 uint32_t multiplier)
1143 {
1144 struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1145
1146 REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
1147 }