new_edid->raw_edid, new_edid->length) == 0);
 }
 
-static bool wait_for_alt_mode(struct dc_link *link)
+static bool wait_for_entering_dp_alt_mode(struct dc_link *link)
 {
        /**
         * something is terribly wrong if time out is > 200ms. (5Hz)
                        /* wa HPD high coming too early*/
                        if (link->link_enc->features.flags.bits.DP_IS_USB_C == 1) {
                                /* if alt mode times out, return false */
-                               if (!wait_for_alt_mode(link))
+                               if (!wait_for_entering_dp_alt_mode(link))
                                        return false;
                        }
 
 
 
 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 {
-       /* Set Default link settings */
-       struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
-                       LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
-
-       /* Higher link settings based on feature supported */
-       if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
-               max_link_cap.link_rate = LINK_RATE_HIGH2;
-
-       if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
-               max_link_cap.link_rate = LINK_RATE_HIGH3;
+       struct dc_link_settings max_link_cap = {0};
 
-       if (link->link_enc->funcs->get_max_link_cap)
-               link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
+       /* get max link encoder capability */
+       link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
 
        /* Lower link settings based on sink's link cap */
        if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
 
        .enable_hpd = dce110_link_encoder_enable_hpd,
        .disable_hpd = dce110_link_encoder_disable_hpd,
        .is_dig_enabled = dce110_is_dig_enabled,
-       .destroy = dce110_link_encoder_destroy
+       .destroy = dce110_link_encoder_destroy,
+       .get_max_link_cap = dce110_link_encoder_get_max_link_cap
 };
 
 static enum bp_result link_transmitter_control(
 
        set_reg_field_value(value, 0, DC_HPD_CONTROL, DC_HPD_EN);
 }
+
+void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings)
+{
+       /* Set Default link settings */
+       struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+                       LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+
+       /* Higher link settings based on feature supported */
+       if (enc->features.flags.bits.IS_HBR2_CAPABLE)
+               max_link_cap.link_rate = LINK_RATE_HIGH2;
+
+       if (enc->features.flags.bits.IS_HBR3_CAPABLE)
+               max_link_cap.link_rate = LINK_RATE_HIGH3;
+
+       *link_settings = max_link_cap;
+}
 
 
 bool dce110_is_dig_enabled(struct link_encoder *enc);
 
+void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings);
+
 #endif /* __DC_LINK_ENCODER__DCE110_H__ */
 
        .is_dig_enabled = dcn10_is_dig_enabled,
        .get_dig_frontend = dcn10_get_dig_frontend,
        .get_dig_mode = dcn10_get_dig_mode,
-       .destroy = dcn10_link_encoder_destroy
+       .destroy = dcn10_link_encoder_destroy,
+       .get_max_link_cap = dcn10_link_encoder_get_max_link_cap,
 };
 
 static enum bp_result link_transmitter_control(
                        DC_HPD_EN, 0);
 }
 
-
 #define AUX_REG(reg)\
        (enc10->aux_regs->reg)
 
        return SIGNAL_TYPE_NONE;
 }
 
+void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings)
+{
+       /* Set Default link settings */
+       struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+                       LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+
+       /* Higher link settings based on feature supported */
+       if (enc->features.flags.bits.IS_HBR2_CAPABLE)
+               max_link_cap.link_rate = LINK_RATE_HIGH2;
+
+       if (enc->features.flags.bits.IS_HBR3_CAPABLE)
+               max_link_cap.link_rate = LINK_RATE_HIGH3;
+
+       *link_settings = max_link_cap;
+}
 
 
 enum signal_type dcn10_get_dig_mode(
        struct link_encoder *enc);
+
+void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings);
 #endif /* __DC_LINK_ENCODER__DCN10_H__ */
 
 #define IND_REG(index) \
        (enc10->link_regs->index)
 
+#ifndef MAX
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+#endif
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
 
 static struct mpll_cfg dcn2_mpll_cfg[] = {
        // RBR
 
 }
 
+void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t is_in_usb_c_dp4_mode = 0;
+
+       dcn10_link_encoder_get_max_link_cap(enc, link_settings);
+
+       /* in usb c dp2 mode, max lane count is 2 */
+       if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
+               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+               if (!is_in_usb_c_dp4_mode)
+                       link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+       }
+
+}
+
+bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t dp_alt_mode_disable = 0;
+       bool is_usb_c_alt_mode = false;
+
+       if (enc->features.flags.bits.DP_IS_USB_C) {
+               /* if value == 1 alt mode is disabled, otherwise it is enabled */
+               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+               is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+       }
+
+       return is_usb_c_alt_mode;
+}
+
 #define AUX_REG(reg)\
        (enc10->aux_regs->reg)
 
        dcn10_aux_initialize(enc10);
 }
 
-void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
-       struct dc_link_settings *link_settings)
-{
-       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-       uint32_t value;
-
-       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
-
-       if (!value && link_settings->lane_count > LANE_COUNT_TWO)
-               link_settings->lane_count = LANE_COUNT_TWO;
-}
-bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc)
-{
-       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-       uint32_t value;
-
-       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
-
-       // if value == 1 alt mode is disabled, otherwise it is enabled
-       return !value;
-}
-
 static const struct link_encoder_funcs dcn20_link_enc_funcs = {
        .read_state = link_enc2_read_state,
        .validate_output_with_stream =
 
        const struct dc_link_settings *link_settings,
        enum clock_source_id clock_source);
 
+bool dcn20_link_encoder_is_in_alt_mode(struct link_encoder *enc);
+void dcn20_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings);
+
 void dcn20_link_encoder_construct(
        struct dcn20_link_encoder *enc20,
        const struct encoder_init_data *init_data,
 
        return true;
 }
 
-void dcn21_link_encoder_get_max_link_cap(struct link_encoder *enc,
-       struct dc_link_settings *link_settings)
-{
-       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-       uint32_t value;
-
-       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &value);
-
-       if (!value && link_settings->lane_count > LANE_COUNT_TWO)
-               link_settings->lane_count = LANE_COUNT_TWO;
-}
-
-bool dcn21_link_encoder_is_in_alt_mode(struct link_encoder *enc)
-{
-       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-       uint32_t value;
-
-       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &value);
-
-       // if value == 1 alt mode is disabled, otherwise it is enabled
-       return !value;
-}
-
 bool dcn21_link_encoder_acquire_phy(struct link_encoder *enc)
 {
        struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
        .fec_set_ready = enc2_fec_set_ready,
        .fec_is_active = enc2_fec_is_active,
        .get_dig_frontend = dcn10_get_dig_frontend,
-       .is_in_alt_mode = dcn21_link_encoder_is_in_alt_mode,
-       .get_max_link_cap = dcn21_link_encoder_get_max_link_cap,
+       .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
+       .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
 };
 
 void dcn21_link_encoder_construct(
 
        *enc = NULL;
 }
 
+static void virtual_link_encoder_get_max_link_cap(struct link_encoder *enc,
+               struct dc_link_settings *link_settings)
+{
+       /* Set Default link settings */
+       struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
+                               LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
+       *link_settings = max_link_cap;
+}
 
 static const struct link_encoder_funcs virtual_lnk_enc_funcs = {
        .validate_output_with_stream =
        .enable_dp_output = virtual_link_encoder_enable_dp_output,
        .enable_dp_mst_output = virtual_link_encoder_enable_dp_mst_output,
        .disable_output = virtual_link_encoder_disable_output,
+       .get_max_link_cap = virtual_link_encoder_get_max_link_cap,
        .dp_set_lane_settings = virtual_link_encoder_dp_set_lane_settings,
        .dp_set_phy_pattern = virtual_link_encoder_dp_set_phy_pattern,
        .update_mst_stream_allocation_table =