On Thu, Apr 18, 2013 at 11:45:32PM +0200, Mark Kettenis wrote:
> > Date: Sat, 6 Apr 2013 16:19:02 +0200
> > From: Matthieu Herrb <[email protected]>
> >
> > 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 <[email protected]>
> > > >
> > > > 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?
Yes that patch work for me. Thanks.
>
>
> 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 );