drm/amd/display: Retry link training again
authorBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Fri, 13 Jul 2018 22:00:06 +0000 (18:00 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 27 Jul 2018 14:07:42 +0000 (09:07 -0500)
[Why]
Some receivers seem to fail the first link training but are good on
subsequent tries. We want to retry link training again. This fixes
HTC vive pro not lighting up after being disabled.

[How]
Check if the link training passed without fall back if this is not
the case then we retry link training.

Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Reviewed-by: Harry Wentland <Harry.Wentland@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/inc/dc_link_dp.h

index 388a0635c38d5fb9f72bc846e9ff2b6d98b799d2..966d2f9c8c995836e6db51a16893753ed53c0ed6 100644 (file)
 
 enum {
        LINK_RATE_REF_FREQ_IN_MHZ = 27,
-       PEAK_FACTOR_X1000 = 1006
+       PEAK_FACTOR_X1000 = 1006,
+       /*
+       * Some receivers fail to train on first try and are good
+       * on subsequent tries. 2 retries should be plenty. If we
+       * don't have a successful training then we don't expect to
+       * ever get one.
+       */
+       LINK_TRAINING_MAX_VERIFY_RETRY = 2
 };
 
 /*******************************************************************************
@@ -760,7 +767,16 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
                                 */
 
                                /* deal with non-mst cases */
-                               dp_verify_link_cap(link, &link->reported_link_cap);
+                               for (i = 0; i < LINK_TRAINING_MAX_VERIFY_RETRY; i++) {
+                                       int fail_count = 0;
+
+                                       dp_verify_link_cap(link,
+                                                         &link->reported_link_cap,
+                                                         &fail_count);
+
+                                       if (fail_count == 0)
+                                               break;
+                               }
                        }
 
                        /* HDMI-DVI Dongle */
index 9d901ca705883efe421ec33931066200bcedd6ba..58ee9aad13fb6242fb9310fd5e04f4538e61e76b 100644 (file)
@@ -1088,7 +1088,8 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
 
 bool dp_verify_link_cap(
        struct dc_link *link,
-       struct dc_link_settings *known_limit_link_setting)
+       struct dc_link_settings *known_limit_link_setting,
+       int *fail_count)
 {
        struct dc_link_settings max_link_cap = {0};
        struct dc_link_settings cur_link_setting = {0};
@@ -1160,6 +1161,8 @@ bool dp_verify_link_cap(
                                                        skip_video_pattern);
                        if (status == LINK_TRAINING_SUCCESS)
                                success = true;
+                       else
+                               (*fail_count)++;
                }
 
                if (success)
index 697b5ee738451dd10fd4f5bb0002f659fbeade18..a37255c757e0ce11f33e9803b63cc26c017e631f 100644 (file)
@@ -35,7 +35,8 @@ struct dc_link_settings;
 
 bool dp_verify_link_cap(
        struct dc_link *link,
-       struct dc_link_settings *known_limit_link_setting);
+       struct dc_link_settings *known_limit_link_setting,
+       int *fail_count);
 
 bool dp_validate_mode_timing(
        struct dc_link *link,