[Intel-gfx] [PATCH] drm/i915: Cache DisplayPort link signal levels

Mika Kahola mika.kahola at intel.com
Wed Apr 20 10:21:08 UTC 2016


Cache DisplayPort signal levels including voltage swing and
pre-emphasis. After resume, the DP link is re-trained by trying
previusly computed voltage swing and pre-emphasis. In case, we
are not able to train the link by using these settings, the link
training is restarted. Now, the link is trained until the signal
levels of previus link training is achieved and clock recovery
is achieved.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91393
Signed-off-by: Mika Kahola <mika.kahola at intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c               | 1 +
 drivers/gpu/drm/i915/intel_dp_link_training.c | 7 ++++++-
 drivers/gpu/drm/i915/intel_drv.h              | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a3fc494..bb44a7c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3622,6 +3622,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
 			DP_TRAIN_PRE_EMPHASIS_SHIFT);
 
 	intel_dp->DP = (intel_dp->DP & ~mask) | signal_levels;
+	intel_dp->signal_levels = signal_levels;
 
 	I915_WRITE(intel_dp->output_reg, intel_dp->DP);
 	POSTING_READ(intel_dp->output_reg);
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 0b8eefc..05d450d 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -149,6 +149,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 	loop_tries = 0;
 	for (;;) {
 		uint8_t link_status[DP_LINK_STATUS_SIZE];
+		DRM_DEBUG_KMS("signal levels (target/current): %.8x/%.8x\n",
+			      intel_dp->target_signal_levels, intel_dp->signal_levels);
 
 		drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
 		if (!intel_dp_get_link_status(intel_dp, link_status)) {
@@ -156,7 +158,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
 			break;
 		}
 
-		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
+		if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count) &&
+			intel_dp->signal_levels >= intel_dp->target_signal_levels) {
 			DRM_DEBUG_KMS("clock recovery OK\n");
 			break;
 		}
@@ -324,6 +327,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
 
 	if (channel_eq) {
 		intel_dp->train_set_valid = true;
+		intel_dp->target_signal_levels = max(intel_dp->signal_levels,
+						     intel_dp->target_signal_levels);
 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index beed9e8..e58f3935 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -859,6 +859,7 @@ struct intel_dp {
 	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
 
 	bool train_set_valid;
+	uint32_t signal_levels, target_signal_levels;
 
 	/* Displayport compliance testing */
 	unsigned long compliance_test_type;
-- 
1.9.1



More information about the Intel-gfx mailing list