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 #include "dcn20_opp.h"
0028 #include "reg_helper.h"
0029
0030 #define REG(reg) \
0031 (oppn20->regs->reg)
0032
0033 #undef FN
0034 #define FN(reg_name, field_name) \
0035 oppn20->opp_shift->field_name, oppn20->opp_mask->field_name
0036
0037 #define CTX \
0038 oppn20->base.ctx
0039
0040
0041 void opp2_set_disp_pattern_generator(
0042 struct output_pixel_processor *opp,
0043 enum controller_dp_test_pattern test_pattern,
0044 enum controller_dp_color_space color_space,
0045 enum dc_color_depth color_depth,
0046 const struct tg_color *solid_color,
0047 int width,
0048 int height,
0049 int offset)
0050 {
0051 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0052 enum test_pattern_color_format bit_depth;
0053 enum test_pattern_dyn_range dyn_range;
0054 enum test_pattern_mode mode;
0055
0056
0057 uint32_t src_bpc = 16;
0058
0059 uint32_t dst_bpc;
0060 uint32_t index;
0061
0062
0063
0064
0065
0066 uint16_t src_color[6] = {0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
0067 0x0000, 0x0000};
0068
0069 uint16_t dst_color[6];
0070 uint32_t inc_base;
0071
0072
0073 switch (color_depth) {
0074 case COLOR_DEPTH_666:
0075 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_6;
0076 break;
0077 case COLOR_DEPTH_888:
0078 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
0079 break;
0080 case COLOR_DEPTH_101010:
0081 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_10;
0082 break;
0083 case COLOR_DEPTH_121212:
0084 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_12;
0085 break;
0086 default:
0087 bit_depth = TEST_PATTERN_COLOR_FORMAT_BPC_8;
0088 break;
0089 }
0090
0091
0092 REG_SET_2(DPG_DIMENSIONS, 0,
0093 DPG_ACTIVE_WIDTH, width,
0094 DPG_ACTIVE_HEIGHT, height);
0095
0096
0097 REG_SET_2(DPG_OFFSET_SEGMENT, 0,
0098 DPG_X_OFFSET, offset,
0099 DPG_SEGMENT_WIDTH, 0);
0100
0101 switch (test_pattern) {
0102 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES:
0103 case CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA:
0104 {
0105 dyn_range = (test_pattern ==
0106 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA ?
0107 TEST_PATTERN_DYN_RANGE_CEA :
0108 TEST_PATTERN_DYN_RANGE_VESA);
0109
0110 switch (color_space) {
0111 case CONTROLLER_DP_COLOR_SPACE_YCBCR601:
0112 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR601;
0113 break;
0114 case CONTROLLER_DP_COLOR_SPACE_YCBCR709:
0115 mode = TEST_PATTERN_MODE_COLORSQUARES_YCBCR709;
0116 break;
0117 case CONTROLLER_DP_COLOR_SPACE_RGB:
0118 default:
0119 mode = TEST_PATTERN_MODE_COLORSQUARES_RGB;
0120 break;
0121 }
0122
0123 REG_UPDATE_6(DPG_CONTROL,
0124 DPG_EN, 1,
0125 DPG_MODE, mode,
0126 DPG_DYNAMIC_RANGE, dyn_range,
0127 DPG_BIT_DEPTH, bit_depth,
0128 DPG_VRES, 6,
0129 DPG_HRES, 6);
0130 }
0131 break;
0132
0133 case CONTROLLER_DP_TEST_PATTERN_VERTICALBARS:
0134 case CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS:
0135 {
0136 mode = (test_pattern ==
0137 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS ?
0138 TEST_PATTERN_MODE_VERTICALBARS :
0139 TEST_PATTERN_MODE_HORIZONTALBARS);
0140
0141 switch (bit_depth) {
0142 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0143 dst_bpc = 6;
0144 break;
0145 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0146 dst_bpc = 8;
0147 break;
0148 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0149 dst_bpc = 10;
0150 break;
0151 default:
0152 dst_bpc = 8;
0153 break;
0154 }
0155
0156
0157 for (index = 0; index < 6; index++) {
0158
0159
0160
0161 dst_color[index] =
0162 src_color[index] >> (src_bpc - dst_bpc);
0163
0164
0165
0166
0167
0168 dst_color[index] <<= (16 - dst_bpc);
0169 }
0170
0171 REG_SET_2(DPG_COLOUR_R_CR, 0,
0172 DPG_COLOUR1_R_CR, dst_color[0],
0173 DPG_COLOUR0_R_CR, dst_color[3]);
0174 REG_SET_2(DPG_COLOUR_G_Y, 0,
0175 DPG_COLOUR1_G_Y, dst_color[1],
0176 DPG_COLOUR0_G_Y, dst_color[4]);
0177 REG_SET_2(DPG_COLOUR_B_CB, 0,
0178 DPG_COLOUR1_B_CB, dst_color[2],
0179 DPG_COLOUR0_B_CB, dst_color[5]);
0180
0181
0182 REG_UPDATE_6(DPG_CONTROL,
0183 DPG_EN, 1,
0184 DPG_MODE, mode,
0185 DPG_DYNAMIC_RANGE, 0,
0186 DPG_BIT_DEPTH, bit_depth,
0187 DPG_VRES, 0,
0188 DPG_HRES, 0);
0189 }
0190 break;
0191
0192 case CONTROLLER_DP_TEST_PATTERN_COLORRAMP:
0193 {
0194 mode = (bit_depth ==
0195 TEST_PATTERN_COLOR_FORMAT_BPC_10 ?
0196 TEST_PATTERN_MODE_DUALRAMP_RGB :
0197 TEST_PATTERN_MODE_SINGLERAMP_RGB);
0198
0199 switch (bit_depth) {
0200 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0201 dst_bpc = 6;
0202 break;
0203 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0204 dst_bpc = 8;
0205 break;
0206 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0207 dst_bpc = 10;
0208 break;
0209 default:
0210 dst_bpc = 8;
0211 break;
0212 }
0213
0214
0215
0216
0217
0218 inc_base = (src_bpc - dst_bpc);
0219
0220 switch (bit_depth) {
0221 case TEST_PATTERN_COLOR_FORMAT_BPC_6:
0222 {
0223 REG_SET_3(DPG_RAMP_CONTROL, 0,
0224 DPG_RAMP0_OFFSET, 0,
0225 DPG_INC0, inc_base,
0226 DPG_INC1, 0);
0227 REG_UPDATE_2(DPG_CONTROL,
0228 DPG_VRES, 6,
0229 DPG_HRES, 6);
0230 }
0231 break;
0232 case TEST_PATTERN_COLOR_FORMAT_BPC_8:
0233 {
0234 REG_SET_3(DPG_RAMP_CONTROL, 0,
0235 DPG_RAMP0_OFFSET, 0,
0236 DPG_INC0, inc_base,
0237 DPG_INC1, 0);
0238 REG_UPDATE_2(DPG_CONTROL,
0239 DPG_VRES, 6,
0240 DPG_HRES, 8);
0241 }
0242 break;
0243 case TEST_PATTERN_COLOR_FORMAT_BPC_10:
0244 {
0245 REG_SET_3(DPG_RAMP_CONTROL, 0,
0246 DPG_RAMP0_OFFSET, 384 << 6,
0247 DPG_INC0, inc_base,
0248 DPG_INC1, inc_base + 2);
0249 REG_UPDATE_2(DPG_CONTROL,
0250 DPG_VRES, 5,
0251 DPG_HRES, 8);
0252 }
0253 break;
0254 default:
0255 break;
0256 }
0257
0258
0259 REG_UPDATE_4(DPG_CONTROL,
0260 DPG_EN, 1,
0261 DPG_MODE, mode,
0262 DPG_DYNAMIC_RANGE, 0,
0263 DPG_BIT_DEPTH, bit_depth);
0264 }
0265 break;
0266 case CONTROLLER_DP_TEST_PATTERN_VIDEOMODE:
0267 {
0268 REG_WRITE(DPG_CONTROL, 0);
0269 REG_WRITE(DPG_COLOUR_R_CR, 0);
0270 REG_WRITE(DPG_COLOUR_G_Y, 0);
0271 REG_WRITE(DPG_COLOUR_B_CB, 0);
0272 REG_WRITE(DPG_RAMP_CONTROL, 0);
0273 }
0274 break;
0275 case CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR:
0276 {
0277 opp2_dpg_set_blank_color(opp, solid_color);
0278 REG_UPDATE_2(DPG_CONTROL,
0279 DPG_EN, 1,
0280 DPG_MODE, TEST_PATTERN_MODE_HORIZONTALBARS);
0281
0282 REG_SET_2(DPG_DIMENSIONS, 0,
0283 DPG_ACTIVE_WIDTH, width,
0284 DPG_ACTIVE_HEIGHT, height);
0285 }
0286 break;
0287 default:
0288 break;
0289
0290 }
0291 }
0292
0293 void opp2_program_dpg_dimensions(
0294 struct output_pixel_processor *opp,
0295 int width, int height)
0296 {
0297 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0298
0299 REG_SET_2(DPG_DIMENSIONS, 0,
0300 DPG_ACTIVE_WIDTH, width,
0301 DPG_ACTIVE_HEIGHT, height);
0302 }
0303
0304 void opp2_dpg_set_blank_color(
0305 struct output_pixel_processor *opp,
0306 const struct tg_color *color)
0307 {
0308 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0309
0310
0311 ASSERT(color);
0312 REG_SET_2(DPG_COLOUR_B_CB, 0,
0313 DPG_COLOUR1_B_CB, color->color_b_cb << 6,
0314 DPG_COLOUR0_B_CB, color->color_b_cb << 6);
0315 REG_SET_2(DPG_COLOUR_G_Y, 0,
0316 DPG_COLOUR1_G_Y, color->color_g_y << 6,
0317 DPG_COLOUR0_G_Y, color->color_g_y << 6);
0318 REG_SET_2(DPG_COLOUR_R_CR, 0,
0319 DPG_COLOUR1_R_CR, color->color_r_cr << 6,
0320 DPG_COLOUR0_R_CR, color->color_r_cr << 6);
0321 }
0322
0323 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp)
0324 {
0325 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0326 uint32_t dpg_en, dpg_mode;
0327 uint32_t double_buffer_pending;
0328
0329 REG_GET_2(DPG_CONTROL,
0330 DPG_EN, &dpg_en,
0331 DPG_MODE, &dpg_mode);
0332
0333 REG_GET(DPG_STATUS,
0334 DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
0335
0336 return (dpg_en == 1) &&
0337 (double_buffer_pending == 0);
0338 }
0339
0340 void opp2_program_left_edge_extra_pixel (
0341 struct output_pixel_processor *opp,
0342 bool count)
0343 {
0344 struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
0345
0346
0347
0348
0349
0350 REG_UPDATE(FMT_422_CONTROL, FMT_LEFT_EDGE_EXTRA_PIXEL_COUNT, count);
0351 }
0352
0353
0354
0355
0356
0357 static struct opp_funcs dcn20_opp_funcs = {
0358 .opp_set_dyn_expansion = opp1_set_dyn_expansion,
0359 .opp_program_fmt = opp1_program_fmt,
0360 .opp_program_bit_depth_reduction = opp1_program_bit_depth_reduction,
0361 .opp_program_stereo = opp1_program_stereo,
0362 .opp_pipe_clock_control = opp1_pipe_clock_control,
0363 .opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
0364 .opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
0365 .dpg_is_blanked = opp2_dpg_is_blanked,
0366 .opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
0367 .opp_destroy = opp1_destroy,
0368 .opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
0369 };
0370
0371 void dcn20_opp_construct(struct dcn20_opp *oppn20,
0372 struct dc_context *ctx,
0373 uint32_t inst,
0374 const struct dcn20_opp_registers *regs,
0375 const struct dcn20_opp_shift *opp_shift,
0376 const struct dcn20_opp_mask *opp_mask)
0377 {
0378 oppn20->base.ctx = ctx;
0379 oppn20->base.inst = inst;
0380 oppn20->base.funcs = &dcn20_opp_funcs;
0381
0382 oppn20->regs = regs;
0383 oppn20->opp_shift = opp_shift;
0384 oppn20->opp_mask = opp_mask;
0385 }
0386