diff options
| author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-07-07 14:11:02 -0400 |
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2011-07-07 16:38:51 -0400 |
| commit | df0c237d124fb8d10b98f7b43d63d962eeed9355 (patch) | |
| tree | cd95a24a6691601a4c9571297e9b8d3459184498 | |
| parent | 885a50147f00a8a80108904bf58a18af357717f3 (diff) | |
drm/i915/dp: consolidate AUX retry code
When checking link status during a hot plug event or detecting sink
presence, we need to retry 3 times per the spec (section 9.1 of the 1.1a
DisplayPort spec). Consolidate the retry code into a
native_aux_read_retry function for use by get_link_status and _detect.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5f97c1751ff0..bca48b05520b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1012,21 +1012,23 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
| 1012 | } | 1012 | } |
| 1013 | 1013 | ||
| 1014 | /* | 1014 | /* |
| 1015 | * Fetch AUX CH registers 0x202 - 0x207 which contain | 1015 | * Native read with retry for link status and receiver capability reads for |
| 1016 | * link status information | 1016 | * cases where the sink may still be asleep. |
| 1017 | */ | 1017 | */ |
| 1018 | static bool | 1018 | static bool |
| 1019 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1019 | intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, |
| 1020 | uint8_t *recv, int recv_bytes) | ||
| 1020 | { | 1021 | { |
| 1021 | int ret, i; | 1022 | int ret, i; |
| 1022 | 1023 | ||
| 1023 | /* Must try AUX reads for this at least 3 times */ | 1024 | /* |
| 1025 | * Sinks are *supposed* to come up within 1ms from an off state, | ||
| 1026 | * but we're also supposed to retry 3 times per the spec. | ||
| 1027 | */ | ||
| 1024 | for (i = 0; i < 3; i++) { | 1028 | for (i = 0; i < 3; i++) { |
| 1025 | ret = intel_dp_aux_native_read(intel_dp, | 1029 | ret = intel_dp_aux_native_read(intel_dp, address, recv, |
| 1026 | DP_LANE0_1_STATUS, | 1030 | recv_bytes); |
| 1027 | intel_dp->link_status, | 1031 | if (ret == recv_bytes) |
| 1028 | DP_LINK_STATUS_SIZE); | ||
| 1029 | if (ret == DP_LINK_STATUS_SIZE) | ||
| 1030 | return true; | 1032 | return true; |
| 1031 | msleep(1); | 1033 | msleep(1); |
| 1032 | } | 1034 | } |
| @@ -1034,6 +1036,19 @@ intel_dp_get_link_status(struct intel_dp *intel_dp) | |||
| 1034 | return false; | 1036 | return false; |
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| 1039 | /* | ||
| 1040 | * Fetch AUX CH registers 0x202 - 0x207 which contain | ||
| 1041 | * link status information | ||
| 1042 | */ | ||
| 1043 | static bool | ||
| 1044 | intel_dp_get_link_status(struct intel_dp *intel_dp) | ||
| 1045 | { | ||
| 1046 | return intel_dp_aux_native_read_retry(intel_dp, | ||
| 1047 | DP_LANE0_1_STATUS, | ||
| 1048 | intel_dp->link_status, | ||
| 1049 | DP_LINK_STATUS_SIZE); | ||
| 1050 | } | ||
| 1051 | |||
| 1037 | static uint8_t | 1052 | static uint8_t |
| 1038 | intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1053 | intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
| 1039 | int r) | 1054 | int r) |
| @@ -1549,7 +1564,7 @@ static enum drm_connector_status | |||
| 1549 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1564 | ironlake_dp_detect(struct intel_dp *intel_dp) |
| 1550 | { | 1565 | { |
| 1551 | enum drm_connector_status status; | 1566 | enum drm_connector_status status; |
| 1552 | int ret, i; | 1567 | bool ret; |
| 1553 | 1568 | ||
| 1554 | /* Can't disconnect eDP, but you can close the lid... */ | 1569 | /* Can't disconnect eDP, but you can close the lid... */ |
| 1555 | if (is_edp(intel_dp)) { | 1570 | if (is_edp(intel_dp)) { |
| @@ -1560,17 +1575,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
| 1560 | } | 1575 | } |
| 1561 | 1576 | ||
| 1562 | status = connector_status_disconnected; | 1577 | status = connector_status_disconnected; |
| 1563 | for (i = 0; i < 3; i++) { | 1578 | ret = intel_dp_aux_native_read_retry(intel_dp, |
| 1564 | ret = intel_dp_aux_native_read(intel_dp, | 1579 | 0x000, intel_dp->dpcd, |
| 1565 | 0x000, intel_dp->dpcd, | 1580 | sizeof (intel_dp->dpcd)); |
| 1566 | sizeof (intel_dp->dpcd)); | 1581 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) |
| 1567 | if (ret == sizeof(intel_dp->dpcd) && | 1582 | status = connector_status_connected; |
| 1568 | intel_dp->dpcd[DP_DPCD_REV] != 0) { | ||
| 1569 | status = connector_status_connected; | ||
| 1570 | break; | ||
| 1571 | } | ||
| 1572 | msleep(1); | ||
| 1573 | } | ||
| 1574 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | 1583 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
| 1575 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | 1584 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
| 1576 | return status; | 1585 | return status; |
