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 "reg_helper.h"
0028
0029 #include "core_types.h"
0030 #include "link_encoder.h"
0031 #include "dcn31_dio_link_encoder.h"
0032 #include "stream_encoder.h"
0033 #include "i2caux_interface.h"
0034 #include "dc_bios_types.h"
0035
0036 #include "gpio_service_interface.h"
0037
0038 #include "link_enc_cfg.h"
0039 #include "dc_dmub_srv.h"
0040 #include "dal_asic_id.h"
0041
0042 #define CTX \
0043 enc10->base.ctx
0044 #define DC_LOGGER \
0045 enc10->base.ctx->logger
0046
0047 #define REG(reg)\
0048 (enc10->link_regs->reg)
0049
0050 #undef FN
0051 #define FN(reg_name, field_name) \
0052 enc10->link_shift->field_name, enc10->link_mask->field_name
0053
0054 #define IND_REG(index) \
0055 (enc10->link_regs->index)
0056
0057 #define AUX_REG(reg)\
0058 (enc10->aux_regs->reg)
0059
0060 #define AUX_REG_READ(reg_name) \
0061 dm_read_reg(CTX, AUX_REG(reg_name))
0062
0063 #define AUX_REG_WRITE(reg_name, val) \
0064 dm_write_reg(CTX, AUX_REG(reg_name), val)
0065
0066 #ifndef MIN
0067 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
0068 #endif
0069
0070 static uint8_t phy_id_from_transmitter(enum transmitter t)
0071 {
0072 uint8_t phy_id;
0073
0074 switch (t) {
0075 case TRANSMITTER_UNIPHY_A:
0076 phy_id = 0;
0077 break;
0078 case TRANSMITTER_UNIPHY_B:
0079 phy_id = 1;
0080 break;
0081 case TRANSMITTER_UNIPHY_C:
0082 phy_id = 2;
0083 break;
0084 case TRANSMITTER_UNIPHY_D:
0085 phy_id = 3;
0086 break;
0087 case TRANSMITTER_UNIPHY_E:
0088 phy_id = 4;
0089 break;
0090 case TRANSMITTER_UNIPHY_F:
0091 phy_id = 5;
0092 break;
0093 case TRANSMITTER_UNIPHY_G:
0094 phy_id = 6;
0095 break;
0096 default:
0097 phy_id = 0;
0098 break;
0099 }
0100 return phy_id;
0101 }
0102
0103 static bool has_query_dp_alt(struct link_encoder *enc)
0104 {
0105 struct dc_dmub_srv *dc_dmub_srv = enc->ctx->dmub_srv;
0106
0107 if (enc->ctx->dce_version >= DCN_VERSION_3_15)
0108 return true;
0109
0110
0111 return dc_dmub_srv &&
0112 !(dc_dmub_srv->dmub->fw_version >= DMUB_FW_VERSION(4, 0, 0) &&
0113 dc_dmub_srv->dmub->fw_version <= DMUB_FW_VERSION(4, 0, 10));
0114 }
0115
0116 static bool query_dp_alt_from_dmub(struct link_encoder *enc,
0117 union dmub_rb_cmd *cmd)
0118 {
0119 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0120 struct dc_dmub_srv *dc_dmub_srv = enc->ctx->dmub_srv;
0121
0122 memset(cmd, 0, sizeof(*cmd));
0123 cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS;
0124 cmd->query_dp_alt.header.sub_type =
0125 DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT;
0126 cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
0127 cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
0128
0129 if (!dc_dmub_srv_cmd_with_reply_data(dc_dmub_srv, cmd))
0130 return false;
0131
0132 return true;
0133 }
0134
0135 void dcn31_link_encoder_set_dio_phy_mux(
0136 struct link_encoder *enc,
0137 enum encoder_type_select sel,
0138 uint32_t hpo_inst)
0139 {
0140 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0141
0142 switch (enc->transmitter) {
0143 case TRANSMITTER_UNIPHY_A:
0144 if (sel == ENCODER_TYPE_HDMI_FRL)
0145 REG_UPDATE(DIO_LINKA_CNTL,
0146 HPO_HDMI_ENC_SEL, hpo_inst);
0147 else if (sel == ENCODER_TYPE_DP_128B132B)
0148 REG_UPDATE(DIO_LINKA_CNTL,
0149 HPO_DP_ENC_SEL, hpo_inst);
0150 REG_UPDATE(DIO_LINKA_CNTL,
0151 ENC_TYPE_SEL, sel);
0152 break;
0153 case TRANSMITTER_UNIPHY_B:
0154 if (sel == ENCODER_TYPE_HDMI_FRL)
0155 REG_UPDATE(DIO_LINKB_CNTL,
0156 HPO_HDMI_ENC_SEL, hpo_inst);
0157 else if (sel == ENCODER_TYPE_DP_128B132B)
0158 REG_UPDATE(DIO_LINKB_CNTL,
0159 HPO_DP_ENC_SEL, hpo_inst);
0160 REG_UPDATE(DIO_LINKB_CNTL,
0161 ENC_TYPE_SEL, sel);
0162 break;
0163 case TRANSMITTER_UNIPHY_C:
0164 if (sel == ENCODER_TYPE_HDMI_FRL)
0165 REG_UPDATE(DIO_LINKC_CNTL,
0166 HPO_HDMI_ENC_SEL, hpo_inst);
0167 else if (sel == ENCODER_TYPE_DP_128B132B)
0168 REG_UPDATE(DIO_LINKC_CNTL,
0169 HPO_DP_ENC_SEL, hpo_inst);
0170 REG_UPDATE(DIO_LINKC_CNTL,
0171 ENC_TYPE_SEL, sel);
0172 break;
0173 case TRANSMITTER_UNIPHY_D:
0174 if (sel == ENCODER_TYPE_HDMI_FRL)
0175 REG_UPDATE(DIO_LINKD_CNTL,
0176 HPO_HDMI_ENC_SEL, hpo_inst);
0177 else if (sel == ENCODER_TYPE_DP_128B132B)
0178 REG_UPDATE(DIO_LINKD_CNTL,
0179 HPO_DP_ENC_SEL, hpo_inst);
0180 REG_UPDATE(DIO_LINKD_CNTL,
0181 ENC_TYPE_SEL, sel);
0182 break;
0183 case TRANSMITTER_UNIPHY_E:
0184 if (sel == ENCODER_TYPE_HDMI_FRL)
0185 REG_UPDATE(DIO_LINKE_CNTL,
0186 HPO_HDMI_ENC_SEL, hpo_inst);
0187 else if (sel == ENCODER_TYPE_DP_128B132B)
0188 REG_UPDATE(DIO_LINKE_CNTL,
0189 HPO_DP_ENC_SEL, hpo_inst);
0190 REG_UPDATE(DIO_LINKE_CNTL,
0191 ENC_TYPE_SEL, sel);
0192 break;
0193 case TRANSMITTER_UNIPHY_F:
0194 if (sel == ENCODER_TYPE_HDMI_FRL)
0195 REG_UPDATE(DIO_LINKF_CNTL,
0196 HPO_HDMI_ENC_SEL, hpo_inst);
0197 else if (sel == ENCODER_TYPE_DP_128B132B)
0198 REG_UPDATE(DIO_LINKF_CNTL,
0199 HPO_DP_ENC_SEL, hpo_inst);
0200 REG_UPDATE(DIO_LINKF_CNTL,
0201 ENC_TYPE_SEL, sel);
0202 break;
0203 default:
0204
0205 break;
0206 }
0207 }
0208
0209 static void enc31_hw_init(struct link_encoder *enc)
0210 {
0211 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245 REG_UPDATE(TMDS_CTL_BITS, TMDS_CTL0, 1);
0246
0247 dcn10_aux_initialize(enc10);
0248 }
0249
0250 static const struct link_encoder_funcs dcn31_link_enc_funcs = {
0251 .read_state = link_enc2_read_state,
0252 .validate_output_with_stream =
0253 dcn30_link_encoder_validate_output_with_stream,
0254 .hw_init = enc31_hw_init,
0255 .setup = dcn10_link_encoder_setup,
0256 .enable_tmds_output = dcn10_link_encoder_enable_tmds_output,
0257 .enable_dp_output = dcn31_link_encoder_enable_dp_output,
0258 .enable_dp_mst_output = dcn31_link_encoder_enable_dp_mst_output,
0259 .disable_output = dcn31_link_encoder_disable_output,
0260 .dp_set_lane_settings = dcn10_link_encoder_dp_set_lane_settings,
0261 .dp_set_phy_pattern = dcn10_link_encoder_dp_set_phy_pattern,
0262 .update_mst_stream_allocation_table =
0263 dcn10_link_encoder_update_mst_stream_allocation_table,
0264 .psr_program_dp_dphy_fast_training =
0265 dcn10_psr_program_dp_dphy_fast_training,
0266 .psr_program_secondary_packet = dcn10_psr_program_secondary_packet,
0267 .connect_dig_be_to_fe = dcn10_link_encoder_connect_dig_be_to_fe,
0268 .enable_hpd = dcn10_link_encoder_enable_hpd,
0269 .disable_hpd = dcn10_link_encoder_disable_hpd,
0270 .is_dig_enabled = dcn10_is_dig_enabled,
0271 .destroy = dcn10_link_encoder_destroy,
0272 .fec_set_enable = enc2_fec_set_enable,
0273 .fec_set_ready = enc2_fec_set_ready,
0274 .fec_is_active = enc2_fec_is_active,
0275 .get_dig_frontend = dcn10_get_dig_frontend,
0276 .get_dig_mode = dcn10_get_dig_mode,
0277 .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
0278 .get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
0279 .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
0280 };
0281
0282 void dcn31_link_encoder_construct(
0283 struct dcn20_link_encoder *enc20,
0284 const struct encoder_init_data *init_data,
0285 const struct encoder_feature_support *enc_features,
0286 const struct dcn10_link_enc_registers *link_regs,
0287 const struct dcn10_link_enc_aux_registers *aux_regs,
0288 const struct dcn10_link_enc_hpd_registers *hpd_regs,
0289 const struct dcn10_link_enc_shift *link_shift,
0290 const struct dcn10_link_enc_mask *link_mask)
0291 {
0292 struct bp_encoder_cap_info bp_cap_info = {0};
0293 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs;
0294 enum bp_result result = BP_RESULT_OK;
0295 struct dcn10_link_encoder *enc10 = &enc20->enc10;
0296
0297 enc10->base.funcs = &dcn31_link_enc_funcs;
0298 enc10->base.ctx = init_data->ctx;
0299 enc10->base.id = init_data->encoder;
0300
0301 enc10->base.hpd_source = init_data->hpd_source;
0302 enc10->base.connector = init_data->connector;
0303
0304 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
0305
0306 enc10->base.features = *enc_features;
0307
0308 enc10->base.transmitter = init_data->transmitter;
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 enc10->base.output_signals =
0320 SIGNAL_TYPE_DVI_SINGLE_LINK |
0321 SIGNAL_TYPE_DVI_DUAL_LINK |
0322 SIGNAL_TYPE_LVDS |
0323 SIGNAL_TYPE_DISPLAY_PORT |
0324 SIGNAL_TYPE_DISPLAY_PORT_MST |
0325 SIGNAL_TYPE_EDP |
0326 SIGNAL_TYPE_HDMI_TYPE_A;
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 enc10->link_regs = link_regs;
0340 enc10->aux_regs = aux_regs;
0341 enc10->hpd_regs = hpd_regs;
0342 enc10->link_shift = link_shift;
0343 enc10->link_mask = link_mask;
0344
0345 switch (enc10->base.transmitter) {
0346 case TRANSMITTER_UNIPHY_A:
0347 enc10->base.preferred_engine = ENGINE_ID_DIGA;
0348 break;
0349 case TRANSMITTER_UNIPHY_B:
0350 enc10->base.preferred_engine = ENGINE_ID_DIGB;
0351 break;
0352 case TRANSMITTER_UNIPHY_C:
0353 enc10->base.preferred_engine = ENGINE_ID_DIGC;
0354 break;
0355 case TRANSMITTER_UNIPHY_D:
0356 enc10->base.preferred_engine = ENGINE_ID_DIGD;
0357 break;
0358 case TRANSMITTER_UNIPHY_E:
0359 enc10->base.preferred_engine = ENGINE_ID_DIGE;
0360 break;
0361 case TRANSMITTER_UNIPHY_F:
0362 enc10->base.preferred_engine = ENGINE_ID_DIGF;
0363 break;
0364 default:
0365 ASSERT_CRITICAL(false);
0366 enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
0367 }
0368
0369
0370 enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
0371
0372 result = bp_funcs->get_encoder_cap_info(enc10->base.ctx->dc_bios,
0373 enc10->base.id, &bp_cap_info);
0374
0375
0376 if (result == BP_RESULT_OK) {
0377 enc10->base.features.flags.bits.IS_HBR2_CAPABLE =
0378 bp_cap_info.DP_HBR2_EN;
0379 enc10->base.features.flags.bits.IS_HBR3_CAPABLE =
0380 bp_cap_info.DP_HBR3_EN;
0381 enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN;
0382 enc10->base.features.flags.bits.IS_DP2_CAPABLE = bp_cap_info.IS_DP2_CAPABLE;
0383 enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN;
0384 enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN;
0385 enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN;
0386 enc10->base.features.flags.bits.DP_IS_USB_C =
0387 bp_cap_info.DP_IS_USB_C;
0388 } else {
0389 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n",
0390 __func__,
0391 result);
0392 }
0393 if (enc10->base.ctx->dc->debug.hdmi20_disable) {
0394 enc10->base.features.flags.bits.HDMI_6GB_EN = 0;
0395 }
0396 }
0397
0398 void dcn31_link_encoder_construct_minimal(
0399 struct dcn20_link_encoder *enc20,
0400 struct dc_context *ctx,
0401 const struct encoder_feature_support *enc_features,
0402 const struct dcn10_link_enc_registers *link_regs,
0403 enum engine_id eng_id)
0404 {
0405 struct dcn10_link_encoder *enc10 = &enc20->enc10;
0406
0407 enc10->base.funcs = &dcn31_link_enc_funcs;
0408 enc10->base.ctx = ctx;
0409 enc10->base.id.type = OBJECT_TYPE_ENCODER;
0410 enc10->base.hpd_source = HPD_SOURCEID_UNKNOWN;
0411 enc10->base.connector.type = OBJECT_TYPE_CONNECTOR;
0412 enc10->base.preferred_engine = eng_id;
0413 enc10->base.features = *enc_features;
0414 enc10->base.transmitter = TRANSMITTER_UNKNOWN;
0415 enc10->link_regs = link_regs;
0416
0417 enc10->base.output_signals =
0418 SIGNAL_TYPE_DISPLAY_PORT |
0419 SIGNAL_TYPE_DISPLAY_PORT_MST |
0420 SIGNAL_TYPE_EDP;
0421 }
0422
0423
0424 static bool link_dpia_control(struct dc_context *dc_ctx,
0425 struct dmub_cmd_dig_dpia_control_data *dpia_control)
0426 {
0427 union dmub_rb_cmd cmd;
0428 struct dc_dmub_srv *dmub = dc_ctx->dmub_srv;
0429
0430 memset(&cmd, 0, sizeof(cmd));
0431
0432 cmd.dig1_dpia_control.header.type = DMUB_CMD__DPIA;
0433 cmd.dig1_dpia_control.header.sub_type =
0434 DMUB_CMD__DPIA_DIG1_DPIA_CONTROL;
0435 cmd.dig1_dpia_control.header.payload_bytes =
0436 sizeof(cmd.dig1_dpia_control) -
0437 sizeof(cmd.dig1_dpia_control.header);
0438
0439 cmd.dig1_dpia_control.dpia_control = *dpia_control;
0440
0441 dc_dmub_srv_cmd_queue(dmub, &cmd);
0442 dc_dmub_srv_cmd_execute(dmub);
0443 dc_dmub_srv_wait_idle(dmub);
0444
0445 return true;
0446 }
0447
0448 static void link_encoder_disable(struct dcn10_link_encoder *enc10)
0449 {
0450
0451 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0);
0452 }
0453
0454 void dcn31_link_encoder_enable_dp_output(
0455 struct link_encoder *enc,
0456 const struct dc_link_settings *link_settings,
0457 enum clock_source_id clock_source)
0458 {
0459 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0460
0461
0462 if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
0463
0464 DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
0465 dcn20_link_encoder_enable_dp_output(enc, link_settings, clock_source);
0466
0467 } else {
0468
0469 struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
0470 struct dc_link *link;
0471
0472 link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
0473
0474 enc1_configure_encoder(enc10, link_settings);
0475
0476 dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
0477 dpia_control.enc_id = enc->preferred_engine;
0478 dpia_control.mode_laneset.digmode = 0;
0479 dpia_control.lanenum = (uint8_t)link_settings->lane_count;
0480 dpia_control.symclk_10khz = link_settings->link_rate *
0481 LINK_RATE_REF_FREQ_IN_KHZ / 10;
0482
0483
0484
0485 dpia_control.hpdsel = 6;
0486
0487 if (link) {
0488 dpia_control.dpia_id = link->ddc_hw_inst;
0489 dpia_control.fec_rdy = dc_link_should_enable_fec(link);
0490 } else {
0491 DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
0492 BREAK_TO_DEBUGGER();
0493 return;
0494 }
0495
0496 DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
0497 link_dpia_control(enc->ctx, &dpia_control);
0498 }
0499 }
0500
0501 void dcn31_link_encoder_enable_dp_mst_output(
0502 struct link_encoder *enc,
0503 const struct dc_link_settings *link_settings,
0504 enum clock_source_id clock_source)
0505 {
0506 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0507
0508
0509 if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
0510
0511 DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
0512 dcn10_link_encoder_enable_dp_mst_output(enc, link_settings, clock_source);
0513
0514 } else {
0515
0516 struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
0517 struct dc_link *link;
0518
0519 link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
0520
0521 enc1_configure_encoder(enc10, link_settings);
0522
0523 dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_ENABLE;
0524 dpia_control.enc_id = enc->preferred_engine;
0525 dpia_control.mode_laneset.digmode = 5;
0526 dpia_control.lanenum = (uint8_t)link_settings->lane_count;
0527 dpia_control.symclk_10khz = link_settings->link_rate *
0528 LINK_RATE_REF_FREQ_IN_KHZ / 10;
0529
0530
0531
0532 dpia_control.hpdsel = 6;
0533
0534 if (link) {
0535 dpia_control.dpia_id = link->ddc_hw_inst;
0536 dpia_control.fec_rdy = dc_link_should_enable_fec(link);
0537 } else {
0538 DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
0539 BREAK_TO_DEBUGGER();
0540 return;
0541 }
0542
0543 DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
0544 link_dpia_control(enc->ctx, &dpia_control);
0545 }
0546 }
0547
0548 void dcn31_link_encoder_disable_output(
0549 struct link_encoder *enc,
0550 enum signal_type signal)
0551 {
0552 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0553
0554
0555 if (!link_enc_cfg_is_transmitter_mappable(enc->ctx->dc, enc)) {
0556
0557 DC_LOG_DEBUG("%s: enc_id(%d)\n", __func__, enc->preferred_engine);
0558 dcn10_link_encoder_disable_output(enc, signal);
0559
0560 } else {
0561
0562 struct dmub_cmd_dig_dpia_control_data dpia_control = { 0 };
0563 struct dc_link *link;
0564
0565 if (!dcn10_is_dig_enabled(enc))
0566 return;
0567
0568 link = link_enc_cfg_get_link_using_link_enc(enc->ctx->dc, enc->preferred_engine);
0569
0570 dpia_control.action = (uint8_t)TRANSMITTER_CONTROL_DISABLE;
0571 dpia_control.enc_id = enc->preferred_engine;
0572 if (signal == SIGNAL_TYPE_DISPLAY_PORT) {
0573 dpia_control.mode_laneset.digmode = 0;
0574 } else if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
0575 dpia_control.mode_laneset.digmode = 5;
0576 } else {
0577 DC_LOG_ERROR("%s: USB4 DPIA only supports DisplayPort.\n", __func__);
0578 BREAK_TO_DEBUGGER();
0579 }
0580
0581 if (link) {
0582 dpia_control.dpia_id = link->ddc_hw_inst;
0583 } else {
0584 DC_LOG_ERROR("%s: Failed to execute DPIA enable DMUB command.\n", __func__);
0585 BREAK_TO_DEBUGGER();
0586 return;
0587 }
0588
0589 DC_LOG_DEBUG("%s: DPIA(%d) - enc_id(%d)\n", __func__, dpia_control.dpia_id, dpia_control.enc_id);
0590 link_dpia_control(enc->ctx, &dpia_control);
0591
0592 link_encoder_disable(enc10);
0593 }
0594 }
0595
0596 bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
0597 {
0598 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0599 union dmub_rb_cmd cmd;
0600 uint32_t dp_alt_mode_disable;
0601
0602
0603 if (!enc->features.flags.bits.DP_IS_USB_C)
0604 return false;
0605
0606
0607
0608
0609
0610 if (has_query_dp_alt(enc)) {
0611 if (!query_dp_alt_from_dmub(enc, &cmd))
0612 return false;
0613
0614 return (cmd.query_dp_alt.data.is_dp_alt_disable == 0);
0615 }
0616
0617
0618 if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
0619 REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE,
0620 &dp_alt_mode_disable);
0621 } else {
0622
0623
0624
0625
0626 if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) ||
0627 (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) ||
0628 (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
0629 REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE,
0630 &dp_alt_mode_disable);
0631 } else {
0632 REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE,
0633 &dp_alt_mode_disable);
0634 }
0635 }
0636
0637 return (dp_alt_mode_disable == 0);
0638 }
0639
0640 void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc, struct dc_link_settings *link_settings)
0641 {
0642 struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
0643 union dmub_rb_cmd cmd;
0644 uint32_t is_in_usb_c_dp4_mode = 0;
0645
0646 dcn10_link_encoder_get_max_link_cap(enc, link_settings);
0647
0648
0649 if (!enc->features.flags.bits.DP_IS_USB_C)
0650 return;
0651
0652
0653
0654
0655
0656 if (has_query_dp_alt(enc)) {
0657 if (!query_dp_alt_from_dmub(enc, &cmd))
0658 return;
0659
0660 if (cmd.query_dp_alt.data.is_usb &&
0661 cmd.query_dp_alt.data.is_dp4 == 0)
0662 link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
0663
0664 return;
0665 }
0666
0667
0668 if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
0669 REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4,
0670 &is_in_usb_c_dp4_mode);
0671 } else {
0672 if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A) ||
0673 (enc10->base.transmitter == TRANSMITTER_UNIPHY_B) ||
0674 (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
0675 REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4,
0676 &is_in_usb_c_dp4_mode);
0677 } else {
0678 REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4,
0679 &is_in_usb_c_dp4_mode);
0680 }
0681 }
0682
0683 if (!is_in_usb_c_dp4_mode)
0684 link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
0685 }