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
0027 #include "dc_bios_types.h"
0028 #include "dcn30/dcn30_dio_stream_encoder.h"
0029 #include "dcn32_dio_stream_encoder.h"
0030 #include "reg_helper.h"
0031 #include "hw_shared.h"
0032 #include "inc/link_dpcd.h"
0033 #include "dpcd_defs.h"
0034
0035 #define DC_LOGGER \
0036 enc1->base.ctx->logger
0037
0038 #define REG(reg)\
0039 (enc1->regs->reg)
0040
0041 #undef FN
0042 #define FN(reg_name, field_name) \
0043 enc1->se_shift->field_name, enc1->se_mask->field_name
0044
0045 #define VBI_LINE_0 0
0046 #define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
0047
0048 #define CTX \
0049 enc1->base.ctx
0050
0051
0052
0053 static void enc32_dp_set_odm_combine(
0054 struct stream_encoder *enc,
0055 bool odm_combine)
0056 {
0057 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0058
0059 REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_PER_CYCLE_PROCESSING_MODE, odm_combine ? 1 : 0);
0060 }
0061
0062
0063 void enc32_stream_encoder_dvi_set_stream_attribute(
0064 struct stream_encoder *enc,
0065 struct dc_crtc_timing *crtc_timing,
0066 bool is_dual_link)
0067 {
0068 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0069
0070 if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
0071 struct bp_encoder_control cntl = {0};
0072
0073 cntl.action = ENCODER_CONTROL_SETUP;
0074 cntl.engine_id = enc1->base.id;
0075 cntl.signal = is_dual_link ?
0076 SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK;
0077 cntl.enable_dp_audio = false;
0078 cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10;
0079 cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
0080
0081 if (enc1->base.bp->funcs->encoder_control(
0082 enc1->base.bp, &cntl) != BP_RESULT_OK)
0083 return;
0084
0085 } else {
0086
0087
0088 REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
0089
0090
0091
0092
0093
0094
0095 }
0096
0097 ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);
0098 ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888);
0099 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
0100 }
0101
0102
0103 static void enc32_stream_encoder_hdmi_set_stream_attribute(
0104 struct stream_encoder *enc,
0105 struct dc_crtc_timing *crtc_timing,
0106 int actual_pix_clk_khz,
0107 bool enable_audio)
0108 {
0109 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0110
0111 if (!enc->ctx->dc->debug.avoid_vbios_exec_table) {
0112 struct bp_encoder_control cntl = {0};
0113
0114 cntl.action = ENCODER_CONTROL_SETUP;
0115 cntl.engine_id = enc1->base.id;
0116 cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
0117 cntl.enable_dp_audio = enable_audio;
0118 cntl.pixel_clock = actual_pix_clk_khz;
0119 cntl.lanes_number = LANE_COUNT_FOUR;
0120
0121 if (enc1->base.bp->funcs->encoder_control(
0122 enc1->base.bp, &cntl) != BP_RESULT_OK)
0123 return;
0124
0125 } else {
0126
0127
0128 REG_UPDATE(DIG_CLOCK_PATTERN, DIG_CLOCK_PATTERN, 0x1F);
0129
0130
0131
0132
0133
0134
0135 }
0136
0137
0138 enc1_stream_encoder_set_stream_attribute_helper(enc1, crtc_timing);
0139
0140
0141 REG_UPDATE_6(HDMI_CONTROL,
0142 HDMI_PACKET_GEN_VERSION, 1,
0143 HDMI_KEEPOUT_MODE, 1,
0144 HDMI_DEEP_COLOR_ENABLE, 0,
0145 HDMI_DATA_SCRAMBLE_EN, 0,
0146 HDMI_NO_EXTRA_NULL_PACKET_FILLED, 1,
0147 HDMI_CLOCK_CHANNEL_RATE, 0);
0148
0149
0150 switch (crtc_timing->display_color_depth) {
0151 case COLOR_DEPTH_888:
0152 REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);
0153 break;
0154 case COLOR_DEPTH_101010:
0155 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
0156 REG_UPDATE_2(HDMI_CONTROL,
0157 HDMI_DEEP_COLOR_DEPTH, 1,
0158 HDMI_DEEP_COLOR_ENABLE, 0);
0159 } else {
0160 REG_UPDATE_2(HDMI_CONTROL,
0161 HDMI_DEEP_COLOR_DEPTH, 1,
0162 HDMI_DEEP_COLOR_ENABLE, 1);
0163 }
0164 break;
0165 case COLOR_DEPTH_121212:
0166 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
0167 REG_UPDATE_2(HDMI_CONTROL,
0168 HDMI_DEEP_COLOR_DEPTH, 2,
0169 HDMI_DEEP_COLOR_ENABLE, 0);
0170 } else {
0171 REG_UPDATE_2(HDMI_CONTROL,
0172 HDMI_DEEP_COLOR_DEPTH, 2,
0173 HDMI_DEEP_COLOR_ENABLE, 1);
0174 }
0175 break;
0176 case COLOR_DEPTH_161616:
0177 REG_UPDATE_2(HDMI_CONTROL,
0178 HDMI_DEEP_COLOR_DEPTH, 3,
0179 HDMI_DEEP_COLOR_ENABLE, 1);
0180 break;
0181 default:
0182 break;
0183 }
0184
0185 if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
0186
0187
0188
0189
0190 REG_UPDATE_2(HDMI_CONTROL,
0191 HDMI_DATA_SCRAMBLE_EN, 1,
0192 HDMI_CLOCK_CHANNEL_RATE, 1);
0193 } else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {
0194
0195
0196
0197
0198
0199
0200
0201
0202 REG_UPDATE_2(HDMI_CONTROL,
0203 HDMI_DATA_SCRAMBLE_EN, 1,
0204 HDMI_CLOCK_CHANNEL_RATE, 0);
0205 }
0206
0207
0208
0209 REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,
0210 HDMI_GC_CONT, 1,
0211 HDMI_GC_SEND, 1,
0212 HDMI_NULL_SEND, 1);
0213
0214 #if defined(CONFIG_DRM_AMD_DC_HDCP)
0215
0216 REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);
0217 #endif
0218
0219
0220
0221 REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);
0222
0223
0224 ASSERT(enc->afmt);
0225 enc->afmt->funcs->audio_info_immediate_update(enc->afmt);
0226
0227
0228 REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE,
0229 VBI_LINE_0 + 2);
0230
0231
0232 REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);
0233 }
0234
0235
0236
0237 static bool is_two_pixels_per_containter(const struct dc_crtc_timing *timing)
0238 {
0239 bool two_pix = timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
0240
0241 two_pix = two_pix || (timing->flags.DSC && timing->pixel_encoding == PIXEL_ENCODING_YCBCR422
0242 && !timing->dsc_cfg.ycbcr422_simple);
0243 return two_pix;
0244 }
0245
0246 static void enc32_stream_encoder_dp_unblank(
0247 struct dc_link *link,
0248 struct stream_encoder *enc,
0249 const struct encoder_unblank_param *param)
0250 {
0251 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0252 struct dc *dc = enc->ctx->dc;
0253
0254 if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
0255 uint32_t n_vid = 0x8000;
0256 uint32_t m_vid;
0257 uint32_t n_multiply = 0;
0258 uint64_t m_vid_l = n_vid;
0259
0260
0261 if (is_two_pixels_per_containter(¶m->timing) || param->opp_cnt > 1
0262 || dc->debug.enable_dp_dig_pixel_rate_div_policy) {
0263
0264 n_multiply = 1;
0265 }
0266
0267
0268
0269
0270 m_vid_l *= param->timing.pix_clk_100hz / 10;
0271 m_vid_l = div_u64(m_vid_l,
0272 param->link_settings.link_rate
0273 * LINK_RATE_REF_FREQ_IN_KHZ);
0274
0275 m_vid = (uint32_t) m_vid_l;
0276
0277
0278
0279 REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);
0280
0281
0282
0283
0284
0285 REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);
0286
0287 REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);
0288
0289 REG_UPDATE_2(DP_VID_TIMING,
0290 DP_VID_M_N_GEN_EN, 1,
0291 DP_VID_N_MUL, n_multiply);
0292 }
0293
0294
0295 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false);
0296 REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000);
0297
0298
0299
0300
0301
0302
0303 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1);
0304 udelay(10);
0305
0306 REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);
0307
0308
0309
0310
0311 REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
0312
0313
0314
0315
0316 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7);
0317
0318 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
0319
0320 REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
0321
0322 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
0323
0324 REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
0325
0326 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
0327
0328
0329
0330
0331 udelay(100);
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);
0342
0343 dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_DP_VID_STREAM);
0344 }
0345
0346
0347
0348
0349
0350
0351 static void enc32_dp_set_dsc_config(struct stream_encoder *enc,
0352 enum optc_dsc_mode dsc_mode,
0353 uint32_t dsc_bytes_per_pixel,
0354 uint32_t dsc_slice_width)
0355 {
0356 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0357
0358 REG_UPDATE(DP_DSC_CNTL, DP_DSC_MODE, dsc_mode);
0359 }
0360
0361
0362
0363
0364 static void enc32_read_state(struct stream_encoder *enc, struct enc_state *s)
0365 {
0366 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0367
0368
0369 REG_GET(DP_DSC_CNTL, DP_DSC_MODE, &s->dsc_mode);
0370 if (s->dsc_mode) {
0371 REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_LINE_NUM, &s->sec_gsp_pps_line_num);
0372
0373 REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_REFERENCE, &s->vbid6_line_reference);
0374 REG_GET(DP_MSA_VBID_MISC, DP_VBID6_LINE_NUM, &s->vbid6_line_num);
0375
0376 REG_GET(DP_GSP11_CNTL, DP_SEC_GSP11_ENABLE, &s->sec_gsp_pps_enable);
0377 REG_GET(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, &s->sec_stream_enable);
0378 }
0379 }
0380
0381 static void enc32_stream_encoder_reset_fifo(struct stream_encoder *enc)
0382 {
0383 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0384 uint32_t fifo_enabled;
0385
0386 REG_GET(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, &fifo_enabled);
0387
0388 if (fifo_enabled == 0) {
0389
0390 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
0391
0392
0393 udelay(1);
0394 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
0395 REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 1, 100);
0396 }
0397 }
0398
0399 static void enc32_set_dig_input_mode(struct stream_encoder *enc, unsigned int pix_per_container)
0400 {
0401 struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
0402
0403
0404
0405
0406 REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_OUTPUT_PIXEL_MODE, pix_per_container == 2 ? 0x1 : 0x0);
0407 }
0408
0409 static const struct stream_encoder_funcs dcn32_str_enc_funcs = {
0410 .dp_set_odm_combine =
0411 enc32_dp_set_odm_combine,
0412 .dp_set_stream_attribute =
0413 enc2_stream_encoder_dp_set_stream_attribute,
0414 .hdmi_set_stream_attribute =
0415 enc32_stream_encoder_hdmi_set_stream_attribute,
0416 .dvi_set_stream_attribute =
0417 enc32_stream_encoder_dvi_set_stream_attribute,
0418 .set_throttled_vcp_size =
0419 enc1_stream_encoder_set_throttled_vcp_size,
0420 .update_hdmi_info_packets =
0421 enc3_stream_encoder_update_hdmi_info_packets,
0422 .stop_hdmi_info_packets =
0423 enc3_stream_encoder_stop_hdmi_info_packets,
0424 .update_dp_info_packets =
0425 enc3_stream_encoder_update_dp_info_packets,
0426 .stop_dp_info_packets =
0427 enc1_stream_encoder_stop_dp_info_packets,
0428 .reset_fifo =
0429 enc32_stream_encoder_reset_fifo,
0430 .dp_blank =
0431 enc1_stream_encoder_dp_blank,
0432 .dp_unblank =
0433 enc32_stream_encoder_dp_unblank,
0434 .audio_mute_control = enc3_audio_mute_control,
0435
0436 .dp_audio_setup = enc3_se_dp_audio_setup,
0437 .dp_audio_enable = enc3_se_dp_audio_enable,
0438 .dp_audio_disable = enc1_se_dp_audio_disable,
0439
0440 .hdmi_audio_setup = enc3_se_hdmi_audio_setup,
0441 .hdmi_audio_disable = enc1_se_hdmi_audio_disable,
0442 .setup_stereo_sync = enc1_setup_stereo_sync,
0443 .set_avmute = enc1_stream_encoder_set_avmute,
0444 .dig_connect_to_otg = enc1_dig_connect_to_otg,
0445 .dig_source_otg = enc1_dig_source_otg,
0446
0447 .dp_get_pixel_format = enc1_stream_encoder_dp_get_pixel_format,
0448
0449 .enc_read_state = enc32_read_state,
0450 .dp_set_dsc_config = enc32_dp_set_dsc_config,
0451 .dp_set_dsc_pps_info_packet = enc3_dp_set_dsc_pps_info_packet,
0452 .set_dynamic_metadata = enc2_set_dynamic_metadata,
0453 .hdmi_reset_stream_attribute = enc1_reset_hdmi_stream_attribute,
0454
0455 .set_input_mode = enc32_set_dig_input_mode,
0456 };
0457
0458 void dcn32_dio_stream_encoder_construct(
0459 struct dcn10_stream_encoder *enc1,
0460 struct dc_context *ctx,
0461 struct dc_bios *bp,
0462 enum engine_id eng_id,
0463 struct vpg *vpg,
0464 struct afmt *afmt,
0465 const struct dcn10_stream_enc_registers *regs,
0466 const struct dcn10_stream_encoder_shift *se_shift,
0467 const struct dcn10_stream_encoder_mask *se_mask)
0468 {
0469 enc1->base.funcs = &dcn32_str_enc_funcs;
0470 enc1->base.ctx = ctx;
0471 enc1->base.id = eng_id;
0472 enc1->base.bp = bp;
0473 enc1->base.vpg = vpg;
0474 enc1->base.afmt = afmt;
0475 enc1->regs = regs;
0476 enc1->se_shift = se_shift;
0477 enc1->se_mask = se_mask;
0478 enc1->base.stream_enc_inst = vpg->inst;
0479 }
0480