[U-Boot] [PATCH V2] arm: omap: i2c: don't zero cnt in i2c_write

Enric Balletbo Serra eballetbo at gmail.com
Fri Nov 29 11:22:26 CET 2013


Hi Nikita,

2013/11/28 Nikita Kiryanov <nikita at 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 <hs at denx.de>
> Cc: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
> Cc: Tom Rini <trini at ti.com>
> Cc: Lubomir Popov <lpopov at mm-sol.com>
> Cc: Enric Balletbo Serra <eballetbo at gmail.com>
> Signed-off-by: Nikita Kiryanov <nikita at 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


More information about the U-Boot mailing list