
Make the i2c delays smaller. The measured delay is 55us at 100Khz. Set the delay to 15us which should work for 400Khz. 100Khz will loop four times and get a 60us delay. Try four times at a 15us delay and then revert to the previous behavior of 1ms delays. --- cpu/mpc5xxx/i2c.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c index e2506d8..dba9071 100644 --- a/cpu/mpc5xxx/i2c.c +++ b/cpu/mpc5xxx/i2c.c @@ -39,6 +39,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif
#define I2C_TIMEOUT 100 +#define I2C_TIMEOUT_QUICK 4 #define I2C_RETRIES 3
struct mpc5xxx_i2c_tap { @@ -80,7 +81,7 @@ static void mpc_reg_out(volatile u32 *reg, int val, int mask) static int wait_for_bb(void) { struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int timeout = I2C_TIMEOUT; + int timeout = I2C_TIMEOUT + I2C_TIMEOUT_QUICK; int status;
status = mpc_reg_in(®s->msr); @@ -94,7 +95,7 @@ static int wait_for_bb(void) mpc_reg_out(®s->mcr, 0, 0); mpc_reg_out(®s->mcr, I2C_EN, 0); #endif - udelay(1000); + timeout > I2C_TIMEOUT ? udelay(15) : udelay(1000); status = mpc_reg_in(®s->msr); }
@@ -104,12 +105,12 @@ static int wait_for_bb(void) static int wait_for_pin(int *status) { struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; - int timeout = I2C_TIMEOUT; + int timeout = I2C_TIMEOUT + I2C_TIMEOUT_QUICK;
*status = mpc_reg_in(®s->msr);
while (timeout-- && !(*status & I2C_IF)) { - udelay(1000); + timeout > I2C_TIMEOUT ? udelay(15) : udelay(1000); *status = mpc_reg_in(®s->msr); }