aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2011-11-01 23:00:06 -0400
committerKeith Packard <keithp@keithp.com>2011-11-16 23:26:26 -0500
commitcdb0e95bf571dccc1f75fef9bdad21b167ef0b37 (patch)
treea4c49806d9a39cb2f3c1d9dd5eda36e5b380dc5e
parent21264c638b4f9179655a39436d0340bd0d4ab1de (diff)
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)
1581 int i; 1581 int i;
1582 uint8_t voltage; 1582 uint8_t voltage;
1583 bool clock_recovery = false; 1583 bool clock_recovery = false;
1584 int tries; 1584 int voltage_tries, loop_tries;
1585 u32 reg; 1585 u32 reg;
1586 uint32_t DP = intel_dp->DP; 1586 uint32_t DP = intel_dp->DP;
1587 1587
@@ -1608,7 +1608,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
1608 DP &= ~DP_LINK_TRAIN_MASK; 1608 DP &= ~DP_LINK_TRAIN_MASK;
1609 memset(intel_dp->train_set, 0, 4); 1609 memset(intel_dp->train_set, 0, 4);
1610 voltage = 0xff; 1610 voltage = 0xff;
1611 tries = 0; 1611 voltage_tries = 0;
1612 loop_tries = 0;
1612 clock_recovery = false; 1613 clock_recovery = false;
1613 for (;;) { 1614 for (;;) {
1614 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ 1615 /* 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)
1651 for (i = 0; i < intel_dp->lane_count; i++) 1652 for (i = 0; i < intel_dp->lane_count; i++)
1652 if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) 1653 if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
1653 break; 1654 break;
1654 if (i == intel_dp->lane_count) 1655 if (i == intel_dp->lane_count) {
1655 break; 1656 ++loop_tries;
1657 if (loop_tries == 5) {
1658 DRM_DEBUG_KMS("too many full retries, give up\n");
1659 break;
1660 }
1661 memset(intel_dp->train_set, 0, 4);
1662 voltage_tries = 0;
1663 continue;
1664 }
1656 1665
1657 /* Check to see if we've tried the same voltage 5 times */ 1666 /* Check to see if we've tried the same voltage 5 times */
1658 if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { 1667 if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
1659 ++tries; 1668 ++voltage_tries;
1660 if (tries == 5) 1669 if (voltage_tries == 5) {
1670 DRM_DEBUG_KMS("too many voltage retries, give up\n");
1661 break; 1671 break;
1672 }
1662 } else 1673 } else
1663 tries = 0; 1674 voltage_tries = 0;
1664 voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; 1675 voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
1665 1676
1666 /* Compute new intel_dp->train_set as requested by target */ 1677 /* Compute new intel_dp->train_set as requested by target */