diff options
Diffstat (limited to 'arch/ppc/boot/simple/embed_config.c')
-rw-r--r-- | arch/ppc/boot/simple/embed_config.c | 981 |
1 files changed, 981 insertions, 0 deletions
diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c new file mode 100644 index 000000000000..c342b47e763e --- /dev/null +++ b/arch/ppc/boot/simple/embed_config.c | |||
@@ -0,0 +1,981 @@ | |||
1 | /* Board specific functions for those embedded 8xx boards that do | ||
2 | * not have boot monitor support for board information. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/config.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <asm/reg.h> | ||
14 | #ifdef CONFIG_8xx | ||
15 | #include <asm/mpc8xx.h> | ||
16 | #endif | ||
17 | #ifdef CONFIG_8260 | ||
18 | #include <asm/mpc8260.h> | ||
19 | #include <asm/immap_cpm2.h> | ||
20 | #endif | ||
21 | #ifdef CONFIG_40x | ||
22 | #include <asm/io.h> | ||
23 | #endif | ||
24 | extern unsigned long timebase_period_ns; | ||
25 | |||
26 | /* For those boards that don't provide one. | ||
27 | */ | ||
28 | #if !defined(CONFIG_MBX) | ||
29 | static bd_t bdinfo; | ||
30 | #endif | ||
31 | |||
32 | /* IIC functions. | ||
33 | * These are just the basic master read/write operations so we can | ||
34 | * examine serial EEPROM. | ||
35 | */ | ||
36 | extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); | ||
37 | |||
38 | /* Supply a default Ethernet address for those eval boards that don't | ||
39 | * ship with one. This is an address from the MBX board I have, so | ||
40 | * it is unlikely you will find it on your network. | ||
41 | */ | ||
42 | static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; | ||
43 | |||
44 | #if defined(CONFIG_MBX) | ||
45 | |||
46 | /* The MBX hands us a pretty much ready to go board descriptor. This | ||
47 | * is where the idea started in the first place. | ||
48 | */ | ||
49 | void | ||
50 | embed_config(bd_t **bdp) | ||
51 | { | ||
52 | u_char *mp; | ||
53 | u_char eebuf[128]; | ||
54 | int i = 8; | ||
55 | bd_t *bd; | ||
56 | |||
57 | bd = *bdp; | ||
58 | |||
59 | /* Read the first 128 bytes of the EEPROM. There is more, | ||
60 | * but this is all we need. | ||
61 | */ | ||
62 | iic_read(0xa4, eebuf, 0, 128); | ||
63 | |||
64 | /* All we are looking for is the Ethernet MAC address. The | ||
65 | * first 8 bytes are 'MOTOROLA', so check for part of that. | ||
66 | * Next, the VPD describes a MAC 'packet' as being of type 08 | ||
67 | * and size 06. So we look for that and the MAC must follow. | ||
68 | * If there are more than one, we still only care about the first. | ||
69 | * If it's there, assume we have a valid MAC address. If not, | ||
70 | * grab our default one. | ||
71 | */ | ||
72 | if ((*(uint *)eebuf) == 0x4d4f544f) { | ||
73 | while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06)) | ||
74 | i += eebuf[i + 1] + 2; /* skip this packet */ | ||
75 | |||
76 | if (i == 127) /* Couldn't find. */ | ||
77 | mp = (u_char *)def_enet_addr; | ||
78 | else | ||
79 | mp = &eebuf[i + 2]; | ||
80 | } | ||
81 | else | ||
82 | mp = (u_char *)def_enet_addr; | ||
83 | |||
84 | for (i=0; i<6; i++) | ||
85 | bd->bi_enetaddr[i] = *mp++; | ||
86 | |||
87 | /* The boot rom passes these to us in MHz. Linux now expects | ||
88 | * them to be in Hz. | ||
89 | */ | ||
90 | bd->bi_intfreq *= 1000000; | ||
91 | bd->bi_busfreq *= 1000000; | ||
92 | |||
93 | /* Stuff a baud rate here as well. | ||
94 | */ | ||
95 | bd->bi_baudrate = 9600; | ||
96 | } | ||
97 | #endif /* CONFIG_MBX */ | ||
98 | |||
99 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \ | ||
100 | defined(CONFIG_RPX8260) || defined(CONFIG_EP405) | ||
101 | /* Helper functions for Embedded Planet boards. | ||
102 | */ | ||
103 | /* Because I didn't find anything that would do this....... | ||
104 | */ | ||
105 | u_char | ||
106 | aschex_to_byte(u_char *cp) | ||
107 | { | ||
108 | u_char byte, c; | ||
109 | |||
110 | c = *cp++; | ||
111 | |||
112 | if ((c >= 'A') && (c <= 'F')) { | ||
113 | c -= 'A'; | ||
114 | c += 10; | ||
115 | } else if ((c >= 'a') && (c <= 'f')) { | ||
116 | c -= 'a'; | ||
117 | c += 10; | ||
118 | } else | ||
119 | c -= '0'; | ||
120 | |||
121 | byte = c * 16; | ||
122 | |||
123 | c = *cp; | ||
124 | |||
125 | if ((c >= 'A') && (c <= 'F')) { | ||
126 | c -= 'A'; | ||
127 | c += 10; | ||
128 | } else if ((c >= 'a') && (c <= 'f')) { | ||
129 | c -= 'a'; | ||
130 | c += 10; | ||
131 | } else | ||
132 | c -= '0'; | ||
133 | |||
134 | byte += c; | ||
135 | |||
136 | return(byte); | ||
137 | } | ||
138 | |||
139 | static void | ||
140 | rpx_eth(bd_t *bd, u_char *cp) | ||
141 | { | ||
142 | int i; | ||
143 | |||
144 | for (i=0; i<6; i++) { | ||
145 | bd->bi_enetaddr[i] = aschex_to_byte(cp); | ||
146 | cp += 2; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | #ifdef CONFIG_RPX8260 | ||
151 | static uint | ||
152 | rpx_baseten(u_char *cp) | ||
153 | { | ||
154 | uint retval; | ||
155 | |||
156 | retval = 0; | ||
157 | |||
158 | while (*cp != '\n') { | ||
159 | retval *= 10; | ||
160 | retval += (*cp) - '0'; | ||
161 | cp++; | ||
162 | } | ||
163 | return(retval); | ||
164 | } | ||
165 | #endif | ||
166 | |||
167 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
168 | static void | ||
169 | rpx_brate(bd_t *bd, u_char *cp) | ||
170 | { | ||
171 | uint rate; | ||
172 | |||
173 | rate = 0; | ||
174 | |||
175 | while (*cp != '\n') { | ||
176 | rate *= 10; | ||
177 | rate += (*cp) - '0'; | ||
178 | cp++; | ||
179 | } | ||
180 | |||
181 | bd->bi_baudrate = rate * 100; | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | rpx_cpuspeed(bd_t *bd, u_char *cp) | ||
186 | { | ||
187 | uint num, den; | ||
188 | |||
189 | num = den = 0; | ||
190 | |||
191 | while (*cp != '\n') { | ||
192 | num *= 10; | ||
193 | num += (*cp) - '0'; | ||
194 | cp++; | ||
195 | if (*cp == '/') { | ||
196 | cp++; | ||
197 | den = (*cp) - '0'; | ||
198 | break; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | /* I don't know why the RPX just can't state the actual | ||
203 | * CPU speed..... | ||
204 | */ | ||
205 | if (den) { | ||
206 | num /= den; | ||
207 | num *= den; | ||
208 | } | ||
209 | bd->bi_intfreq = bd->bi_busfreq = num * 1000000; | ||
210 | |||
211 | /* The 8xx can only run a maximum 50 MHz bus speed (until | ||
212 | * Motorola changes this :-). Greater than 50 MHz parts | ||
213 | * run internal/2 for bus speed. | ||
214 | */ | ||
215 | if (num > 50) | ||
216 | bd->bi_busfreq /= 2; | ||
217 | } | ||
218 | #endif | ||
219 | |||
220 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405) | ||
221 | static void | ||
222 | rpx_memsize(bd_t *bd, u_char *cp) | ||
223 | { | ||
224 | uint size; | ||
225 | |||
226 | size = 0; | ||
227 | |||
228 | while (*cp != '\n') { | ||
229 | size *= 10; | ||
230 | size += (*cp) - '0'; | ||
231 | cp++; | ||
232 | } | ||
233 | |||
234 | bd->bi_memsize = size * 1024 * 1024; | ||
235 | } | ||
236 | #endif /* LITE || CLASSIC || EP405 */ | ||
237 | #if defined(CONFIG_EP405) | ||
238 | static void | ||
239 | rpx_nvramsize(bd_t *bd, u_char *cp) | ||
240 | { | ||
241 | uint size; | ||
242 | |||
243 | size = 0; | ||
244 | |||
245 | while (*cp != '\n') { | ||
246 | size *= 10; | ||
247 | size += (*cp) - '0'; | ||
248 | cp++; | ||
249 | } | ||
250 | |||
251 | bd->bi_nvramsize = size * 1024; | ||
252 | } | ||
253 | #endif /* CONFIG_EP405 */ | ||
254 | |||
255 | #endif /* Embedded Planet boards */ | ||
256 | |||
257 | #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) | ||
258 | |||
259 | /* Read the EEPROM on the RPX-Lite board. | ||
260 | */ | ||
261 | void | ||
262 | embed_config(bd_t **bdp) | ||
263 | { | ||
264 | u_char eebuf[256], *cp; | ||
265 | bd_t *bd; | ||
266 | |||
267 | /* Read the first 256 bytes of the EEPROM. I think this | ||
268 | * is really all there is, and I hope if it gets bigger the | ||
269 | * info we want is still up front. | ||
270 | */ | ||
271 | bd = &bdinfo; | ||
272 | *bdp = bd; | ||
273 | |||
274 | #if 1 | ||
275 | iic_read(0xa8, eebuf, 0, 128); | ||
276 | iic_read(0xa8, &eebuf[128], 128, 128); | ||
277 | |||
278 | /* We look for two things, the Ethernet address and the | ||
279 | * serial baud rate. The records are separated by | ||
280 | * newlines. | ||
281 | */ | ||
282 | cp = eebuf; | ||
283 | for (;;) { | ||
284 | if (*cp == 'E') { | ||
285 | cp++; | ||
286 | if (*cp == 'A') { | ||
287 | cp += 2; | ||
288 | rpx_eth(bd, cp); | ||
289 | } | ||
290 | } | ||
291 | if (*cp == 'S') { | ||
292 | cp++; | ||
293 | if (*cp == 'B') { | ||
294 | cp += 2; | ||
295 | rpx_brate(bd, cp); | ||
296 | } | ||
297 | } | ||
298 | if (*cp == 'D') { | ||
299 | cp++; | ||
300 | if (*cp == '1') { | ||
301 | cp += 2; | ||
302 | rpx_memsize(bd, cp); | ||
303 | } | ||
304 | } | ||
305 | if (*cp == 'H') { | ||
306 | cp++; | ||
307 | if (*cp == 'Z') { | ||
308 | cp += 2; | ||
309 | rpx_cpuspeed(bd, cp); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | /* Scan to the end of the record. | ||
314 | */ | ||
315 | while ((*cp != '\n') && (*cp != 0xff)) | ||
316 | cp++; | ||
317 | |||
318 | /* If the next character is a 0 or ff, we are done. | ||
319 | */ | ||
320 | cp++; | ||
321 | if ((*cp == 0) || (*cp == 0xff)) | ||
322 | break; | ||
323 | } | ||
324 | bd->bi_memstart = 0; | ||
325 | #else | ||
326 | /* For boards without initialized EEPROM. | ||
327 | */ | ||
328 | bd->bi_memstart = 0; | ||
329 | bd->bi_memsize = (8 * 1024 * 1024); | ||
330 | bd->bi_intfreq = 48000000; | ||
331 | bd->bi_busfreq = 48000000; | ||
332 | bd->bi_baudrate = 9600; | ||
333 | #endif | ||
334 | } | ||
335 | #endif /* RPXLITE || RPXCLASSIC */ | ||
336 | |||
337 | #ifdef CONFIG_BSEIP | ||
338 | /* Build a board information structure for the BSE ip-Engine. | ||
339 | * There is more to come since we will add some environment | ||
340 | * variables and a function to read them. | ||
341 | */ | ||
342 | void | ||
343 | embed_config(bd_t **bdp) | ||
344 | { | ||
345 | u_char *cp; | ||
346 | int i; | ||
347 | bd_t *bd; | ||
348 | |||
349 | bd = &bdinfo; | ||
350 | *bdp = bd; | ||
351 | |||
352 | /* Baud rate and processor speed will eventually come | ||
353 | * from the environment variables. | ||
354 | */ | ||
355 | bd->bi_baudrate = 9600; | ||
356 | |||
357 | /* Get the Ethernet station address from the Flash ROM. | ||
358 | */ | ||
359 | cp = (u_char *)0xfe003ffa; | ||
360 | for (i=0; i<6; i++) { | ||
361 | bd->bi_enetaddr[i] = *cp++; | ||
362 | } | ||
363 | |||
364 | /* The rest of this should come from the environment as well. | ||
365 | */ | ||
366 | bd->bi_memstart = 0; | ||
367 | bd->bi_memsize = (16 * 1024 * 1024); | ||
368 | bd->bi_intfreq = 48000000; | ||
369 | bd->bi_busfreq = 48000000; | ||
370 | } | ||
371 | #endif /* BSEIP */ | ||
372 | |||
373 | #ifdef CONFIG_FADS | ||
374 | /* Build a board information structure for the FADS. | ||
375 | */ | ||
376 | void | ||
377 | embed_config(bd_t **bdp) | ||
378 | { | ||
379 | u_char *cp; | ||
380 | int i; | ||
381 | bd_t *bd; | ||
382 | |||
383 | bd = &bdinfo; | ||
384 | *bdp = bd; | ||
385 | |||
386 | /* Just fill in some known values. | ||
387 | */ | ||
388 | bd->bi_baudrate = 9600; | ||
389 | |||
390 | /* Use default enet. | ||
391 | */ | ||
392 | cp = (u_char *)def_enet_addr; | ||
393 | for (i=0; i<6; i++) { | ||
394 | bd->bi_enetaddr[i] = *cp++; | ||
395 | } | ||
396 | |||
397 | bd->bi_memstart = 0; | ||
398 | bd->bi_memsize = (8 * 1024 * 1024); | ||
399 | bd->bi_intfreq = 40000000; | ||
400 | bd->bi_busfreq = 40000000; | ||
401 | } | ||
402 | #endif /* FADS */ | ||
403 | |||
404 | #ifdef CONFIG_8260 | ||
405 | /* Compute 8260 clock values if the rom doesn't provide them. | ||
406 | */ | ||
407 | static unsigned char bus2core_8260[] = { | ||
408 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
409 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
410 | 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2, | ||
411 | }; | ||
412 | |||
413 | static void | ||
414 | clk_8260(bd_t *bd) | ||
415 | { | ||
416 | uint scmr, vco_out, clkin; | ||
417 | uint plldf, pllmf, corecnf; | ||
418 | volatile cpm2_map_t *ip; | ||
419 | |||
420 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
421 | scmr = ip->im_clkrst.car_scmr; | ||
422 | |||
423 | /* The clkin is always bus frequency. | ||
424 | */ | ||
425 | clkin = bd->bi_busfreq; | ||
426 | |||
427 | /* Collect the bits from the scmr. | ||
428 | */ | ||
429 | plldf = (scmr >> 12) & 1; | ||
430 | pllmf = scmr & 0xfff; | ||
431 | corecnf = (scmr >> 24) &0x1f; | ||
432 | |||
433 | /* This is arithmetic from the 8260 manual. | ||
434 | */ | ||
435 | vco_out = clkin / (plldf + 1); | ||
436 | vco_out *= 2 * (pllmf + 1); | ||
437 | bd->bi_vco = vco_out; /* Save for later */ | ||
438 | |||
439 | bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ | ||
440 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2; | ||
441 | |||
442 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
443 | * but we set it again here in case it was changed. | ||
444 | */ | ||
445 | ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ | ||
446 | bd->bi_brgfreq = vco_out / 16; | ||
447 | } | ||
448 | |||
449 | static unsigned char bus2core_8280[] = { | ||
450 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
451 | 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, | ||
452 | 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2, | ||
453 | }; | ||
454 | |||
455 | static void | ||
456 | clk_8280(bd_t *bd) | ||
457 | { | ||
458 | uint scmr, main_clk, clkin; | ||
459 | uint pllmf, corecnf; | ||
460 | volatile cpm2_map_t *ip; | ||
461 | |||
462 | ip = (cpm2_map_t *)CPM_MAP_ADDR; | ||
463 | scmr = ip->im_clkrst.car_scmr; | ||
464 | |||
465 | /* The clkin is always bus frequency. | ||
466 | */ | ||
467 | clkin = bd->bi_busfreq; | ||
468 | |||
469 | /* Collect the bits from the scmr. | ||
470 | */ | ||
471 | pllmf = scmr & 0xf; | ||
472 | corecnf = (scmr >> 24) & 0x1f; | ||
473 | |||
474 | /* This is arithmetic from the 8280 manual. | ||
475 | */ | ||
476 | main_clk = clkin * (pllmf + 1); | ||
477 | |||
478 | bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */ | ||
479 | bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2; | ||
480 | |||
481 | /* Set Baud rate divisor. The power up default is divide by 16, | ||
482 | * but we set it again here in case it was changed. | ||
483 | */ | ||
484 | ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1; | ||
485 | bd->bi_brgfreq = main_clk / 16; | ||
486 | } | ||
487 | #endif | ||
488 | |||
489 | #ifdef CONFIG_SBC82xx | ||
490 | void | ||
491 | embed_config(bd_t **bdp) | ||
492 | { | ||
493 | u_char *cp; | ||
494 | int i; | ||
495 | bd_t *bd; | ||
496 | unsigned long pvr; | ||
497 | |||
498 | bd = *bdp; | ||
499 | |||
500 | bd = &bdinfo; | ||
501 | *bdp = bd; | ||
502 | bd->bi_baudrate = 9600; | ||
503 | bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */ | ||
504 | |||
505 | cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1; | ||
506 | memcpy(bd->bi_enetaddr, cp, 6); | ||
507 | |||
508 | /* can busfreq be calculated? */ | ||
509 | pvr = mfspr(SPRN_PVR); | ||
510 | if ((pvr & 0xffff0000) == 0x80820000) { | ||
511 | bd->bi_busfreq = 100000000; | ||
512 | clk_8280(bd); | ||
513 | } else { | ||
514 | bd->bi_busfreq = 66000000; | ||
515 | clk_8260(bd); | ||
516 | } | ||
517 | |||
518 | } | ||
519 | #endif /* SBC82xx */ | ||
520 | |||
521 | #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260) | ||
522 | void | ||
523 | embed_config(bd_t **bdp) | ||
524 | { | ||
525 | u_char *cp; | ||
526 | int i; | ||
527 | bd_t *bd; | ||
528 | |||
529 | bd = *bdp; | ||
530 | #if 0 | ||
531 | /* This is actually provided by my boot rom. I have it | ||
532 | * here for those people that may load the kernel with | ||
533 | * a JTAG/COP tool and not the rom monitor. | ||
534 | */ | ||
535 | bd->bi_baudrate = 115200; | ||
536 | bd->bi_intfreq = 200000000; | ||
537 | bd->bi_busfreq = 66666666; | ||
538 | bd->bi_cpmfreq = 66666666; | ||
539 | bd->bi_brgfreq = 33333333; | ||
540 | bd->bi_memsize = 16 * 1024 * 1024; | ||
541 | #else | ||
542 | /* The boot rom passes these to us in MHz. Linux now expects | ||
543 | * them to be in Hz. | ||
544 | */ | ||
545 | bd->bi_intfreq *= 1000000; | ||
546 | bd->bi_busfreq *= 1000000; | ||
547 | bd->bi_cpmfreq *= 1000000; | ||
548 | bd->bi_brgfreq *= 1000000; | ||
549 | #endif | ||
550 | |||
551 | cp = (u_char *)def_enet_addr; | ||
552 | for (i=0; i<6; i++) { | ||
553 | bd->bi_enetaddr[i] = *cp++; | ||
554 | } | ||
555 | } | ||
556 | #endif /* EST8260 */ | ||
557 | |||
558 | #ifdef CONFIG_SBS8260 | ||
559 | void | ||
560 | embed_config(bd_t **bdp) | ||
561 | { | ||
562 | u_char *cp; | ||
563 | int i; | ||
564 | bd_t *bd; | ||
565 | |||
566 | /* This should provided by the boot rom. | ||
567 | */ | ||
568 | bd = &bdinfo; | ||
569 | *bdp = bd; | ||
570 | bd->bi_baudrate = 9600; | ||
571 | bd->bi_memsize = 64 * 1024 * 1024; | ||
572 | |||
573 | /* Set all of the clocks. We have to know the speed of the | ||
574 | * external clock. The development board had 66 MHz. | ||
575 | */ | ||
576 | bd->bi_busfreq = 66666666; | ||
577 | clk_8260(bd); | ||
578 | |||
579 | /* I don't know how to compute this yet. | ||
580 | */ | ||
581 | bd->bi_intfreq = 133000000; | ||
582 | |||
583 | |||
584 | cp = (u_char *)def_enet_addr; | ||
585 | for (i=0; i<6; i++) { | ||
586 | bd->bi_enetaddr[i] = *cp++; | ||
587 | } | ||
588 | } | ||
589 | #endif /* SBS8260 */ | ||
590 | |||
591 | #ifdef CONFIG_RPX8260 | ||
592 | void | ||
593 | embed_config(bd_t **bdp) | ||
594 | { | ||
595 | u_char *cp, *keyvals; | ||
596 | int i; | ||
597 | bd_t *bd; | ||
598 | |||
599 | keyvals = (u_char *)*bdp; | ||
600 | |||
601 | bd = &bdinfo; | ||
602 | *bdp = bd; | ||
603 | |||
604 | /* This is almost identical to the RPX-Lite/Classic functions | ||
605 | * on the 8xx boards. It would be nice to have a key lookup | ||
606 | * function in a string, but the format of all of the fields | ||
607 | * is slightly different. | ||
608 | */ | ||
609 | cp = keyvals; | ||
610 | for (;;) { | ||
611 | if (*cp == 'E') { | ||
612 | cp++; | ||
613 | if (*cp == 'A') { | ||
614 | cp += 2; | ||
615 | rpx_eth(bd, cp); | ||
616 | } | ||
617 | } | ||
618 | if (*cp == 'S') { | ||
619 | cp++; | ||
620 | if (*cp == 'B') { | ||
621 | cp += 2; | ||
622 | bd->bi_baudrate = rpx_baseten(cp); | ||
623 | } | ||
624 | } | ||
625 | if (*cp == 'D') { | ||
626 | cp++; | ||
627 | if (*cp == '1') { | ||
628 | cp += 2; | ||
629 | bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024; | ||
630 | } | ||
631 | } | ||
632 | if (*cp == 'X') { | ||
633 | cp++; | ||
634 | if (*cp == 'T') { | ||
635 | cp += 2; | ||
636 | bd->bi_busfreq = rpx_baseten(cp); | ||
637 | } | ||
638 | } | ||
639 | if (*cp == 'N') { | ||
640 | cp++; | ||
641 | if (*cp == 'V') { | ||
642 | cp += 2; | ||
643 | bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | /* Scan to the end of the record. | ||
648 | */ | ||
649 | while ((*cp != '\n') && (*cp != 0xff)) | ||
650 | cp++; | ||
651 | |||
652 | /* If the next character is a 0 or ff, we are done. | ||
653 | */ | ||
654 | cp++; | ||
655 | if ((*cp == 0) || (*cp == 0xff)) | ||
656 | break; | ||
657 | } | ||
658 | bd->bi_memstart = 0; | ||
659 | |||
660 | /* The memory size includes both the 60x and local bus DRAM. | ||
661 | * I don't want to use the local bus DRAM for real memory, | ||
662 | * so subtract it out. It would be nice if they were separate | ||
663 | * keys. | ||
664 | */ | ||
665 | bd->bi_memsize -= 32 * 1024 * 1024; | ||
666 | |||
667 | /* Set all of the clocks. We have to know the speed of the | ||
668 | * external clock. | ||
669 | */ | ||
670 | clk_8260(bd); | ||
671 | |||
672 | /* I don't know how to compute this yet. | ||
673 | */ | ||
674 | bd->bi_intfreq = 200000000; | ||
675 | } | ||
676 | #endif /* RPX6 for testing */ | ||
677 | |||
678 | #ifdef CONFIG_ADS8260 | ||
679 | void | ||
680 | embed_config(bd_t **bdp) | ||
681 | { | ||
682 | u_char *cp; | ||
683 | int i; | ||
684 | bd_t *bd; | ||
685 | |||
686 | /* This should provided by the boot rom. | ||
687 | */ | ||
688 | bd = &bdinfo; | ||
689 | *bdp = bd; | ||
690 | bd->bi_baudrate = 9600; | ||
691 | bd->bi_memsize = 16 * 1024 * 1024; | ||
692 | |||
693 | /* Set all of the clocks. We have to know the speed of the | ||
694 | * external clock. The development board had 66 MHz. | ||
695 | */ | ||
696 | bd->bi_busfreq = 66666666; | ||
697 | clk_8260(bd); | ||
698 | |||
699 | /* I don't know how to compute this yet. | ||
700 | */ | ||
701 | bd->bi_intfreq = 200000000; | ||
702 | |||
703 | |||
704 | cp = (u_char *)def_enet_addr; | ||
705 | for (i=0; i<6; i++) { | ||
706 | bd->bi_enetaddr[i] = *cp++; | ||
707 | } | ||
708 | } | ||
709 | #endif /* ADS8260 */ | ||
710 | |||
711 | #ifdef CONFIG_WILLOW | ||
712 | void | ||
713 | embed_config(bd_t **bdp) | ||
714 | { | ||
715 | u_char *cp; | ||
716 | int i; | ||
717 | bd_t *bd; | ||
718 | |||
719 | /* Willow has Open Firmware....I should learn how to get this | ||
720 | * information from it. | ||
721 | */ | ||
722 | bd = &bdinfo; | ||
723 | *bdp = bd; | ||
724 | bd->bi_baudrate = 9600; | ||
725 | bd->bi_memsize = 32 * 1024 * 1024; | ||
726 | |||
727 | /* Set all of the clocks. We have to know the speed of the | ||
728 | * external clock. The development board had 66 MHz. | ||
729 | */ | ||
730 | bd->bi_busfreq = 66666666; | ||
731 | clk_8260(bd); | ||
732 | |||
733 | /* I don't know how to compute this yet. | ||
734 | */ | ||
735 | bd->bi_intfreq = 200000000; | ||
736 | |||
737 | |||
738 | cp = (u_char *)def_enet_addr; | ||
739 | for (i=0; i<6; i++) { | ||
740 | bd->bi_enetaddr[i] = *cp++; | ||
741 | } | ||
742 | } | ||
743 | #endif /* WILLOW */ | ||
744 | |||
745 | #ifdef CONFIG_XILINX_ML300 | ||
746 | void | ||
747 | embed_config(bd_t ** bdp) | ||
748 | { | ||
749 | static const unsigned long line_size = 32; | ||
750 | static const unsigned long congruence_classes = 256; | ||
751 | unsigned long addr; | ||
752 | unsigned long dccr; | ||
753 | bd_t *bd; | ||
754 | |||
755 | /* | ||
756 | * Invalidate the data cache if the data cache is turned off. | ||
757 | * - The 405 core does not invalidate the data cache on power-up | ||
758 | * or reset but does turn off the data cache. We cannot assume | ||
759 | * that the cache contents are valid. | ||
760 | * - If the data cache is turned on this must have been done by | ||
761 | * a bootloader and we assume that the cache contents are | ||
762 | * valid. | ||
763 | */ | ||
764 | __asm__("mfdccr %0": "=r" (dccr)); | ||
765 | if (dccr == 0) { | ||
766 | for (addr = 0; | ||
767 | addr < (congruence_classes * line_size); | ||
768 | addr += line_size) { | ||
769 | __asm__("dccci 0,%0": :"b"(addr)); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | bd = &bdinfo; | ||
774 | *bdp = bd; | ||
775 | bd->bi_memsize = XPAR_DDR_0_SIZE; | ||
776 | bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ; | ||
777 | bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ; | ||
778 | bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ; | ||
779 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
780 | /* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */ | ||
781 | } | ||
782 | #endif /* CONFIG_XILINX_ML300 */ | ||
783 | |||
784 | #ifdef CONFIG_IBM_OPENBIOS | ||
785 | /* This could possibly work for all treeboot roms. | ||
786 | */ | ||
787 | #if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA) | ||
788 | #define BOARD_INFO_VECTOR 0xFFF80B50 /* openbios 1.19 moved this vector down - armin */ | ||
789 | #else | ||
790 | #define BOARD_INFO_VECTOR 0xFFFE0B50 | ||
791 | #endif | ||
792 | |||
793 | #ifdef CONFIG_BEECH | ||
794 | static void | ||
795 | get_board_info(bd_t **bdp) | ||
796 | { | ||
797 | typedef void (*PFV)(bd_t *bd); | ||
798 | ((PFV)(*(unsigned long *)BOARD_INFO_VECTOR))(*bdp); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | void | ||
803 | embed_config(bd_t **bdp) | ||
804 | { | ||
805 | *bdp = &bdinfo; | ||
806 | get_board_info(bdp); | ||
807 | } | ||
808 | #else /* !CONFIG_BEECH */ | ||
809 | void | ||
810 | embed_config(bd_t **bdp) | ||
811 | { | ||
812 | u_char *cp; | ||
813 | int i; | ||
814 | bd_t *bd, *treeboot_bd; | ||
815 | bd_t *(*get_board_info)(void) = | ||
816 | (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); | ||
817 | #if !defined(CONFIG_STB03xxx) | ||
818 | |||
819 | /* shut down the Ethernet controller that the boot rom | ||
820 | * sometimes leaves running. | ||
821 | */ | ||
822 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
823 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
824 | out_be32((volatile u32*)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
825 | #endif | ||
826 | |||
827 | bd = &bdinfo; | ||
828 | *bdp = bd; | ||
829 | if ((treeboot_bd = get_board_info()) != NULL) { | ||
830 | memcpy(bd, treeboot_bd, sizeof(bd_t)); | ||
831 | } | ||
832 | else { | ||
833 | /* Hmmm...better try to stuff some defaults. | ||
834 | */ | ||
835 | bd->bi_memsize = 16 * 1024 * 1024; | ||
836 | cp = (u_char *)def_enet_addr; | ||
837 | for (i=0; i<6; i++) { | ||
838 | /* I should probably put different ones here, | ||
839 | * hopefully only one is used. | ||
840 | */ | ||
841 | bd->BD_EMAC_ADDR(0,i) = *cp; | ||
842 | |||
843 | #ifdef CONFIG_PCI | ||
844 | bd->bi_pci_enetaddr[i] = *cp++; | ||
845 | #endif | ||
846 | } | ||
847 | bd->bi_tbfreq = 200 * 1000 * 1000; | ||
848 | bd->bi_intfreq = 200000000; | ||
849 | bd->bi_busfreq = 100000000; | ||
850 | #ifdef CONFIG_PCI | ||
851 | bd->bi_pci_busfreq = 66666666; | ||
852 | #endif | ||
853 | } | ||
854 | /* Yeah, this look weird, but on Redwood 4 they are | ||
855 | * different object in the structure. Sincr Redwwood 5 | ||
856 | * and Redwood 6 use OpenBIOS, it requires a special value. | ||
857 | */ | ||
858 | #if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6) | ||
859 | bd->bi_tbfreq = 27 * 1000 * 1000; | ||
860 | #endif | ||
861 | timebase_period_ns = 1000000000 / bd->bi_tbfreq; | ||
862 | } | ||
863 | #endif /* CONFIG_BEECH */ | ||
864 | #endif /* CONFIG_IBM_OPENBIOS */ | ||
865 | |||
866 | #ifdef CONFIG_EP405 | ||
867 | #include <linux/serial_reg.h> | ||
868 | |||
869 | void | ||
870 | embed_config(bd_t **bdp) | ||
871 | { | ||
872 | u32 chcr0; | ||
873 | u_char *cp; | ||
874 | bd_t *bd; | ||
875 | |||
876 | /* Different versions of the PlanetCore firmware vary in how | ||
877 | they set up the serial port - in particular whether they | ||
878 | use the internal or external serial clock for UART0. Make | ||
879 | sure the UART is in a known state. */ | ||
880 | /* FIXME: We should use the board's 11.0592MHz external serial | ||
881 | clock - it will be more accurate for serial rates. For | ||
882 | now, however the baud rates in ep405.h are for the internal | ||
883 | clock. */ | ||
884 | chcr0 = mfdcr(DCRN_CHCR0); | ||
885 | if ( (chcr0 & 0x1fff) != 0x103e ) { | ||
886 | mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e); | ||
887 | /* The following tricks serial_init() into resetting the baud rate */ | ||
888 | writeb(0, UART0_IO_BASE + UART_LCR); | ||
889 | } | ||
890 | |||
891 | /* We haven't seen actual problems with the EP405 leaving the | ||
892 | * EMAC running (as we have on Walnut). But the registers | ||
893 | * suggest it may not be left completely quiescent. Reset it | ||
894 | * just to be sure. */ | ||
895 | mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */ | ||
896 | while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */ | ||
897 | out_be32((unsigned *)EMAC0_BASE,0x20000000); /* then reset EMAC */ | ||
898 | |||
899 | bd = &bdinfo; | ||
900 | *bdp = bd; | ||
901 | #if 1 | ||
902 | cp = (u_char *)0xF0000EE0; | ||
903 | for (;;) { | ||
904 | if (*cp == 'E') { | ||
905 | cp++; | ||
906 | if (*cp == 'A') { | ||
907 | cp += 2; | ||
908 | rpx_eth(bd, cp); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | if (*cp == 'D') { | ||
913 | cp++; | ||
914 | if (*cp == '1') { | ||
915 | cp += 2; | ||
916 | rpx_memsize(bd, cp); | ||
917 | } | ||
918 | } | ||
919 | |||
920 | if (*cp == 'N') { | ||
921 | cp++; | ||
922 | if (*cp == 'V') { | ||
923 | cp += 2; | ||
924 | rpx_nvramsize(bd, cp); | ||
925 | } | ||
926 | } | ||
927 | while ((*cp != '\n') && (*cp != 0xff)) | ||
928 | cp++; | ||
929 | |||
930 | cp++; | ||
931 | if ((*cp == 0) || (*cp == 0xff)) | ||
932 | break; | ||
933 | } | ||
934 | bd->bi_intfreq = 200000000; | ||
935 | bd->bi_busfreq = 100000000; | ||
936 | bd->bi_pci_busfreq= 33000000 ; | ||
937 | #else | ||
938 | |||
939 | bd->bi_memsize = 64000000; | ||
940 | bd->bi_intfreq = 200000000; | ||
941 | bd->bi_busfreq = 100000000; | ||
942 | bd->bi_pci_busfreq= 33000000 ; | ||
943 | #endif | ||
944 | } | ||
945 | #endif | ||
946 | |||
947 | #ifdef CONFIG_RAINIER | ||
948 | /* Rainier uses vxworks bootrom */ | ||
949 | void | ||
950 | embed_config(bd_t **bdp) | ||
951 | { | ||
952 | u_char *cp; | ||
953 | int i; | ||
954 | bd_t *bd; | ||
955 | |||
956 | bd = &bdinfo; | ||
957 | *bdp = bd; | ||
958 | |||
959 | for(i=0;i<8192;i+=32) { | ||
960 | __asm__("dccci 0,%0" :: "r" (i)); | ||
961 | } | ||
962 | __asm__("iccci 0,0"); | ||
963 | __asm__("sync;isync"); | ||
964 | |||
965 | /* init ram for parity */ | ||
966 | memset(0, 0,0x400000); /* Lo memory */ | ||
967 | |||
968 | |||
969 | bd->bi_memsize = (32 * 1024 * 1024) ; | ||
970 | bd->bi_intfreq = 133000000; //the internal clock is 133 MHz | ||
971 | bd->bi_busfreq = 100000000; | ||
972 | bd->bi_pci_busfreq= 33000000; | ||
973 | |||
974 | cp = (u_char *)def_enet_addr; | ||
975 | for (i=0; i<6; i++) { | ||
976 | bd->bi_enetaddr[i] = *cp++; | ||
977 | } | ||
978 | |||
979 | } | ||
980 | #endif | ||
981 | |||