diff mbox

[6/7] drm/i915/dp: consolidate AUX retry code

Message ID 1310062263-5595-7-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes July 7, 2011, 6:11 p.m. UTC
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>
---
 drivers/gpu/drm/i915/intel_dp.c |   51 +++++++++++++++++++++++----------------
 1 files changed, 30 insertions(+), 21 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5f97c17..bca48b0 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)
 }
 
 /*
- * Fetch AUX CH registers 0x202 - 0x207 which contain
- * link status information
+ * Native read with retry for link status and receiver capability reads for
+ * cases where the sink may still be asleep.
  */
 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;
 
-	/* 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++) {
-		ret = intel_dp_aux_native_read(intel_dp,
-					       DP_LANE0_1_STATUS,
-					       intel_dp->link_status,
-					       DP_LINK_STATUS_SIZE);
-		if (ret == DP_LINK_STATUS_SIZE)
+		ret = intel_dp_aux_native_read(intel_dp, address, recv,
+					       recv_bytes);
+		if (ret == recv_bytes)
 			return true;
 		msleep(1);
 	}
@@ -1034,6 +1036,19 @@  intel_dp_get_link_status(struct intel_dp *intel_dp)
 	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
 intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 		     int r)
@@ -1549,7 +1564,7 @@  static enum drm_connector_status
 ironlake_dp_detect(struct intel_dp *intel_dp)
 {
 	enum drm_connector_status status;
-	int ret, i;
+	bool ret;
 
 	/* Can't disconnect eDP, but you can close the lid... */
 	if (is_edp(intel_dp)) {
@@ -1560,17 +1575,11 @@  ironlake_dp_detect(struct intel_dp *intel_dp)
 	}
 
 	status = connector_status_disconnected;
-	for (i = 0; i < 3; i++) {
-		ret = intel_dp_aux_native_read(intel_dp,
-					       0x000, intel_dp->dpcd,
-					       sizeof (intel_dp->dpcd));
-		if (ret == sizeof(intel_dp->dpcd) &&
-		    intel_dp->dpcd[DP_DPCD_REV] != 0) {
-			status = connector_status_connected;
-			break;
-		}
-		msleep(1);
-	}
+	ret = intel_dp_aux_native_read_retry(intel_dp,
+					     0x000, intel_dp->dpcd,
+					     sizeof (intel_dp->dpcd));
+	if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0)
+		status = connector_status_connected;
 	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]);
 	return status;