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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx>
Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx>
Cc: Mika Kahola <mika.kahola@xxxxxxxxx>
Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx>
---
 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux