> 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 );