Hi Nikita, 2013/11/28 Nikita Kiryanov <nik...@compulab.co.il>: > Writing zero into I2Ci.I2C_CNT register causes random I2C failures in OMAP3 > based devices. This seems to be related to the following advisory which > apears in multiple erratas for OMAP3 SoCs (OMAP35xx, DM37xx), as well as > OMAP4430 TRM: > > Advisory: > I2C Module Does Not Allow 0-Byte Data Requests > Details: > When configured as the master, the I2C module does not allow 0-byte data > transfers. Note: Programming I2Ci.I2C_CNT[15:0]: DCOUNT = 0 will cause > undefined behavior. > Workaround(s): > No workaround. Do not use 0-byte data requests. > > The writes in question are unnecessary from a functional point of view. > Most of them are done after I/O has finished, and the only one that preceds > I/O (in i2c_probe()) is also unnecessary because a stop bit is sent before > actual data transmission takes place. > > Therefore, remove all writes that zero the cnt register. > > Cc: Heiko Schocher <h...@denx.de> > Cc: Thomas Petazzoni <thomas.petazz...@free-electrons.com> > Cc: Tom Rini <tr...@ti.com> > Cc: Lubomir Popov <lpo...@mm-sol.com> > Cc: Enric Balletbo Serra <eballe...@gmail.com> > Signed-off-by: Nikita Kiryanov <nik...@compulab.co.il> > --- > Changes in V2: > Removed all instances of writew(0, &i2c_base->cnt) instead of just the > one in i2c_write (following a test of V1 by Thomas Petazzoni). > > drivers/i2c/omap24xx_i2c.c | 6 ------ > 1 file changed, 6 deletions(-) > > diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c > index 3d38c03..c784004 100644 > --- a/drivers/i2c/omap24xx_i2c.c > +++ b/drivers/i2c/omap24xx_i2c.c > @@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int > speed, int slaveadd) > udelay(1000); > flush_fifo(adap); > writew(0xFFFF, &i2c_base->stat); > - writew(0, &i2c_base->cnt); > } > > static void flush_fifo(struct i2c_adapter *adap) > @@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, > uchar chip) > return res; > > /* No data transfer, slave addr only */ > - writew(0, &i2c_base->cnt); > - /* Set slave address */ > writew(chip, &i2c_base->sa); > /* Stop bit needed here */ > writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | > @@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, > uchar chip) > pr_exit: > flush_fifo(adap); > writew(0xFFFF, &i2c_base->stat); > - writew(0, &i2c_base->cnt); > return res; > } > > @@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, > uchar chip, uint addr, > rd_exit: > flush_fifo(adap); > writew(0xFFFF, &i2c_base->stat); > - writew(0, &i2c_base->cnt); > return i2c_error; > } > > @@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, > uchar chip, uint addr, > wr_exit: > flush_fifo(adap); > writew(0xFFFF, &i2c_base->stat); > - writew(0, &i2c_base->cnt); > return i2c_error; > } > > -- > 1.8.1.2 > Tested with various OMAP3 IGEP boards (with OMAP353x and DM373x) and works.
Thanks, Enric _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot