Commit 9ca880a250870a7d55754291b5591d2b5fe89b54

Authored by Timur Tabi
Committed by Kim Phillips
1 parent ac4b5622ce

mpc83xx: Fix dual I2C support for the MPC8349ITX, MPC8349EMDS, TQM834x, and MPC8360EMDS

This patch also adds an improved I2C set_speed(), which handles all clock
frequencies.

Signed-off-by: Timur Tabi <timur@freescale.com>

Showing 9 changed files with 154 additions and 109 deletions Side-by-side Diff

board/mpc8349emds/pci.c
... ... @@ -75,11 +75,9 @@
75 75 /* Switch temporarily to I2C bus #2 */
76 76 orig_i2c_bus = i2c_get_bus_num();
77 77  
78   - if(orig_i2c_bus != I2C_BUS_2)
79   - i2c_set_bus_num(I2C_BUS_2);
  78 + if(orig_i2c_bus != 2)
  79 + i2c_set_bus_num(2);
80 80  
81   - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
82   -
83 81 val8 = 0;
84 82 i2c_write(0x23, 0x6, 1, &val8, 1);
85 83 i2c_write(0x23, 0x7, 1, &val8, 1);
... ... @@ -124,7 +122,7 @@
124 122 printf("PCI2: 32-bit on PMC3\n");
125 123 #endif
126 124 /* Reset to original I2C bus */
127   - if(orig_i2c_bus != I2C_BUS_2)
  125 + if(orig_i2c_bus != 2)
128 126 i2c_set_bus_num(orig_i2c_bus);
129 127 }
130 128  
board/mpc8349itx/mpc8349itx.c
... ... @@ -259,7 +259,7 @@
259 259 puts("Board: Freescale MPC8349E-mITX");
260 260  
261 261 #ifdef CONFIG_HARD_I2C
262   - i2c_set_bus_num(I2C_BUS_2);
  262 + i2c_set_bus_num(2);
263 263 if (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) ==
264 264 0)
265 265 printf(" %u.%u (PCF8475A)", (i2c_data & 0x02) >> 1,
... ... @@ -379,7 +379,7 @@
379 379  
380 380 u8 data[sizeof(eeprom_data)];
381 381  
382   - i2c_set_bus_num(I2C_BUS_1);
  382 + i2c_set_bus_num(1);
383 383  
384 384 if (i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {
385 385 if (memcmp(data, eeprom_data, sizeof(data)) != 0) {
... ... @@ -397,7 +397,7 @@
397 397 #endif
398 398  
399 399 #ifdef CFG_I2C_RTC_ADDR
400   - i2c_set_bus_num(I2C_BUS_2);
  400 + i2c_set_bus_num(2);
401 401  
402 402 if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data, sizeof(ds1339_data))
403 403 == 0) {
board/mpc8349itx/pci.c
... ... @@ -105,7 +105,7 @@
105 105 udelay(2000);
106 106  
107 107 #ifdef CONFIG_HARD_I2C
108   - i2c_set_bus_num(I2C_BUS_2);
  108 + i2c_set_bus_num(2);
109 109 /* Read the PCI_M66EN jumper setting */
110 110 if ((i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0) ||
111 111 (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0)) {
board/mpc8360emds/pci.c
... ... @@ -198,9 +198,12 @@
198 198 * Assign PIB PMC slot to desired PCI bus
199 199 */
200 200  
201   - mpc83xx_i2c = (i2c_t *) (CFG_IMMRBAR + CFG_I2C2_OFFSET);
202   - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
  201 + /* Switch temporarily to I2C bus #2 */
  202 + orig_i2c_bus = i2c_get_bus_num();
203 203  
  204 + if(orig_i2c_bus != 2)
  205 + i2c_set_bus_num(2);
  206 +
204 207 val8 = 0;
205 208 i2c_write(0x23, 0x6, 1, &val8, 1);
206 209 i2c_write(0x23, 0x7, 1, &val8, 1);
... ... @@ -226,6 +229,10 @@
226 229 val8 = 0xef;
227 230 i2c_write(0x27, 0x3, 1, &val8, 1);
228 231 asm("eieio");
  232 +
  233 + /* Reset to original I2C bus */
  234 + if(orig_i2c_bus != 2)
  235 + i2c_set_bus_num(orig_i2c_bus);
229 236  
230 237 /*
231 238 * Release PCI RST Output signal
... ... @@ -47,75 +47,121 @@
47 47  
48 48 DECLARE_GLOBAL_DATA_PTR;
49 49  
50   -/* Three I2C bus speeds are supported here (50kHz, 100kHz
51   - * and 400kHz). It should be easy to add more. Note that
52   - * the maximum bus speed for I2C bus 1 is CSB/3, while I2C
53   - * bus 2 can go as high as CSB.
54   - * Typical values for CSB are 266MHz and 200MHz. */
55   -
56   - /* 50kH 100kHz 400kHz */
57   -static const uchar speed_map_266[][3] =
58   - {{0x2e, 0x2a, 0x20}, /* base 88MHz */
59   - {0x34, 0x30, 0x28}}; /* base 266 MHz */
60   -
61   -static const uchar speed_map_200[][3] =
62   - {{0x2c, 0x28, 0x20}, /* base 66 MHz */
63   - {0x33, 0x2f, 0x26}}; /* base 200 MHz */
64   -
65 50 /* Initialize the bus pointer to whatever one the SPD EEPROM is on.
66 51 * Default is bus 1. This is necessary because the DDR initialization
67 52 * runs from ROM, and we can't switch buses because we can't modify
68 53 * the i2c_dev variable. Everything gets straightened out once i2c_init
69 54 * is called from RAM. */
70 55  
71   -#if defined CFG_SPD_BUS_NUM
72   -static i2c_t *i2c_dev = CFG_SPD_BUS_NUM;
  56 +#ifndef CFG_SPD_BUS_NUM
  57 +#define CFG_SPD_BUS_NUM 1
  58 +#endif
  59 +
  60 +static unsigned int i2c_bus_num = CFG_SPD_BUS_NUM;
  61 +
  62 +#if CFG_SPD_BUS_NUM == 1
  63 +static volatile i2c_t *i2c_dev = I2C_1;
73 64 #else
74   -static i2c_t *i2c_dev = I2C_1;
  65 +static volatile i2c_t *i2c_dev = I2C_2;
75 66 #endif
76 67  
77   -static uchar busNum = I2C_BUS_1 ;
78   -static int bus_speed[2] = {0, 0};
  68 +static int i2c_bus_speed[2] = {0, 0};
79 69  
80   -static int set_speed(int speed)
  70 +/*
  71 + * Map the frequency divider to the FDR. This data is taken from table 17-5
  72 + * of the MPC8349EA reference manual, with duplicates removed.
  73 + */
  74 +static struct {
  75 + unsigned int divider;
  76 + u8 fdr;
  77 +} i2c_speed_map[] =
81 78 {
82   - uchar value;
83   - const uchar *spdPtr;
  79 + {0, 0x20},
  80 + {256, 0x20},
  81 + {288, 0x21},
  82 + {320, 0x22},
  83 + {352, 0x23},
  84 + {384, 0x24},
  85 + {416, 0x01},
  86 + {448, 0x25},
  87 + {480, 0x02},
  88 + {512, 0x26},
  89 + {576, 0x27},
  90 + {640, 0x28},
  91 + {704, 0x05},
  92 + {768, 0x29},
  93 + {832, 0x06},
  94 + {896, 0x2A},
  95 + {1024, 0x2B},
  96 + {1152, 0x08},
  97 + {1280, 0x2C},
  98 + {1536, 0x2D},
  99 + {1792, 0x2E},
  100 + {1920, 0x0B},
  101 + {2048, 0x2F},
  102 + {2304, 0x0C},
  103 + {2560, 0x30},
  104 + {3072, 0x31},
  105 + {3584, 0x32},
  106 + {3840, 0x0F},
  107 + {4096, 0x33},
  108 + {4608, 0x10},
  109 + {5120, 0x34},
  110 + {6144, 0x35},
  111 + {7168, 0x36},
  112 + {7680, 0x13},
  113 + {8192, 0x37},
  114 + {9216, 0x14},
  115 + {10240, 0x38},
  116 + {12288, 0x39},
  117 + {14336, 0x3A},
  118 + {15360, 0x17},
  119 + {16384, 0x3B},
  120 + {18432, 0x18},
  121 + {20480, 0x3C},
  122 + {24576, 0x3D},
  123 + {28672, 0x3E},
  124 + {30720, 0x1B},
  125 + {32768, 0x3F},
  126 + {36864, 0x1C},
  127 + {40960, 0x1D},
  128 + {49152, 0x1E},
  129 + {61440, 0x1F},
  130 + {-1, 0x1F}
  131 +};
84 132  
85   - /* Global data contains maximum I2C bus 1 speed, which is CSB/3 */
86   - if(gd->i2c_clk == 88000000)
87   - {
88   - spdPtr = speed_map_266[busNum];
89   - }
90   - else if(gd->i2c_clk == 66000000)
91   - {
92   - spdPtr = speed_map_200[busNum];
93   - }
94   - else
95   - {
96   - printf("Max I2C bus speed %d not supported\n", gd->i2c_clk);
97   - return -1;
98   - }
  133 +#define NUM_I2C_SPEEDS (sizeof(i2c_speed_map) / sizeof(i2c_speed_map[0]))
99 134  
100   - switch(speed)
101   - {
102   - case 50000:
103   - value = *(spdPtr + 0);
104   - break;
105   - case 100000:
106   - value = *(spdPtr + 1);
107   - break;
108   - case 400000:
109   - value = *(spdPtr + 2);
110   - break;
111   - default:
112   - printf("I2C bus speed %d not supported\n", speed);
113   - return -2;
114   - }
115   - /* set clock */
116   - writeb(value, &i2c_dev->fdr);
117   - bus_speed[busNum] = speed;
118   - return 0;
  135 +static int set_speed(unsigned int speed)
  136 +{
  137 + unsigned long i2c_clk;
  138 + unsigned int divider, i;
  139 + u8 fdr = 0x3F;
  140 +
  141 + i2c_clk = (i2c_bus_num == 2) ? gd->i2c2_clk : gd->i2c1_clk;
  142 +
  143 + divider = i2c_clk / speed;
  144 +
  145 + /* Scan i2c_speed_map[] for the closest matching divider.*/
  146 +
  147 + for (i = 0; i < NUM_I2C_SPEEDS-1; i++) {
  148 + /* Locate our divider in between two entries in i2c_speed_map[] */
  149 + if ((divider >= i2c_speed_map[i].divider) &&
  150 + (divider <= i2c_speed_map[i+1].divider)) {
  151 + /* Which one is closer? */
  152 + if ((divider - i2c_speed_map[i].divider) < (i2c_speed_map[i+1].divider - divider)) {
  153 + fdr = i2c_speed_map[i].fdr;
  154 + } else {
  155 + fdr = i2c_speed_map[i+1].fdr;
  156 + }
  157 + break;
  158 + }
  159 + }
  160 +
  161 + writeb(fdr, &i2c_dev->fdr);
  162 + i2c_bus_speed[i2c_bus_num - 1] = speed;
  163 +
  164 + return 0;
119 165 }
120 166  
121 167  
122 168  
123 169  
... ... @@ -125,16 +171,16 @@
125 171 writeb(0x00 , &i2c_dev->cr);
126 172  
127 173 /* set clock */
128   - writeb(speed, &i2c_dev->fdr);
  174 + set_speed(speed);
129 175  
130 176 /* set default filter */
131   - writeb(0x10,&i2c_dev->dfsrr);
  177 + writeb(IC2_FDR,&i2c_dev->dfsrr);
132 178  
133 179 /* write slave address */
134 180 writeb(slaveadd, &i2c_dev->adr);
135 181  
136 182 /* clear status register */
137   - writeb(0x00, &i2c_dev->sr);
  183 + writeb(I2C_CR_MTX, &i2c_dev->sr);
138 184  
139 185 /* start I2C controller */
140 186 writeb(I2C_CR_MEN, &i2c_dev->cr);
141 187  
... ... @@ -142,19 +188,19 @@
142 188  
143 189 void i2c_init(int speed, int slaveadd)
144 190 {
145   - /* Set both interfaces to the same speed and slave address */
146   - /* Note: This function gets called twice - before and after
147   - * relocation to RAM. The first time it's called, we are unable
148   - * to change buses, so whichever one 'i2c_dev' was initialized to
149   - * gets set twice. When run from RAM both buses get set properly */
  191 + /* Set both interfaces to the same speed and slave address */
  192 + /* Note: This function gets called twice - before and after
  193 + * relocation to RAM. The first time it's called, we are unable
  194 + * to change buses, so whichever one 'i2c_dev' was initialized to
  195 + * gets set twice. When run from RAM both buses get set properly */
150 196  
151   - i2c_set_bus_num(I2C_BUS_1);
152   - _i2c_init(speed, slaveadd);
153   -#ifdef CFG_I2C2_OFFSET
154   - i2c_set_bus_num(I2C_BUS_2);
155   - _i2c_init(speed, slaveadd);
156   - i2c_set_bus_num(I2C_BUS_1);
157   -#endif /* CFG_I2C2_OFFSET */
  197 + i2c_set_bus_num(1);
  198 + _i2c_init(speed, slaveadd);
  199 +#ifdef CFG_I2C2_OFFSET
  200 + i2c_set_bus_num(2);
  201 + _i2c_init(speed, slaveadd);
  202 + i2c_set_bus_num(1);
  203 +#endif /* CFG_I2C2_OFFSET */
158 204 }
159 205  
160 206 static __inline__ int
161 207  
162 208  
163 209  
164 210  
165 211  
166 212  
167 213  
168 214  
169 215  
... ... @@ -340,39 +386,39 @@
340 386 i2c_write (i2c_addr, reg, 1, &val, 1);
341 387 }
342 388  
343   -int i2c_set_bus_num(uchar bus)
  389 +int i2c_set_bus_num(unsigned int bus)
344 390 {
345   - if(bus == I2C_BUS_1)
  391 + if(bus == 1)
346 392 {
347 393 i2c_dev = I2C_1;
348 394 }
349 395 #ifdef CFG_I2C2_OFFSET
350   - else if(bus == I2C_BUS_2)
  396 + else if(bus == 2)
351 397 {
352 398 i2c_dev = I2C_2;
353 399 }
354   -#endif /* CFG_I2C2_OFFSET */
  400 +#endif
355 401 else
356 402 {
357 403 return -1;
358 404 }
359   - busNum = bus;
  405 + i2c_bus_num = bus;
360 406 return 0;
361 407 }
362 408  
363   -int i2c_set_bus_speed(int speed)
  409 +int i2c_set_bus_speed(unsigned int speed)
364 410 {
365 411 return set_speed(speed);
366 412 }
367 413  
368   -uchar i2c_get_bus_num(void)
  414 +unsigned int i2c_get_bus_num(void)
369 415 {
370   - return busNum;
  416 + return i2c_bus_num;
371 417 }
372 418  
373   -int i2c_get_bus_speed(void)
  419 +unsigned int i2c_get_bus_speed(void)
374 420 {
375   - return bus_speed[busNum];
  421 + return i2c_bus_speed[i2c_bus_num - 1];
376 422 }
377 423 #endif /* CONFIG_HARD_I2C */
include/asm-ppc/i2c.h
... ... @@ -79,12 +79,6 @@
79 79 #endif
80 80 #define I2C_TIMEOUT (CFG_HZ/4)
81 81  
82   -enum I2C_BUS_NUM
83   -{
84   - I2C_BUS_1 = 0,
85   - I2C_BUS_2,
86   -};
87   -
88 82 #ifndef CFG_IMMRBAR
89 83 #error CFG_IMMRBAR is not defined in /include/configs/${BOARD}.h
90 84 #endif
91 85  
... ... @@ -96,9 +90,9 @@
96 90 #define I2C_1 ((i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET))
97 91  
98 92 /* Optional support for second I2C bus */
99   -#ifdef CFG_I2C2_OFFSET
  93 +#ifdef CFG_I2C2_OFFSET
100 94 #define I2C_2 ((i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET))
101   -#endif /* CFG_I2C2_OFFSET */
  95 +#endif /* CFG_I2C2_OFFSET */
102 96  
103 97 #define I2C_READ 1
104 98 #define I2C_WRITE 0
include/configs/MPC8349ITX.h
... ... @@ -81,7 +81,7 @@
81 81 #define CONFIG_I2C_CMD_TREE
82 82 #define CFG_I2C_OFFSET 0x3000
83 83 #define CFG_I2C2_OFFSET 0x3100
84   -#define CFG_SPD_BUS_NUM I2C_2
  84 +#define CFG_SPD_BUS_NUM 2
85 85  
86 86 #define CFG_I2C_8574_ADDR1 0x20 /* I2C2, PCF8574 */
87 87 #define CFG_I2C_8574_ADDR2 0x21 /* I2C2, PCF8574 */
include/configs/TQM834x.h
... ... @@ -36,8 +36,8 @@
36 36 */
37 37 #define CONFIG_E300 1 /* E300 Family */
38 38 #define CONFIG_MPC83XX 1 /* MPC83XX family */
39   -#define CONFIG_MPC8349 1 /* MPC8349 specific */
40 39 #define CONFIG_MPC834X 1 /* MPC834X specific */
  40 +#define CONFIG_MPC8349 1 /* MPC8349 specific */
41 41 #define CONFIG_TQM834X 1 /* TQM834X board specific */
42 42  
43 43 /* IMMR Base Addres Register, use Freescale default: 0xff400000 */
... ... @@ -97,7 +97,7 @@
97 97 * Returns: 0 on success, not 0 on failure
98 98 *
99 99 */
100   -int i2c_set_bus_num(uchar bus);
  100 +int i2c_set_bus_num(unsigned int bus);
101 101  
102 102 /*
103 103 * i2c_get_bus_num:
... ... @@ -105,7 +105,7 @@
105 105 * Returns index of currently active I2C bus. Zero-based.
106 106 */
107 107  
108   -uchar i2c_get_bus_num(void);
  108 +unsigned int i2c_get_bus_num(void);
109 109  
110 110 /*
111 111 * i2c_set_bus_speed:
... ... @@ -117,7 +117,7 @@
117 117 * Returns: 0 on success, not 0 on failure
118 118 *
119 119 */
120   -int i2c_set_bus_speed(int);
  120 +int i2c_set_bus_speed(unsigned int);
121 121  
122 122 /*
123 123 * i2c_get_bus_speed:
... ... @@ -125,7 +125,7 @@
125 125 * Returns speed of currently active I2C bus in Hz
126 126 */
127 127  
128   -int i2c_get_bus_speed(void);
  128 +unsigned int i2c_get_bus_speed(void);
129 129  
130 130 #endif /* _I2C_H_ */