[U-Boot] [PATCH 1/4] OMAP3 I2C Fix the sampling clock.

Menon, Nishanth
2009-06-10T14:52:46Z

> -----Original Message-----
> From: Tom Rix [mailto:Tom.Rix at windriver.com]
> Sent: Wednesday, June 10, 2009 7:54 AM
>
> void i2c_init (int speed, int slaveadd)
> {
> - u16 scl;
> + int psc, iclk, scll, sclh;
> +
> + /* Only handle standard and fast speeds */
> + if ((speed != OMAP_I2C_STANDARD) &&
> + (speed != OMAP_I2C_FAST_MODE)) {
> + printf("Error : I2C unsupported speed %d\n", speed);
> + return;
> + }
> +
> + /*
> + * Calculate the prescalar to go from from the function clock
> + * to the internal sampling clock, 12MHz.
> + */
> + psc = I2C_PSC_MAX;
> + while (psc >= I2C_PSC_MIN) {
> + iclk = I2C_IP_CLK / (psc + 1);
> + if (12000000 <= iclk)
> + break;
> + psc--;
> + }
> + if (psc < I2C_PSC_MIN) {
> + printf("Error : I2C unsupported prescalar %d\n", psc);
> + return;
> + }
> +
> + /*
> + * How the low and high time periods are calculated
> + * See the OMAP3xxx Reference Manual for more details
> + *
> + * tlow + thigh = 1 / speed
> + * thigh = tlow, nice square wave..
> + *
> + * tlow = 1 / (2 * speed) = (scll + 7) / iclk;
> + * scll + 7 = iclk / 2 * speed
> + * sclh + 5 = iclk / 2 * speed
> + */
> + scll = sclh = iclk / (2 * speed);
> + scll -= 7;
> + sclh -= 5;
> + if ((scll < 0) || (sclh < 0)) {
> + printf("Error : I2C initializing clock\n");
> + return;
> + }
>
> writew(0x2, I2C_SYSC); /* for ES2 after soft reset */
> udelay(1000);
> @@ -42,12 +84,10 @@ void i2c_init (int speed, int slaveadd)
> udelay (50000);

This is a repeat story of what happened in linux-omap and kernel. We had a similar discussion in [1] and related patch [2] to change equations. I have the same reservations with this patch:
a) using speed as default does not scale for all board combinations.
b) need flexible option to provide scll and sclh on a platform basis.
Regards,
Nishanth Menon
Ref:
[1] http://marc.info/?t=123540865900002&r=1&w=2
[2] http://marc.info/?l=linux-omap&m=122770723311340&w=2