drm_get_edid i2c failure

Michael Buesch mb at bu3sch.de
Sat Mar 5 06:56:20 PST 2011


Getting the EDID succeeds most of the time on my system. However,
every now and then, especially when the machine is highly loaded,
i2c communication and thus drm_get_edid() fails.
My guess is that some kind of electrical noise and/or misdesign in
the used components is the root cause of this.

The display with the issues is an Apple Cinema connected via DVI.
Another LG display is connected through VGA to the other connector
of the ATI Radeon HD 5450. (xrandr is used)

This is what kernel log shows on errors:

[ 9509.250829] i2c i2c-3: sendbytes: NAK bailout.
[ 9519.655190] i2c i2c-3: readbytes: ack/nak timeout
[ 9519.655258] [drm:radeon_dvi_detect] *ERROR* DVI-I-1: probed a monitor but no|invalid EDID
[ 9550.716078] [drm:radeon_dvi_detect] *ERROR* DVI-I-1: probed a monitor but no|invalid EDID
[ 9560.738835] i2c i2c-3: sendbytes: NAK bailout.
[ 9612.778073] [drm:radeon_dvi_detect] *ERROR* DVI-I-1: probed a monitor but no|invalid EDID

The display flickers for a few seconds and then continues to
work correctly.

So I applied the following patch to the kernel to workaround the issue:

Index: linux-2.6.37/drivers/gpu/drm/drm_edid.c
===================================================================
--- linux-2.6.37.orig/drivers/gpu/drm/drm_edid.c	2011-03-05 13:09:17.001960834 +0100
+++ linux-2.6.37/drivers/gpu/drm/drm_edid.c	2011-03-05 13:11:34.974194354 +0100
@@ -343,9 +343,16 @@ struct edid *drm_get_edid(struct drm_con
 			  struct i2c_adapter *adapter)
 {
 	struct edid *edid = NULL;
+	unsigned int tries;
 
-	if (drm_probe_ddc(adapter))
-		edid = (struct edid *)drm_do_get_edid(connector, adapter);
+	for (tries = 0; tries < 20; tries++) {
+		if (drm_probe_ddc(adapter))
+			edid = (struct edid *)drm_do_get_edid(connector, adapter);
+		if (edid)
+			break;
+	}
+	if (tries > 0 && tries < 20)
+		printk(KERN_INFO "drm_get_edid(): Succeed after %u tries\n", tries);
 
 	connector->display_info.raw_edid = (char *)edid;
 

This seems to help. I get messages like:

[ 6506.029922] i2c i2c-3: sendbytes: NAK bailout.
[ 6506.030828] i2c i2c-3: sendbytes: NAK bailout.
[ 6506.137459] drm_get_edid(): Succeed after 3 tries
[ 8647.073894] i2c i2c-3: sendbytes: NAK bailout.
[ 8647.196343] drm_get_edid(): Succeed after 2 tries
[ 8749.381956] drm_get_edid(): Succeed after 1 tries
[ 8759.523868] i2c i2c-3: readbytes: ack/nak timeout
[ 8759.668134] drm_get_edid(): Succeed after 1 tries

I was wondering if a real fix or workaround could be found for mainline inclusion.
Would it be acceptable to have a retry loop similar to the above patch?
Some suggestions?

-- 
Greetings, Michael.






More information about the dri-devel mailing list