diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 111 |
1 files changed, 70 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f797fb58ba9c..0feae908bb37 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -50,9 +50,10 @@ struct intel_dp { | |||
50 | bool has_audio; | 50 | bool has_audio; |
51 | int force_audio; | 51 | int force_audio; |
52 | uint32_t color_range; | 52 | uint32_t color_range; |
53 | int dpms_mode; | ||
53 | uint8_t link_bw; | 54 | uint8_t link_bw; |
54 | uint8_t lane_count; | 55 | uint8_t lane_count; |
55 | uint8_t dpcd[4]; | 56 | uint8_t dpcd[8]; |
56 | struct i2c_adapter adapter; | 57 | struct i2c_adapter adapter; |
57 | struct i2c_algo_dp_aux_data algo; | 58 | struct i2c_algo_dp_aux_data algo; |
58 | bool is_pch_edp; | 59 | bool is_pch_edp; |
@@ -316,9 +317,17 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
316 | else | 317 | else |
317 | precharge = 5; | 318 | precharge = 5; |
318 | 319 | ||
319 | if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { | 320 | /* Try to wait for any previous AUX channel activity */ |
320 | DRM_ERROR("dp_aux_ch not started status 0x%08x\n", | 321 | for (try = 0; try < 3; try++) { |
321 | I915_READ(ch_ctl)); | 322 | status = I915_READ(ch_ctl); |
323 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | ||
324 | break; | ||
325 | msleep(1); | ||
326 | } | ||
327 | |||
328 | if (try == 3) { | ||
329 | WARN(1, "dp_aux_ch not started status 0x%08x\n", | ||
330 | I915_READ(ch_ctl)); | ||
322 | return -EBUSY; | 331 | return -EBUSY; |
323 | } | 332 | } |
324 | 333 | ||
@@ -770,6 +779,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
770 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 779 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
771 | intel_dp->link_configuration[0] = intel_dp->link_bw; | 780 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
772 | intel_dp->link_configuration[1] = intel_dp->lane_count; | 781 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
782 | intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; | ||
773 | 783 | ||
774 | /* | 784 | /* |
775 | * Check for DPCD version > 1.1 and enhanced framing support | 785 | * Check for DPCD version > 1.1 and enhanced framing support |
@@ -1011,6 +1021,8 @@ static void intel_dp_commit(struct drm_encoder *encoder) | |||
1011 | 1021 | ||
1012 | if (is_edp(intel_dp)) | 1022 | if (is_edp(intel_dp)) |
1013 | ironlake_edp_backlight_on(dev); | 1023 | ironlake_edp_backlight_on(dev); |
1024 | |||
1025 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; | ||
1014 | } | 1026 | } |
1015 | 1027 | ||
1016 | static void | 1028 | static void |
@@ -1045,6 +1057,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1045 | if (is_edp(intel_dp)) | 1057 | if (is_edp(intel_dp)) |
1046 | ironlake_edp_backlight_on(dev); | 1058 | ironlake_edp_backlight_on(dev); |
1047 | } | 1059 | } |
1060 | intel_dp->dpms_mode = mode; | ||
1048 | } | 1061 | } |
1049 | 1062 | ||
1050 | /* | 1063 | /* |
@@ -1334,10 +1347,16 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1334 | u32 reg; | 1347 | u32 reg; |
1335 | uint32_t DP = intel_dp->DP; | 1348 | uint32_t DP = intel_dp->DP; |
1336 | 1349 | ||
1337 | /* Enable output, wait for it to become active */ | 1350 | /* |
1338 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | 1351 | * On CPT we have to enable the port in training pattern 1, which |
1339 | POSTING_READ(intel_dp->output_reg); | 1352 | * will happen below in intel_dp_set_link_train. Otherwise, enable |
1340 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1353 | * the port and wait for it to become active. |
1354 | */ | ||
1355 | if (!HAS_PCH_CPT(dev)) { | ||
1356 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
1357 | POSTING_READ(intel_dp->output_reg); | ||
1358 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1359 | } | ||
1341 | 1360 | ||
1342 | /* Write the link configuration data */ | 1361 | /* Write the link configuration data */ |
1343 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1362 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
@@ -1370,7 +1389,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1370 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1389 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1371 | 1390 | ||
1372 | if (!intel_dp_set_link_train(intel_dp, reg, | 1391 | if (!intel_dp_set_link_train(intel_dp, reg, |
1373 | DP_TRAINING_PATTERN_1)) | 1392 | DP_TRAINING_PATTERN_1 | |
1393 | DP_LINK_SCRAMBLING_DISABLE)) | ||
1374 | break; | 1394 | break; |
1375 | /* Set training pattern 1 */ | 1395 | /* Set training pattern 1 */ |
1376 | 1396 | ||
@@ -1445,7 +1465,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1445 | 1465 | ||
1446 | /* channel eq pattern */ | 1466 | /* channel eq pattern */ |
1447 | if (!intel_dp_set_link_train(intel_dp, reg, | 1467 | if (!intel_dp_set_link_train(intel_dp, reg, |
1448 | DP_TRAINING_PATTERN_2)) | 1468 | DP_TRAINING_PATTERN_2 | |
1469 | DP_LINK_SCRAMBLING_DISABLE)) | ||
1449 | break; | 1470 | break; |
1450 | 1471 | ||
1451 | udelay(400); | 1472 | udelay(400); |
@@ -1559,6 +1580,18 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1559 | POSTING_READ(intel_dp->output_reg); | 1580 | POSTING_READ(intel_dp->output_reg); |
1560 | } | 1581 | } |
1561 | 1582 | ||
1583 | static bool | ||
1584 | intel_dp_get_dpcd(struct intel_dp *intel_dp) | ||
1585 | { | ||
1586 | if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, | ||
1587 | sizeof (intel_dp->dpcd)) && | ||
1588 | (intel_dp->dpcd[DP_DPCD_REV] != 0)) { | ||
1589 | return true; | ||
1590 | } | ||
1591 | |||
1592 | return false; | ||
1593 | } | ||
1594 | |||
1562 | /* | 1595 | /* |
1563 | * According to DP spec | 1596 | * According to DP spec |
1564 | * 5.1.2: | 1597 | * 5.1.2: |
@@ -1571,36 +1604,44 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1571 | static void | 1604 | static void |
1572 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1605 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1573 | { | 1606 | { |
1574 | int ret; | 1607 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) |
1608 | return; | ||
1575 | 1609 | ||
1576 | if (!intel_dp->base.base.crtc) | 1610 | if (!intel_dp->base.base.crtc) |
1577 | return; | 1611 | return; |
1578 | 1612 | ||
1613 | /* Try to read receiver status if the link appears to be up */ | ||
1579 | if (!intel_dp_get_link_status(intel_dp)) { | 1614 | if (!intel_dp_get_link_status(intel_dp)) { |
1580 | intel_dp_link_down(intel_dp); | 1615 | intel_dp_link_down(intel_dp); |
1581 | return; | 1616 | return; |
1582 | } | 1617 | } |
1583 | 1618 | ||
1584 | /* Try to read receiver status if the link appears to be up */ | 1619 | /* Now read the DPCD to see if it's actually running */ |
1585 | ret = intel_dp_aux_native_read(intel_dp, | 1620 | if (!intel_dp_get_dpcd(intel_dp)) { |
1586 | 0x000, intel_dp->dpcd, | ||
1587 | sizeof (intel_dp->dpcd)); | ||
1588 | if (ret != sizeof(intel_dp->dpcd)) { | ||
1589 | intel_dp_link_down(intel_dp); | 1621 | intel_dp_link_down(intel_dp); |
1590 | return; | 1622 | return; |
1591 | } | 1623 | } |
1592 | 1624 | ||
1593 | if (!intel_channel_eq_ok(intel_dp)) { | 1625 | if (!intel_channel_eq_ok(intel_dp)) { |
1626 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", | ||
1627 | drm_get_encoder_name(&intel_dp->base.base)); | ||
1594 | intel_dp_start_link_train(intel_dp); | 1628 | intel_dp_start_link_train(intel_dp); |
1595 | intel_dp_complete_link_train(intel_dp); | 1629 | intel_dp_complete_link_train(intel_dp); |
1596 | } | 1630 | } |
1597 | } | 1631 | } |
1598 | 1632 | ||
1599 | static enum drm_connector_status | 1633 | static enum drm_connector_status |
1634 | intel_dp_detect_dpcd(struct intel_dp *intel_dp) | ||
1635 | { | ||
1636 | if (intel_dp_get_dpcd(intel_dp)) | ||
1637 | return connector_status_connected; | ||
1638 | return connector_status_disconnected; | ||
1639 | } | ||
1640 | |||
1641 | static enum drm_connector_status | ||
1600 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1642 | ironlake_dp_detect(struct intel_dp *intel_dp) |
1601 | { | 1643 | { |
1602 | enum drm_connector_status status; | 1644 | enum drm_connector_status status; |
1603 | bool ret; | ||
1604 | 1645 | ||
1605 | /* Can't disconnect eDP, but you can close the lid... */ | 1646 | /* Can't disconnect eDP, but you can close the lid... */ |
1606 | if (is_edp(intel_dp)) { | 1647 | if (is_edp(intel_dp)) { |
@@ -1610,15 +1651,7 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
1610 | return status; | 1651 | return status; |
1611 | } | 1652 | } |
1612 | 1653 | ||
1613 | status = connector_status_disconnected; | 1654 | return intel_dp_detect_dpcd(intel_dp); |
1614 | ret = intel_dp_aux_native_read_retry(intel_dp, | ||
1615 | 0x000, intel_dp->dpcd, | ||
1616 | sizeof (intel_dp->dpcd)); | ||
1617 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) | ||
1618 | status = connector_status_connected; | ||
1619 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | ||
1620 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | ||
1621 | return status; | ||
1622 | } | 1655 | } |
1623 | 1656 | ||
1624 | static enum drm_connector_status | 1657 | static enum drm_connector_status |
@@ -1626,7 +1659,6 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1626 | { | 1659 | { |
1627 | struct drm_device *dev = intel_dp->base.base.dev; | 1660 | struct drm_device *dev = intel_dp->base.base.dev; |
1628 | struct drm_i915_private *dev_priv = dev->dev_private; | 1661 | struct drm_i915_private *dev_priv = dev->dev_private; |
1629 | enum drm_connector_status status; | ||
1630 | uint32_t temp, bit; | 1662 | uint32_t temp, bit; |
1631 | 1663 | ||
1632 | switch (intel_dp->output_reg) { | 1664 | switch (intel_dp->output_reg) { |
@@ -1648,15 +1680,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1648 | if ((temp & bit) == 0) | 1680 | if ((temp & bit) == 0) |
1649 | return connector_status_disconnected; | 1681 | return connector_status_disconnected; |
1650 | 1682 | ||
1651 | status = connector_status_disconnected; | 1683 | return intel_dp_detect_dpcd(intel_dp); |
1652 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, | ||
1653 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | ||
1654 | { | ||
1655 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) | ||
1656 | status = connector_status_connected; | ||
1657 | } | ||
1658 | |||
1659 | return status; | ||
1660 | } | 1684 | } |
1661 | 1685 | ||
1662 | /** | 1686 | /** |
@@ -1679,6 +1703,12 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
1679 | status = ironlake_dp_detect(intel_dp); | 1703 | status = ironlake_dp_detect(intel_dp); |
1680 | else | 1704 | else |
1681 | status = g4x_dp_detect(intel_dp); | 1705 | status = g4x_dp_detect(intel_dp); |
1706 | |||
1707 | DRM_DEBUG_KMS("DPCD: %02hx%02hx%02hx%02hx%02hx%02hx%02hx%02hx\n", | ||
1708 | intel_dp->dpcd[0], intel_dp->dpcd[1], intel_dp->dpcd[2], | ||
1709 | intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5], | ||
1710 | intel_dp->dpcd[6], intel_dp->dpcd[7]); | ||
1711 | |||
1682 | if (status != connector_status_connected) | 1712 | if (status != connector_status_connected) |
1683 | return status; | 1713 | return status; |
1684 | 1714 | ||
@@ -1924,6 +1954,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1924 | return; | 1954 | return; |
1925 | 1955 | ||
1926 | intel_dp->output_reg = output_reg; | 1956 | intel_dp->output_reg = output_reg; |
1957 | intel_dp->dpms_mode = -1; | ||
1927 | 1958 | ||
1928 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1959 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1929 | if (!intel_connector) { | 1960 | if (!intel_connector) { |
@@ -2000,7 +2031,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2000 | 2031 | ||
2001 | /* Cache some DPCD data in the eDP case */ | 2032 | /* Cache some DPCD data in the eDP case */ |
2002 | if (is_edp(intel_dp)) { | 2033 | if (is_edp(intel_dp)) { |
2003 | int ret; | 2034 | bool ret; |
2004 | u32 pp_on, pp_div; | 2035 | u32 pp_on, pp_div; |
2005 | 2036 | ||
2006 | pp_on = I915_READ(PCH_PP_ON_DELAYS); | 2037 | pp_on = I915_READ(PCH_PP_ON_DELAYS); |
@@ -2013,11 +2044,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2013 | dev_priv->panel_t12 *= 100; /* t12 in 100ms units */ | 2044 | dev_priv->panel_t12 *= 100; /* t12 in 100ms units */ |
2014 | 2045 | ||
2015 | ironlake_edp_panel_vdd_on(intel_dp); | 2046 | ironlake_edp_panel_vdd_on(intel_dp); |
2016 | ret = intel_dp_aux_native_read(intel_dp, DP_DPCD_REV, | 2047 | ret = intel_dp_get_dpcd(intel_dp); |
2017 | intel_dp->dpcd, | ||
2018 | sizeof(intel_dp->dpcd)); | ||
2019 | ironlake_edp_panel_vdd_off(intel_dp); | 2048 | ironlake_edp_panel_vdd_off(intel_dp); |
2020 | if (ret == sizeof(intel_dp->dpcd)) { | 2049 | if (ret) { |
2021 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) | 2050 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
2022 | dev_priv->no_aux_handshake = | 2051 | dev_priv->no_aux_handshake = |
2023 | intel_dp->dpcd[DP_MAX_DOWNSPREAD] & | 2052 | intel_dp->dpcd[DP_MAX_DOWNSPREAD] & |