aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1dc60408d5b..1f4242b682c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1153,18 +1153,27 @@ intel_dp_signal_levels(uint8_t train_set, int lane_count)
1153static uint32_t 1153static uint32_t
1154intel_gen6_edp_signal_levels(uint8_t train_set) 1154intel_gen6_edp_signal_levels(uint8_t train_set)
1155{ 1155{
1156 switch (train_set & (DP_TRAIN_VOLTAGE_SWING_MASK|DP_TRAIN_PRE_EMPHASIS_MASK)) { 1156 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
1157 DP_TRAIN_PRE_EMPHASIS_MASK);
1158 switch (signal_levels) {
1157 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: 1159 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
1158 return EDP_LINK_TRAIN_400MV_0DB_SNB_B; 1160 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
1161 return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1162 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
1163 return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
1159 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: 1164 case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
1160 return EDP_LINK_TRAIN_400MV_6DB_SNB_B; 1165 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
1166 return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
1161 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: 1167 case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
1162 return EDP_LINK_TRAIN_600MV_3_5DB_SNB_B; 1168 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
1169 return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
1163 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: 1170 case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
1164 return EDP_LINK_TRAIN_800MV_0DB_SNB_B; 1171 case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
1172 return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
1165 default: 1173 default:
1166 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level\n"); 1174 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
1167 return EDP_LINK_TRAIN_400MV_0DB_SNB_B; 1175 "0x%x\n", signal_levels);
1176 return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
1168 } 1177 }
1169} 1178}
1170 1179
@@ -1334,17 +1343,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
1334 struct drm_device *dev = intel_dp->base.base.dev; 1343 struct drm_device *dev = intel_dp->base.base.dev;
1335 struct drm_i915_private *dev_priv = dev->dev_private; 1344 struct drm_i915_private *dev_priv = dev->dev_private;
1336 bool channel_eq = false; 1345 bool channel_eq = false;
1337 int tries; 1346 int tries, cr_tries;
1338 u32 reg; 1347 u32 reg;
1339 uint32_t DP = intel_dp->DP; 1348 uint32_t DP = intel_dp->DP;
1340 1349
1341 /* channel equalization */ 1350 /* channel equalization */
1342 tries = 0; 1351 tries = 0;
1352 cr_tries = 0;
1343 channel_eq = false; 1353 channel_eq = false;
1344 for (;;) { 1354 for (;;) {
1345 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ 1355 /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
1346 uint32_t signal_levels; 1356 uint32_t signal_levels;
1347 1357
1358 if (cr_tries > 5) {
1359 DRM_ERROR("failed to train DP, aborting\n");
1360 intel_dp_link_down(intel_dp);
1361 break;
1362 }
1363
1348 if (IS_GEN6(dev) && is_edp(intel_dp)) { 1364 if (IS_GEN6(dev) && is_edp(intel_dp)) {
1349 signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); 1365 signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
1350 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; 1366 DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
@@ -1367,14 +1383,26 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
1367 if (!intel_dp_get_link_status(intel_dp)) 1383 if (!intel_dp_get_link_status(intel_dp))
1368 break; 1384 break;
1369 1385
1386 /* Make sure clock is still ok */
1387 if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) {
1388 intel_dp_start_link_train(intel_dp);
1389 cr_tries++;
1390 continue;
1391 }
1392
1370 if (intel_channel_eq_ok(intel_dp)) { 1393 if (intel_channel_eq_ok(intel_dp)) {
1371 channel_eq = true; 1394 channel_eq = true;
1372 break; 1395 break;
1373 } 1396 }
1374 1397
1375 /* Try 5 times */ 1398 /* Try 5 times, then try clock recovery if that fails */
1376 if (tries > 5) 1399 if (tries > 5) {
1377 break; 1400 intel_dp_link_down(intel_dp);
1401 intel_dp_start_link_train(intel_dp);
1402 tries = 0;
1403 cr_tries++;
1404 continue;
1405 }
1378 1406
1379 /* Compute new intel_dp->train_set as requested by target */ 1407 /* Compute new intel_dp->train_set as requested by target */
1380 intel_get_adjust_train(intel_dp); 1408 intel_get_adjust_train(intel_dp);