[Intel-gfx] [PATCH] drm/i915: Adaptive backoff delay on link training

Mika Kuoppala mika.kuoppala at linux.intel.com
Fri Feb 26 10:54:56 UTC 2016


If the panel don't give us the information how long to wait
before starting a new link training phase, it is not productive
to poke it at 100us or 400us intervals and then give up if it
fails to respond in time. Instead gradually increase the training
delay so that we reach the slower kind and get display up.

This was needed to reach panel:

0000: 12 14 c4 41 00 00 01 c0 02 00 00 00 1f 0b 00
0070: 01 00
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0100: 14 84 00 00 00 00 00 00 01 10 00
0200: 01 00 00 00 80 00 00 00
0600: 01
0700: 02
0701: b7 f6 00 00
0720: 00 04 02 00 0a 04 0a 00 1b 00 00 01 00 ff ff 03
0732: 04 10

on kbl (8086:591e)

Cc: Ander Conselvan de Oliveira <conselvan2 at gmail.com>
Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
Cc: Mika Kahola <mika.kahola at intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala at intel.com>
---
 drivers/gpu/drm/i915/intel_dp_link_training.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 0b8eefc2acc5..aec81e28e347 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -104,6 +104,19 @@ intel_dp_update_link_train(struct intel_dp *intel_dp)
 	return ret == intel_dp->lane_count;
 }
 
+static void intel_dp_link_training_delay(struct intel_dp *intel_dp,
+					 int retry_count)
+{
+	if (intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL]) {
+		mdelay(intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
+	} else {
+		if (retry_count)
+			mdelay(retry_count * 4);
+		else
+			udelay(400);
+	}
+}
+
 /* Enable corresponding port and start training pattern 1 */
 static void
 intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
@@ -150,7 +163,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
 
-		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+		intel_dp_link_training_delay(intel_dp, loop_tries);
+
 		if (!intel_dp_get_link_status(intel_dp, link_status)) {
 			DRM_ERROR("failed to get link status\n");
 			break;
@@ -184,7 +198,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 				break;
 		if (i == intel_dp->lane_count) {
 			++loop_tries;
-			if (loop_tries == 5) {
+			if (loop_tries == 10) {
 				DRM_ERROR("too many full retries, give up\n");
 				break;
 			}
@@ -275,7 +289,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 			break;
 		}
 
-		drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
+		intel_dp_link_training_delay(intel_dp, cr_tries);
+
 		if (!intel_dp_get_link_status(intel_dp, link_status)) {
 			DRM_ERROR("failed to get link status\n");
 			break;
-- 
2.5.0



More information about the Intel-gfx mailing list