Commit df0c237d authored by Jesse Barnes's avatar Jesse Barnes Committed by Keith Packard

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: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Reviewed-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 885a5014
...@@ -1012,21 +1012,23 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) ...@@ -1012,21 +1012,23 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
} }
/* /*
* Fetch AUX CH registers 0x202 - 0x207 which contain * Native read with retry for link status and receiver capability reads for
* link status information * cases where the sink may still be asleep.
*/ */
static bool static bool
intel_dp_get_link_status(struct intel_dp *intel_dp) intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
uint8_t *recv, int recv_bytes)
{ {
int ret, i; int ret, i;
/* Must try AUX reads for this at least 3 times */ /*
* Sinks are *supposed* to come up within 1ms from an off state,
* but we're also supposed to retry 3 times per the spec.
*/
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
ret = intel_dp_aux_native_read(intel_dp, ret = intel_dp_aux_native_read(intel_dp, address, recv,
DP_LANE0_1_STATUS, recv_bytes);
intel_dp->link_status, if (ret == recv_bytes)
DP_LINK_STATUS_SIZE);
if (ret == DP_LINK_STATUS_SIZE)
return true; return true;
msleep(1); msleep(1);
} }
...@@ -1034,6 +1036,19 @@ intel_dp_get_link_status(struct intel_dp *intel_dp) ...@@ -1034,6 +1036,19 @@ intel_dp_get_link_status(struct intel_dp *intel_dp)
return false; return false;
} }
/*
* Fetch AUX CH registers 0x202 - 0x207 which contain
* link status information
*/
static bool
intel_dp_get_link_status(struct intel_dp *intel_dp)
{
return intel_dp_aux_native_read_retry(intel_dp,
DP_LANE0_1_STATUS,
intel_dp->link_status,
DP_LINK_STATUS_SIZE);
}
static uint8_t static uint8_t
intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
int r) int r)
...@@ -1549,7 +1564,7 @@ static enum drm_connector_status ...@@ -1549,7 +1564,7 @@ static enum drm_connector_status
ironlake_dp_detect(struct intel_dp *intel_dp) ironlake_dp_detect(struct intel_dp *intel_dp)
{ {
enum drm_connector_status status; enum drm_connector_status status;
int ret, i; bool ret;
/* Can't disconnect eDP, but you can close the lid... */ /* Can't disconnect eDP, but you can close the lid... */
if (is_edp(intel_dp)) { if (is_edp(intel_dp)) {
...@@ -1560,17 +1575,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp) ...@@ -1560,17 +1575,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
} }
status = connector_status_disconnected; status = connector_status_disconnected;
for (i = 0; i < 3; i++) { ret = intel_dp_aux_native_read_retry(intel_dp,
ret = intel_dp_aux_native_read(intel_dp,
0x000, intel_dp->dpcd, 0x000, intel_dp->dpcd,
sizeof (intel_dp->dpcd)); sizeof (intel_dp->dpcd));
if (ret == sizeof(intel_dp->dpcd) && if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0)
intel_dp->dpcd[DP_DPCD_REV] != 0) {
status = connector_status_connected; status = connector_status_connected;
break;
}
msleep(1);
}
DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0],
intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]);
return status; return status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment