drm/amd/display: check phy dpalt lane count config
authorLewis Huang <Lewis.Huang@amd.com>
Thu, 5 Sep 2019 07:33:58 +0000 (15:33 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 11 Oct 2019 00:32:03 +0000 (19:32 -0500)
[Why]
Type-c PHY config is not align with dpcd lane count.
When those values didn't match, it cause driver do
link training with 4 lane but phy only can output 2 lane.
The link trainig always fail.

[How]
1. Modify get_max_link_cap function. According DPALT_DP4
to update max lane count.
2. Add dp_mst_verify_link_cap to handle MST case because
we didn't call dp_mst_verify_link_cap for MST case.

Signed-off-by: Lewis Huang <Lewis.Huang@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h

index 34213bb..a560e61 100644 (file)
@@ -872,7 +872,8 @@ bool dc_link_detect_helper(struct dc_link *link, enum dc_detect_reason reason)
                                 * empty which leads to allocate_mst_payload() has "0"
                                 * pbn_per_slot value leading to exception on dc_fixpt_div()
                                 */
-                               link->verified_link_cap = link->reported_link_cap;
+                               dp_verify_mst_link_cap(link);
+
                                if (prev_sink != NULL)
                                        dc_sink_release(prev_sink);
                                return false;
index 7c78caf..701b739 100644 (file)
@@ -1409,6 +1409,9 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
        if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
                max_link_cap.link_rate = LINK_RATE_HIGH3;
 
+       if (link->link_enc->funcs->get_max_link_cap)
+               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)
                max_link_cap.lane_count =
@@ -1670,6 +1673,19 @@ bool dp_verify_link_cap_with_retries(
        return success;
 }
 
+bool dp_verify_mst_link_cap(
+       struct dc_link *link)
+{
+       struct dc_link_settings max_link_cap = {0};
+
+       max_link_cap = get_max_link_cap(link);
+       link->verified_link_cap = get_common_supported_link_settings(
+               link->reported_link_cap,
+               max_link_cap);
+
+       return true;
+}
+
 static struct dc_link_settings get_common_supported_link_settings(
                struct dc_link_settings link_setting_a,
                struct dc_link_settings link_setting_b)
index 8bf5f0f..0c12395 100644 (file)
@@ -337,6 +337,7 @@ struct dcn10_link_enc_registers {
                type RDPCS_TX_FIFO_ERROR_MASK;\
                type RDPCS_DPALT_DISABLE_TOGGLE_MASK;\
                type RDPCS_DPALT_4LANE_TOGGLE_MASK;\
+               type RDPCS_PHY_DPALT_DP4;\
                type RDPCS_PHY_DPALT_DISABLE;\
                type RDPCS_PHY_DPALT_DISABLE_ACK;\
                type RDPCS_PHY_DP_MPLLB_V2I;\
index 08a4df2..967706e 100644 (file)
@@ -43,6 +43,9 @@ bool dp_verify_link_cap_with_retries(
        struct dc_link_settings *known_limit_link_setting,
        int attempts);
 
+bool dp_verify_mst_link_cap(
+       struct dc_link *link);
+
 bool dp_validate_mode_timing(
        struct dc_link *link,
        const struct dc_crtc_timing *timing);
index abb4e42..b219092 100644 (file)
@@ -184,6 +184,10 @@ struct link_encoder_funcs {
        bool (*fec_is_active)(struct link_encoder *enc);
 #endif
        bool (*is_in_alt_mode) (struct link_encoder *enc);
+
+       void (*get_max_link_cap)(struct link_encoder *enc,
+               struct dc_link_settings *link_settings);
+
        enum signal_type (*get_dig_mode)(
                struct link_encoder *enc);
 };