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

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

 



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@xxxxxxxxx>
---
 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

_______________________________________________
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