diff options
| -rw-r--r-- | board/mpc8349emds/pci.c | 8 | ||||
| -rw-r--r-- | board/mpc8349itx/mpc8349itx.c | 6 | ||||
| -rw-r--r-- | board/mpc8349itx/pci.c | 2 | ||||
| -rw-r--r-- | board/mpc8360emds/pci.c | 11 | ||||
| -rw-r--r-- | cpu/mpc83xx/i2c.c | 208 | ||||
| -rw-r--r-- | include/asm-ppc/i2c.h | 10 | ||||
| -rw-r--r-- | include/configs/MPC8349ITX.h | 2 | ||||
| -rw-r--r-- | include/configs/TQM834x.h | 2 | ||||
| -rw-r--r-- | include/i2c.h | 8 | 
9 files changed, 151 insertions, 106 deletions
| diff --git a/board/mpc8349emds/pci.c b/board/mpc8349emds/pci.c index a916245ae..93827f11d 100644 --- a/board/mpc8349emds/pci.c +++ b/board/mpc8349emds/pci.c @@ -75,10 +75,8 @@ pib_init(void)  	/* Switch temporarily to I2C bus #2 */  	orig_i2c_bus = i2c_get_bus_num(); -	if(orig_i2c_bus != I2C_BUS_2) -	 	i2c_set_bus_num(I2C_BUS_2); - -	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); +	if(orig_i2c_bus != 2) +	 	i2c_set_bus_num(2);  	val8 = 0;  	i2c_write(0x23, 0x6, 1, &val8, 1); @@ -124,7 +122,7 @@ pib_init(void)  	printf("PCI2: 32-bit on PMC3\n");  #endif  	/* Reset to original I2C bus */ -	if(orig_i2c_bus != I2C_BUS_2) +	if(orig_i2c_bus != 2)  	 	i2c_set_bus_num(orig_i2c_bus);  } diff --git a/board/mpc8349itx/mpc8349itx.c b/board/mpc8349itx/mpc8349itx.c index 9a5cbec85..466264588 100644 --- a/board/mpc8349itx/mpc8349itx.c +++ b/board/mpc8349itx/mpc8349itx.c @@ -259,7 +259,7 @@ int checkboard(void)  	puts("Board: Freescale MPC8349E-mITX");  #ifdef CONFIG_HARD_I2C -	i2c_set_bus_num(I2C_BUS_2); +	i2c_set_bus_num(2);  	if (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) ==  	    0)  		printf(" %u.%u (PCF8475A)", (i2c_data & 0x02) >> 1, @@ -379,7 +379,7 @@ int misc_init_r(void)  	u8 data[sizeof(eeprom_data)]; -	i2c_set_bus_num(I2C_BUS_1); +	i2c_set_bus_num(1);  	if (i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {  		if (memcmp(data, eeprom_data, sizeof(data)) != 0) { @@ -397,7 +397,7 @@ int misc_init_r(void)  #endif  #ifdef CFG_I2C_RTC_ADDR -	i2c_set_bus_num(I2C_BUS_2); +	i2c_set_bus_num(2);  	if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data, sizeof(ds1339_data))  	    == 0) { diff --git a/board/mpc8349itx/pci.c b/board/mpc8349itx/pci.c index acac185d5..cf07020b6 100644 --- a/board/mpc8349itx/pci.c +++ b/board/mpc8349itx/pci.c @@ -105,7 +105,7 @@ void pci_init_board(void)  	udelay(2000);  #ifdef CONFIG_HARD_I2C -	i2c_set_bus_num(I2C_BUS_2); +	i2c_set_bus_num(2);  	/* Read the PCI_M66EN jumper setting */  	if ((i2c_read(CFG_I2C_8574_ADDR2, 0, 0, ®8, sizeof(reg8)) == 0) ||  	    (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, ®8, sizeof(reg8)) == 0)) { diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c index 880b2ecc3..64ea50979 100644 --- a/board/mpc8360emds/pci.c +++ b/board/mpc8360emds/pci.c @@ -198,8 +198,11 @@ void pci_init_board(void)  	 * Assign PIB PMC slot to desired PCI bus  	 */ -	mpc83xx_i2c = (i2c_t *) (CFG_IMMRBAR + CFG_I2C2_OFFSET); -	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); +	/* Switch temporarily to I2C bus #2 */ +	orig_i2c_bus = i2c_get_bus_num(); + +	if(orig_i2c_bus != 2) +	 	i2c_set_bus_num(2);  	val8 = 0;  	i2c_write(0x23, 0x6, 1, &val8, 1); @@ -227,6 +230,10 @@ void pci_init_board(void)  	i2c_write(0x27, 0x3, 1, &val8, 1);  	asm("eieio"); +	/* Reset to original I2C bus */ +	if(orig_i2c_bus != 2) +	 	i2c_set_bus_num(orig_i2c_bus); +  	/*  	 * Release PCI RST Output signal  	 */ diff --git a/cpu/mpc83xx/i2c.c b/cpu/mpc83xx/i2c.c index fc89fb1e2..ce7849161 100644 --- a/cpu/mpc83xx/i2c.c +++ b/cpu/mpc83xx/i2c.c @@ -47,75 +47,121 @@  DECLARE_GLOBAL_DATA_PTR; -/* Three I2C bus speeds are supported here (50kHz, 100kHz - * and 400kHz).  It should be easy to add more.  Note that - * the maximum bus speed for I2C bus 1 is CSB/3, while I2C - * bus 2 can go as high as CSB. - * Typical values for CSB are 266MHz and 200MHz.  */ - -                                                                      /* 50kH  100kHz  400kHz */ -static const uchar speed_map_266[][3] = -                                                                      {{0x2e,         0x2a,   0x20},  /* base 88MHz */ -                                                                       {0x34,         0x30,   0x28}}; /* base 266 MHz */ - -static const uchar speed_map_200[][3] = -                                                                      {{0x2c,         0x28,   0x20},  /* base 66 MHz */ -                                                                       {0x33,         0x2f,   0x26}}; /* base 200 MHz */ -  /* Initialize the bus pointer to whatever one the SPD EEPROM is on.   * Default is bus 1.  This is necessary because the DDR initialization   * runs from ROM, and we can't switch buses because we can't modify   * the i2c_dev variable.  Everything gets straightened out once i2c_init   * is called from RAM.  */ -#if defined CFG_SPD_BUS_NUM -static i2c_t *i2c_dev = CFG_SPD_BUS_NUM; +#ifndef CFG_SPD_BUS_NUM +#define CFG_SPD_BUS_NUM 1 +#endif + +static unsigned int i2c_bus_num = CFG_SPD_BUS_NUM; + +#if CFG_SPD_BUS_NUM == 1 +static volatile i2c_t *i2c_dev = I2C_1;  #else -static i2c_t *i2c_dev = I2C_1; +static volatile i2c_t *i2c_dev = I2C_2;  #endif -static uchar busNum = I2C_BUS_1 ; -static int bus_speed[2] = {0, 0}; +static int i2c_bus_speed[2] = {0, 0}; -static int set_speed(int speed) +/* + * Map the frequency divider to the FDR.  This data is taken from table 17-5 + * of the MPC8349EA reference manual, with duplicates removed. + */ +static struct { +    unsigned int divider; +    u8 fdr; +} i2c_speed_map[] = +{ +	{0, 0x20}, +	{256, 0x20}, +	{288, 0x21}, +	{320, 0x22}, +	{352, 0x23}, +	{384, 0x24}, +	{416, 0x01}, +	{448, 0x25}, +	{480, 0x02}, +	{512, 0x26}, +	{576, 0x27}, +	{640, 0x28}, +	{704, 0x05}, +	{768, 0x29}, +	{832, 0x06}, +	{896, 0x2A}, +	{1024, 0x2B}, +	{1152, 0x08}, +	{1280, 0x2C}, +	{1536, 0x2D}, +	{1792, 0x2E}, +	{1920, 0x0B}, +	{2048, 0x2F}, +	{2304, 0x0C}, +	{2560, 0x30}, +	{3072, 0x31}, +	{3584, 0x32}, +	{3840, 0x0F}, +	{4096, 0x33}, +	{4608, 0x10}, +	{5120, 0x34}, +	{6144, 0x35}, +	{7168, 0x36}, +	{7680, 0x13}, +	{8192, 0x37}, +	{9216, 0x14}, +	{10240, 0x38}, +	{12288, 0x39}, +	{14336, 0x3A}, +	{15360, 0x17}, +	{16384, 0x3B}, +	{18432, 0x18}, +	{20480, 0x3C}, +	{24576, 0x3D}, +	{28672, 0x3E}, +	{30720, 0x1B}, +	{32768, 0x3F}, +	{36864, 0x1C}, +	{40960, 0x1D}, +	{49152, 0x1E}, +	{61440, 0x1F}, +	{-1, 0x1F} +}; + +#define NUM_I2C_SPEEDS (sizeof(i2c_speed_map) / sizeof(i2c_speed_map[0])) + +static int set_speed(unsigned int speed)  { -      uchar value; -      const uchar *spdPtr; +	unsigned long i2c_clk; +	unsigned int divider, i; +	u8 fdr = 0x3F; + +	i2c_clk = (i2c_bus_num == 2) ? gd->i2c2_clk : gd->i2c1_clk; -      /* Global data contains maximum I2C bus 1 speed, which is CSB/3 */ -      if(gd->i2c_clk == 88000000) -      { -              spdPtr = speed_map_266[busNum]; -      } -      else if(gd->i2c_clk == 66000000) -      { -              spdPtr = speed_map_200[busNum]; -      } -      else -      { -              printf("Max I2C bus speed %d not supported\n", gd->i2c_clk); -              return -1; -      } +	divider = i2c_clk / speed; -      switch(speed) -      { -              case 50000: -                      value   = *(spdPtr + 0); -                      break; -              case 100000: -                      value   = *(spdPtr + 1); -                      break; -              case 400000: -                      value   = *(spdPtr + 2); -                      break; -              default: -                      printf("I2C bus speed %d not supported\n", speed); -                      return -2; -      } -      /* set clock */ -      writeb(value, &i2c_dev->fdr); -      bus_speed[busNum] = speed; -      return 0; +	/* Scan i2c_speed_map[] for the closest matching divider.*/ + +	for (i = 0; i < NUM_I2C_SPEEDS-1; i++) { +		/* Locate our divider in between two entries in i2c_speed_map[] */ +		if ((divider >= i2c_speed_map[i].divider) && +		    (divider <= i2c_speed_map[i+1].divider)) { +			/* Which one is closer? */ +			if ((divider - i2c_speed_map[i].divider) < (i2c_speed_map[i+1].divider - divider)) { +				fdr = i2c_speed_map[i].fdr; +			} else { +				fdr = i2c_speed_map[i+1].fdr; +			} +			break; +		} +	} + +	writeb(fdr, &i2c_dev->fdr); +	i2c_bus_speed[i2c_bus_num - 1] = speed; + +	return 0;  } @@ -125,16 +171,16 @@ static void _i2c_init(int speed, int slaveadd)  	writeb(0x00 , &i2c_dev->cr);  	/* set clock */ -	writeb(speed, &i2c_dev->fdr); +	set_speed(speed);  	/* set default filter */ -	writeb(0x10,&i2c_dev->dfsrr); +	writeb(IC2_FDR,&i2c_dev->dfsrr);  	/* write slave address */  	writeb(slaveadd, &i2c_dev->adr);  	/* clear status register */ -	writeb(0x00, &i2c_dev->sr); +	writeb(I2C_CR_MTX, &i2c_dev->sr);  	/* start I2C controller */  	writeb(I2C_CR_MEN, &i2c_dev->cr); @@ -142,19 +188,19 @@ static void _i2c_init(int speed, int slaveadd)  void i2c_init(int speed, int slaveadd)  { -      /* Set both interfaces to the same speed and slave address */ -      /* Note: This function gets called twice - before and after -       * relocation to RAM.  The first time it's called, we are unable -       * to change buses, so whichever one 'i2c_dev' was initialized to -       * gets set twice.  When run from RAM both buses get set properly */ +	/* Set both interfaces to the same speed and slave address */ +	/* Note: This function gets called twice - before and after +	 * relocation to RAM.  The first time it's called, we are unable +	 * to change buses, so whichever one 'i2c_dev' was initialized to +	 * gets set twice.  When run from RAM both buses get set properly */ -      i2c_set_bus_num(I2C_BUS_1); -      _i2c_init(speed, slaveadd); -#ifdef        CFG_I2C2_OFFSET -      i2c_set_bus_num(I2C_BUS_2); -      _i2c_init(speed, slaveadd); -      i2c_set_bus_num(I2C_BUS_1); -#endif        /* CFG_I2C2_OFFSET */ +	i2c_set_bus_num(1); +	_i2c_init(speed, slaveadd); +#ifdef	CFG_I2C2_OFFSET +	i2c_set_bus_num(2); +	_i2c_init(speed, slaveadd); +	i2c_set_bus_num(1); +#endif	/* CFG_I2C2_OFFSET */  }  static __inline__ int @@ -340,38 +386,38 @@ void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val)  	i2c_write (i2c_addr, reg, 1, &val, 1);  } -int 	i2c_set_bus_num(uchar bus) +int i2c_set_bus_num(unsigned int bus)  { -	if(bus == I2C_BUS_1) +	if(bus == 1)  	{  		i2c_dev = I2C_1;  	}  #ifdef	CFG_I2C2_OFFSET -	else if(bus == I2C_BUS_2) +	else if(bus == 2)  	{  		i2c_dev = I2C_2;  	} -#endif	/* CFG_I2C2_OFFSET */ +#endif  	else  	{  		return -1;  	} -	busNum = bus; +	i2c_bus_num = bus;  	return 0;  } -int 	i2c_set_bus_speed(int speed) +int i2c_set_bus_speed(unsigned int speed)  {  	return set_speed(speed);  } -uchar i2c_get_bus_num(void) +unsigned int i2c_get_bus_num(void)  { -	return busNum; +	return i2c_bus_num;  } -int 	i2c_get_bus_speed(void) +unsigned int i2c_get_bus_speed(void)  { -	return bus_speed[busNum]; +	return i2c_bus_speed[i2c_bus_num - 1];  }  #endif /* CONFIG_HARD_I2C */ diff --git a/include/asm-ppc/i2c.h b/include/asm-ppc/i2c.h index baf9d9a26..8afdda2ce 100644 --- a/include/asm-ppc/i2c.h +++ b/include/asm-ppc/i2c.h @@ -79,12 +79,6 @@ typedef struct i2c  #endif  #define I2C_TIMEOUT (CFG_HZ/4) -enum	I2C_BUS_NUM -{ -	I2C_BUS_1 = 0, -	I2C_BUS_2, -}; -  #ifndef CFG_IMMRBAR  #error CFG_IMMRBAR is not defined in /include/configs/${BOARD}.h  #endif @@ -96,9 +90,9 @@ enum	I2C_BUS_NUM  #define I2C_1 ((i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET))  /* Optional support for second I2C bus */ -#ifdef        CFG_I2C2_OFFSET +#ifdef	CFG_I2C2_OFFSET  #define I2C_2 ((i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET)) -#endif        /* CFG_I2C2_OFFSET */ +#endif	/* CFG_I2C2_OFFSET */  #define I2C_READ  1  #define I2C_WRITE 0 diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index 20f3c6d39..2fbc73618 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -81,7 +81,7 @@  #define CONFIG_I2C_CMD_TREE  #define CFG_I2C_OFFSET      	0x3000  #define CFG_I2C2_OFFSET      	0x3100 -#define CFG_SPD_BUS_NUM		I2C_2 +#define CFG_SPD_BUS_NUM		2  #define CFG_I2C_8574_ADDR1	0x20	/* I2C2, PCF8574 */  #define CFG_I2C_8574_ADDR2	0x21	/* I2C2, PCF8574 */ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index f0e49007d..727094b20 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -36,8 +36,8 @@   */  #define CONFIG_E300		1	/* E300 Family */  #define CONFIG_MPC83XX		1	/* MPC83XX family */ -#define CONFIG_MPC8349		1	/* MPC8349 specific */  #define CONFIG_MPC834X		1	/* MPC834X specific */ +#define CONFIG_MPC8349		1	/* MPC8349 specific */  #define CONFIG_TQM834X		1	/* TQM834X board specific */  /* IMMR Base Addres Register, use Freescale default: 0xff400000 */ diff --git a/include/i2c.h b/include/i2c.h index 97e006163..a8f729afe 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -97,7 +97,7 @@ void  i2c_reg_write(uchar chip, uchar reg, uchar val);   * 	Returns: 0 on success, not 0 on failure   *   */ -int		i2c_set_bus_num(uchar bus); +int i2c_set_bus_num(unsigned int bus);  /*   * i2c_get_bus_num: @@ -105,7 +105,7 @@ int		i2c_set_bus_num(uchar bus);   *  Returns index of currently active I2C bus.  Zero-based.   */ -uchar	i2c_get_bus_num(void); +unsigned int i2c_get_bus_num(void);  /*   * i2c_set_bus_speed: @@ -117,7 +117,7 @@ uchar	i2c_get_bus_num(void);   * 	Returns: 0 on success, not 0 on failure   *   */ -int		i2c_set_bus_speed(int); +int i2c_set_bus_speed(unsigned int);  /*   * i2c_get_bus_speed: @@ -125,6 +125,6 @@ int		i2c_set_bus_speed(int);   *  Returns speed of currently active I2C bus in Hz   */ -int		i2c_get_bus_speed(void); +unsigned int i2c_get_bus_speed(void);  #endif	/* _I2C_H_ */ |