On Fri, Apr 04, 2014 at 10:40:57AM -0400, Alex Deucher wrote: > We need bare address packets at the start and end of > each i2c over aux transaction to properly reset the connection > between transactions. This mirrors what the existing dp i2c > over aux algo currently does. > > This fixes EDID fetches on certain monitors especially with > dp bridges. > > Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> The i915 dp aux code will work the same way still, but curiously the hw spec doesn't mention anything for this really. I didn't check tegra. -Daniel > --- > drivers/gpu/drm/drm_dp_helper.c | 53 +++++++++++++++++++++++------------------ > 1 file changed, 30 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > index f4babed..f0c2850 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -664,12 +664,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, > int num) > { > struct drm_dp_aux *aux = adapter->algo_data; > - unsigned int i, j; > + unsigned int m, b; > + struct drm_dp_aux_msg msg; > + int err = 0; > + u8 buf = 0; > > - for (i = 0; i < num; i++) { > - struct drm_dp_aux_msg msg; > - int err; > + memset(&msg, 0, sizeof(msg)); > > + for (m = 0; m < num; m++) { > + msg.address = msgs[m].addr; > + msg.request = (msgs[m].flags & I2C_M_RD) ? > + DP_AUX_I2C_READ : > + DP_AUX_I2C_WRITE; > + msg.request |= DP_AUX_I2C_MOT; > + msg.buffer = &buf; > + msg.size = 0; > + err = drm_dp_i2c_do_msg(aux, &msg); > + if (err < 0) { > + printk("error %d in bare address write\n", err); > + break; > + } > /* > * Many hardware implementations support FIFOs larger than a > * single byte, but it has been empirically determined that > @@ -677,31 +691,24 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, > * decreased performance. Therefore each message is simply > * transferred byte-by-byte. > */ > - for (j = 0; j < msgs[i].len; j++) { > - memset(&msg, 0, sizeof(msg)); > - msg.address = msgs[i].addr; > - > - msg.request = (msgs[i].flags & I2C_M_RD) ? > - DP_AUX_I2C_READ : > - DP_AUX_I2C_WRITE; > - > - /* > - * All messages except the last one are middle-of- > - * transfer messages. > - */ > - if ((i < num - 1) || (j < msgs[i].len - 1)) > - msg.request |= DP_AUX_I2C_MOT; > - > - msg.buffer = msgs[i].buf + j; > + for (b = 0; b < msgs[m].len; b++) { > + msg.buffer = msgs[m].buf + b; > msg.size = 1; > > err = drm_dp_i2c_do_msg(aux, &msg); > if (err < 0) > - return err; > + break; > } > } > - > - return num; > + if (err >= 0) > + err = num; > + /* send a bare address packet to close out the connection */ > + msg.request &= ~DP_AUX_I2C_MOT; > + msg.buffer = &buf; > + msg.size = 0; > + (void)drm_dp_i2c_do_msg(aux, &msg); > + > + return err; > } > > static const struct i2c_algorithm drm_dp_i2c_algo = { > -- > 1.8.3.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel