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
0028 #include "core_types.h"
0029 #include "link_encoder.h"
0030 #include "dce_link_encoder.h"
0031 #include "stream_encoder.h"
0032 #include "i2caux_interface.h"
0033 #include "dc_bios_types.h"
0034
0035 #include "gpio_service_interface.h"
0036
0037 #include "dce/dce_11_0_d.h"
0038 #include "dce/dce_11_0_sh_mask.h"
0039 #include "dce/dce_11_0_enum.h"
0040
0041 #ifndef DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE__SHIFT
0042 #define DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE__SHIFT 0xa
0043 #endif
0044
0045 #ifndef DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE_MASK
0046 #define DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE_MASK 0x00000400L
0047 #endif
0048
0049 #ifndef HPD0_DC_HPD_CONTROL__DC_HPD_EN_MASK
0050 #define HPD0_DC_HPD_CONTROL__DC_HPD_EN_MASK 0x10000000L
0051 #endif
0052
0053 #ifndef HPD0_DC_HPD_CONTROL__DC_HPD_EN__SHIFT
0054 #define HPD0_DC_HPD_CONTROL__DC_HPD_EN__SHIFT 0x1c
0055 #endif
0056
0057 #define CTX \
0058 enc110->base.ctx
0059 #define DC_LOGGER \
0060 enc110->base.ctx->logger
0061
0062 #define REG(reg)\
0063 (enc110->link_regs->reg)
0064
0065 #define AUX_REG(reg)\
0066 (enc110->aux_regs->reg)
0067
0068 #define HPD_REG(reg)\
0069 (enc110->hpd_regs->reg)
0070
0071 #define DEFAULT_AUX_MAX_DATA_SIZE 16
0072 #define AUX_MAX_DEFER_WRITE_RETRY 20
0073
0074
0075
0076
0077
0078 #define DCE110_DIG_FE_SOURCE_SELECT_INVALID 0x0
0079 #define DCE110_DIG_FE_SOURCE_SELECT_DIGA 0x1
0080 #define DCE110_DIG_FE_SOURCE_SELECT_DIGB 0x2
0081 #define DCE110_DIG_FE_SOURCE_SELECT_DIGC 0x4
0082 #define DCE110_DIG_FE_SOURCE_SELECT_DIGD 0x08
0083 #define DCE110_DIG_FE_SOURCE_SELECT_DIGE 0x10
0084 #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20
0085 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40
0086
0087 enum {
0088 DP_MST_UPDATE_MAX_RETRY = 50
0089 };
0090
0091 #define DIG_REG(reg)\
0092 (reg + enc110->offsets.dig)
0093
0094 #define DP_REG(reg)\
0095 (reg + enc110->offsets.dp)
0096
0097 static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
0098 .validate_output_with_stream =
0099 dce110_link_encoder_validate_output_with_stream,
0100 .hw_init = dce110_link_encoder_hw_init,
0101 .setup = dce110_link_encoder_setup,
0102 .enable_tmds_output = dce110_link_encoder_enable_tmds_output,
0103 .enable_dp_output = dce110_link_encoder_enable_dp_output,
0104 .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output,
0105 .enable_lvds_output = dce110_link_encoder_enable_lvds_output,
0106 .disable_output = dce110_link_encoder_disable_output,
0107 .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
0108 .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern,
0109 .update_mst_stream_allocation_table =
0110 dce110_link_encoder_update_mst_stream_allocation_table,
0111 .psr_program_dp_dphy_fast_training =
0112 dce110_psr_program_dp_dphy_fast_training,
0113 .psr_program_secondary_packet = dce110_psr_program_secondary_packet,
0114 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
0115 .enable_hpd = dce110_link_encoder_enable_hpd,
0116 .disable_hpd = dce110_link_encoder_disable_hpd,
0117 .is_dig_enabled = dce110_is_dig_enabled,
0118 .destroy = dce110_link_encoder_destroy,
0119 .get_max_link_cap = dce110_link_encoder_get_max_link_cap,
0120 .get_dig_frontend = dce110_get_dig_frontend,
0121 };
0122
0123 static enum bp_result link_transmitter_control(
0124 struct dce110_link_encoder *enc110,
0125 struct bp_transmitter_control *cntl)
0126 {
0127 enum bp_result result;
0128 struct dc_bios *bp = enc110->base.ctx->dc_bios;
0129
0130 result = bp->funcs->transmitter_control(bp, cntl);
0131
0132 return result;
0133 }
0134
0135 static void enable_phy_bypass_mode(
0136 struct dce110_link_encoder *enc110,
0137 bool enable)
0138 {
0139
0140
0141
0142 REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable);
0143
0144 }
0145
0146 static void disable_prbs_symbols(
0147 struct dce110_link_encoder *enc110,
0148 bool disable)
0149 {
0150
0151
0152
0153 REG_UPDATE_4(DP_DPHY_CNTL,
0154 DPHY_ATEST_SEL_LANE0, disable,
0155 DPHY_ATEST_SEL_LANE1, disable,
0156 DPHY_ATEST_SEL_LANE2, disable,
0157 DPHY_ATEST_SEL_LANE3, disable);
0158 }
0159
0160 static void disable_prbs_mode(
0161 struct dce110_link_encoder *enc110)
0162 {
0163 REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0);
0164 }
0165
0166 static void program_pattern_symbols(
0167 struct dce110_link_encoder *enc110,
0168 uint16_t pattern_symbols[8])
0169 {
0170
0171
0172
0173 REG_SET_3(DP_DPHY_SYM0, 0,
0174 DPHY_SYM1, pattern_symbols[0],
0175 DPHY_SYM2, pattern_symbols[1],
0176 DPHY_SYM3, pattern_symbols[2]);
0177
0178
0179
0180
0181 REG_SET_3(DP_DPHY_SYM1, 0,
0182 DPHY_SYM4, pattern_symbols[3],
0183 DPHY_SYM5, pattern_symbols[4],
0184 DPHY_SYM6, pattern_symbols[5]);
0185
0186
0187
0188
0189 REG_SET_2(DP_DPHY_SYM2, 0,
0190 DPHY_SYM7, pattern_symbols[6],
0191 DPHY_SYM8, pattern_symbols[7]);
0192 }
0193
0194 static void set_dp_phy_pattern_d102(
0195 struct dce110_link_encoder *enc110)
0196 {
0197
0198 enable_phy_bypass_mode(enc110, false);
0199
0200
0201
0202
0203
0204
0205 disable_prbs_symbols(enc110, true);
0206
0207
0208 disable_prbs_mode(enc110);
0209
0210
0211 {
0212 uint16_t pattern_symbols[8] = {
0213 0x2AA, 0x2AA, 0x2AA, 0x2AA,
0214 0x2AA, 0x2AA, 0x2AA, 0x2AA
0215 };
0216
0217 program_pattern_symbols(enc110, pattern_symbols);
0218 }
0219
0220
0221
0222 enable_phy_bypass_mode(enc110, true);
0223 }
0224
0225 static void set_link_training_complete(
0226 struct dce110_link_encoder *enc110,
0227 bool complete)
0228 {
0229
0230
0231
0232 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete);
0233
0234 }
0235
0236 unsigned int dce110_get_dig_frontend(struct link_encoder *enc)
0237 {
0238 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0239 u32 value;
0240 enum engine_id result;
0241
0242 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value);
0243
0244 switch (value) {
0245 case DCE110_DIG_FE_SOURCE_SELECT_DIGA:
0246 result = ENGINE_ID_DIGA;
0247 break;
0248 case DCE110_DIG_FE_SOURCE_SELECT_DIGB:
0249 result = ENGINE_ID_DIGB;
0250 break;
0251 case DCE110_DIG_FE_SOURCE_SELECT_DIGC:
0252 result = ENGINE_ID_DIGC;
0253 break;
0254 case DCE110_DIG_FE_SOURCE_SELECT_DIGD:
0255 result = ENGINE_ID_DIGD;
0256 break;
0257 case DCE110_DIG_FE_SOURCE_SELECT_DIGE:
0258 result = ENGINE_ID_DIGE;
0259 break;
0260 case DCE110_DIG_FE_SOURCE_SELECT_DIGF:
0261 result = ENGINE_ID_DIGF;
0262 break;
0263 case DCE110_DIG_FE_SOURCE_SELECT_DIGG:
0264 result = ENGINE_ID_DIGG;
0265 break;
0266 default:
0267
0268 result = ENGINE_ID_UNKNOWN;
0269 }
0270
0271 return result;
0272 }
0273
0274 void dce110_link_encoder_set_dp_phy_pattern_training_pattern(
0275 struct link_encoder *enc,
0276 uint32_t index)
0277 {
0278 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0279
0280
0281 REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index);
0282
0283
0284
0285 set_link_training_complete(enc110, false);
0286
0287
0288
0289 enable_phy_bypass_mode(enc110, false);
0290
0291
0292 disable_prbs_mode(enc110);
0293 }
0294
0295 static void setup_panel_mode(
0296 struct dce110_link_encoder *enc110,
0297 enum dp_panel_mode panel_mode)
0298 {
0299 uint32_t value;
0300 struct dc_context *ctx = enc110->base.ctx;
0301
0302
0303 if (ctx->dc->caps.psp_setup_panel_mode)
0304 return;
0305
0306 ASSERT(REG(DP_DPHY_INTERNAL_CTRL));
0307 value = REG_READ(DP_DPHY_INTERNAL_CTRL);
0308
0309 switch (panel_mode) {
0310 case DP_PANEL_MODE_EDP:
0311 value = 0x1;
0312 break;
0313 case DP_PANEL_MODE_SPECIAL:
0314 value = 0x11;
0315 break;
0316 default:
0317 value = 0x0;
0318 break;
0319 }
0320
0321 REG_WRITE(DP_DPHY_INTERNAL_CTRL, value);
0322 }
0323
0324 static void set_dp_phy_pattern_symbol_error(
0325 struct dce110_link_encoder *enc110)
0326 {
0327
0328 enable_phy_bypass_mode(enc110, false);
0329
0330
0331 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT);
0332
0333
0334
0335
0336 disable_prbs_symbols(enc110, false);
0337
0338
0339 REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
0340 DPHY_PRBS_SEL, 1,
0341 DPHY_PRBS_EN, 1);
0342
0343
0344 enable_phy_bypass_mode(enc110, true);
0345 }
0346
0347 static void set_dp_phy_pattern_prbs7(
0348 struct dce110_link_encoder *enc110)
0349 {
0350
0351 enable_phy_bypass_mode(enc110, false);
0352
0353
0354
0355
0356 disable_prbs_symbols(enc110, false);
0357
0358
0359 REG_UPDATE_2(DP_DPHY_PRBS_CNTL,
0360 DPHY_PRBS_SEL, 0,
0361 DPHY_PRBS_EN, 1);
0362
0363
0364 enable_phy_bypass_mode(enc110, true);
0365 }
0366
0367 static void set_dp_phy_pattern_80bit_custom(
0368 struct dce110_link_encoder *enc110,
0369 const uint8_t *pattern)
0370 {
0371
0372 enable_phy_bypass_mode(enc110, false);
0373
0374
0375
0376 disable_prbs_symbols(enc110, true);
0377
0378
0379
0380
0381 enable_phy_bypass_mode(enc110, true);
0382
0383
0384 {
0385 uint16_t pattern_symbols[8];
0386
0387 pattern_symbols[0] =
0388 ((pattern[1] & 0x03) << 8) | pattern[0];
0389 pattern_symbols[1] =
0390 ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
0391 pattern_symbols[2] =
0392 ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
0393 pattern_symbols[3] =
0394 (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
0395 pattern_symbols[4] =
0396 ((pattern[6] & 0x03) << 8) | pattern[5];
0397 pattern_symbols[5] =
0398 ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
0399 pattern_symbols[6] =
0400 ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
0401 pattern_symbols[7] =
0402 (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
0403
0404 program_pattern_symbols(enc110, pattern_symbols);
0405 }
0406
0407
0408
0409 enable_phy_bypass_mode(enc110, true);
0410 }
0411
0412 static void set_dp_phy_pattern_hbr2_compliance_cp2520_2(
0413 struct dce110_link_encoder *enc110,
0414 unsigned int cp2520_pattern)
0415 {
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 enable_phy_bypass_mode(enc110, false);
0428
0429
0430 enc110->base.funcs->setup(&enc110->base, SIGNAL_TYPE_DISPLAY_PORT);
0431
0432
0433 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT);
0434
0435
0436
0437
0438 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0439 DP_IDLE_BS_INTERVAL, 0xFC,
0440 DP_VBID_DISABLE, 1,
0441 DP_VID_ENHANCED_FRAME_MODE, 1);
0442
0443
0444 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0);
0445
0446
0447 if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
0448 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
0449 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
0450 else
0451
0452 ASSERT(cp2520_pattern == 2);
0453
0454
0455 set_link_training_complete(enc110, true);
0456
0457
0458 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
0459
0460
0461 enable_phy_bypass_mode(enc110, false);
0462 }
0463
0464 #if defined(CONFIG_DRM_AMD_DC_SI)
0465 static void dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(
0466 struct dce110_link_encoder *enc110,
0467 unsigned int cp2520_pattern)
0468 {
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 enable_phy_bypass_mode(enc110, false);
0481
0482
0483 enc110->base.funcs->setup(&enc110->base, SIGNAL_TYPE_DISPLAY_PORT);
0484
0485
0486 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT);
0487
0488
0489
0490
0491 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0492 DP_IDLE_BS_INTERVAL, 0xFC,
0493 DP_VBID_DISABLE, 1,
0494 DP_VID_ENHANCED_FRAME_MODE, 1);
0495
0496
0497
0498
0499 if (REG(DP_DPHY_HBR2_PATTERN_CONTROL))
0500 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL,
0501 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern);
0502 else
0503
0504 ASSERT(cp2520_pattern == 2);
0505
0506
0507 set_link_training_complete(enc110, true);
0508
0509
0510 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);
0511
0512
0513 enable_phy_bypass_mode(enc110, false);
0514 }
0515 #endif
0516
0517 static void set_dp_phy_pattern_passthrough_mode(
0518 struct dce110_link_encoder *enc110,
0519 enum dp_panel_mode panel_mode)
0520 {
0521
0522 setup_panel_mode(enc110, panel_mode);
0523
0524
0525
0526
0527 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0528 DP_IDLE_BS_INTERVAL, 0x2000,
0529 DP_VBID_DISABLE, 0,
0530 DP_VID_ENHANCED_FRAME_MODE, 1);
0531
0532 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF);
0533
0534
0535 set_link_training_complete(enc110, true);
0536
0537
0538 enable_phy_bypass_mode(enc110, false);
0539
0540
0541 disable_prbs_mode(enc110);
0542 }
0543
0544 #if defined(CONFIG_DRM_AMD_DC_SI)
0545 static void dce60_set_dp_phy_pattern_passthrough_mode(
0546 struct dce110_link_encoder *enc110,
0547 enum dp_panel_mode panel_mode)
0548 {
0549
0550 setup_panel_mode(enc110, panel_mode);
0551
0552
0553
0554
0555 REG_UPDATE_3(DP_LINK_FRAMING_CNTL,
0556 DP_IDLE_BS_INTERVAL, 0x2000,
0557 DP_VBID_DISABLE, 0,
0558 DP_VID_ENHANCED_FRAME_MODE, 1);
0559
0560
0561
0562
0563 set_link_training_complete(enc110, true);
0564
0565
0566 enable_phy_bypass_mode(enc110, false);
0567
0568
0569 disable_prbs_mode(enc110);
0570 }
0571 #endif
0572
0573
0574 static uint8_t get_frontend_source(
0575 enum engine_id engine)
0576 {
0577 switch (engine) {
0578 case ENGINE_ID_DIGA:
0579 return DCE110_DIG_FE_SOURCE_SELECT_DIGA;
0580 case ENGINE_ID_DIGB:
0581 return DCE110_DIG_FE_SOURCE_SELECT_DIGB;
0582 case ENGINE_ID_DIGC:
0583 return DCE110_DIG_FE_SOURCE_SELECT_DIGC;
0584 case ENGINE_ID_DIGD:
0585 return DCE110_DIG_FE_SOURCE_SELECT_DIGD;
0586 case ENGINE_ID_DIGE:
0587 return DCE110_DIG_FE_SOURCE_SELECT_DIGE;
0588 case ENGINE_ID_DIGF:
0589 return DCE110_DIG_FE_SOURCE_SELECT_DIGF;
0590 case ENGINE_ID_DIGG:
0591 return DCE110_DIG_FE_SOURCE_SELECT_DIGG;
0592 default:
0593 ASSERT_CRITICAL(false);
0594 return DCE110_DIG_FE_SOURCE_SELECT_INVALID;
0595 }
0596 }
0597
0598 static void configure_encoder(
0599 struct dce110_link_encoder *enc110,
0600 const struct dc_link_settings *link_settings)
0601 {
0602
0603
0604 REG_SET(DP_CONFIG, 0,
0605 DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
0606
0607
0608 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1);
0609 }
0610
0611 #if defined(CONFIG_DRM_AMD_DC_SI)
0612 static void dce60_configure_encoder(
0613 struct dce110_link_encoder *enc110,
0614 const struct dc_link_settings *link_settings)
0615 {
0616
0617
0618 REG_SET(DP_CONFIG, 0,
0619 DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE);
0620
0621
0622 }
0623 #endif
0624
0625 static void aux_initialize(
0626 struct dce110_link_encoder *enc110)
0627 {
0628 struct dc_context *ctx = enc110->base.ctx;
0629 enum hpd_source_id hpd_source = enc110->base.hpd_source;
0630 uint32_t addr = AUX_REG(AUX_CONTROL);
0631 uint32_t value = dm_read_reg(ctx, addr);
0632
0633 set_reg_field_value(value, hpd_source, AUX_CONTROL, AUX_HPD_SEL);
0634 set_reg_field_value(value, 0, AUX_CONTROL, AUX_LS_READ_EN);
0635 dm_write_reg(ctx, addr, value);
0636
0637 addr = AUX_REG(AUX_DPHY_RX_CONTROL0);
0638 value = dm_read_reg(ctx, addr);
0639
0640
0641 set_reg_field_value(value, 1,
0642 AUX_DPHY_RX_CONTROL0, AUX_RX_RECEIVE_WINDOW);
0643 dm_write_reg(ctx, addr, value);
0644
0645 }
0646
0647 void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc,
0648 bool exit_link_training_required)
0649 {
0650 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0651
0652 if (exit_link_training_required)
0653 REG_UPDATE(DP_DPHY_FAST_TRAINING,
0654 DPHY_RX_FAST_TRAINING_CAPABLE, 1);
0655 else {
0656 REG_UPDATE(DP_DPHY_FAST_TRAINING,
0657 DPHY_RX_FAST_TRAINING_CAPABLE, 0);
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5);
0668 }
0669 }
0670
0671 void dce110_psr_program_secondary_packet(struct link_encoder *enc,
0672 unsigned int sdp_transmit_line_num_deadline)
0673 {
0674 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0675
0676 REG_UPDATE_2(DP_SEC_CNTL1,
0677 DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline,
0678 DP_SEC_GSP0_PRIORITY, 1);
0679 }
0680
0681 bool dce110_is_dig_enabled(struct link_encoder *enc)
0682 {
0683 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0684 uint32_t value;
0685
0686 REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value);
0687 return value;
0688 }
0689
0690 static void link_encoder_disable(struct dce110_link_encoder *enc110)
0691 {
0692
0693 REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0,
0694 DPHY_TRAINING_PATTERN_SEL, 0);
0695
0696
0697 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
0698
0699
0700 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT);
0701 }
0702
0703 static void hpd_initialize(
0704 struct dce110_link_encoder *enc110)
0705 {
0706
0707 enum hpd_source_id hpd_source = enc110->base.hpd_source;
0708
0709 REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source);
0710 }
0711
0712 bool dce110_link_encoder_validate_dvi_output(
0713 const struct dce110_link_encoder *enc110,
0714 enum signal_type connector_signal,
0715 enum signal_type signal,
0716 const struct dc_crtc_timing *crtc_timing)
0717 {
0718 uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
0719
0720 if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
0721 max_pixel_clock *= 2;
0722
0723
0724
0725
0726 if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
0727 connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
0728 max_pixel_clock = enc110->base.features.max_hdmi_pixel_clock;
0729
0730
0731 if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
0732 return false;
0733
0734
0735 if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
0736 connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) &&
0737 signal != SIGNAL_TYPE_HDMI_TYPE_A &&
0738 crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10))
0739 return false;
0740 if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10))
0741 return false;
0742
0743 if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10))
0744 return false;
0745
0746
0747 switch (crtc_timing->display_color_depth) {
0748 case COLOR_DEPTH_666:
0749 case COLOR_DEPTH_888:
0750 break;
0751 case COLOR_DEPTH_101010:
0752 case COLOR_DEPTH_161616:
0753 if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
0754 return false;
0755 break;
0756 default:
0757 return false;
0758 }
0759
0760 return true;
0761 }
0762
0763 static bool dce110_link_encoder_validate_hdmi_output(
0764 const struct dce110_link_encoder *enc110,
0765 const struct dc_crtc_timing *crtc_timing,
0766 int adjusted_pix_clk_khz)
0767 {
0768 enum dc_color_depth max_deep_color =
0769 enc110->base.features.max_hdmi_deep_color;
0770
0771 if (max_deep_color < crtc_timing->display_color_depth)
0772 return false;
0773
0774 if (crtc_timing->display_color_depth < COLOR_DEPTH_888)
0775 return false;
0776 if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
0777 return false;
0778
0779 if ((adjusted_pix_clk_khz == 0) ||
0780 (adjusted_pix_clk_khz > enc110->base.features.max_hdmi_pixel_clock))
0781 return false;
0782
0783
0784 if (!enc110->base.features.hdmi_ycbcr420_supported &&
0785 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
0786 return false;
0787
0788 if ((!enc110->base.features.flags.bits.HDMI_6GB_EN ||
0789 enc110->base.ctx->dc->debug.hdmi20_disable) &&
0790 adjusted_pix_clk_khz >= 300000)
0791 return false;
0792 if (enc110->base.ctx->dc->debug.hdmi20_disable &&
0793 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
0794 return false;
0795 return true;
0796 }
0797
0798 bool dce110_link_encoder_validate_dp_output(
0799 const struct dce110_link_encoder *enc110,
0800 const struct dc_crtc_timing *crtc_timing)
0801 {
0802 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
0803 return false;
0804
0805 return true;
0806 }
0807
0808 void dce110_link_encoder_construct(
0809 struct dce110_link_encoder *enc110,
0810 const struct encoder_init_data *init_data,
0811 const struct encoder_feature_support *enc_features,
0812 const struct dce110_link_enc_registers *link_regs,
0813 const struct dce110_link_enc_aux_registers *aux_regs,
0814 const struct dce110_link_enc_hpd_registers *hpd_regs)
0815 {
0816 struct bp_encoder_cap_info bp_cap_info = {0};
0817 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
0818 enum bp_result result = BP_RESULT_OK;
0819
0820 enc110->base.funcs = &dce110_lnk_enc_funcs;
0821 enc110->base.ctx = init_data->ctx;
0822 enc110->base.id = init_data->encoder;
0823
0824 enc110->base.hpd_source = init_data->hpd_source;
0825 enc110->base.connector = init_data->connector;
0826
0827 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
0828
0829 enc110->base.features = *enc_features;
0830
0831 enc110->base.transmitter = init_data->transmitter;
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842 enc110->base.output_signals =
0843 SIGNAL_TYPE_DVI_SINGLE_LINK |
0844 SIGNAL_TYPE_DVI_DUAL_LINK |
0845 SIGNAL_TYPE_LVDS |
0846 SIGNAL_TYPE_DISPLAY_PORT |
0847 SIGNAL_TYPE_DISPLAY_PORT_MST |
0848 SIGNAL_TYPE_EDP |
0849 SIGNAL_TYPE_HDMI_TYPE_A;
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862 enc110->link_regs = link_regs;
0863 enc110->aux_regs = aux_regs;
0864 enc110->hpd_regs = hpd_regs;
0865
0866 switch (enc110->base.transmitter) {
0867 case TRANSMITTER_UNIPHY_A:
0868 enc110->base.preferred_engine = ENGINE_ID_DIGA;
0869 break;
0870 case TRANSMITTER_UNIPHY_B:
0871 enc110->base.preferred_engine = ENGINE_ID_DIGB;
0872 break;
0873 case TRANSMITTER_UNIPHY_C:
0874 enc110->base.preferred_engine = ENGINE_ID_DIGC;
0875 break;
0876 case TRANSMITTER_UNIPHY_D:
0877 enc110->base.preferred_engine = ENGINE_ID_DIGD;
0878 break;
0879 case TRANSMITTER_UNIPHY_E:
0880 enc110->base.preferred_engine = ENGINE_ID_DIGE;
0881 break;
0882 case TRANSMITTER_UNIPHY_F:
0883 enc110->base.preferred_engine = ENGINE_ID_DIGF;
0884 break;
0885 case TRANSMITTER_UNIPHY_G:
0886 enc110->base.preferred_engine = ENGINE_ID_DIGG;
0887 break;
0888 default:
0889 ASSERT_CRITICAL(false);
0890 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
0891 }
0892
0893
0894 enc110->base.features.flags.bits.HDMI_6GB_EN = 1;
0895
0896 result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios,
0897 enc110->base.id, &bp_cap_info);
0898
0899
0900 if (BP_RESULT_OK == result) {
0901 enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
0902 bp_cap_info.DP_HBR2_EN;
0903 enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
0904 bp_cap_info.DP_HBR3_EN;
0905 enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
0906 } else {
0907 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
0908 __func__,
0909 result);
0910 }
0911 if (enc110->base.ctx->dc->debug.hdmi20_disable) {
0912 enc110->base.features.flags.bits.HDMI_6GB_EN = 0;
0913 }
0914 }
0915
0916 bool dce110_link_encoder_validate_output_with_stream(
0917 struct link_encoder *enc,
0918 const struct dc_stream_state *stream)
0919 {
0920 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0921 bool is_valid;
0922
0923 switch (stream->signal) {
0924 case SIGNAL_TYPE_DVI_SINGLE_LINK:
0925 case SIGNAL_TYPE_DVI_DUAL_LINK:
0926 is_valid = dce110_link_encoder_validate_dvi_output(
0927 enc110,
0928 stream->link->connector_signal,
0929 stream->signal,
0930 &stream->timing);
0931 break;
0932 case SIGNAL_TYPE_HDMI_TYPE_A:
0933 is_valid = dce110_link_encoder_validate_hdmi_output(
0934 enc110,
0935 &stream->timing,
0936 stream->phy_pix_clk);
0937 break;
0938 case SIGNAL_TYPE_DISPLAY_PORT:
0939 case SIGNAL_TYPE_DISPLAY_PORT_MST:
0940 is_valid = dce110_link_encoder_validate_dp_output(
0941 enc110, &stream->timing);
0942 break;
0943 case SIGNAL_TYPE_EDP:
0944 case SIGNAL_TYPE_LVDS:
0945 is_valid =
0946 (stream->timing.
0947 pixel_encoding == PIXEL_ENCODING_RGB) ? true : false;
0948 break;
0949 case SIGNAL_TYPE_VIRTUAL:
0950 is_valid = true;
0951 break;
0952 default:
0953 is_valid = false;
0954 break;
0955 }
0956
0957 return is_valid;
0958 }
0959
0960 void dce110_link_encoder_hw_init(
0961 struct link_encoder *enc)
0962 {
0963 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
0964 struct bp_transmitter_control cntl = { 0 };
0965 enum bp_result result;
0966
0967 cntl.action = TRANSMITTER_CONTROL_INIT;
0968 cntl.engine_id = ENGINE_ID_UNKNOWN;
0969 cntl.transmitter = enc110->base.transmitter;
0970 cntl.connector_obj_id = enc110->base.connector;
0971 cntl.lanes_number = LANE_COUNT_FOUR;
0972 cntl.coherent = false;
0973 cntl.hpd_sel = enc110->base.hpd_source;
0974
0975 if (enc110->base.connector.id == CONNECTOR_ID_EDP)
0976 cntl.signal = SIGNAL_TYPE_EDP;
0977
0978 result = link_transmitter_control(enc110, &cntl);
0979
0980 if (result != BP_RESULT_OK) {
0981 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
0982 __func__);
0983 BREAK_TO_DEBUGGER();
0984 return;
0985 }
0986
0987 if (enc110->base.connector.id == CONNECTOR_ID_LVDS) {
0988 cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
0989
0990 result = link_transmitter_control(enc110, &cntl);
0991
0992 ASSERT(result == BP_RESULT_OK);
0993
0994 }
0995 aux_initialize(enc110);
0996
0997
0998
0999
1000
1001
1002 hpd_initialize(enc110);
1003 }
1004
1005 void dce110_link_encoder_destroy(struct link_encoder **enc)
1006 {
1007 kfree(TO_DCE110_LINK_ENC(*enc));
1008 *enc = NULL;
1009 }
1010
1011 void dce110_link_encoder_setup(
1012 struct link_encoder *enc,
1013 enum signal_type signal)
1014 {
1015 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1016
1017 switch (signal) {
1018 case SIGNAL_TYPE_EDP:
1019 case SIGNAL_TYPE_DISPLAY_PORT:
1020
1021 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0);
1022 break;
1023 case SIGNAL_TYPE_LVDS:
1024
1025 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1);
1026 break;
1027 case SIGNAL_TYPE_DVI_SINGLE_LINK:
1028 case SIGNAL_TYPE_DVI_DUAL_LINK:
1029
1030 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2);
1031 break;
1032 case SIGNAL_TYPE_HDMI_TYPE_A:
1033
1034 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3);
1035 break;
1036 case SIGNAL_TYPE_DISPLAY_PORT_MST:
1037
1038 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5);
1039 break;
1040 default:
1041 ASSERT_CRITICAL(false);
1042
1043 break;
1044 }
1045
1046 }
1047
1048
1049 void dce110_link_encoder_enable_tmds_output(
1050 struct link_encoder *enc,
1051 enum clock_source_id clock_source,
1052 enum dc_color_depth color_depth,
1053 enum signal_type signal,
1054 uint32_t pixel_clock)
1055 {
1056 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1057 struct bp_transmitter_control cntl = { 0 };
1058 enum bp_result result;
1059
1060
1061 cntl.connector_obj_id = enc110->base.connector;
1062 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1063 cntl.engine_id = enc->preferred_engine;
1064 cntl.transmitter = enc110->base.transmitter;
1065 cntl.pll_id = clock_source;
1066 cntl.signal = signal;
1067 if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK)
1068 cntl.lanes_number = 8;
1069 else
1070 cntl.lanes_number = 4;
1071
1072 cntl.hpd_sel = enc110->base.hpd_source;
1073
1074 cntl.pixel_clock = pixel_clock;
1075 cntl.color_depth = color_depth;
1076
1077 result = link_transmitter_control(enc110, &cntl);
1078
1079 if (result != BP_RESULT_OK) {
1080 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1081 __func__);
1082 BREAK_TO_DEBUGGER();
1083 }
1084 }
1085
1086
1087 void dce110_link_encoder_enable_lvds_output(
1088 struct link_encoder *enc,
1089 enum clock_source_id clock_source,
1090 uint32_t pixel_clock)
1091 {
1092 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1093 struct bp_transmitter_control cntl = { 0 };
1094 enum bp_result result;
1095
1096
1097 cntl.connector_obj_id = enc110->base.connector;
1098 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1099 cntl.engine_id = enc->preferred_engine;
1100 cntl.transmitter = enc110->base.transmitter;
1101 cntl.pll_id = clock_source;
1102 cntl.signal = SIGNAL_TYPE_LVDS;
1103 cntl.lanes_number = 4;
1104
1105 cntl.hpd_sel = enc110->base.hpd_source;
1106
1107 cntl.pixel_clock = pixel_clock;
1108
1109 result = link_transmitter_control(enc110, &cntl);
1110
1111 if (result != BP_RESULT_OK) {
1112 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1113 __func__);
1114 BREAK_TO_DEBUGGER();
1115 }
1116 }
1117
1118
1119 void dce110_link_encoder_enable_dp_output(
1120 struct link_encoder *enc,
1121 const struct dc_link_settings *link_settings,
1122 enum clock_source_id clock_source)
1123 {
1124 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1125 struct bp_transmitter_control cntl = { 0 };
1126 enum bp_result result;
1127
1128
1129
1130
1131
1132
1133
1134 configure_encoder(enc110, link_settings);
1135 cntl.connector_obj_id = enc110->base.connector;
1136 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1137 cntl.engine_id = enc->preferred_engine;
1138 cntl.transmitter = enc110->base.transmitter;
1139 cntl.pll_id = clock_source;
1140 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
1141 cntl.lanes_number = link_settings->lane_count;
1142 cntl.hpd_sel = enc110->base.hpd_source;
1143 cntl.pixel_clock = link_settings->link_rate
1144 * LINK_RATE_REF_FREQ_IN_KHZ;
1145
1146 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1147
1148 result = link_transmitter_control(enc110, &cntl);
1149
1150 if (result != BP_RESULT_OK) {
1151 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1152 __func__);
1153 BREAK_TO_DEBUGGER();
1154 }
1155 }
1156
1157
1158 void dce110_link_encoder_enable_dp_mst_output(
1159 struct link_encoder *enc,
1160 const struct dc_link_settings *link_settings,
1161 enum clock_source_id clock_source)
1162 {
1163 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1164 struct bp_transmitter_control cntl = { 0 };
1165 enum bp_result result;
1166
1167
1168
1169
1170
1171
1172
1173 configure_encoder(enc110, link_settings);
1174
1175 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1176 cntl.engine_id = ENGINE_ID_UNKNOWN;
1177 cntl.transmitter = enc110->base.transmitter;
1178 cntl.pll_id = clock_source;
1179 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1180 cntl.lanes_number = link_settings->lane_count;
1181 cntl.hpd_sel = enc110->base.hpd_source;
1182 cntl.pixel_clock = link_settings->link_rate
1183 * LINK_RATE_REF_FREQ_IN_KHZ;
1184
1185 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1186
1187 result = link_transmitter_control(enc110, &cntl);
1188
1189 if (result != BP_RESULT_OK) {
1190 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1191 __func__);
1192 BREAK_TO_DEBUGGER();
1193 }
1194 }
1195
1196 #if defined(CONFIG_DRM_AMD_DC_SI)
1197
1198 static void dce60_link_encoder_enable_dp_output(
1199 struct link_encoder *enc,
1200 const struct dc_link_settings *link_settings,
1201 enum clock_source_id clock_source)
1202 {
1203 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1204 struct bp_transmitter_control cntl = { 0 };
1205 enum bp_result result;
1206
1207
1208
1209
1210
1211
1212
1213 dce60_configure_encoder(enc110, link_settings);
1214 cntl.connector_obj_id = enc110->base.connector;
1215 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1216 cntl.engine_id = enc->preferred_engine;
1217 cntl.transmitter = enc110->base.transmitter;
1218 cntl.pll_id = clock_source;
1219 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
1220 cntl.lanes_number = link_settings->lane_count;
1221 cntl.hpd_sel = enc110->base.hpd_source;
1222 cntl.pixel_clock = link_settings->link_rate
1223 * LINK_RATE_REF_FREQ_IN_KHZ;
1224
1225 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1226
1227 result = link_transmitter_control(enc110, &cntl);
1228
1229 if (result != BP_RESULT_OK) {
1230 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1231 __func__);
1232 BREAK_TO_DEBUGGER();
1233 }
1234 }
1235
1236
1237 static void dce60_link_encoder_enable_dp_mst_output(
1238 struct link_encoder *enc,
1239 const struct dc_link_settings *link_settings,
1240 enum clock_source_id clock_source)
1241 {
1242 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1243 struct bp_transmitter_control cntl = { 0 };
1244 enum bp_result result;
1245
1246
1247
1248
1249
1250
1251
1252 dce60_configure_encoder(enc110, link_settings);
1253
1254 cntl.action = TRANSMITTER_CONTROL_ENABLE;
1255 cntl.engine_id = ENGINE_ID_UNKNOWN;
1256 cntl.transmitter = enc110->base.transmitter;
1257 cntl.pll_id = clock_source;
1258 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1259 cntl.lanes_number = link_settings->lane_count;
1260 cntl.hpd_sel = enc110->base.hpd_source;
1261 cntl.pixel_clock = link_settings->link_rate
1262 * LINK_RATE_REF_FREQ_IN_KHZ;
1263
1264 cntl.color_depth = COLOR_DEPTH_UNDEFINED;
1265
1266 result = link_transmitter_control(enc110, &cntl);
1267
1268 if (result != BP_RESULT_OK) {
1269 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1270 __func__);
1271 BREAK_TO_DEBUGGER();
1272 }
1273 }
1274 #endif
1275
1276
1277
1278
1279
1280 void dce110_link_encoder_disable_output(
1281 struct link_encoder *enc,
1282 enum signal_type signal)
1283 {
1284 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1285 struct bp_transmitter_control cntl = { 0 };
1286 enum bp_result result;
1287
1288 if (!dce110_is_dig_enabled(enc)) {
1289
1290 return;
1291 }
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303 cntl.action = TRANSMITTER_CONTROL_DISABLE;
1304 cntl.transmitter = enc110->base.transmitter;
1305 cntl.hpd_sel = enc110->base.hpd_source;
1306 cntl.signal = signal;
1307 cntl.connector_obj_id = enc110->base.connector;
1308
1309 result = link_transmitter_control(enc110, &cntl);
1310
1311 if (result != BP_RESULT_OK) {
1312 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
1313 __func__);
1314 BREAK_TO_DEBUGGER();
1315 return;
1316 }
1317
1318
1319 if (dc_is_dp_signal(signal))
1320 link_encoder_disable(enc110);
1321 }
1322
1323 void dce110_link_encoder_dp_set_lane_settings(
1324 struct link_encoder *enc,
1325 const struct dc_link_settings *link_settings,
1326 const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
1327 {
1328 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1329 union dpcd_training_lane_set training_lane_set = { { 0 } };
1330 int32_t lane = 0;
1331 struct bp_transmitter_control cntl = { 0 };
1332
1333 if (!link_settings) {
1334 BREAK_TO_DEBUGGER();
1335 return;
1336 }
1337
1338 cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
1339 cntl.transmitter = enc110->base.transmitter;
1340 cntl.connector_obj_id = enc110->base.connector;
1341 cntl.lanes_number = link_settings->lane_count;
1342 cntl.hpd_sel = enc110->base.hpd_source;
1343 cntl.pixel_clock = link_settings->link_rate *
1344 LINK_RATE_REF_FREQ_IN_KHZ;
1345
1346 for (lane = 0; lane < link_settings->lane_count; lane++) {
1347
1348
1349 training_lane_set.bits.VOLTAGE_SWING_SET =
1350 lane_settings[lane].VOLTAGE_SWING;
1351 training_lane_set.bits.PRE_EMPHASIS_SET =
1352 lane_settings[lane].PRE_EMPHASIS;
1353
1354
1355 if (link_settings->link_rate == LINK_RATE_HIGH2) {
1356
1357
1358
1359 training_lane_set.bits.POST_CURSOR2_SET =
1360 lane_settings[lane].POST_CURSOR2;
1361 }
1362
1363 cntl.lane_select = lane;
1364 cntl.lane_settings = training_lane_set.raw;
1365
1366
1367 link_transmitter_control(enc110, &cntl);
1368 }
1369 }
1370
1371
1372 void dce110_link_encoder_dp_set_phy_pattern(
1373 struct link_encoder *enc,
1374 const struct encoder_set_dp_phy_pattern_param *param)
1375 {
1376 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1377
1378 switch (param->dp_phy_pattern) {
1379 case DP_TEST_PATTERN_TRAINING_PATTERN1:
1380 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1381 break;
1382 case DP_TEST_PATTERN_TRAINING_PATTERN2:
1383 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1384 break;
1385 case DP_TEST_PATTERN_TRAINING_PATTERN3:
1386 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1387 break;
1388 case DP_TEST_PATTERN_TRAINING_PATTERN4:
1389 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1390 break;
1391 case DP_TEST_PATTERN_D102:
1392 set_dp_phy_pattern_d102(enc110);
1393 break;
1394 case DP_TEST_PATTERN_SYMBOL_ERROR:
1395 set_dp_phy_pattern_symbol_error(enc110);
1396 break;
1397 case DP_TEST_PATTERN_PRBS7:
1398 set_dp_phy_pattern_prbs7(enc110);
1399 break;
1400 case DP_TEST_PATTERN_80BIT_CUSTOM:
1401 set_dp_phy_pattern_80bit_custom(
1402 enc110, param->custom_pattern);
1403 break;
1404 case DP_TEST_PATTERN_CP2520_1:
1405 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 1);
1406 break;
1407 case DP_TEST_PATTERN_CP2520_2:
1408 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 2);
1409 break;
1410 case DP_TEST_PATTERN_CP2520_3:
1411 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 3);
1412 break;
1413 case DP_TEST_PATTERN_VIDEO_MODE: {
1414 set_dp_phy_pattern_passthrough_mode(
1415 enc110, param->dp_panel_mode);
1416 break;
1417 }
1418
1419 default:
1420
1421 ASSERT_CRITICAL(false);
1422 break;
1423 }
1424 }
1425
1426 #if defined(CONFIG_DRM_AMD_DC_SI)
1427
1428 static void dce60_link_encoder_dp_set_phy_pattern(
1429 struct link_encoder *enc,
1430 const struct encoder_set_dp_phy_pattern_param *param)
1431 {
1432 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1433
1434 switch (param->dp_phy_pattern) {
1435 case DP_TEST_PATTERN_TRAINING_PATTERN1:
1436 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0);
1437 break;
1438 case DP_TEST_PATTERN_TRAINING_PATTERN2:
1439 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1);
1440 break;
1441 case DP_TEST_PATTERN_TRAINING_PATTERN3:
1442 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2);
1443 break;
1444 case DP_TEST_PATTERN_TRAINING_PATTERN4:
1445 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
1446 break;
1447 case DP_TEST_PATTERN_D102:
1448 set_dp_phy_pattern_d102(enc110);
1449 break;
1450 case DP_TEST_PATTERN_SYMBOL_ERROR:
1451 set_dp_phy_pattern_symbol_error(enc110);
1452 break;
1453 case DP_TEST_PATTERN_PRBS7:
1454 set_dp_phy_pattern_prbs7(enc110);
1455 break;
1456 case DP_TEST_PATTERN_80BIT_CUSTOM:
1457 set_dp_phy_pattern_80bit_custom(
1458 enc110, param->custom_pattern);
1459 break;
1460 case DP_TEST_PATTERN_CP2520_1:
1461 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 1);
1462 break;
1463 case DP_TEST_PATTERN_CP2520_2:
1464 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 2);
1465 break;
1466 case DP_TEST_PATTERN_CP2520_3:
1467 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 3);
1468 break;
1469 case DP_TEST_PATTERN_VIDEO_MODE: {
1470 dce60_set_dp_phy_pattern_passthrough_mode(
1471 enc110, param->dp_panel_mode);
1472 break;
1473 }
1474
1475 default:
1476
1477 ASSERT_CRITICAL(false);
1478 break;
1479 }
1480 }
1481 #endif
1482
1483 static void fill_stream_allocation_row_info(
1484 const struct link_mst_stream_allocation *stream_allocation,
1485 uint32_t *src,
1486 uint32_t *slots)
1487 {
1488 const struct stream_encoder *stream_enc = stream_allocation->stream_enc;
1489
1490 if (stream_enc) {
1491 *src = stream_enc->id;
1492 *slots = stream_allocation->slot_count;
1493 } else {
1494 *src = 0;
1495 *slots = 0;
1496 }
1497 }
1498
1499
1500 void dce110_link_encoder_update_mst_stream_allocation_table(
1501 struct link_encoder *enc,
1502 const struct link_mst_stream_allocation_table *table)
1503 {
1504 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1505 uint32_t value1 = 0;
1506 uint32_t value2 = 0;
1507 uint32_t slots = 0;
1508 uint32_t src = 0;
1509 uint32_t retries = 0;
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520 if (table->stream_count >= 1) {
1521 fill_stream_allocation_row_info(
1522 &table->stream_allocations[0],
1523 &src,
1524 &slots);
1525 } else {
1526 src = 0;
1527 slots = 0;
1528 }
1529
1530 REG_UPDATE_2(DP_MSE_SAT0,
1531 DP_MSE_SAT_SRC0, src,
1532 DP_MSE_SAT_SLOT_COUNT0, slots);
1533
1534 if (table->stream_count >= 2) {
1535 fill_stream_allocation_row_info(
1536 &table->stream_allocations[1],
1537 &src,
1538 &slots);
1539 } else {
1540 src = 0;
1541 slots = 0;
1542 }
1543
1544 REG_UPDATE_2(DP_MSE_SAT0,
1545 DP_MSE_SAT_SRC1, src,
1546 DP_MSE_SAT_SLOT_COUNT1, slots);
1547
1548 if (table->stream_count >= 3) {
1549 fill_stream_allocation_row_info(
1550 &table->stream_allocations[2],
1551 &src,
1552 &slots);
1553 } else {
1554 src = 0;
1555 slots = 0;
1556 }
1557
1558 REG_UPDATE_2(DP_MSE_SAT1,
1559 DP_MSE_SAT_SRC2, src,
1560 DP_MSE_SAT_SLOT_COUNT2, slots);
1561
1562 if (table->stream_count >= 4) {
1563 fill_stream_allocation_row_info(
1564 &table->stream_allocations[3],
1565 &src,
1566 &slots);
1567 } else {
1568 src = 0;
1569 slots = 0;
1570 }
1571
1572 REG_UPDATE_2(DP_MSE_SAT1,
1573 DP_MSE_SAT_SRC3, src,
1574 DP_MSE_SAT_SLOT_COUNT3, slots);
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589 REG_UPDATE(DP_MSE_SAT_UPDATE,
1590 DP_MSE_SAT_UPDATE, 1);
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602 do {
1603 udelay(10);
1604
1605 REG_READ(DP_MSE_SAT_UPDATE);
1606
1607 REG_GET(DP_MSE_SAT_UPDATE,
1608 DP_MSE_SAT_UPDATE, &value1);
1609
1610 REG_GET(DP_MSE_SAT_UPDATE,
1611 DP_MSE_16_MTP_KEEPOUT, &value2);
1612
1613
1614 if (!value1 && !value2)
1615 break;
1616 ++retries;
1617 } while (retries < DP_MST_UPDATE_MAX_RETRY);
1618 }
1619
1620 void dce110_link_encoder_connect_dig_be_to_fe(
1621 struct link_encoder *enc,
1622 enum engine_id engine,
1623 bool connect)
1624 {
1625 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1626 uint32_t field;
1627
1628 if (engine != ENGINE_ID_UNKNOWN) {
1629
1630 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field);
1631
1632 if (connect)
1633 field |= get_frontend_source(engine);
1634 else
1635 field &= ~get_frontend_source(engine);
1636
1637 REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field);
1638 }
1639 }
1640
1641 void dce110_link_encoder_enable_hpd(struct link_encoder *enc)
1642 {
1643 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1644 struct dc_context *ctx = enc110->base.ctx;
1645 uint32_t addr = HPD_REG(DC_HPD_CONTROL);
1646 uint32_t hpd_enable = 0;
1647 uint32_t value = dm_read_reg(ctx, addr);
1648
1649 get_reg_field_value(hpd_enable, DC_HPD_CONTROL, DC_HPD_EN);
1650
1651 if (hpd_enable == 0)
1652 set_reg_field_value(value, 1, DC_HPD_CONTROL, DC_HPD_EN);
1653 }
1654
1655 void dce110_link_encoder_disable_hpd(struct link_encoder *enc)
1656 {
1657 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
1658 struct dc_context *ctx = enc110->base.ctx;
1659 uint32_t addr = HPD_REG(DC_HPD_CONTROL);
1660 uint32_t value = dm_read_reg(ctx, addr);
1661
1662 set_reg_field_value(value, 0, DC_HPD_CONTROL, DC_HPD_EN);
1663 }
1664
1665 void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
1666 struct dc_link_settings *link_settings)
1667 {
1668
1669 struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
1670 LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
1671
1672
1673 if (enc->features.flags.bits.IS_HBR2_CAPABLE)
1674 max_link_cap.link_rate = LINK_RATE_HIGH2;
1675
1676 if (enc->features.flags.bits.IS_HBR3_CAPABLE)
1677 max_link_cap.link_rate = LINK_RATE_HIGH3;
1678
1679 *link_settings = max_link_cap;
1680 }
1681
1682 #if defined(CONFIG_DRM_AMD_DC_SI)
1683 static const struct link_encoder_funcs dce60_lnk_enc_funcs = {
1684 .validate_output_with_stream =
1685 dce110_link_encoder_validate_output_with_stream,
1686 .hw_init = dce110_link_encoder_hw_init,
1687 .setup = dce110_link_encoder_setup,
1688 .enable_tmds_output = dce110_link_encoder_enable_tmds_output,
1689 .enable_dp_output = dce60_link_encoder_enable_dp_output,
1690 .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output,
1691 .enable_lvds_output = dce110_link_encoder_enable_lvds_output,
1692 .disable_output = dce110_link_encoder_disable_output,
1693 .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
1694 .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern,
1695 .update_mst_stream_allocation_table =
1696 dce110_link_encoder_update_mst_stream_allocation_table,
1697 .psr_program_dp_dphy_fast_training =
1698 dce110_psr_program_dp_dphy_fast_training,
1699 .psr_program_secondary_packet = dce110_psr_program_secondary_packet,
1700 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe,
1701 .enable_hpd = dce110_link_encoder_enable_hpd,
1702 .disable_hpd = dce110_link_encoder_disable_hpd,
1703 .is_dig_enabled = dce110_is_dig_enabled,
1704 .destroy = dce110_link_encoder_destroy,
1705 .get_max_link_cap = dce110_link_encoder_get_max_link_cap,
1706 .get_dig_frontend = dce110_get_dig_frontend
1707 };
1708
1709 void dce60_link_encoder_construct(
1710 struct dce110_link_encoder *enc110,
1711 const struct encoder_init_data *init_data,
1712 const struct encoder_feature_support *enc_features,
1713 const struct dce110_link_enc_registers *link_regs,
1714 const struct dce110_link_enc_aux_registers *aux_regs,
1715 const struct dce110_link_enc_hpd_registers *hpd_regs)
1716 {
1717 struct bp_encoder_cap_info bp_cap_info = {0};
1718 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
1719 enum bp_result result = BP_RESULT_OK;
1720
1721 enc110->base.funcs = &dce60_lnk_enc_funcs;
1722 enc110->base.ctx = init_data->ctx;
1723 enc110->base.id = init_data->encoder;
1724
1725 enc110->base.hpd_source = init_data->hpd_source;
1726 enc110->base.connector = init_data->connector;
1727
1728 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
1729
1730 enc110->base.features = *enc_features;
1731
1732 enc110->base.transmitter = init_data->transmitter;
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743 enc110->base.output_signals =
1744 SIGNAL_TYPE_DVI_SINGLE_LINK |
1745 SIGNAL_TYPE_DVI_DUAL_LINK |
1746 SIGNAL_TYPE_LVDS |
1747 SIGNAL_TYPE_DISPLAY_PORT |
1748 SIGNAL_TYPE_DISPLAY_PORT_MST |
1749 SIGNAL_TYPE_EDP |
1750 SIGNAL_TYPE_HDMI_TYPE_A;
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763 enc110->link_regs = link_regs;
1764 enc110->aux_regs = aux_regs;
1765 enc110->hpd_regs = hpd_regs;
1766
1767 switch (enc110->base.transmitter) {
1768 case TRANSMITTER_UNIPHY_A:
1769 enc110->base.preferred_engine = ENGINE_ID_DIGA;
1770 break;
1771 case TRANSMITTER_UNIPHY_B:
1772 enc110->base.preferred_engine = ENGINE_ID_DIGB;
1773 break;
1774 case TRANSMITTER_UNIPHY_C:
1775 enc110->base.preferred_engine = ENGINE_ID_DIGC;
1776 break;
1777 case TRANSMITTER_UNIPHY_D:
1778 enc110->base.preferred_engine = ENGINE_ID_DIGD;
1779 break;
1780 case TRANSMITTER_UNIPHY_E:
1781 enc110->base.preferred_engine = ENGINE_ID_DIGE;
1782 break;
1783 case TRANSMITTER_UNIPHY_F:
1784 enc110->base.preferred_engine = ENGINE_ID_DIGF;
1785 break;
1786 case TRANSMITTER_UNIPHY_G:
1787 enc110->base.preferred_engine = ENGINE_ID_DIGG;
1788 break;
1789 default:
1790 ASSERT_CRITICAL(false);
1791 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
1792 }
1793
1794
1795 enc110->base.features.flags.bits.HDMI_6GB_EN = 1;
1796
1797 result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios,
1798 enc110->base.id, &bp_cap_info);
1799
1800
1801 if (BP_RESULT_OK == result) {
1802 enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
1803 bp_cap_info.DP_HBR2_EN;
1804 enc110->base.features.flags.bits.IS_HBR3_CAPABLE =
1805 bp_cap_info.DP_HBR3_EN;
1806 enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
1807 } else {
1808 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
1809 __func__,
1810 result);
1811 }
1812 if (enc110->base.ctx->dc->debug.hdmi20_disable) {
1813 enc110->base.features.flags.bits.HDMI_6GB_EN = 0;
1814 }
1815 }
1816 #endif