diff mbox series

[1/1,V2,SRU,OEM-5.6] UBUNTU: SAUCE: drm/i915/dp_mst: wait longer during the clock recovery

Message ID 20201111071133.486948-2-koba.ko@canonical.com
State New
Headers show
Series UBUNTU: SAUCE: drm/i915/dp_mst - wait longer during the clock recovery for DisplayPort | expand

Commit Message

Koba Ko Nov. 11, 2020, 7:11 a.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1902861

For TGL platform, Connect with the MST hub, it always failed to recovery
the clock for the dispaly port during the boot-up.

Wait longer during the clock recovery and check the display port's
status.

Signed-off-by: Koba Ko <koba.ko@canonical.com>
---
 drivers/gpu/drm/drm_dp_helper.c                | 18 ++++++++++++++++++
 .../drm/i915/display/intel_dp_link_training.c  | 12 +++++++++++-
 include/drm/drm_dp_helper.h                    |  1 +
 3 files changed, 30 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 0814be525455..ce5ed08995b3 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -131,6 +131,24 @@  u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
 }
 EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor);
 
+void drm_dp_link_train_clock_recovery_larger_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	unsigned long rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+					 DP_TRAINING_AUX_RD_MASK;
+
+	if (rd_interval > 4)
+		DRM_DEBUG_KMS("AUX interval %lu, out of range (max 4)\n",
+			      rd_interval);
+
+	if (rd_interval == 0 || dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14)
+		rd_interval = 100;
+	else
+		rd_interval *= 4 * USEC_PER_MSEC;
+
+	usleep_range(rd_interval, rd_interval * 4);
+}
+EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_larger_delay);
+
 void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 {
 	unsigned long rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 2a1130dd1ad0..26674eaeabd5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -130,12 +130,17 @@  static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
 static bool
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 {
+	struct drm_i915_private *dev_priv;
 	u8 voltage;
 	int voltage_tries, cr_tries, max_cr_tries;
 	bool max_vswing_reached = false;
 	u8 link_config[2];
 	u8 link_bw, rate_select;
 
+	if (intel_dp->attached_connector) {
+		dev_priv = to_i915(intel_dp->attached_connector->base.dev);
+	}
+
 	if (intel_dp->prepare_link_retrain)
 		intel_dp->prepare_link_retrain(intel_dp);
 
@@ -187,10 +192,15 @@  intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 		max_cr_tries = 80;
 
 	voltage_tries = 1;
+
 	for (cr_tries = 0; cr_tries < max_cr_tries; ++cr_tries) {
 		u8 link_status[DP_LINK_STATUS_SIZE];
 
-		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+		if (dev_priv && IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0)) {
+			drm_dp_link_train_clock_recovery_larger_delay(intel_dp->dpcd);
+		} else {
+			drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+		}
 
 		if (!intel_dp_get_link_status(intel_dp, link_status)) {
 			DRM_ERROR("failed to get link status\n");
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index f3ebf695651c..e31e4048f89d 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1143,6 +1143,7 @@  u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
 #define EDP_PSR_RECEIVER_CAP_SIZE	2
 #define EDP_DISPLAY_CTL_CAP_SIZE	3
 
+void drm_dp_link_train_clock_recovery_larger_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
 void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
 void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);