]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/tqc/tqm8272/tqm8272.c
Make sure that argv[] argument pointers are not modified.
[karo-tx-uboot.git] / board / tqc / tqm8272 / tqm8272.c
1 /*
2  * (C) Copyright 2006
3  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <ioports.h>
26 #include <mpc8260.h>
27
28 #include <command.h>
29 #include <netdev.h>
30 #ifdef CONFIG_PCI
31 #include <pci.h>
32 #include <asm/m8260_pci.h>
33 #endif
34 #include "tqm8272.h"
35
36 #if 0
37 #define deb_printf(fmt,arg...) \
38         printf ("TQM8272 %s %s: " fmt,__FILE__, __FUNCTION__, ##arg)
39 #else
40 #define deb_printf(fmt,arg...) \
41         do { } while (0)
42 #endif
43
44 #if defined(CONFIG_BOARD_GET_CPU_CLK_F)
45 unsigned long board_get_cpu_clk_f (void);
46 #endif
47
48 /*
49  * I/O Port configuration table
50  *
51  * if conf is 1, then that port pin will be configured at boot time
52  * according to the five values podr/pdir/ppar/psor/pdat for that entry
53  */
54
55 const iop_conf_t iop_conf_tab[4][32] = {
56
57     /* Port A configuration */
58     {   /*            conf ppar psor pdir podr pdat */
59         /* PA31 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 *ATMTXEN */
60         /* PA30 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTCA   */
61         /* PA29 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTSOC  */
62         /* PA28 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 *ATMRXEN */
63         /* PA27 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRSOC */
64         /* PA26 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRCA */
65         /* PA25 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[0] */
66         /* PA24 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[1] */
67         /* PA23 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[2] */
68         /* PA22 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[3] */
69         /* PA21 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[4] */
70         /* PA20 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[5] */
71         /* PA19 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[6] */
72         /* PA18 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMTXD[7] */
73         /* PA17 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[7] */
74         /* PA16 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[6] */
75         /* PA15 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[5] */
76         /* PA14 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[4] */
77         /* PA13 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[3] */
78         /* PA12 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[2] */
79         /* PA11 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[1] */
80         /* PA10 */ {   0,   0,   0,   1,   0,   0   }, /* FCC1 ATMRXD[0] */
81         /* PA9  */ {   1,   1,   0,   1,   0,   0   }, /* SMC2 TXD */
82         /* PA8  */ {   1,   1,   0,   0,   0,   0   }, /* SMC2 RXD */
83         /* PA7  */ {   0,   0,   0,   1,   0,   0   }, /* PA7 */
84         /* PA6  */ {   0,   0,   0,   1,   0,   0   }, /* PA6 */
85         /* PA5  */ {   0,   0,   0,   1,   0,   0   }, /* PA5 */
86         /* PA4  */ {   0,   0,   0,   1,   0,   0   }, /* PA4 */
87         /* PA3  */ {   0,   0,   0,   1,   0,   0   }, /* PA3 */
88         /* PA2  */ {   0,   0,   0,   1,   0,   0   }, /* PA2 */
89         /* PA1  */ {   0,   0,   0,   1,   0,   0   }, /* PA1 */
90         /* PA0  */ {   0,   0,   0,   1,   0,   0   }  /* PA0 */
91     },
92
93     /* Port B configuration */
94     {   /*            conf ppar psor pdir podr pdat */
95         /* PB31 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TX_ER */
96         /* PB30 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_DV */
97         /* PB29 */ {   1,   1,   1,   1,   0,   0   }, /* FCC2 MII TX_EN */
98         /* PB28 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_ER */
99         /* PB27 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII COL */
100         /* PB26 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII CRS */
101         /* PB25 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[3] */
102         /* PB24 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[2] */
103         /* PB23 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[1] */
104         /* PB22 */ {   1,   1,   0,   1,   0,   0   }, /* FCC2 MII TxD[0] */
105         /* PB21 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[0] */
106         /* PB20 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[1] */
107         /* PB19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[2] */
108         /* PB18 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RxD[3] */
109         /* PB17 */ {   0,   0,   0,   0,   0,   0   }, /* PB17 */
110         /* PB16 */ {   0,   0,   0,   0,   0,   0   }, /* PB16 */
111         /* PB15 */ {   0,   0,   0,   0,   0,   0   }, /* PB15 */
112         /* PB14 */ {   0,   0,   0,   0,   0,   0   }, /* PB14 */
113         /* PB13 */ {   0,   0,   0,   0,   0,   0   }, /* PB13 */
114         /* PB12 */ {   0,   0,   0,   0,   0,   0   }, /* PB12 */
115         /* PB11 */ {   0,   0,   0,   0,   0,   0   }, /* PB11 */
116         /* PB10 */ {   0,   0,   0,   0,   0,   0   }, /* PB10 */
117         /* PB9  */ {   0,   0,   0,   0,   0,   0   }, /* PB9 */
118         /* PB8  */ {   0,   0,   0,   0,   0,   0   }, /* PB8 */
119         /* PB7  */ {   0,   0,   0,   0,   0,   0   }, /* PB7 */
120         /* PB6  */ {   0,   0,   0,   0,   0,   0   }, /* PB6 */
121         /* PB5  */ {   0,   0,   0,   0,   0,   0   }, /* PB5 */
122         /* PB4  */ {   0,   0,   0,   0,   0,   0   }, /* PB4 */
123         /* PB3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
124         /* PB2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
125         /* PB1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
126         /* PB0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
127     },
128
129     /* Port C */
130     {   /*            conf ppar psor pdir podr pdat */
131         /* PC31 */ {   0,   0,   0,   1,   0,   0   }, /* PC31 */
132         /* PC30 */ {   0,   0,   0,   0,   0,   0   }, /* PC30 */
133         /* PC29 */ {   1,   1,   1,   0,   0,   0   }, /* SCC1 EN *CLSN */
134         /* PC28 */ {   0,   0,   0,   1,   0,   0   }, /* PC28 */
135         /* PC27 */ {   0,   0,   0,   1,   0,   0   }, /* PC27 */
136         /* PC26 */ {   0,   0,   0,   1,   0,   0   }, /* PC26 */
137         /* PC25 */ {   0,   0,   0,   1,   0,   0   }, /* PC25 */
138         /* PC24 */ {   0,   0,   0,   1,   0,   0   }, /* PC24 */
139         /* PC23 */ {   0,   1,   0,   1,   0,   0   }, /* ATMTFCLK */
140         /* PC22 */ {   0,   1,   0,   0,   0,   0   }, /* ATMRFCLK */
141         /* PC21 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN RXCLK */
142         /* PC20 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN TXCLK */
143         /* PC19 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII RX_CLK */
144         /* PC18 */ {   1,   1,   0,   0,   0,   0   }, /* FCC2 MII TX_CLK */
145         /* PC17 */ {   1,   0,   0,   1,   0,   0   }, /* PC17 MDC */
146         /* PC16 */ {   1,   0,   0,   0,   0,   0   }, /* PC16 MDIO*/
147         /* PC15 */ {   0,   0,   0,   1,   0,   0   }, /* PC15 */
148         /* PC14 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN *CD */
149         /* PC13 */ {   0,   0,   0,   1,   0,   0   }, /* PC13 */
150         /* PC12 */ {   0,   0,   0,   1,   0,   0   }, /* PC12 */
151         /* PC11 */ {   0,   0,   0,   1,   0,   0   }, /* PC11 */
152         /* PC10 */ {   0,   0,   0,   1,   0,   0   }, /* PC10 */
153         /* PC9  */ {   0,   0,   0,   1,   0,   0   }, /* PC9 */
154         /* PC8  */ {   0,   0,   0,   1,   0,   0   }, /* PC8 */
155         /* PC7  */ {   0,   0,   0,   1,   0,   0   }, /* PC7 */
156         /* PC6  */ {   0,   0,   0,   1,   0,   0   }, /* PC6 */
157         /* PC5  */ {   1,   1,   0,   1,   0,   0   }, /* PC5 SMC1 TXD */
158         /* PC4  */ {   1,   1,   0,   0,   0,   0   }, /* PC4 SMC1 RXD */
159         /* PC3  */ {   0,   0,   0,   1,   0,   0   }, /* PC3 */
160         /* PC2  */ {   0,   0,   0,   1,   0,   1   }, /* ENET FDE */
161         /* PC1  */ {   0,   0,   0,   1,   0,   0   }, /* ENET DSQE */
162         /* PC0  */ {   0,   0,   0,   1,   0,   0   }, /* ENET LBK */
163     },
164
165     /* Port D */
166     {   /*            conf ppar psor pdir podr pdat */
167         /* PD31 */ {   1,   1,   0,   0,   0,   0   }, /* SCC1 EN RxD */
168         /* PD30 */ {   1,   1,   1,   1,   0,   0   }, /* SCC1 EN TxD */
169         /* PD29 */ {   1,   1,   0,   1,   0,   0   }, /* SCC1 EN TENA */
170         /* PD28 */ {   0,   0,   0,   1,   0,   0   }, /* PD28 */
171         /* PD27 */ {   0,   0,   0,   1,   0,   0   }, /* PD27 */
172         /* PD26 */ {   0,   0,   0,   1,   0,   0   }, /* PD26 */
173         /* PD25 */ {   0,   0,   0,   1,   0,   0   }, /* PD25 */
174         /* PD24 */ {   0,   0,   0,   1,   0,   0   }, /* PD24 */
175         /* PD23 */ {   0,   0,   0,   1,   0,   0   }, /* PD23 */
176         /* PD22 */ {   0,   0,   0,   1,   0,   0   }, /* PD22 */
177         /* PD21 */ {   0,   0,   0,   1,   0,   0   }, /* PD21 */
178         /* PD20 */ {   0,   0,   0,   1,   0,   0   }, /* PD20 */
179         /* PD19 */ {   0,   0,   0,   1,   0,   0   }, /* PD19 */
180         /* PD18 */ {   0,   0,   0,   1,   0,   0   }, /* PD19 */
181         /* PD17 */ {   0,   1,   0,   0,   0,   0   }, /* FCC1 ATMRXPRTY */
182         /* PD16 */ {   0,   1,   0,   1,   0,   0   }, /* FCC1 ATMTXPRTY */
183 #if defined(CONFIG_SOFT_I2C)
184         /* PD15 */ {   1,   0,   0,   1,   1,   1   }, /* I2C SDA */
185         /* PD14 */ {   1,   0,   0,   1,   1,   1   }, /* I2C SCL */
186 #else
187 #if defined(CONFIG_HARD_I2C)
188         /* PD15 */ {   1,   1,   1,   0,   1,   0   }, /* I2C SDA */
189         /* PD14 */ {   1,   1,   1,   0,   1,   0   }, /* I2C SCL */
190 #else /* normal I/O port pins */
191         /* PD15 */ {   0,   1,   1,   0,   1,   0   }, /* I2C SDA */
192         /* PD14 */ {   0,   1,   1,   0,   1,   0   }, /* I2C SCL */
193 #endif
194 #endif
195         /* PD13 */ {   0,   0,   0,   0,   0,   0   }, /* PD13 */
196         /* PD12 */ {   0,   0,   0,   0,   0,   0   }, /* PD12 */
197         /* PD11 */ {   0,   0,   0,   0,   0,   0   }, /* PD11 */
198         /* PD10 */ {   0,   0,   0,   0,   0,   0   }, /* PD10 */
199         /* PD9  */ {   1,   1,   0,   1,   0,   0   }, /* SMC1 TXD */
200         /* PD8  */ {   1,   1,   0,   0,   0,   0   }, /* SMC1 RXD */
201         /* PD7  */ {   0,   0,   0,   1,   0,   1   }, /* PD7 */
202         /* PD6  */ {   0,   0,   0,   1,   0,   1   }, /* PD6 */
203         /* PD5  */ {   0,   0,   0,   1,   0,   0   }, /* PD5 */
204         /* PD4  */ {   0,   0,   0,   1,   0,   1   }, /* PD4 */
205         /* PD3  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
206         /* PD2  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
207         /* PD1  */ {   0,   0,   0,   0,   0,   0   }, /* pin doesn't exist */
208         /* PD0  */ {   0,   0,   0,   0,   0,   0   }  /* pin doesn't exist */
209     }
210 };
211
212 /* UPM pattern for slow init */
213 static const uint upmTableSlow[] =
214 {
215     /* Offset   UPM Read Single RAM array entry */
216     /* 0x00 */  0xffffee00, 0x00ffcc80, 0x00ffcf00, 0x00ffdc00,
217     /* 0x04 */  0x00ffce80, 0x00ffcc00, 0x00ffee00, 0x3fffcc07,
218
219                 /* UPM Read Burst RAM array entry -> unused */
220     /* 0x08 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
221     /* 0x0C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
222
223                 /* UPM Read Burst RAM array entry -> unused */
224     /* 0x10 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
225     /* 0x14 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
226
227                 /* UPM Write Single RAM array entry */
228     /* 0x18 */  0xffffee00, 0x00ffec80, 0x00ffef00, 0x00fffc80,
229     /* 0x1C */  0x00fffe00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
230
231                 /* UPM Write Burst RAM array entry -> unused */
232     /* 0x20 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
233     /* 0x24 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
234     /* 0x28 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
235     /* 0x2C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
236
237                 /* UPM Refresh Timer RAM array entry -> unused */
238     /* 0x30 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
239     /* 0x34 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
240     /* 0x38 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
241
242                 /* UPM Exception RAM array entry -> unused */
243     /* 0x3C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
244 };
245
246 /* UPM pattern for fast init */
247 static const uint upmTableFast[] =
248 {
249     /* Offset   UPM Read Single RAM array entry */
250     /* 0x00 */  0xffffee00, 0x00ffcc80, 0x00ffcd80, 0x00ffdc00,
251     /* 0x04 */  0x00ffdc00, 0x00ffcf00, 0x00ffec00, 0x3fffcc07,
252
253                 /* UPM Read Burst RAM array entry -> unused */
254     /* 0x08 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
255     /* 0x0C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
256
257                 /* UPM Read Burst RAM array entry -> unused */
258     /* 0x10 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
259     /* 0x14 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
260
261                 /* UPM Write Single RAM array entry */
262     /* 0x18 */  0xffffee00, 0x00ffec80, 0x00ffee80, 0x00fffc00,
263     /* 0x1C */  0x00fffc00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
264
265                 /* UPM Write Burst RAM array entry -> unused */
266     /* 0x20 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
267     /* 0x24 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
268     /* 0x28 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
269     /* 0x2C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
270
271                 /* UPM Refresh Timer RAM array entry -> unused */
272     /* 0x30 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
273     /* 0x34 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
274     /* 0x38 */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
275
276                 /* UPM Exception RAM array entry -> unused */
277     /* 0x3C */  0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
278 };
279
280
281 /* ------------------------------------------------------------------------- */
282
283 /* Check Board Identity:
284  */
285 int checkboard (void)
286 {
287         char *p = (char *) HWIB_INFO_START_ADDR;
288
289         puts ("Board: ");
290         if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
291                 puts (p);
292         } else {
293                 puts ("No HWIB assuming TQM8272");
294         }
295         putc ('\n');
296
297         return 0;
298 }
299
300 /* ------------------------------------------------------------------------- */
301 #if defined(CONFIG_BOARD_GET_CPU_CLK_F)
302 static int get_cas_latency (void)
303 {
304         /* get it from the option -ts in CIB */
305         /* default is 3 */
306         int     ret = 3;
307         int     pos = 0;
308         char    *p = (char *) CIB_INFO_START_ADDR;
309
310         while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
311                 if (*p < ' ' || *p > '~') { /* ASCII strings! */
312                         return ret;
313                 }
314                 if (*p == '-') {
315                         if ((p[1] == 't') && (p[2] == 's')) {
316                                 return (p[4] - '0');
317                         }
318                 }
319                 p++;
320                 pos++;
321         }
322         return ret;
323 }
324 #endif
325
326 static ulong set_sdram_timing (volatile uint *sdmr_ptr, ulong sdmr, int col)
327 {
328 #if defined(CONFIG_BOARD_GET_CPU_CLK_F)
329         int     clk = board_get_cpu_clk_f ();
330         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
331         int     busmode = (immr->im_siu_conf.sc_bcr & BCR_EBM ? 1 : 0);
332         int     cas;
333
334         sdmr = sdmr & ~(PSDMR_RFRC_MSK | PSDMR_PRETOACT_MSK | PSDMR_WRC_MSK | \
335                          PSDMR_BUFCMD);
336         if (busmode) {
337                 switch (clk) {
338                         case 66666666:
339                                 sdmr |= (PSDMR_RFRC_66MHZ_60X | \
340                                         PSDMR_PRETOACT_66MHZ_60X | \
341                                         PSDMR_WRC_66MHZ_60X | \
342                                         PSDMR_BUFCMD_66MHZ_60X);
343                                 break;
344                         case 100000000:
345                                 sdmr |= (PSDMR_RFRC_100MHZ_60X | \
346                                         PSDMR_PRETOACT_100MHZ_60X | \
347                                         PSDMR_WRC_100MHZ_60X | \
348                                         PSDMR_BUFCMD_100MHZ_60X);
349                                 break;
350
351                 }
352         } else {
353                 switch (clk) {
354                         case 66666666:
355                                 sdmr |= (PSDMR_RFRC_66MHZ_SINGLE | \
356                                         PSDMR_PRETOACT_66MHZ_SINGLE | \
357                                         PSDMR_WRC_66MHZ_SINGLE | \
358                                         PSDMR_BUFCMD_66MHZ_SINGLE);
359                                 break;
360                         case 100000000:
361                                 sdmr |= (PSDMR_RFRC_100MHZ_SINGLE | \
362                                         PSDMR_PRETOACT_100MHZ_SINGLE | \
363                                         PSDMR_WRC_100MHZ_SINGLE | \
364                                         PSDMR_BUFCMD_100MHZ_SINGLE);
365                                 break;
366                         case 133333333:
367                                 sdmr |= (PSDMR_RFRC_133MHZ_SINGLE | \
368                                         PSDMR_PRETOACT_133MHZ_SINGLE | \
369                                         PSDMR_WRC_133MHZ_SINGLE | \
370                                         PSDMR_BUFCMD_133MHZ_SINGLE);
371                                 break;
372                 }
373         }
374         cas = get_cas_latency();
375         sdmr &=~ (PSDMR_CL_MSK | PSDMR_LDOTOPRE_MSK);
376         sdmr |= cas;
377         sdmr |= ((cas - 1) << 6);
378         return sdmr;
379 #else
380         return sdmr;
381 #endif
382 }
383
384 /* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
385  *
386  * This routine performs standard 8260 initialization sequence
387  * and calculates the available memory size. It may be called
388  * several times to try different SDRAM configurations on both
389  * 60x and local buses.
390  */
391 static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
392                                                   ulong orx, volatile uchar * base, int col)
393 {
394         volatile uchar c = 0xff;
395         volatile uint *sdmr_ptr;
396         volatile uint *orx_ptr;
397         ulong maxsize, size;
398         int i;
399
400         /* We must be able to test a location outsize the maximum legal size
401          * to find out THAT we are outside; but this address still has to be
402          * mapped by the controller. That means, that the initial mapping has
403          * to be (at least) twice as large as the maximum expected size.
404          */
405         maxsize = (1 + (~orx | 0x7fff)) / 2;
406
407         /* Since CONFIG_SYS_SDRAM_BASE is always 0 (??), we assume that
408          * we are configuring CS1 if base != 0
409          */
410         sdmr_ptr = base ? &memctl->memc_lsdmr : &memctl->memc_psdmr;
411         orx_ptr = base ? &memctl->memc_or2 : &memctl->memc_or1;
412
413         *orx_ptr = orx;
414         sdmr = set_sdram_timing (sdmr_ptr, sdmr, col);
415         /*
416          * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
417          *
418          * "At system reset, initialization software must set up the
419          *  programmable parameters in the memory controller banks registers
420          *  (ORx, BRx, P/LSDMR). After all memory parameters are configured,
421          *  system software should execute the following initialization sequence
422          *  for each SDRAM device.
423          *
424          *  1. Issue a PRECHARGE-ALL-BANKS command
425          *  2. Issue eight CBR REFRESH commands
426          *  3. Issue a MODE-SET command to initialize the mode register
427          *
428          *  The initial commands are executed by setting P/LSDMR[OP] and
429          *  accessing the SDRAM with a single-byte transaction."
430          *
431          * The appropriate BRx/ORx registers have already been set when we
432          * get here. The SDRAM can be accessed at the address CONFIG_SYS_SDRAM_BASE.
433          */
434
435         *sdmr_ptr = sdmr | PSDMR_OP_PREA;
436         *base = c;
437
438         *sdmr_ptr = sdmr | PSDMR_OP_CBRR;
439         for (i = 0; i < 8; i++)
440                 *base = c;
441
442         *sdmr_ptr = sdmr | PSDMR_OP_MRW;
443         *(base + CONFIG_SYS_MRS_OFFS) = c;      /* setting MR on address lines */
444
445         *sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
446         *base = c;
447
448         size = get_ram_size((long *)base, maxsize);
449         *orx_ptr = orx | ~(size - 1);
450
451         return (size);
452 }
453
454 phys_size_t initdram (int board_type)
455 {
456         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
457         volatile memctl8260_t *memctl = &immap->im_memctl;
458
459 #ifndef CONFIG_SYS_RAMBOOT
460         long size8, size9;
461 #endif
462         long psize, lsize;
463
464         psize = 16 * 1024 * 1024;
465         lsize = 0;
466
467         memctl->memc_psrt = CONFIG_SYS_PSRT;
468         memctl->memc_mptpr = CONFIG_SYS_MPTPR;
469
470 #ifndef CONFIG_SYS_RAMBOOT
471         /* 60x SDRAM setup:
472          */
473         size8 = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
474                                           (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
475         size9 = try_init (memctl, CONFIG_SYS_PSDMR_9COL, CONFIG_SYS_OR1_9COL,
476                                           (uchar *) CONFIG_SYS_SDRAM_BASE, 9);
477
478         if (size8 < size9) {
479                 psize = size9;
480                 printf ("(60x:9COL - %ld MB, ", psize >> 20);
481         } else {
482                 psize = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
483                                                   (uchar *) CONFIG_SYS_SDRAM_BASE, 8);
484                 printf ("(60x:8COL - %ld MB, ", psize >> 20);
485         }
486
487 #endif /* CONFIG_SYS_RAMBOOT */
488
489         icache_enable ();
490
491         return (psize);
492 }
493
494
495 static inline int scanChar (char *p, int len, unsigned long *number)
496 {
497         int     akt = 0;
498
499         *number = 0;
500         while (akt < len) {
501                 if ((*p >= '0') && (*p <= '9')) {
502                         *number *= 10;
503                         *number += *p - '0';
504                         p += 1;
505                 } else {
506                         if (*p == '-')  return akt;
507                         return -1;
508                 }
509                 akt ++;
510         }
511         return akt;
512 }
513
514 static int dump_hwib(void)
515 {
516         HWIB_INFO       *hw = &hwinf;
517         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
518         char *s = getenv("serial#");
519
520         if (hw->OK) {
521                 printf ("HWIB on %x\n", HWIB_INFO_START_ADDR);
522                 printf ("serial : %s\n", s);
523                 printf ("ethaddr: %s\n", hw->ethaddr);
524                 printf ("FLASH  : %x nr:%d\n", hw->flash, hw->flash_nr);
525                 printf ("RAM    : %x cs:%d\n", hw->ram, hw->ram_cs);
526                 printf ("CPU    : %lu\n", hw->cpunr);
527                 printf ("CAN    : %d\n", hw->can);
528                 if (hw->eeprom) printf ("EEprom : %x\n", hw->eeprom);
529                 else printf ("No EEprom\n");
530                 if (hw->nand) {
531                         printf ("NAND   : %x\n", hw->nand);
532                         printf ("NAND CS: %d\n", hw->nand_cs);
533                 } else { printf ("No NAND\n");}
534                 printf ("Bus %s mode.\n", (hw->Bus ? "60x" : "Single PQII"));
535                 printf ("  real : %s\n", (immr->im_siu_conf.sc_bcr & BCR_EBM ? \
536                                  "60x" : "Single PQII"));
537                 printf ("Option : %lx\n", hw->option);
538                 printf ("%s Security Engine\n", (hw->SecEng ? "with" : "no"));
539                 printf ("CPM Clk: %d\n", hw->cpmcl);
540                 printf ("CPU Clk: %d\n", hw->cpucl);
541                 printf ("Bus Clk: %d\n", hw->buscl);
542                 if (hw->busclk_real_ok) {
543                         printf ("  real Clk: %d\n", hw->busclk_real);
544                 }
545                 printf ("CAS    : %d\n", get_cas_latency());
546         } else {
547                 printf("HWIB @%x not OK\n", HWIB_INFO_START_ADDR);
548         }
549         return 0;
550 }
551
552 static inline int search_real_busclk (int *clk)
553 {
554         int     part = 0, pos = 0;
555         char *p = (char *) CIB_INFO_START_ADDR;
556         int     ok = 0;
557
558         while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
559                 if (*p < ' ' || *p > '~') { /* ASCII strings! */
560                         return 0;
561                 }
562                 switch (part) {
563                 default:
564                         if (*p == '-') {
565                                 ++part;
566                         }
567                         break;
568                 case 3:
569                         if (*p == '-') {
570                                 ++part;
571                                 break;
572                         }
573                         if (*p == 'b') {
574                                 ok = 1;
575                                 p++;
576                                 break;
577                         }
578                         if (ok) {
579                                 switch (*p) {
580                                 case '6':
581                                         *clk = 66666666;
582                                         return 1;
583                                         break;
584                                 case '1':
585                                         if (p[1] == '3') {
586                                                 *clk = 133333333;
587                                         } else {
588                                                 *clk = 100000000;
589                                         }
590                                         return 1;
591                                         break;
592                                 }
593                         }
594                         break;
595                 }
596                 p++;
597         }
598         return 0;
599 }
600
601 int analyse_hwib (void)
602 {
603         char    *p = (char *) HWIB_INFO_START_ADDR;
604         int     anz;
605         int     part = 1, i = 0, pos = 0;
606         HWIB_INFO       *hw = &hwinf;
607
608         deb_printf(" %s pointer: %p\n", __FUNCTION__, p);
609         /* Head = TQM */
610         if (*((unsigned long *)p) != (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
611                 deb_printf("No HWIB\n");
612                 return -1;
613         }
614         p += 3;
615         if (scanChar (p, 4, &hw->cpunr) < 0) {
616                 deb_printf("No CPU\n");
617                 return -2;
618         }
619         p +=4;
620
621         hw->flash = 0x200000 << (*p - 'A');
622         p++;
623         hw->flash_nr = *p - '0';
624         p++;
625
626         hw->ram = 0x2000000 << (*p - 'A');
627         p++;
628         if (*p == '2') {
629                 hw->ram_cs = 2;
630                 p++;
631         }
632
633         if (*p == 'A') hw->can = 1;
634         if (*p == 'B') hw->can = 2;
635         p +=1;
636         p +=1;  /* connector */
637         if (*p != '0') {
638                 hw->eeprom = 0x1000 << (*p - 'A');
639         }
640         p++;
641
642         if ((*p < '0') || (*p > '9')) {
643                 /* NAND before z-option */
644                 hw->nand = 0x8000000 << (*p - 'A');
645                 p++;
646                 hw->nand_cs = *p - '0';
647                 p += 2;
648         }
649         /* z-option */
650         anz = scanChar (p, 4, &hw->option);
651         if (anz < 0) {
652                 deb_printf("No option\n");
653                 return -3;
654         }
655         if (hw->option & 0x8) hw->Bus = 1;
656         p += anz;
657         if (*p != '-') {
658                 deb_printf("No -\n");
659                 return -4;
660         }
661         p++;
662         /* C option */
663         if (*p == 'E') {
664                 hw->SecEng = 1;
665                 p++;
666         }
667         switch (*p) {
668                 case 'M': hw->cpucl = 266666666;
669                         break;
670                 case 'P': hw->cpucl = 300000000;
671                         break;
672                 case 'T': hw->cpucl = 400000000;
673                         break;
674                 default:
675                         deb_printf("No CPU Clk: %c\n", *p);
676                         return -5;
677                         break;
678         }
679         p++;
680         switch (*p) {
681                 case 'I': hw->cpmcl = 200000000;
682                         break;
683                 case 'M': hw->cpmcl = 300000000;
684                         break;
685                 default:
686                         deb_printf("No CPM Clk\n");
687                         return -6;
688                         break;
689         }
690         p++;
691         switch (*p) {
692                 case 'B': hw->buscl = 66666666;
693                         break;
694                 case 'E': hw->buscl = 100000000;
695                         break;
696                 case 'F': hw->buscl = 133333333;
697                         break;
698                 default:
699                         deb_printf("No BUS Clk\n");
700                         return -7;
701                         break;
702         }
703         p++;
704
705         hw->OK = 1;
706         /* search MAC Address */
707         while ((*p != '\0') && (pos < CONFIG_SYS_HWINFO_SIZE)) {
708                 if (*p < ' ' || *p > '~') { /* ASCII strings! */
709                         return 0;
710                 }
711                 switch (part) {
712                 default:
713                         if (*p == ' ') {
714                                 ++part;
715                                 i = 0;
716                         }
717                         break;
718                 case 3:                 /* Copy MAC address */
719                         if (*p == ' ') {
720                                 ++part;
721                                 i = 0;
722                                 break;
723                         }
724                         hw->ethaddr[i++] = *p;
725                         if ((i % 3) == 2)
726                                 hw->ethaddr[i++] = ':';
727                         break;
728
729                 }
730                 p++;
731         }
732
733         hw->busclk_real_ok = search_real_busclk (&hw->busclk_real);
734         return 0;
735 }
736
737 #if defined(CONFIG_GET_CPU_STR_F)
738 /* !! This routine runs from Flash */
739 char get_cpu_str_f (char *buf)
740 {
741         char *p = (char *) HWIB_INFO_START_ADDR;
742         int     i = 0;
743
744         buf[i++] = 'M';
745         buf[i++] = 'P';
746         buf[i++] = 'C';
747         if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
748                 buf[i++] = *&p[3];
749                 buf[i++] = *&p[4];
750                 buf[i++] = *&p[5];
751                 buf[i++] = *&p[6];
752         } else {
753                 buf[i++] = '8';
754                 buf[i++] = '2';
755                 buf[i++] = '7';
756                 buf[i++] = 'x';
757         }
758         buf[i++] = 0;
759         return 0;
760 }
761 #endif
762
763 #if defined(CONFIG_BOARD_GET_CPU_CLK_F)
764 /* !! This routine runs from Flash */
765 unsigned long board_get_cpu_clk_f (void)
766 {
767         char *p = (char *) HWIB_INFO_START_ADDR;
768         int i = 0;
769
770         if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
771                 if (search_real_busclk (&i))
772                         return i;
773         }
774         return CONFIG_8260_CLKIN;
775 }
776 #endif
777
778 #if CONFIG_BOARD_EARLY_INIT_R
779
780 static int can_test (unsigned long off)
781 {
782         volatile unsigned char  *base   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
783
784         *(base + 0x17) = 'T';
785         *(base + 0x18) = 'Q';
786         *(base + 0x19) = 'M';
787         if ((*(base + 0x17) != 'T') ||
788             (*(base + 0x18) != 'Q') ||
789             (*(base + 0x19) != 'M')) {
790                 return 0;
791         }
792         return 1;
793 }
794
795 static int can_config_one (unsigned long off)
796 {
797         volatile unsigned char  *ctrl   = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
798         volatile unsigned char  *cpu_if = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x02);
799         volatile unsigned char  *clkout = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x1f);
800         unsigned char temp;
801
802         *cpu_if = 0x45;
803         temp = *ctrl;
804         temp |= 0x40;
805         *ctrl   = temp;
806         *clkout = 0x20;
807         temp = *ctrl;
808         temp &= ~0x40;
809         *ctrl   = temp;
810         return 0;
811 }
812
813 static int can_config (void)
814 {
815         int     ret = 0;
816         can_config_one (0);
817         if (hwinf.can == 2) {
818                 can_config_one (0x100);
819         }
820         /* make Test if they really there */
821         ret += can_test (0);
822         ret += can_test (0x100);
823         return ret;
824 }
825
826 static int init_can (void)
827 {
828         volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
829         volatile memctl8260_t *memctl = &immr->im_memctl;
830         int     count = 0;
831
832         if ((hwinf.OK) && (hwinf.can)) {
833                 memctl->memc_or4 = CONFIG_SYS_CAN_OR;
834                 memctl->memc_br4 = CONFIG_SYS_CAN_BR;
835                 /* upm Init */
836                 upmconfig (UPMC, (uint *) upmTableFast,
837                            sizeof (upmTableFast) / sizeof (uint));
838                 memctl->memc_mcmr =     (MxMR_DSx_3_CYCL |
839                                         MxMR_GPL_x4DIS |
840                                         MxMR_RLFx_2X |
841                                         MxMR_WLFx_2X |
842                                         MxMR_OP_NORM);
843                 /* can configure */
844                 count = can_config ();
845                 printf ("CAN:   %d @ %x\n", count, CONFIG_SYS_CAN_BASE);
846                 if (hwinf.can != count) printf("!!! difference to HWIB\n");
847         } else {
848                 printf ("CAN:   No\n");
849         }
850         return 0;
851 }
852
853 int board_early_init_r(void)
854 {
855         analyse_hwib ();
856         init_can ();
857         return 0;
858 }
859 #endif
860
861 int do_hwib_dump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
862 {
863         dump_hwib ();
864         return 0;
865 }
866
867 U_BOOT_CMD(
868           hwib, 1,      1,      do_hwib_dump,
869           "dump HWIB'",
870           ""
871 );
872
873 #ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
874 static int get_flash_timing (void)
875 {
876         /* get it from the option -tf in CIB */
877         /* default is 0x00000c84 */
878         int     ret = 0x00000c84;
879         int     pos = 0;
880         int     nr = 0;
881         char    *p = (char *) CIB_INFO_START_ADDR;
882
883         while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
884                 if (*p < ' ' || *p > '~') { /* ASCII strings! */
885                         return ret;
886                 }
887                 if (*p == '-') {
888                         if ((p[1] == 't') && (p[2] == 'f')) {
889                                 p += 6;
890                                 ret = 0;
891                                 while (nr < 8) {
892                                 if ((*p >= '0') && (*p <= '9')) {
893                                         ret *= 0x10;
894                                         ret += *p - '0';
895                                         p += 1;
896                                         nr ++;
897                                 } else if ((*p >= 'A') && (*p <= 'F')) {
898                                         ret *= 10;
899                                         ret += *p - '7';
900                                         p += 1;
901                                         nr ++;
902                                 } else {
903                                         if (nr < 8) return 0x00000c84;
904                                         return ret;
905                                 }
906                                 }
907                         }
908                 }
909                 p++;
910                 pos++;
911         }
912         return ret;
913 }
914
915 /* Update the Flash_Size and the Flash Timing */
916 int update_flash_size (int flash_size)
917 {
918         volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
919         volatile memctl8260_t *memctl = &immr->im_memctl;
920         unsigned long reg;
921         unsigned long tim;
922
923         /* I must use reg, otherwise the board hang */
924         reg = memctl->memc_or0;
925         reg &= ~ORxU_AM_MSK;
926         reg |= MEG_TO_AM(flash_size >> 20);
927         tim = get_flash_timing ();
928         reg &= ~0xfff;
929         reg |= (tim & 0xfff);
930         memctl->memc_or0 = reg;
931         return 0;
932 }
933 #endif
934
935 #ifdef CONFIG_PCI
936 struct pci_controller hose;
937
938 int board_early_init_f (void)
939 {
940         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
941
942         immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
943         return 0;
944 }
945
946 extern void pci_mpc8250_init(struct pci_controller *);
947
948 void pci_init_board(void)
949 {
950         pci_mpc8250_init(&hose);
951 }
952 #endif
953
954 int board_eth_init(bd_t *bis)
955 {
956         return pci_eth_init(bis);
957 }