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

Commit 4819d2e4 authored by Chris Wilson's avatar Chris Wilson Committed by Dave Airlie
Browse files

drm: Retry i2c transfer of EDID block after failure



Usually EDID retrieval is fine. However, sometimes, especially when the
machine is loaded, it fails, but succeeds after a few retries.

Based on a patch by Michael Buesch.

Reported-by: default avatarMichael Buesch <mb@bu3sch.de>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 942b0e95
Loading
Loading
Loading
Loading
+24 −16
Original line number Diff line number Diff line
@@ -230,6 +230,15 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
		      int block, int len)
{
	unsigned char start = block * EDID_LENGTH;
	int ret, retries = 5;

	/* The core i2c driver will automatically retry the transfer if the
	 * adapter reports EAGAIN. However, we find that bit-banging transfers
	 * are susceptible to errors under a heavily loaded machine and
	 * generate spurious NAKs and timeouts. Retrying the transfer
	 * of the individual block a few times seems to overcome this.
	 */
	do {
		struct i2c_msg msgs[] = {
			{
				.addr	= DDC_ADDR,
@@ -243,11 +252,10 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
				.buf	= buf,
			}
		};
		ret = i2c_transfer(adapter, msgs, 2);
	} while (ret != 2 && --retries);

	if (i2c_transfer(adapter, msgs, 2) == 2)
		return 0;

	return -1;
	return ret == 2 ? 0 : -1;
}

static u8 *