@@ -100,6 +100,35 @@ static uint8_t phy_id_from_transmitter(enum transmitter t)
100100 return phy_id ;
101101}
102102
103+ static bool has_query_dp_alt (struct link_encoder * enc )
104+ {
105+ struct dc_dmub_srv * dc_dmub_srv = enc -> ctx -> dmub_srv ;
106+
107+ /* Supports development firmware and firmware >= 4.0.11 */
108+ return dc_dmub_srv &&
109+ !(dc_dmub_srv -> dmub -> fw_version >= DMUB_FW_VERSION (4 , 0 , 0 ) &&
110+ dc_dmub_srv -> dmub -> fw_version <= DMUB_FW_VERSION (4 , 0 , 10 ));
111+ }
112+
113+ static bool query_dp_alt_from_dmub (struct link_encoder * enc ,
114+ union dmub_rb_cmd * cmd )
115+ {
116+ struct dcn10_link_encoder * enc10 = TO_DCN10_LINK_ENC (enc );
117+ struct dc_dmub_srv * dc_dmub_srv = enc -> ctx -> dmub_srv ;
118+
119+ memset (cmd , 0 , sizeof (* cmd ));
120+ cmd -> query_dp_alt .header .type = DMUB_CMD__VBIOS ;
121+ cmd -> query_dp_alt .header .sub_type =
122+ DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT ;
123+ cmd -> query_dp_alt .header .payload_bytes = sizeof (cmd -> query_dp_alt .data );
124+ cmd -> query_dp_alt .data .phy_id = phy_id_from_transmitter (enc10 -> base .transmitter );
125+
126+ if (!dc_dmub_srv_cmd_with_reply_data (dc_dmub_srv , cmd ))
127+ return false;
128+
129+ return true;
130+ }
131+
103132void dcn31_link_encoder_set_dio_phy_mux (
104133 struct link_encoder * enc ,
105134 enum encoder_type_select sel ,
@@ -569,45 +598,90 @@ void dcn31_link_encoder_disable_output(
569598bool dcn31_link_encoder_is_in_alt_mode (struct link_encoder * enc )
570599{
571600 struct dcn10_link_encoder * enc10 = TO_DCN10_LINK_ENC (enc );
572- struct dc_dmub_srv * dc_dmub_srv = enc -> ctx -> dmub_srv ;
573601 union dmub_rb_cmd cmd ;
574- bool is_usb_c_alt_mode = false ;
602+ uint32_t dp_alt_mode_disable ;
575603
576- if (enc -> features .flags .bits .DP_IS_USB_C && dc_dmub_srv ) {
577- memset (& cmd , 0 , sizeof (cmd ));
578- cmd .query_dp_alt .header .type = DMUB_CMD__VBIOS ;
579- cmd .query_dp_alt .header .sub_type = DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT ;
580- cmd .query_dp_alt .header .payload_bytes = sizeof (cmd .panel_cntl .data );
581- cmd .query_dp_alt .data .phy_id = phy_id_from_transmitter (enc10 -> base .transmitter );
604+ /* Only applicable to USB-C PHY. */
605+ if (!enc -> features .flags .bits .DP_IS_USB_C )
606+ return false;
582607
583- if (!dc_dmub_srv_cmd_with_reply_data (dc_dmub_srv , & cmd ))
608+ /*
609+ * Use the new interface from DMCUB if available.
610+ * Avoids hanging the RDCPSPIPE if DMCUB wasn't already running.
611+ */
612+ if (has_query_dp_alt (enc )) {
613+ if (!query_dp_alt_from_dmub (enc , & cmd ))
584614 return false;
585615
586- is_usb_c_alt_mode = (cmd .query_dp_alt .data .is_dp_alt_disable == 0 );
616+ return (cmd .query_dp_alt .data .is_dp_alt_disable == 0 );
587617 }
588618
589- return is_usb_c_alt_mode ;
619+ /* Legacy path, avoid if possible. */
620+ if (enc -> ctx -> asic_id .hw_internal_rev != YELLOW_CARP_B0 ) {
621+ REG_GET (RDPCSTX_PHY_CNTL6 , RDPCS_PHY_DPALT_DISABLE ,
622+ & dp_alt_mode_disable );
623+ } else {
624+ /*
625+ * B0 phys use a new set of registers to check whether alt mode is disabled.
626+ * if value == 1 alt mode is disabled, otherwise it is enabled.
627+ */
628+ if ((enc10 -> base .transmitter == TRANSMITTER_UNIPHY_A ) ||
629+ (enc10 -> base .transmitter == TRANSMITTER_UNIPHY_B ) ||
630+ (enc10 -> base .transmitter == TRANSMITTER_UNIPHY_E )) {
631+ REG_GET (RDPCSTX_PHY_CNTL6 , RDPCS_PHY_DPALT_DISABLE ,
632+ & dp_alt_mode_disable );
633+ } else {
634+ REG_GET (RDPCSPIPE_PHY_CNTL6 , RDPCS_PHY_DPALT_DISABLE ,
635+ & dp_alt_mode_disable );
636+ }
637+ }
638+
639+ return (dp_alt_mode_disable == 0 );
590640}
591641
592642void dcn31_link_encoder_get_max_link_cap (struct link_encoder * enc , struct dc_link_settings * link_settings )
593643{
594644 struct dcn10_link_encoder * enc10 = TO_DCN10_LINK_ENC (enc );
595- struct dc_dmub_srv * dc_dmub_srv = enc -> ctx -> dmub_srv ;
596645 union dmub_rb_cmd cmd ;
646+ uint32_t is_in_usb_c_dp4_mode = 0 ;
597647
598648 dcn10_link_encoder_get_max_link_cap (enc , link_settings );
599649
600- if (enc -> features .flags .bits .DP_IS_USB_C && dc_dmub_srv ) {
601- memset (& cmd , 0 , sizeof (cmd ));
602- cmd .query_dp_alt .header .type = DMUB_CMD__VBIOS ;
603- cmd .query_dp_alt .header .sub_type = DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT ;
604- cmd .query_dp_alt .header .payload_bytes = sizeof (cmd .panel_cntl .data );
605- cmd .query_dp_alt .data .phy_id = phy_id_from_transmitter (enc10 -> base .transmitter );
650+ /* Take the link cap directly if not USB */
651+ if (!enc -> features .flags .bits .DP_IS_USB_C )
652+ return ;
606653
607- if (!dc_dmub_srv_cmd_with_reply_data (dc_dmub_srv , & cmd ))
654+ /*
655+ * Use the new interface from DMCUB if available.
656+ * Avoids hanging the RDCPSPIPE if DMCUB wasn't already running.
657+ */
658+ if (has_query_dp_alt (enc )) {
659+ if (!query_dp_alt_from_dmub (enc , & cmd ))
608660 return ;
609661
610- if (cmd .query_dp_alt .data .is_usb && cmd .query_dp_alt .data .is_dp4 == 0 )
662+ if (cmd .query_dp_alt .data .is_usb &&
663+ cmd .query_dp_alt .data .is_dp4 == 0 )
611664 link_settings -> lane_count = MIN (LANE_COUNT_TWO , link_settings -> lane_count );
665+
666+ return ;
612667 }
668+
669+ /* Legacy path, avoid if possible. */
670+ if (enc -> ctx -> asic_id .hw_internal_rev != YELLOW_CARP_B0 ) {
671+ REG_GET (RDPCSTX_PHY_CNTL6 , RDPCS_PHY_DPALT_DP4 ,
672+ & is_in_usb_c_dp4_mode );
673+ } else {
674+ if ((enc10 -> base .transmitter == TRANSMITTER_UNIPHY_A ) ||
675+ (enc10 -> base .transmitter == TRANSMITTER_UNIPHY_B ) ||
676+ (enc10 -> base .transmitter == TRANSMITTER_UNIPHY_E )) {
677+ REG_GET (RDPCSTX_PHY_CNTL6 , RDPCS_PHY_DPALT_DP4 ,
678+ & is_in_usb_c_dp4_mode );
679+ } else {
680+ REG_GET (RDPCSPIPE_PHY_CNTL6 , RDPCS_PHY_DPALT_DP4 ,
681+ & is_in_usb_c_dp4_mode );
682+ }
683+ }
684+
685+ if (!is_in_usb_c_dp4_mode )
686+ link_settings -> lane_count = MIN (LANE_COUNT_TWO , link_settings -> lane_count );
613687}
0 commit comments