Blob Blame History Raw
From: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Date: Fri, 13 Jul 2018 18:00:06 -0400
Subject: drm/amd/display: Retry link training again
Git-commit: 824474ba38e27ccacc9d2dd066f780e9b3c2ad78
Patch-mainline: v4.19-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

[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>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c    |   20 ++++++++++++++++++--
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c |    5 ++++-
 drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h  |    3 ++-
 3 files changed, 24 insertions(+), 4 deletions(-)

--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -60,7 +60,14 @@
 
 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
 				 */
 
 				/* 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 */
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -1088,7 +1088,8 @@ static struct dc_link_settings get_max_l
 
 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)
--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h
@@ -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,