diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 171 |
1 files changed, 82 insertions, 89 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c8e005553310..df648cb4c296 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -584,17 +584,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
584 | mode->clock = dev_priv->panel_fixed_mode->clock; | 584 | mode->clock = dev_priv->panel_fixed_mode->clock; |
585 | } | 585 | } |
586 | 586 | ||
587 | /* Just use VBT values for eDP */ | ||
588 | if (is_edp(intel_dp)) { | ||
589 | intel_dp->lane_count = dev_priv->edp.lanes; | ||
590 | intel_dp->link_bw = dev_priv->edp.rate; | ||
591 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); | ||
592 | DRM_DEBUG_KMS("eDP link bw %02x lane count %d clock %d\n", | ||
593 | intel_dp->link_bw, intel_dp->lane_count, | ||
594 | adjusted_mode->clock); | ||
595 | return true; | ||
596 | } | ||
597 | |||
598 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | 587 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { |
599 | for (clock = 0; clock <= max_clock; clock++) { | 588 | for (clock = 0; clock <= max_clock; clock++) { |
600 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 589 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
@@ -613,6 +602,19 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
613 | } | 602 | } |
614 | } | 603 | } |
615 | 604 | ||
605 | if (is_edp(intel_dp)) { | ||
606 | /* okay we failed just pick the highest */ | ||
607 | intel_dp->lane_count = max_lane_count; | ||
608 | intel_dp->link_bw = bws[max_clock]; | ||
609 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); | ||
610 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | ||
611 | "count %d clock %d\n", | ||
612 | intel_dp->link_bw, intel_dp->lane_count, | ||
613 | adjusted_mode->clock); | ||
614 | |||
615 | return true; | ||
616 | } | ||
617 | |||
616 | return false; | 618 | return false; |
617 | } | 619 | } |
618 | 620 | ||
@@ -1087,21 +1089,11 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1087 | } | 1089 | } |
1088 | 1090 | ||
1089 | static uint32_t | 1091 | static uint32_t |
1090 | intel_dp_signal_levels(struct intel_dp *intel_dp) | 1092 | intel_dp_signal_levels(uint8_t train_set, int lane_count) |
1091 | { | 1093 | { |
1092 | struct drm_device *dev = intel_dp->base.base.dev; | 1094 | uint32_t signal_levels = 0; |
1093 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1094 | uint32_t signal_levels = 0; | ||
1095 | u8 train_set = intel_dp->train_set[0]; | ||
1096 | u32 vswing = train_set & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1097 | u32 preemphasis = train_set & DP_TRAIN_PRE_EMPHASIS_MASK; | ||
1098 | 1095 | ||
1099 | if (is_edp(intel_dp)) { | 1096 | switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { |
1100 | vswing = dev_priv->edp.vswing; | ||
1101 | preemphasis = dev_priv->edp.preemphasis; | ||
1102 | } | ||
1103 | |||
1104 | switch (vswing) { | ||
1105 | case DP_TRAIN_VOLTAGE_SWING_400: | 1097 | case DP_TRAIN_VOLTAGE_SWING_400: |
1106 | default: | 1098 | default: |
1107 | signal_levels |= DP_VOLTAGE_0_4; | 1099 | signal_levels |= DP_VOLTAGE_0_4; |
@@ -1116,7 +1108,7 @@ intel_dp_signal_levels(struct intel_dp *intel_dp) | |||
1116 | signal_levels |= DP_VOLTAGE_1_2; | 1108 | signal_levels |= DP_VOLTAGE_1_2; |
1117 | break; | 1109 | break; |
1118 | } | 1110 | } |
1119 | switch (preemphasis) { | 1111 | switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { |
1120 | case DP_TRAIN_PRE_EMPHASIS_0: | 1112 | case DP_TRAIN_PRE_EMPHASIS_0: |
1121 | default: | 1113 | default: |
1122 | signal_levels |= DP_PRE_EMPHASIS_0; | 1114 | signal_levels |= DP_PRE_EMPHASIS_0; |
@@ -1203,18 +1195,6 @@ intel_channel_eq_ok(struct intel_dp *intel_dp) | |||
1203 | } | 1195 | } |
1204 | 1196 | ||
1205 | static bool | 1197 | static bool |
1206 | intel_dp_aux_handshake_required(struct intel_dp *intel_dp) | ||
1207 | { | ||
1208 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1209 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1210 | |||
1211 | if (is_edp(intel_dp) && dev_priv->no_aux_handshake) | ||
1212 | return false; | ||
1213 | |||
1214 | return true; | ||
1215 | } | ||
1216 | |||
1217 | static bool | ||
1218 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1198 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1219 | uint32_t dp_reg_value, | 1199 | uint32_t dp_reg_value, |
1220 | uint8_t dp_train_pat) | 1200 | uint8_t dp_train_pat) |
@@ -1226,9 +1206,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
1226 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1206 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1227 | POSTING_READ(intel_dp->output_reg); | 1207 | POSTING_READ(intel_dp->output_reg); |
1228 | 1208 | ||
1229 | if (!intel_dp_aux_handshake_required(intel_dp)) | ||
1230 | return true; | ||
1231 | |||
1232 | intel_dp_aux_native_write_1(intel_dp, | 1209 | intel_dp_aux_native_write_1(intel_dp, |
1233 | DP_TRAINING_PATTERN_SET, | 1210 | DP_TRAINING_PATTERN_SET, |
1234 | dp_train_pat); | 1211 | dp_train_pat); |
@@ -1261,11 +1238,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1261 | POSTING_READ(intel_dp->output_reg); | 1238 | POSTING_READ(intel_dp->output_reg); |
1262 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1239 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1263 | 1240 | ||
1264 | if (intel_dp_aux_handshake_required(intel_dp)) | 1241 | /* Write the link configuration data */ |
1265 | /* Write the link configuration data */ | 1242 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
1266 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1243 | intel_dp->link_configuration, |
1267 | intel_dp->link_configuration, | 1244 | DP_LINK_CONFIGURATION_SIZE); |
1268 | DP_LINK_CONFIGURATION_SIZE); | ||
1269 | 1245 | ||
1270 | DP |= DP_PORT_EN; | 1246 | DP |= DP_PORT_EN; |
1271 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) | 1247 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) |
@@ -1283,7 +1259,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1283 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1259 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1284 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1260 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1285 | } else { | 1261 | } else { |
1286 | signal_levels = intel_dp_signal_levels(intel_dp); | 1262 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1287 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1263 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1288 | } | 1264 | } |
1289 | 1265 | ||
@@ -1297,37 +1273,33 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1297 | break; | 1273 | break; |
1298 | /* Set training pattern 1 */ | 1274 | /* Set training pattern 1 */ |
1299 | 1275 | ||
1300 | udelay(500); | 1276 | udelay(100); |
1301 | if (intel_dp_aux_handshake_required(intel_dp)) { | 1277 | if (!intel_dp_get_link_status(intel_dp)) |
1278 | break; | ||
1279 | |||
1280 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | ||
1281 | clock_recovery = true; | ||
1302 | break; | 1282 | break; |
1303 | } else { | 1283 | } |
1304 | if (!intel_dp_get_link_status(intel_dp)) | ||
1305 | break; | ||
1306 | 1284 | ||
1307 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1285 | /* Check to see if we've tried the max voltage */ |
1308 | clock_recovery = true; | 1286 | for (i = 0; i < intel_dp->lane_count; i++) |
1287 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
1309 | break; | 1288 | break; |
1310 | } | 1289 | if (i == intel_dp->lane_count) |
1290 | break; | ||
1311 | 1291 | ||
1312 | /* Check to see if we've tried the max voltage */ | 1292 | /* Check to see if we've tried the same voltage 5 times */ |
1313 | for (i = 0; i < intel_dp->lane_count; i++) | 1293 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { |
1314 | if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1294 | ++tries; |
1315 | break; | 1295 | if (tries == 5) |
1316 | if (i == intel_dp->lane_count) | ||
1317 | break; | 1296 | break; |
1297 | } else | ||
1298 | tries = 0; | ||
1299 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1318 | 1300 | ||
1319 | /* Check to see if we've tried the same voltage 5 times */ | 1301 | /* Compute new intel_dp->train_set as requested by target */ |
1320 | if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | 1302 | intel_get_adjust_train(intel_dp); |
1321 | ++tries; | ||
1322 | if (tries == 5) | ||
1323 | break; | ||
1324 | } else | ||
1325 | tries = 0; | ||
1326 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
1327 | |||
1328 | /* Compute new intel_dp->train_set as requested by target */ | ||
1329 | intel_get_adjust_train(intel_dp); | ||
1330 | } | ||
1331 | } | 1303 | } |
1332 | 1304 | ||
1333 | intel_dp->DP = DP; | 1305 | intel_dp->DP = DP; |
@@ -1354,7 +1326,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1354 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1326 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1355 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1327 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1356 | } else { | 1328 | } else { |
1357 | signal_levels = intel_dp_signal_levels(intel_dp); | 1329 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); |
1358 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1330 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1359 | } | 1331 | } |
1360 | 1332 | ||
@@ -1368,28 +1340,24 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1368 | DP_TRAINING_PATTERN_2)) | 1340 | DP_TRAINING_PATTERN_2)) |
1369 | break; | 1341 | break; |
1370 | 1342 | ||
1371 | udelay(500); | 1343 | udelay(400); |
1372 | 1344 | if (!intel_dp_get_link_status(intel_dp)) | |
1373 | if (!intel_dp_aux_handshake_required(intel_dp)) { | ||
1374 | break; | 1345 | break; |
1375 | } else { | ||
1376 | if (!intel_dp_get_link_status(intel_dp)) | ||
1377 | break; | ||
1378 | 1346 | ||
1379 | if (intel_channel_eq_ok(intel_dp)) { | 1347 | if (intel_channel_eq_ok(intel_dp)) { |
1380 | channel_eq = true; | 1348 | channel_eq = true; |
1381 | break; | 1349 | break; |
1382 | } | 1350 | } |
1383 | 1351 | ||
1384 | /* Try 5 times */ | 1352 | /* Try 5 times */ |
1385 | if (tries > 5) | 1353 | if (tries > 5) |
1386 | break; | 1354 | break; |
1387 | 1355 | ||
1388 | /* Compute new intel_dp->train_set as requested by target */ | 1356 | /* Compute new intel_dp->train_set as requested by target */ |
1389 | intel_get_adjust_train(intel_dp); | 1357 | intel_get_adjust_train(intel_dp); |
1390 | ++tries; | 1358 | ++tries; |
1391 | } | ||
1392 | } | 1359 | } |
1360 | |||
1393 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) | 1361 | if (HAS_PCH_CPT(dev) && !is_edp(intel_dp)) |
1394 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1362 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
1395 | else | 1363 | else |
@@ -1408,6 +1376,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1408 | struct drm_i915_private *dev_priv = dev->dev_private; | 1376 | struct drm_i915_private *dev_priv = dev->dev_private; |
1409 | uint32_t DP = intel_dp->DP; | 1377 | uint32_t DP = intel_dp->DP; |
1410 | 1378 | ||
1379 | if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
1380 | return; | ||
1381 | |||
1411 | DRM_DEBUG_KMS("\n"); | 1382 | DRM_DEBUG_KMS("\n"); |
1412 | 1383 | ||
1413 | if (is_edp(intel_dp)) { | 1384 | if (is_edp(intel_dp)) { |
@@ -1430,6 +1401,28 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1430 | 1401 | ||
1431 | if (is_edp(intel_dp)) | 1402 | if (is_edp(intel_dp)) |
1432 | DP |= DP_LINK_TRAIN_OFF; | 1403 | DP |= DP_LINK_TRAIN_OFF; |
1404 | |||
1405 | if (!HAS_PCH_CPT(dev) && | ||
1406 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | ||
1407 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | ||
1408 | /* Hardware workaround: leaving our transcoder select | ||
1409 | * set to transcoder B while it's off will prevent the | ||
1410 | * corresponding HDMI output on transcoder A. | ||
1411 | * | ||
1412 | * Combine this with another hardware workaround: | ||
1413 | * transcoder select bit can only be cleared while the | ||
1414 | * port is enabled. | ||
1415 | */ | ||
1416 | DP &= ~DP_PIPEB_SELECT; | ||
1417 | I915_WRITE(intel_dp->output_reg, DP); | ||
1418 | |||
1419 | /* Changes to enable or select take place the vblank | ||
1420 | * after being written. | ||
1421 | */ | ||
1422 | intel_wait_for_vblank(intel_dp->base.base.dev, | ||
1423 | intel_crtc->pipe); | ||
1424 | } | ||
1425 | |||
1433 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1426 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1434 | POSTING_READ(intel_dp->output_reg); | 1427 | POSTING_READ(intel_dp->output_reg); |
1435 | } | 1428 | } |