Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+30 −21
Original line number Diff line number Diff line
@@ -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,
	ret = intel_dp_aux_native_read_retry(intel_dp,
					     0x000, intel_dp->dpcd,
					     sizeof (intel_dp->dpcd));
		if (ret == sizeof(intel_dp->dpcd) &&
		    intel_dp->dpcd[DP_DPCD_REV] != 0) {
	if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0)
		status = connector_status_connected;
			break;
		}
		msleep(1);
	}
	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;