> Date: Sat, 6 Apr 2013 16:19:02 +0200
> From: Matthieu Herrb <matthieu.he...@laas.fr>
> 
> On Mon, Apr 01, 2013 at 12:24:39PM +0200, Mark Kettenis wrote:
> > > Date: Mon, 1 Apr 2013 10:09:27 +0200
> > > From: Matthieu Herrb <matthieu.he...@laas.fr>
> > > 
> > > On Sun, Mar 31, 2013 at 11:51:55AM +0200, Mark Kettenis wrote:
> > > > > Date: Fri, 29 Mar 2013 15:22:57 +0100
> > > > 
> > > > Ralf, Matthieu,
> > > > 
> > > > Yesterday I committed some changes that fix some issues in the SDVO
> > > > code.  For my setup, whhere HDMI output is provided over SDVO this
> > > > still isn't enough to give me output.  For that I need some further
> > > > changes.  But I'm interested to see if what's now in -current works
> > > > for you.  Could you send me a dmesg from a kernel with DRMDEBUG enabled?
> > > > 
> > > 
> > > Hi Mark,
> > > 
> > > 
> > > I've tried with intel_svdo.c 1.6 and the bitbang timing patch, my
> > > system still doesn't work. Below is dmesg with DRMDEBUG defined and
> > > Xorg.0.log. 
> > 
> > To bad.  Perhaps the timings in the I2C bit-banging code need to be
> > adjusted a bit more.  Can you play with that a bit?
> > 
> 
> Hi, yes adjusting timing a bit more makes my machine work. I first
> doubled all values like you suggested, then tried to go back to
> smaller values.
> 
> This seems to be the minimal set of value that makes my machine work:

Did some more digging, and realized that the i2c protocol has a
mechanism for slave devices to slow down the master.  Our current code
doesn't handle that, but here's a diff (mostly stolen from NetBSD)
that does.  Works for my SDVO setups.  Can you give this a go?


Index: pci/drm/i915/intel_display.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_display.c,v
retrieving revision 1.5
diff -u -p -r1.5 intel_display.c
--- pci/drm/i915/intel_display.c        17 Apr 2013 20:04:04 -0000      1.5
+++ pci/drm/i915/intel_display.c        18 Apr 2013 21:40:21 -0000
@@ -2598,8 +2598,8 @@ i9xx_update_plane(struct drm_crtc *crtc,
                intel_crtc->dspaddr_offset = linear_offset;
        }
 
-       DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
-                     obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
+//     DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
+//                   obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
        I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
        if (INTEL_INFO(dev)->gen >= 4) {
                I915_MODIFY_DISPBASE(DSPSURF(plane),
Index: i2c/i2c_bitbang.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/i2c_bitbang.c,v
retrieving revision 1.3
diff -u -p -r1.3 i2c_bitbang.c
--- i2c/i2c_bitbang.c   13 Jan 2006 23:56:46 -0000      1.3
+++ i2c/i2c_bitbang.c   18 Apr 2013 21:40:21 -0000
@@ -54,6 +54,27 @@
 #define        OUTPUT          ops->ibo_bits[I2C_BIT_OUTPUT]   /* SDA is 
output */
 #define        INPUT           ops->ibo_bits[I2C_BIT_INPUT]    /* SDA is input 
*/
 
+#define SCL_BAIL_COUNT 1000
+
+int i2c_wait_for_scl(void *, i2c_bitbang_ops_t);
+
+int
+i2c_wait_for_scl(void *v, i2c_bitbang_ops_t ops)
+{
+       int bail = 0;
+
+       while(((BB_READ & SCL) == 0) && bail < SCL_BAIL_COUNT) {
+               delay(1);
+               bail++;
+       }
+       if (bail == SCL_BAIL_COUNT) {
+               i2c_bitbang_send_stop(v, 0, ops);
+               return (EIO);
+       }
+
+       return (0);
+}
+
 /*ARGSUSED*/
 int
 i2c_bitbang_send_start(void *v, int flags, i2c_bitbang_ops_t ops)
@@ -64,6 +85,8 @@ i2c_bitbang_send_start(void *v, int flag
        BB_SET(SDA | SCL);
        delay(5);               /* bus free time (4.7 uS) */
        BB_SET(      SCL);
+       if (i2c_wait_for_scl(v, ops) != 0)
+               return (EIO);
        delay(4);               /* start hold time (4.0 uS) */
        BB_SET(        0);
        delay(5);               /* clock low time (4.7 uS) */
@@ -115,6 +138,8 @@ i2c_bitbang_read_byte(void *v, uint8_t *
        for (i = 0; i < 8; i++) {
                val <<= 1;
                BB_SET(SDA | SCL);
+               if (i2c_wait_for_scl(v, ops) != 0)
+                       return (EIO);
                delay(4);       /* clock high time (4.0 uS) */
                if (BB_READ & SDA)
                        val |= 1;
@@ -127,6 +152,8 @@ i2c_bitbang_read_byte(void *v, uint8_t *
        BB_SET(bit      );
        delay(1);       /* data setup time (250 nS) */
        BB_SET(bit | SCL);
+       if (i2c_wait_for_scl(v, ops) != 0)
+               return (EIO);
        delay(4);       /* clock high time (4.0 uS) */
        BB_SET(bit      );
        delay(5);       /* clock low time (4.7 uS) */
@@ -157,6 +184,8 @@ i2c_bitbang_write_byte(void *v, uint8_t 
                BB_SET(bit      );
                delay(1);       /* data setup time (250 nS) */
                BB_SET(bit | SCL);
+               if (i2c_wait_for_scl(v, ops) != 0)
+                       return (EIO);
                delay(4);       /* clock high time (4.0 uS) */
                BB_SET(bit      );
                delay(5);       /* clock low time (4.7 uS) */
@@ -167,6 +196,8 @@ i2c_bitbang_write_byte(void *v, uint8_t 
        BB_SET(SDA      );
        delay(5);
        BB_SET(SDA | SCL);
+       if (i2c_wait_for_scl(v, ops) != 0)
+               return (EIO);
        delay(4);
        error = (BB_READ & SDA) ? EIO : 0;
        BB_SET(SDA      );

Reply via email to