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>
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,26 +1012,41 @@
 }
 
 /*
+ * Native read with retry for link status and receiver capability reads for
+ * cases where the sink may still be asleep.
+ */
+static bool
+intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address,
+			       uint8_t *recv, int recv_bytes)
+{
+	int ret, i;
+
+	/*
+	 * 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, address, recv,
+					       recv_bytes);
+		if (ret == recv_bytes)
+			return true;
+		msleep(1);
+	}
+
+	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)
 {
-	int ret, i;
-
-	/* Must try AUX reads for this at least 3 times */
-	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)
-			return true;
-		msleep(1);
-	}
-
-	return false;
+	return intel_dp_aux_native_read_retry(intel_dp,
+					      DP_LANE0_1_STATUS,
+					      intel_dp->link_status,
+					      DP_LINK_STATUS_SIZE);
 }
 
 static uint8_t
@@ -1549,7 +1564,7 @@
 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 @@
 	}
 
 	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;