1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> |
4 | * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> |
5 | */ |
6 | |
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
8 | |
9 | #include <linux/init.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/string.h> |
12 | #include <linux/platform_device.h> |
13 | #include <linux/ssb/ssb.h> |
14 | #include <asm/addrspace.h> |
15 | #include <bcm63xx_board.h> |
16 | #include <bcm63xx_cpu.h> |
17 | #include <bcm63xx_dev_uart.h> |
18 | #include <bcm63xx_regs.h> |
19 | #include <bcm63xx_io.h> |
20 | #include <bcm63xx_nvram.h> |
21 | #include <bcm63xx_dev_pci.h> |
22 | #include <bcm63xx_dev_enet.h> |
23 | #include <bcm63xx_dev_flash.h> |
24 | #include <bcm63xx_dev_hsspi.h> |
25 | #include <bcm63xx_dev_pcmcia.h> |
26 | #include <bcm63xx_dev_spi.h> |
27 | #include <bcm63xx_dev_usb_usbd.h> |
28 | #include <board_bcm963xx.h> |
29 | |
30 | #include <uapi/linux/bcm933xx_hcs.h> |
31 | |
32 | #define HCS_OFFSET_128K 0x20000 |
33 | |
34 | static struct board_info board; |
35 | |
36 | /* |
37 | * known 3368 boards |
38 | */ |
39 | #ifdef CONFIG_BCM63XX_CPU_3368 |
40 | static struct board_info __initdata board_cvg834g = { |
41 | .name = "CVG834G_E15R3921" , |
42 | .expected_cpu_id = 0x3368, |
43 | |
44 | .ephy_reset_gpio = 36, |
45 | .ephy_reset_gpio_flags = GPIOF_INIT_HIGH, |
46 | .has_pci = 1, |
47 | .has_uart0 = 1, |
48 | .has_uart1 = 1, |
49 | |
50 | .has_enet0 = 1, |
51 | .enet0 = { |
52 | .has_phy = 1, |
53 | .use_internal_phy = 1, |
54 | }, |
55 | |
56 | .leds = { |
57 | { |
58 | .name = "CVG834G:green:power" , |
59 | .gpio = 37, |
60 | .default_trigger= "default-on" , |
61 | }, |
62 | }, |
63 | }; |
64 | #endif /* CONFIG_BCM63XX_CPU_3368 */ |
65 | |
66 | /* |
67 | * known 6328 boards |
68 | */ |
69 | #ifdef CONFIG_BCM63XX_CPU_6328 |
70 | static struct board_info __initdata board_96328avng = { |
71 | .name = "96328avng" , |
72 | .expected_cpu_id = 0x6328, |
73 | |
74 | .has_pci = 1, |
75 | .has_uart0 = 1, |
76 | |
77 | .has_usbd = 0, |
78 | .usbd = { |
79 | .use_fullspeed = 0, |
80 | .port_no = 0, |
81 | }, |
82 | |
83 | .leds = { |
84 | { |
85 | .name = "96328avng::ppp-fail" , |
86 | .gpio = 2, |
87 | .active_low = 1, |
88 | }, |
89 | { |
90 | .name = "96328avng::power" , |
91 | .gpio = 4, |
92 | .active_low = 1, |
93 | .default_trigger = "default-on" , |
94 | }, |
95 | { |
96 | .name = "96328avng::power-fail" , |
97 | .gpio = 8, |
98 | .active_low = 1, |
99 | }, |
100 | { |
101 | .name = "96328avng::wps" , |
102 | .gpio = 9, |
103 | .active_low = 1, |
104 | }, |
105 | { |
106 | .name = "96328avng::ppp" , |
107 | .gpio = 11, |
108 | .active_low = 1, |
109 | }, |
110 | }, |
111 | }; |
112 | #endif /* CONFIG_BCM63XX_CPU_6328 */ |
113 | |
114 | /* |
115 | * known 6338 boards |
116 | */ |
117 | #ifdef CONFIG_BCM63XX_CPU_6338 |
118 | static struct board_info __initdata board_96338gw = { |
119 | .name = "96338GW" , |
120 | .expected_cpu_id = 0x6338, |
121 | |
122 | .has_ohci0 = 1, |
123 | .has_uart0 = 1, |
124 | |
125 | .has_enet0 = 1, |
126 | .enet0 = { |
127 | .force_speed_100 = 1, |
128 | .force_duplex_full = 1, |
129 | }, |
130 | |
131 | .leds = { |
132 | { |
133 | .name = "adsl" , |
134 | .gpio = 3, |
135 | .active_low = 1, |
136 | }, |
137 | { |
138 | .name = "ses" , |
139 | .gpio = 5, |
140 | .active_low = 1, |
141 | }, |
142 | { |
143 | .name = "ppp-fail" , |
144 | .gpio = 4, |
145 | .active_low = 1, |
146 | }, |
147 | { |
148 | .name = "power" , |
149 | .gpio = 0, |
150 | .active_low = 1, |
151 | .default_trigger = "default-on" , |
152 | }, |
153 | { |
154 | .name = "stop" , |
155 | .gpio = 1, |
156 | .active_low = 1, |
157 | } |
158 | }, |
159 | }; |
160 | |
161 | static struct board_info __initdata board_96338w = { |
162 | .name = "96338W" , |
163 | .expected_cpu_id = 0x6338, |
164 | |
165 | .has_uart0 = 1, |
166 | |
167 | .has_enet0 = 1, |
168 | .enet0 = { |
169 | .force_speed_100 = 1, |
170 | .force_duplex_full = 1, |
171 | }, |
172 | |
173 | .leds = { |
174 | { |
175 | .name = "adsl" , |
176 | .gpio = 3, |
177 | .active_low = 1, |
178 | }, |
179 | { |
180 | .name = "ses" , |
181 | .gpio = 5, |
182 | .active_low = 1, |
183 | }, |
184 | { |
185 | .name = "ppp-fail" , |
186 | .gpio = 4, |
187 | .active_low = 1, |
188 | }, |
189 | { |
190 | .name = "power" , |
191 | .gpio = 0, |
192 | .active_low = 1, |
193 | .default_trigger = "default-on" , |
194 | }, |
195 | { |
196 | .name = "stop" , |
197 | .gpio = 1, |
198 | .active_low = 1, |
199 | }, |
200 | }, |
201 | }; |
202 | #endif /* CONFIG_BCM63XX_CPU_6338 */ |
203 | |
204 | /* |
205 | * known 6345 boards |
206 | */ |
207 | #ifdef CONFIG_BCM63XX_CPU_6345 |
208 | static struct board_info __initdata board_96345gw2 = { |
209 | .name = "96345GW2" , |
210 | .expected_cpu_id = 0x6345, |
211 | |
212 | .has_uart0 = 1, |
213 | }; |
214 | #endif /* CONFIG_BCM63XX_CPU_6345 */ |
215 | |
216 | /* |
217 | * known 6348 boards |
218 | */ |
219 | #ifdef CONFIG_BCM63XX_CPU_6348 |
220 | static struct board_info __initdata board_96348r = { |
221 | .name = "96348R" , |
222 | .expected_cpu_id = 0x6348, |
223 | |
224 | .has_pci = 1, |
225 | .has_uart0 = 1, |
226 | |
227 | .has_enet0 = 1, |
228 | .enet0 = { |
229 | .has_phy = 1, |
230 | .use_internal_phy = 1, |
231 | }, |
232 | |
233 | .leds = { |
234 | { |
235 | .name = "adsl-fail" , |
236 | .gpio = 2, |
237 | .active_low = 1, |
238 | }, |
239 | { |
240 | .name = "ppp" , |
241 | .gpio = 3, |
242 | .active_low = 1, |
243 | }, |
244 | { |
245 | .name = "ppp-fail" , |
246 | .gpio = 4, |
247 | .active_low = 1, |
248 | }, |
249 | { |
250 | .name = "power" , |
251 | .gpio = 0, |
252 | .active_low = 1, |
253 | .default_trigger = "default-on" , |
254 | |
255 | }, |
256 | { |
257 | .name = "stop" , |
258 | .gpio = 1, |
259 | .active_low = 1, |
260 | }, |
261 | }, |
262 | }; |
263 | |
264 | static struct board_info __initdata board_96348gw_10 = { |
265 | .name = "96348GW-10" , |
266 | .expected_cpu_id = 0x6348, |
267 | |
268 | .has_ohci0 = 1, |
269 | .has_pccard = 1, |
270 | .has_pci = 1, |
271 | .has_uart0 = 1, |
272 | |
273 | .has_enet0 = 1, |
274 | .enet0 = { |
275 | .has_phy = 1, |
276 | .use_internal_phy = 1, |
277 | }, |
278 | |
279 | .has_enet1 = 1, |
280 | .enet1 = { |
281 | .force_speed_100 = 1, |
282 | .force_duplex_full = 1, |
283 | }, |
284 | |
285 | .leds = { |
286 | { |
287 | .name = "adsl-fail" , |
288 | .gpio = 2, |
289 | .active_low = 1, |
290 | }, |
291 | { |
292 | .name = "ppp" , |
293 | .gpio = 3, |
294 | .active_low = 1, |
295 | }, |
296 | { |
297 | .name = "ppp-fail" , |
298 | .gpio = 4, |
299 | .active_low = 1, |
300 | }, |
301 | { |
302 | .name = "power" , |
303 | .gpio = 0, |
304 | .active_low = 1, |
305 | .default_trigger = "default-on" , |
306 | }, |
307 | { |
308 | .name = "stop" , |
309 | .gpio = 1, |
310 | .active_low = 1, |
311 | }, |
312 | }, |
313 | }; |
314 | |
315 | static struct board_info __initdata board_96348gw_11 = { |
316 | .name = "96348GW-11" , |
317 | .expected_cpu_id = 0x6348, |
318 | |
319 | .has_ohci0 = 1, |
320 | .has_pccard = 1, |
321 | .has_pci = 1, |
322 | .has_uart0 = 1, |
323 | |
324 | .has_enet0 = 1, |
325 | .enet0 = { |
326 | .has_phy = 1, |
327 | .use_internal_phy = 1, |
328 | }, |
329 | |
330 | .has_enet1 = 1, |
331 | .enet1 = { |
332 | .force_speed_100 = 1, |
333 | .force_duplex_full = 1, |
334 | }, |
335 | |
336 | .leds = { |
337 | { |
338 | .name = "adsl-fail" , |
339 | .gpio = 2, |
340 | .active_low = 1, |
341 | }, |
342 | { |
343 | .name = "ppp" , |
344 | .gpio = 3, |
345 | .active_low = 1, |
346 | }, |
347 | { |
348 | .name = "ppp-fail" , |
349 | .gpio = 4, |
350 | .active_low = 1, |
351 | }, |
352 | { |
353 | .name = "power" , |
354 | .gpio = 0, |
355 | .active_low = 1, |
356 | .default_trigger = "default-on" , |
357 | }, |
358 | { |
359 | .name = "stop" , |
360 | .gpio = 1, |
361 | .active_low = 1, |
362 | }, |
363 | }, |
364 | }; |
365 | |
366 | static struct board_info __initdata board_96348gw = { |
367 | .name = "96348GW" , |
368 | .expected_cpu_id = 0x6348, |
369 | |
370 | .has_ohci0 = 1, |
371 | .has_pci = 1, |
372 | .has_uart0 = 1, |
373 | |
374 | .has_enet0 = 1, |
375 | .enet0 = { |
376 | .has_phy = 1, |
377 | .use_internal_phy = 1, |
378 | }, |
379 | |
380 | .has_enet1 = 1, |
381 | .enet1 = { |
382 | .force_speed_100 = 1, |
383 | .force_duplex_full = 1, |
384 | }, |
385 | |
386 | .leds = { |
387 | { |
388 | .name = "adsl-fail" , |
389 | .gpio = 2, |
390 | .active_low = 1, |
391 | }, |
392 | { |
393 | .name = "ppp" , |
394 | .gpio = 3, |
395 | .active_low = 1, |
396 | }, |
397 | { |
398 | .name = "ppp-fail" , |
399 | .gpio = 4, |
400 | .active_low = 1, |
401 | }, |
402 | { |
403 | .name = "power" , |
404 | .gpio = 0, |
405 | .active_low = 1, |
406 | .default_trigger = "default-on" , |
407 | }, |
408 | { |
409 | .name = "stop" , |
410 | .gpio = 1, |
411 | .active_low = 1, |
412 | }, |
413 | }, |
414 | }; |
415 | |
416 | static struct board_info __initdata board_FAST2404 = { |
417 | .name = "F@ST2404" , |
418 | .expected_cpu_id = 0x6348, |
419 | |
420 | .has_ohci0 = 1, |
421 | .has_pccard = 1, |
422 | .has_pci = 1, |
423 | .has_uart0 = 1, |
424 | |
425 | .has_enet0 = 1, |
426 | .enet0 = { |
427 | .has_phy = 1, |
428 | .use_internal_phy = 1, |
429 | }, |
430 | |
431 | .has_enet1 = 1, |
432 | .enet1 = { |
433 | .force_speed_100 = 1, |
434 | .force_duplex_full = 1, |
435 | }, |
436 | }; |
437 | |
438 | static struct board_info __initdata board_rta1025w_16 = { |
439 | .name = "RTA1025W_16" , |
440 | .expected_cpu_id = 0x6348, |
441 | |
442 | .has_pci = 1, |
443 | |
444 | .has_enet0 = 1, |
445 | .enet0 = { |
446 | .has_phy = 1, |
447 | .use_internal_phy = 1, |
448 | }, |
449 | |
450 | .has_enet1 = 1, |
451 | .enet1 = { |
452 | .force_speed_100 = 1, |
453 | .force_duplex_full = 1, |
454 | }, |
455 | }; |
456 | |
457 | static struct board_info __initdata board_DV201AMR = { |
458 | .name = "DV201AMR" , |
459 | .expected_cpu_id = 0x6348, |
460 | |
461 | .has_ohci0 = 1, |
462 | .has_pci = 1, |
463 | .has_uart0 = 1, |
464 | |
465 | .has_enet0 = 1, |
466 | .enet0 = { |
467 | .has_phy = 1, |
468 | .use_internal_phy = 1, |
469 | }, |
470 | |
471 | .has_enet1 = 1, |
472 | .enet1 = { |
473 | .force_speed_100 = 1, |
474 | .force_duplex_full = 1, |
475 | }, |
476 | }; |
477 | |
478 | static struct board_info __initdata board_96348gw_a = { |
479 | .name = "96348GW-A" , |
480 | .expected_cpu_id = 0x6348, |
481 | |
482 | .has_ohci0 = 1, |
483 | .has_pci = 1, |
484 | .has_uart0 = 1, |
485 | |
486 | .has_enet0 = 1, |
487 | .enet0 = { |
488 | .has_phy = 1, |
489 | .use_internal_phy = 1, |
490 | }, |
491 | |
492 | .has_enet1 = 1, |
493 | .enet1 = { |
494 | .force_speed_100 = 1, |
495 | .force_duplex_full = 1, |
496 | }, |
497 | }; |
498 | #endif /* CONFIG_BCM63XX_CPU_6348 */ |
499 | |
500 | /* |
501 | * known 6358 boards |
502 | */ |
503 | #ifdef CONFIG_BCM63XX_CPU_6358 |
504 | static struct board_info __initdata board_96358vw = { |
505 | .name = "96358VW" , |
506 | .expected_cpu_id = 0x6358, |
507 | |
508 | .has_ehci0 = 1, |
509 | .has_ohci0 = 1, |
510 | .has_pccard = 1, |
511 | .has_pci = 1, |
512 | .has_uart0 = 1, |
513 | |
514 | .has_enet0 = 1, |
515 | .enet0 = { |
516 | .has_phy = 1, |
517 | .use_internal_phy = 1, |
518 | }, |
519 | |
520 | .has_enet1 = 1, |
521 | .enet1 = { |
522 | .force_speed_100 = 1, |
523 | .force_duplex_full = 1, |
524 | }, |
525 | |
526 | .leds = { |
527 | { |
528 | .name = "adsl-fail" , |
529 | .gpio = 15, |
530 | .active_low = 1, |
531 | }, |
532 | { |
533 | .name = "ppp" , |
534 | .gpio = 22, |
535 | .active_low = 1, |
536 | }, |
537 | { |
538 | .name = "ppp-fail" , |
539 | .gpio = 23, |
540 | .active_low = 1, |
541 | }, |
542 | { |
543 | .name = "power" , |
544 | .gpio = 4, |
545 | .default_trigger = "default-on" , |
546 | }, |
547 | { |
548 | .name = "stop" , |
549 | .gpio = 5, |
550 | }, |
551 | }, |
552 | }; |
553 | |
554 | static struct board_info __initdata board_96358vw2 = { |
555 | .name = "96358VW2" , |
556 | .expected_cpu_id = 0x6358, |
557 | |
558 | .has_ehci0 = 1, |
559 | .has_ohci0 = 1, |
560 | .has_pccard = 1, |
561 | .has_pci = 1, |
562 | .has_uart0 = 1, |
563 | |
564 | .has_enet0 = 1, |
565 | .enet0 = { |
566 | .has_phy = 1, |
567 | .use_internal_phy = 1, |
568 | }, |
569 | |
570 | .has_enet1 = 1, |
571 | .enet1 = { |
572 | .force_speed_100 = 1, |
573 | .force_duplex_full = 1, |
574 | }, |
575 | |
576 | .leds = { |
577 | { |
578 | .name = "adsl" , |
579 | .gpio = 22, |
580 | .active_low = 1, |
581 | }, |
582 | { |
583 | .name = "ppp-fail" , |
584 | .gpio = 23, |
585 | }, |
586 | { |
587 | .name = "power" , |
588 | .gpio = 5, |
589 | .active_low = 1, |
590 | .default_trigger = "default-on" , |
591 | }, |
592 | { |
593 | .name = "stop" , |
594 | .gpio = 4, |
595 | .active_low = 1, |
596 | }, |
597 | }, |
598 | }; |
599 | |
600 | static struct board_info __initdata board_AGPFS0 = { |
601 | .name = "AGPF-S0" , |
602 | .expected_cpu_id = 0x6358, |
603 | |
604 | .has_ehci0 = 1, |
605 | .has_ohci0 = 1, |
606 | .has_pci = 1, |
607 | .has_uart0 = 1, |
608 | |
609 | .has_enet0 = 1, |
610 | .enet0 = { |
611 | .has_phy = 1, |
612 | .use_internal_phy = 1, |
613 | }, |
614 | |
615 | .has_enet1 = 1, |
616 | .enet1 = { |
617 | .force_speed_100 = 1, |
618 | .force_duplex_full = 1, |
619 | }, |
620 | }; |
621 | |
622 | static struct board_info __initdata board_DWVS0 = { |
623 | .name = "DWV-S0" , |
624 | .expected_cpu_id = 0x6358, |
625 | |
626 | .has_ehci0 = 1, |
627 | .has_ohci0 = 1, |
628 | .has_pci = 1, |
629 | |
630 | .has_enet0 = 1, |
631 | .enet0 = { |
632 | .has_phy = 1, |
633 | .use_internal_phy = 1, |
634 | }, |
635 | |
636 | .has_enet1 = 1, |
637 | .enet1 = { |
638 | .force_speed_100 = 1, |
639 | .force_duplex_full = 1, |
640 | }, |
641 | }; |
642 | #endif /* CONFIG_BCM63XX_CPU_6358 */ |
643 | |
644 | /* |
645 | * all boards |
646 | */ |
647 | static const struct board_info __initconst *bcm963xx_boards[] = { |
648 | #ifdef CONFIG_BCM63XX_CPU_3368 |
649 | &board_cvg834g, |
650 | #endif /* CONFIG_BCM63XX_CPU_3368 */ |
651 | #ifdef CONFIG_BCM63XX_CPU_6328 |
652 | &board_96328avng, |
653 | #endif /* CONFIG_BCM63XX_CPU_6328 */ |
654 | #ifdef CONFIG_BCM63XX_CPU_6338 |
655 | &board_96338gw, |
656 | &board_96338w, |
657 | #endif /* CONFIG_BCM63XX_CPU_6338 */ |
658 | #ifdef CONFIG_BCM63XX_CPU_6345 |
659 | &board_96345gw2, |
660 | #endif /* CONFIG_BCM63XX_CPU_6345 */ |
661 | #ifdef CONFIG_BCM63XX_CPU_6348 |
662 | &board_96348r, |
663 | &board_96348gw, |
664 | &board_96348gw_10, |
665 | &board_96348gw_11, |
666 | &board_FAST2404, |
667 | &board_DV201AMR, |
668 | &board_96348gw_a, |
669 | &board_rta1025w_16, |
670 | #endif /* CONFIG_BCM63XX_CPU_6348 */ |
671 | #ifdef CONFIG_BCM63XX_CPU_6358 |
672 | &board_96358vw, |
673 | &board_96358vw2, |
674 | &board_AGPFS0, |
675 | &board_DWVS0, |
676 | #endif /* CONFIG_BCM63XX_CPU_6358 */ |
677 | }; |
678 | |
679 | /* |
680 | * Register a sane SPROMv2 to make the on-board |
681 | * bcm4318 WLAN work |
682 | */ |
683 | #ifdef CONFIG_SSB_PCIHOST |
684 | static struct ssb_sprom bcm63xx_sprom = { |
685 | .revision = 0x02, |
686 | .board_rev = 0x17, |
687 | .country_code = 0x0, |
688 | .ant_available_bg = 0x3, |
689 | .pa0b0 = 0x15ae, |
690 | .pa0b1 = 0xfa85, |
691 | .pa0b2 = 0xfe8d, |
692 | .pa1b0 = 0xffff, |
693 | .pa1b1 = 0xffff, |
694 | .pa1b2 = 0xffff, |
695 | .gpio0 = 0xff, |
696 | .gpio1 = 0xff, |
697 | .gpio2 = 0xff, |
698 | .gpio3 = 0xff, |
699 | .maxpwr_bg = 0x004c, |
700 | .itssi_bg = 0x00, |
701 | .boardflags_lo = 0x2848, |
702 | .boardflags_hi = 0x0000, |
703 | }; |
704 | |
705 | static int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) |
706 | { |
707 | if (bus->bustype == SSB_BUSTYPE_PCI) { |
708 | memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom)); |
709 | return 0; |
710 | } else { |
711 | pr_err("unable to fill SPROM for given bustype\n" ); |
712 | return -EINVAL; |
713 | } |
714 | } |
715 | #endif /* CONFIG_SSB_PCIHOST */ |
716 | |
717 | /* |
718 | * return board name for /proc/cpuinfo |
719 | */ |
720 | const char *board_get_name(void) |
721 | { |
722 | return board.name; |
723 | } |
724 | |
725 | /* |
726 | * early init callback, read nvram data from flash and checksum it |
727 | */ |
728 | void __init board_prom_init(void) |
729 | { |
730 | unsigned int i; |
731 | u8 *boot_addr, *cfe; |
732 | char cfe_version[32]; |
733 | char *board_name = NULL; |
734 | u32 val; |
735 | struct bcm_hcs *hcs; |
736 | |
737 | /* read base address of boot chip select (0) |
738 | * 6328/6362 do not have MPI but boot from a fixed address |
739 | */ |
740 | if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) { |
741 | val = 0x18000000; |
742 | } else { |
743 | val = bcm_mpi_readl(MPI_CSBASE_REG(0)); |
744 | val &= MPI_CSBASE_BASE_MASK; |
745 | } |
746 | boot_addr = (u8 *)KSEG1ADDR(val); |
747 | |
748 | /* dump cfe version */ |
749 | cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET; |
750 | if (strstarts(str: cfe, prefix: "cfe-" )) { |
751 | if(cfe[4] == 'v') { |
752 | if(cfe[5] == 'd') |
753 | snprintf(buf: cfe_version, size: 11, fmt: "%s" , |
754 | (char *) &cfe[5]); |
755 | else if (cfe[10] > 0) |
756 | snprintf(buf: cfe_version, size: sizeof(cfe_version), |
757 | fmt: "%u.%u.%u-%u.%u-%u" , cfe[5], cfe[6], |
758 | cfe[7], cfe[8], cfe[9], cfe[10]); |
759 | else |
760 | snprintf(buf: cfe_version, size: sizeof(cfe_version), |
761 | fmt: "%u.%u.%u-%u.%u" , cfe[5], cfe[6], |
762 | cfe[7], cfe[8], cfe[9]); |
763 | } else { |
764 | snprintf(buf: cfe_version, size: 12, fmt: "%s" , (char *) &cfe[4]); |
765 | } |
766 | } else { |
767 | strcpy(p: cfe_version, q: "unknown" ); |
768 | } |
769 | pr_info("CFE version: %s\n" , cfe_version); |
770 | |
771 | bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); |
772 | |
773 | if (BCMCPU_IS_3368()) { |
774 | hcs = (struct bcm_hcs *)boot_addr; |
775 | board_name = hcs->filename; |
776 | } else { |
777 | board_name = bcm63xx_nvram_get_name(); |
778 | } |
779 | /* find board by name */ |
780 | for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { |
781 | if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) |
782 | continue; |
783 | /* copy, board desc array is marked initdata */ |
784 | memcpy(&board, bcm963xx_boards[i], sizeof(board)); |
785 | break; |
786 | } |
787 | |
788 | /* bail out if board is not found, will complain later */ |
789 | if (!board.name[0]) { |
790 | char name[17]; |
791 | memcpy(name, board_name, 16); |
792 | name[16] = 0; |
793 | pr_err("unknown bcm963xx board: %s\n" , name); |
794 | return; |
795 | } |
796 | |
797 | /* setup pin multiplexing depending on board enabled device, |
798 | * this has to be done this early since PCI init is done |
799 | * inside arch_initcall */ |
800 | val = 0; |
801 | |
802 | #ifdef CONFIG_PCI |
803 | if (board.has_pci) { |
804 | bcm63xx_pci_enabled = 1; |
805 | if (BCMCPU_IS_6348()) |
806 | val |= GPIO_MODE_6348_G2_PCI; |
807 | } |
808 | #endif /* CONFIG_PCI */ |
809 | |
810 | if (board.has_pccard) { |
811 | if (BCMCPU_IS_6348()) |
812 | val |= GPIO_MODE_6348_G1_MII_PCCARD; |
813 | } |
814 | |
815 | if (board.has_enet0 && !board.enet0.use_internal_phy) { |
816 | if (BCMCPU_IS_6348()) |
817 | val |= GPIO_MODE_6348_G3_EXT_MII | |
818 | GPIO_MODE_6348_G0_EXT_MII; |
819 | } |
820 | |
821 | if (board.has_enet1 && !board.enet1.use_internal_phy) { |
822 | if (BCMCPU_IS_6348()) |
823 | val |= GPIO_MODE_6348_G3_EXT_MII | |
824 | GPIO_MODE_6348_G0_EXT_MII; |
825 | } |
826 | |
827 | bcm_gpio_writel(val, GPIO_MODE_REG); |
828 | } |
829 | |
830 | /* |
831 | * second stage init callback, good time to panic if we couldn't |
832 | * identify on which board we're running since early printk is working |
833 | */ |
834 | void __init board_setup(void) |
835 | { |
836 | if (!board.name[0]) |
837 | panic(fmt: "unable to detect bcm963xx board" ); |
838 | pr_info("board name: %s\n" , board.name); |
839 | |
840 | /* make sure we're running on expected cpu */ |
841 | if (bcm63xx_get_cpu_id() != board.expected_cpu_id) |
842 | panic(fmt: "unexpected CPU for bcm963xx board" ); |
843 | } |
844 | |
845 | static struct gpio_led_platform_data bcm63xx_led_data; |
846 | |
847 | static struct platform_device bcm63xx_gpio_leds = { |
848 | .name = "leds-gpio" , |
849 | .id = 0, |
850 | .dev.platform_data = &bcm63xx_led_data, |
851 | }; |
852 | |
853 | /* |
854 | * third stage init callback, register all board devices. |
855 | */ |
856 | int __init board_register_devices(void) |
857 | { |
858 | if (board.has_uart0) |
859 | bcm63xx_uart_register(0); |
860 | |
861 | if (board.has_uart1) |
862 | bcm63xx_uart_register(1); |
863 | |
864 | if (board.has_pccard) |
865 | bcm63xx_pcmcia_register(); |
866 | |
867 | if (board.has_enet0 && |
868 | !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) |
869 | bcm63xx_enet_register(0, &board.enet0); |
870 | |
871 | if (board.has_enet1 && |
872 | !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) |
873 | bcm63xx_enet_register(1, &board.enet1); |
874 | |
875 | if (board.has_enetsw && |
876 | !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr)) |
877 | bcm63xx_enetsw_register(&board.enetsw); |
878 | |
879 | if (board.has_usbd) |
880 | bcm63xx_usbd_register(&board.usbd); |
881 | |
882 | /* Generate MAC address for WLAN and register our SPROM, |
883 | * do this after registering enet devices |
884 | */ |
885 | #ifdef CONFIG_SSB_PCIHOST |
886 | if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { |
887 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
888 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
889 | if (ssb_arch_register_fallback_sprom( |
890 | sprom_callback: &bcm63xx_get_fallback_sprom) < 0) |
891 | pr_err("failed to register fallback SPROM\n" ); |
892 | } |
893 | #endif /* CONFIG_SSB_PCIHOST */ |
894 | |
895 | bcm63xx_spi_register(); |
896 | |
897 | bcm63xx_hsspi_register(); |
898 | |
899 | bcm63xx_flash_register(); |
900 | |
901 | bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); |
902 | bcm63xx_led_data.leds = board.leds; |
903 | |
904 | platform_device_register(&bcm63xx_gpio_leds); |
905 | |
906 | if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags) |
907 | gpio_request_one(board.ephy_reset_gpio, |
908 | board.ephy_reset_gpio_flags, "ephy-reset" ); |
909 | |
910 | return 0; |
911 | } |
912 | |