summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Packard2011-11-02 04:00:06 +0100
committerKeith Packard2011-11-17 05:26:26 +0100
commitcdb0e95bf571dccc1f75fef9bdad21b167ef0b37 (patch)
treea4c49806d9a39cb2f3c1d9dd5eda36e5b380dc5e
parentdrm/i915: Make DP prepare/commit consistent with DP dpms (diff)
downloadkernel-qcow2-linux-cdb0e95bf571dccc1f75fef9bdad21b167ef0b37.tar.gz
kernel-qcow2-linux-cdb0e95bf571dccc1f75fef9bdad21b167ef0b37.tar.xz
kernel-qcow2-linux-cdb0e95bf571dccc1f75fef9bdad21b167ef0b37.zip
drm/i915: Try harder during dp pattern 1 link training
Instead of going through the sequence just once, run through the whole set up to 5 times to see if something can work. This isn't part of the DP spec, but the BIOS seems to do it, and given that link training failure is so bad, it seems reasonable to follow suit. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8e37fdd1fa2f..7101b8b4f8b4 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1581,7 +1581,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
int i;
uint8_t voltage;
bool clock_recovery = false;
- int tries;
+ int voltage_tries, loop_tries;
u32 reg;
uint32_t DP = intel_dp->DP;
@@ -1608,7 +1608,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
DP &= ~DP_LINK_TRAIN_MASK;
memset(intel_dp->train_set, 0, 4);
voltage = 0xff;
- tries = 0;
+ voltage_tries = 0;
+ loop_tries = 0;
clock_recovery = false;
for (;;) {
/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
@@ -1651,16 +1652,26 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
for (i = 0; i < intel_dp->lane_count; i++)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break;
- if (i == intel_dp->lane_count)
- break;
+ if (i == intel_dp->lane_count) {
+ ++loop_tries;
+ if (loop_tries == 5) {
+ DRM_DEBUG_KMS("too many full retries, give up\n");
+ break;
+ }
+ memset(intel_dp->train_set, 0, 4);
+ voltage_tries = 0;
+ continue;
+ }
/* Check to see if we've tried the same voltage 5 times */
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
- ++tries;
- if (tries == 5)
+ ++voltage_tries;
+ if (voltage_tries == 5) {
+ DRM_DEBUG_KMS("too many voltage retries, give up\n");
break;
+ }
} else
- tries = 0;
+ voltage_tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Compute new intel_dp->train_set as requested by target */