9
0
Fork 0

Fix problems with I2C support for mpc5200

This commit is contained in:
dzu 2003-09-30 14:08:43 +00:00
parent 87970ebeb5
commit ab209d5107
3 changed files with 61 additions and 11 deletions

View File

@ -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

View File

@ -28,15 +28,22 @@
#include <mpc5xxx.h>
#include <i2c.h>
#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(&regs->mfdr, speed, 0);
mpc_reg_out(&regs->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;

View File

@ -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