diff mbox

drm/i915: Cache DisplayPort link signal levels

Message ID 1461147668-4283-1-git-send-email-mika.kahola@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kahola, Mika April 20, 2016, 10:21 a.m. UTC
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@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 mbox

Patch

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;