From ab209d510710e0059260e3ea17c11741573296b9 Mon Sep 17 00:00:00 2001 From: dzu Date: Tue, 30 Sep 2003 14:08:43 +0000 Subject: Fix problems with I2C support for mpc5200 --- cpu/mpc5xxx/fec.c | 2 ++ cpu/mpc5xxx/i2c.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--- include/configs/IceCube.h | 12 ++++------ 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/cpu/mpc5xxx/fec.c b/cpu/mpc5xxx/fec.c index ae4e52950..a30037fd5 100644 --- a/cpu/mpc5xxx/fec.c +++ b/cpu/mpc5xxx/fec.c @@ -424,7 +424,9 @@ static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis) #endif } while (!(phyStatus & 0x0004)); /* !link up */ +#if (DEBUG & 0x2) printf ("done.\n"); +#endif } else { /* MII100 */ /* * Set the auto-negotiation advertisement register bits diff --git a/cpu/mpc5xxx/i2c.c b/cpu/mpc5xxx/i2c.c index 640d14022..74a610f94 100644 --- a/cpu/mpc5xxx/i2c.c +++ b/cpu/mpc5xxx/i2c.c @@ -28,15 +28,22 @@ #include #include -#ifdef CFG_I2C_MODULE +#if (CFG_I2C_MODULE == 2) #define I2C_BASE MPC5XXX_I2C2 -#else +#elif (CFG_I2C_MODULE == 1) #define I2C_BASE MPC5XXX_I2C1 +#else +#error CFG_I2C_MODULE is not properly configured #endif #define I2C_TIMEOUT 100 #define I2C_RETRIES 3 +struct mpc5xxx_i2c_tap { + int scl2tap; + int tap2tap; +}; + static int mpc_reg_in (volatile u32 *reg); static void mpc_reg_out (volatile u32 *reg, int val, int mask); static int wait_for_bb (void); @@ -44,6 +51,7 @@ static int wait_for_pin (int *status); static int do_address (uchar chip, char rdwr_flag); static int send_bytes (uchar chip, char *buf, int len); static int receive_bytes (uchar chip, char *buf, int len); +static int mpc_get_fdr (int); static int mpc_reg_in(volatile u32 *reg) { @@ -207,7 +215,7 @@ void i2c_init(int speed, int saddr) /* Set clock */ - mpc_reg_out(®s->mfdr, speed, 0); + mpc_reg_out(®s->mfdr, mpc_get_fdr(speed), 0); /* Enable module */ @@ -217,6 +225,50 @@ void i2c_init(int speed, int saddr) return; } +static int mpc_get_fdr(int speed) +{ + DECLARE_GLOBAL_DATA_PTR; + static int fdr = -1; + static int best_speed = 0; + + if (fdr == -1) { + ulong ipb, scl; + ulong bestmatch = 0xffffffffUL; + int best_i = 0, best_j = 0, i, j; + int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8}; + struct mpc5xxx_i2c_tap scltap[] = { + {4, 1}, + {4, 2}, + {6, 4}, + {6, 8}, + {14, 16}, + {30, 32}, + {62, 64}, + {126, 128} + }; + + ipb = gd->ipb_clk; + for (i = 7; i >= 0; i--) { + for (j = 7; j >= 0; j--) { + scl = 2 * (scltap[j].scl2tap + + (SCL_Tap[i] - 1) * scltap[j].tap2tap + 2); + if (ipb <= speed*scl) { + if ((speed*scl - ipb) < bestmatch) { + bestmatch = speed*scl - ipb; + best_i = i; + best_j = j; + best_speed = ipb/scl; + } + } + } + } + fdr = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2); + printf("%d kHz, ", best_speed / 1000); + } + + return fdr; +} + int i2c_probe(uchar chip) { struct mpc5xxx_i2c *regs = (struct mpc5xxx_i2c *)I2C_BASE; diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index 9b3b4b458..49abedeb3 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -107,13 +107,9 @@ * I2C configuration */ #define CONFIG_HARD_I2C 1 /* I2C with hardware support */ -#define CFG_I2C_MODULE 1 /* If defined then I2C module #2 is used - * otherwise I2C module #1 is used */ -#ifdef CONFIG_MPC5200 -#define CFG_I2C_SPEED 0x3D /* 86KHz given 133MHz IPBI */ -#else -#define CFG_I2C_SPEED 0x35 /* 86KHz given 33MHz IPBI */ -#endif +#define CFG_I2C_MODULE 2 /* Select I2C module #1 or #2 */ + +#define CFG_I2C_SPEED 100000 /* 100 kHz */ #define CFG_I2C_SLAVE 0x7F /* @@ -122,7 +118,7 @@ #define CFG_I2C_EEPROM_ADDR 0x50 /* 1010000x */ #define CFG_I2C_EEPROM_ADDR_LEN 1 #define CFG_EEPROM_PAGE_WRITE_BITS 3 -#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 35 +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 70 /* * Flash configuration -- cgit v1.2.3