diff options
author | Keith Packard <keithp@keithp.com> | 2011-11-01 22:45:03 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-11-16 23:26:25 -0500 |
commit | 93f62dad5ffe0962d83772fd16c0c1a9dd69767d (patch) | |
tree | da2715fcff925b4075a0273d3477bcfbd65de160 /drivers/gpu | |
parent | 832dd3c17f7829fe8e4c257531d6c5c9e19bd7ac (diff) |
drm/i915: Remove link_status field from intel_dp structure
No persistent data was ever stored here, so link_status is instead
allocated on the stack as needed.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index efe5f9e0de9e..2c0c482222e1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -58,7 +58,6 @@ struct intel_dp { | |||
58 | struct i2c_algo_dp_aux_data algo; | 58 | struct i2c_algo_dp_aux_data algo; |
59 | bool is_pch_edp; | 59 | bool is_pch_edp; |
60 | uint8_t train_set[4]; | 60 | uint8_t train_set[4]; |
61 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
62 | int panel_power_up_delay; | 61 | int panel_power_up_delay; |
63 | int panel_power_down_delay; | 62 | int panel_power_down_delay; |
64 | int panel_power_cycle_delay; | 63 | int panel_power_cycle_delay; |
@@ -1285,11 +1284,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | |||
1285 | * link status information | 1284 | * link status information |
1286 | */ | 1285 | */ |
1287 | static bool | 1286 | static bool |
1288 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1287 | intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1289 | { | 1288 | { |
1290 | return intel_dp_aux_native_read_retry(intel_dp, | 1289 | return intel_dp_aux_native_read_retry(intel_dp, |
1291 | DP_LANE0_1_STATUS, | 1290 | DP_LANE0_1_STATUS, |
1292 | intel_dp->link_status, | 1291 | link_status, |
1293 | DP_LINK_STATUS_SIZE); | 1292 | DP_LINK_STATUS_SIZE); |
1294 | } | 1293 | } |
1295 | 1294 | ||
@@ -1301,27 +1300,25 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | |||
1301 | } | 1300 | } |
1302 | 1301 | ||
1303 | static uint8_t | 1302 | static uint8_t |
1304 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1303 | intel_get_adjust_request_voltage(uint8_t adjust_request[2], |
1305 | int lane) | 1304 | int lane) |
1306 | { | 1305 | { |
1307 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1308 | int s = ((lane & 1) ? | 1306 | int s = ((lane & 1) ? |
1309 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | 1307 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : |
1310 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | 1308 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); |
1311 | uint8_t l = intel_dp_link_status(link_status, i); | 1309 | uint8_t l = adjust_request[lane>>1]; |
1312 | 1310 | ||
1313 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | 1311 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; |
1314 | } | 1312 | } |
1315 | 1313 | ||
1316 | static uint8_t | 1314 | static uint8_t |
1317 | intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1315 | intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2], |
1318 | int lane) | 1316 | int lane) |
1319 | { | 1317 | { |
1320 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
1321 | int s = ((lane & 1) ? | 1318 | int s = ((lane & 1) ? |
1322 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | 1319 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : |
1323 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | 1320 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); |
1324 | uint8_t l = intel_dp_link_status(link_status, i); | 1321 | uint8_t l = adjust_request[lane>>1]; |
1325 | 1322 | ||
1326 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | 1323 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; |
1327 | } | 1324 | } |
@@ -1362,15 +1359,18 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
1362 | } | 1359 | } |
1363 | 1360 | ||
1364 | static void | 1361 | static void |
1365 | intel_get_adjust_train(struct intel_dp *intel_dp) | 1362 | intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1366 | { | 1363 | { |
1364 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1367 | uint8_t v = 0; | 1365 | uint8_t v = 0; |
1368 | uint8_t p = 0; | 1366 | uint8_t p = 0; |
1369 | int lane; | 1367 | int lane; |
1368 | uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); | ||
1369 | int voltage_max; | ||
1370 | 1370 | ||
1371 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1371 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1372 | uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); | 1372 | uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); |
1373 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); | 1373 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane); |
1374 | 1374 | ||
1375 | if (this_v > v) | 1375 | if (this_v > v) |
1376 | v = this_v; | 1376 | v = this_v; |
@@ -1389,7 +1389,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp) | |||
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | static uint32_t | 1391 | static uint32_t |
1392 | intel_dp_signal_levels(uint8_t train_set, int lane_count) | 1392 | intel_dp_signal_levels(uint8_t train_set) |
1393 | { | 1393 | { |
1394 | uint32_t signal_levels = 0; | 1394 | uint32_t signal_levels = 0; |
1395 | 1395 | ||
@@ -1458,9 +1458,8 @@ static uint8_t | |||
1458 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1458 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
1459 | int lane) | 1459 | int lane) |
1460 | { | 1460 | { |
1461 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
1462 | int s = (lane & 1) * 4; | 1461 | int s = (lane & 1) * 4; |
1463 | uint8_t l = intel_dp_link_status(link_status, i); | 1462 | uint8_t l = link_status[lane>>1]; |
1464 | 1463 | ||
1465 | return (l >> s) & 0xf; | 1464 | return (l >> s) & 0xf; |
1466 | } | 1465 | } |
@@ -1485,18 +1484,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count | |||
1485 | DP_LANE_CHANNEL_EQ_DONE|\ | 1484 | DP_LANE_CHANNEL_EQ_DONE|\ |
1486 | DP_LANE_SYMBOL_LOCKED) | 1485 | DP_LANE_SYMBOL_LOCKED) |
1487 | static bool | 1486 | static bool |
1488 | intel_channel_eq_ok(struct intel_dp *intel_dp) | 1487 | intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1489 | { | 1488 | { |
1490 | uint8_t lane_align; | 1489 | uint8_t lane_align; |
1491 | uint8_t lane_status; | 1490 | uint8_t lane_status; |
1492 | int lane; | 1491 | int lane; |
1493 | 1492 | ||
1494 | lane_align = intel_dp_link_status(intel_dp->link_status, | 1493 | lane_align = intel_dp_link_status(link_status, |
1495 | DP_LANE_ALIGN_STATUS_UPDATED); | 1494 | DP_LANE_ALIGN_STATUS_UPDATED); |
1496 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | 1495 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) |
1497 | return false; | 1496 | return false; |
1498 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1497 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1499 | lane_status = intel_get_lane_status(intel_dp->link_status, lane); | 1498 | lane_status = intel_get_lane_status(link_status, lane); |
1500 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | 1499 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) |
1501 | return false; | 1500 | return false; |
1502 | } | 1501 | } |
@@ -1569,12 +1568,14 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1569 | clock_recovery = false; | 1568 | clock_recovery = false; |
1570 | for (;;) { | 1569 | for (;;) { |
1571 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1570 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1571 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1572 | uint32_t signal_levels; | 1572 | uint32_t signal_levels; |
1573 | if (IS_GEN6(dev) && is_edp(intel_dp)) { | 1573 | if (IS_GEN6(dev) && is_edp(intel_dp)) { |
1574 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1574 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1575 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1575 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1576 | } else { | 1576 | } else { |
1577 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1577 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1578 | DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); | ||
1578 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1579 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1579 | } | 1580 | } |
1580 | 1581 | ||
@@ -1590,10 +1591,13 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1590 | /* Set training pattern 1 */ | 1591 | /* Set training pattern 1 */ |
1591 | 1592 | ||
1592 | udelay(100); | 1593 | udelay(100); |
1593 | if (!intel_dp_get_link_status(intel_dp)) | 1594 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1595 | DRM_ERROR("failed to get link status\n"); | ||
1594 | break; | 1596 | break; |
1597 | } | ||
1595 | 1598 | ||
1596 | if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1599 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1600 | DRM_DEBUG_KMS("clock recovery OK\n"); | ||
1597 | clock_recovery = true; | 1601 | clock_recovery = true; |
1598 | break; | 1602 | break; |
1599 | } | 1603 | } |
@@ -1615,7 +1619,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1615 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1619 | voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1616 | 1620 | ||
1617 | /* Compute new intel_dp->train_set as requested by target */ | 1621 | /* Compute new intel_dp->train_set as requested by target */ |
1618 | intel_get_adjust_train(intel_dp); | 1622 | intel_get_adjust_train(intel_dp, link_status); |
1619 | } | 1623 | } |
1620 | 1624 | ||
1621 | intel_dp->DP = DP; | 1625 | intel_dp->DP = DP; |
@@ -1638,6 +1642,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1638 | for (;;) { | 1642 | for (;;) { |
1639 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ | 1643 | /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ |
1640 | uint32_t signal_levels; | 1644 | uint32_t signal_levels; |
1645 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
1641 | 1646 | ||
1642 | if (cr_tries > 5) { | 1647 | if (cr_tries > 5) { |
1643 | DRM_ERROR("failed to train DP, aborting\n"); | 1648 | DRM_ERROR("failed to train DP, aborting\n"); |
@@ -1649,7 +1654,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1649 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1654 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1650 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1655 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1651 | } else { | 1656 | } else { |
1652 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); | 1657 | signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); |
1658 | DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); | ||
1653 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1659 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1654 | } | 1660 | } |
1655 | 1661 | ||
@@ -1665,17 +1671,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1665 | break; | 1671 | break; |
1666 | 1672 | ||
1667 | udelay(400); | 1673 | udelay(400); |
1668 | if (!intel_dp_get_link_status(intel_dp)) | 1674 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1669 | break; | 1675 | break; |
1670 | 1676 | ||
1671 | /* Make sure clock is still ok */ | 1677 | /* Make sure clock is still ok */ |
1672 | if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { | 1678 | if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1673 | intel_dp_start_link_train(intel_dp); | 1679 | intel_dp_start_link_train(intel_dp); |
1674 | cr_tries++; | 1680 | cr_tries++; |
1675 | continue; | 1681 | continue; |
1676 | } | 1682 | } |
1677 | 1683 | ||
1678 | if (intel_channel_eq_ok(intel_dp)) { | 1684 | if (intel_channel_eq_ok(intel_dp, link_status)) { |
1679 | channel_eq = true; | 1685 | channel_eq = true; |
1680 | break; | 1686 | break; |
1681 | } | 1687 | } |
@@ -1690,7 +1696,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1690 | } | 1696 | } |
1691 | 1697 | ||
1692 | /* Compute new intel_dp->train_set as requested by target */ | 1698 | /* Compute new intel_dp->train_set as requested by target */ |
1693 | intel_get_adjust_train(intel_dp); | 1699 | intel_get_adjust_train(intel_dp, link_status); |
1694 | ++tries; | 1700 | ++tries; |
1695 | } | 1701 | } |
1696 | 1702 | ||
@@ -1822,6 +1828,7 @@ static void | |||
1822 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1828 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1823 | { | 1829 | { |
1824 | u8 sink_irq_vector; | 1830 | u8 sink_irq_vector; |
1831 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
1825 | 1832 | ||
1826 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) | 1833 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) |
1827 | return; | 1834 | return; |
@@ -1830,7 +1837,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1830 | return; | 1837 | return; |
1831 | 1838 | ||
1832 | /* Try to read receiver status if the link appears to be up */ | 1839 | /* Try to read receiver status if the link appears to be up */ |
1833 | if (!intel_dp_get_link_status(intel_dp)) { | 1840 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1834 | intel_dp_link_down(intel_dp); | 1841 | intel_dp_link_down(intel_dp); |
1835 | return; | 1842 | return; |
1836 | } | 1843 | } |
@@ -1855,7 +1862,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1855 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); | 1862 | DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); |
1856 | } | 1863 | } |
1857 | 1864 | ||
1858 | if (!intel_channel_eq_ok(intel_dp)) { | 1865 | if (!intel_channel_eq_ok(intel_dp, link_status)) { |
1859 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", | 1866 | DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", |
1860 | drm_get_encoder_name(&intel_dp->base.base)); | 1867 | drm_get_encoder_name(&intel_dp->base.base)); |
1861 | intel_dp_start_link_train(intel_dp); | 1868 | intel_dp_start_link_train(intel_dp); |