dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* drm_get_edid i2c failure
@ 2011-03-05 14:56 Michael Buesch
  2011-03-15 11:04 ` [PATCH] drm: Retry i2c transfer of EDID block after failure Chris Wilson
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Buesch @ 2011-03-05 14:56 UTC (permalink / raw)
  To: David Airlie; +Cc: dri-devel

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.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-03-15 22:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-05 14:56 drm_get_edid i2c failure Michael Buesch
2011-03-15 11:04 ` [PATCH] drm: Retry i2c transfer of EDID block after failure Chris Wilson
2011-03-15 17:02   ` Alex Deucher
2011-03-15 22:20   ` Michael Buesch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox