blob: 9c0ddafafb6cee7116bf22638bca552c334601c4 [file] [log] [blame]
Maxime Bizone7300d02009-08-18 13:23:37 +01001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
8 */
9
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/platform_device.h>
Maxime Bizone7300d02009-08-18 13:23:37 +010014#include <linux/ssb/ssb.h>
15#include <asm/addrspace.h>
16#include <bcm63xx_board.h>
17#include <bcm63xx_cpu.h>
Maxime Bizon524ef292010-01-30 18:34:55 +010018#include <bcm63xx_dev_uart.h>
Maxime Bizone7300d02009-08-18 13:23:37 +010019#include <bcm63xx_regs.h>
20#include <bcm63xx_io.h>
Jonas Gorskie7e333c2012-11-07 08:25:28 +000021#include <bcm63xx_nvram.h>
Maxime Bizone7300d02009-08-18 13:23:37 +010022#include <bcm63xx_dev_pci.h>
23#include <bcm63xx_dev_enet.h>
24#include <bcm63xx_dev_dsp.h>
Jonas Gorski4b897d52012-07-24 16:33:11 +020025#include <bcm63xx_dev_flash.h>
Maxime Bizon553d6d52009-09-28 14:49:43 +020026#include <bcm63xx_dev_pcmcia.h>
Florian Fainelli76ca4e12012-07-04 16:58:37 +020027#include <bcm63xx_dev_spi.h>
Kevin Cernekee22df90f2012-07-14 18:01:09 +000028#include <bcm63xx_dev_usb_usbd.h>
Maxime Bizone7300d02009-08-18 13:23:37 +010029#include <board_bcm963xx.h>
30
31#define PFX "board_bcm963xx: "
32
Maxime Bizone7300d02009-08-18 13:23:37 +010033static struct board_info board;
34
35/*
Jonas Gorski2f74b772012-07-24 16:33:14 +020036 * known 6328 boards
37 */
38#ifdef CONFIG_BCM63XX_CPU_6328
39static struct board_info __initdata board_96328avng = {
40 .name = "96328avng",
41 .expected_cpu_id = 0x6328,
42
43 .has_uart0 = 1,
44 .has_pci = 1,
Kevin Cernekee22df90f2012-07-14 18:01:09 +000045 .has_usbd = 0,
46
47 .usbd = {
48 .use_fullspeed = 0,
49 .port_no = 0,
50 },
Jonas Gorski2f74b772012-07-24 16:33:14 +020051
52 .leds = {
53 {
54 .name = "96328avng::ppp-fail",
55 .gpio = 2,
56 .active_low = 1,
57 },
58 {
59 .name = "96328avng::power",
60 .gpio = 4,
61 .active_low = 1,
62 .default_trigger = "default-on",
63 },
64 {
65 .name = "96328avng::power-fail",
66 .gpio = 8,
67 .active_low = 1,
68 },
69 {
70 .name = "96328avng::wps",
71 .gpio = 9,
72 .active_low = 1,
73 },
74 {
75 .name = "96328avng::ppp",
76 .gpio = 11,
77 .active_low = 1,
78 },
79 },
80};
81#endif
82
83/*
Maxime Bizone7300d02009-08-18 13:23:37 +010084 * known 6338 boards
85 */
86#ifdef CONFIG_BCM63XX_CPU_6338
87static struct board_info __initdata board_96338gw = {
88 .name = "96338GW",
89 .expected_cpu_id = 0x6338,
90
Maxime Bizon524ef292010-01-30 18:34:55 +010091 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +010092 .has_enet0 = 1,
93 .enet0 = {
94 .force_speed_100 = 1,
95 .force_duplex_full = 1,
96 },
97
98 .has_ohci0 = 1,
99
100 .leds = {
101 {
102 .name = "adsl",
103 .gpio = 3,
104 .active_low = 1,
105 },
106 {
107 .name = "ses",
108 .gpio = 5,
109 .active_low = 1,
110 },
111 {
112 .name = "ppp-fail",
113 .gpio = 4,
114 .active_low = 1,
115 },
116 {
117 .name = "power",
118 .gpio = 0,
119 .active_low = 1,
120 .default_trigger = "default-on",
121 },
122 {
123 .name = "stop",
124 .gpio = 1,
125 .active_low = 1,
126 }
127 },
128};
129
130static struct board_info __initdata board_96338w = {
131 .name = "96338W",
132 .expected_cpu_id = 0x6338,
133
Maxime Bizon524ef292010-01-30 18:34:55 +0100134 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100135 .has_enet0 = 1,
136 .enet0 = {
137 .force_speed_100 = 1,
138 .force_duplex_full = 1,
139 },
140
141 .leds = {
142 {
143 .name = "adsl",
144 .gpio = 3,
145 .active_low = 1,
146 },
147 {
148 .name = "ses",
149 .gpio = 5,
150 .active_low = 1,
151 },
152 {
153 .name = "ppp-fail",
154 .gpio = 4,
155 .active_low = 1,
156 },
157 {
158 .name = "power",
159 .gpio = 0,
160 .active_low = 1,
161 .default_trigger = "default-on",
162 },
163 {
164 .name = "stop",
165 .gpio = 1,
166 .active_low = 1,
167 },
168 },
169};
170#endif
171
172/*
173 * known 6345 boards
174 */
175#ifdef CONFIG_BCM63XX_CPU_6345
176static struct board_info __initdata board_96345gw2 = {
177 .name = "96345GW2",
178 .expected_cpu_id = 0x6345,
Maxime Bizon524ef292010-01-30 18:34:55 +0100179
180 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100181};
182#endif
183
184/*
185 * known 6348 boards
186 */
187#ifdef CONFIG_BCM63XX_CPU_6348
188static struct board_info __initdata board_96348r = {
189 .name = "96348R",
190 .expected_cpu_id = 0x6348,
191
Maxime Bizon524ef292010-01-30 18:34:55 +0100192 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100193 .has_enet0 = 1,
194 .has_pci = 1,
195
196 .enet0 = {
197 .has_phy = 1,
198 .use_internal_phy = 1,
199 },
200
201 .leds = {
202 {
203 .name = "adsl-fail",
204 .gpio = 2,
205 .active_low = 1,
206 },
207 {
208 .name = "ppp",
209 .gpio = 3,
210 .active_low = 1,
211 },
212 {
213 .name = "ppp-fail",
214 .gpio = 4,
215 .active_low = 1,
216 },
217 {
218 .name = "power",
219 .gpio = 0,
220 .active_low = 1,
221 .default_trigger = "default-on",
222
223 },
224 {
225 .name = "stop",
226 .gpio = 1,
227 .active_low = 1,
228 },
229 },
230};
231
232static struct board_info __initdata board_96348gw_10 = {
233 .name = "96348GW-10",
234 .expected_cpu_id = 0x6348,
235
Maxime Bizon524ef292010-01-30 18:34:55 +0100236 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100237 .has_enet0 = 1,
238 .has_enet1 = 1,
239 .has_pci = 1,
240
241 .enet0 = {
242 .has_phy = 1,
243 .use_internal_phy = 1,
244 },
245 .enet1 = {
246 .force_speed_100 = 1,
247 .force_duplex_full = 1,
248 },
249
250 .has_ohci0 = 1,
251 .has_pccard = 1,
252 .has_ehci0 = 1,
253
254 .has_dsp = 1,
255 .dsp = {
256 .gpio_rst = 6,
257 .gpio_int = 34,
258 .cs = 2,
259 .ext_irq = 2,
260 },
261
262 .leds = {
263 {
264 .name = "adsl-fail",
265 .gpio = 2,
266 .active_low = 1,
267 },
268 {
269 .name = "ppp",
270 .gpio = 3,
271 .active_low = 1,
272 },
273 {
274 .name = "ppp-fail",
275 .gpio = 4,
276 .active_low = 1,
277 },
278 {
279 .name = "power",
280 .gpio = 0,
281 .active_low = 1,
282 .default_trigger = "default-on",
283 },
284 {
285 .name = "stop",
286 .gpio = 1,
287 .active_low = 1,
288 },
289 },
290};
291
292static struct board_info __initdata board_96348gw_11 = {
293 .name = "96348GW-11",
294 .expected_cpu_id = 0x6348,
295
Maxime Bizon524ef292010-01-30 18:34:55 +0100296 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100297 .has_enet0 = 1,
298 .has_enet1 = 1,
299 .has_pci = 1,
300
301 .enet0 = {
302 .has_phy = 1,
303 .use_internal_phy = 1,
304 },
305
306 .enet1 = {
307 .force_speed_100 = 1,
308 .force_duplex_full = 1,
309 },
310
311
312 .has_ohci0 = 1,
313 .has_pccard = 1,
314 .has_ehci0 = 1,
315
316 .leds = {
317 {
318 .name = "adsl-fail",
319 .gpio = 2,
320 .active_low = 1,
321 },
322 {
323 .name = "ppp",
324 .gpio = 3,
325 .active_low = 1,
326 },
327 {
328 .name = "ppp-fail",
329 .gpio = 4,
330 .active_low = 1,
331 },
332 {
333 .name = "power",
334 .gpio = 0,
335 .active_low = 1,
336 .default_trigger = "default-on",
337 },
338 {
339 .name = "stop",
340 .gpio = 1,
341 .active_low = 1,
342 },
343 },
344};
345
346static struct board_info __initdata board_96348gw = {
347 .name = "96348GW",
348 .expected_cpu_id = 0x6348,
349
Maxime Bizon524ef292010-01-30 18:34:55 +0100350 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100351 .has_enet0 = 1,
352 .has_enet1 = 1,
353 .has_pci = 1,
354
355 .enet0 = {
356 .has_phy = 1,
357 .use_internal_phy = 1,
358 },
359 .enet1 = {
360 .force_speed_100 = 1,
361 .force_duplex_full = 1,
362 },
363
364 .has_ohci0 = 1,
365
366 .has_dsp = 1,
367 .dsp = {
368 .gpio_rst = 6,
369 .gpio_int = 34,
370 .ext_irq = 2,
371 .cs = 2,
372 },
373
374 .leds = {
375 {
376 .name = "adsl-fail",
377 .gpio = 2,
378 .active_low = 1,
379 },
380 {
381 .name = "ppp",
382 .gpio = 3,
383 .active_low = 1,
384 },
385 {
386 .name = "ppp-fail",
387 .gpio = 4,
388 .active_low = 1,
389 },
390 {
391 .name = "power",
392 .gpio = 0,
393 .active_low = 1,
394 .default_trigger = "default-on",
395 },
396 {
397 .name = "stop",
398 .gpio = 1,
399 .active_low = 1,
400 },
401 },
402};
403
404static struct board_info __initdata board_FAST2404 = {
Florian Fainelli05c69462009-12-12 17:57:39 +0100405 .name = "F@ST2404",
406 .expected_cpu_id = 0x6348,
Maxime Bizone7300d02009-08-18 13:23:37 +0100407
Maxime Bizon524ef292010-01-30 18:34:55 +0100408 .has_uart0 = 1,
Ralf Baechle70342282013-01-22 12:59:30 +0100409 .has_enet0 = 1,
410 .has_enet1 = 1,
411 .has_pci = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100412
Florian Fainelli05c69462009-12-12 17:57:39 +0100413 .enet0 = {
414 .has_phy = 1,
415 .use_internal_phy = 1,
416 },
Maxime Bizone7300d02009-08-18 13:23:37 +0100417
Florian Fainelli05c69462009-12-12 17:57:39 +0100418 .enet1 = {
419 .force_speed_100 = 1,
420 .force_duplex_full = 1,
421 },
Maxime Bizone7300d02009-08-18 13:23:37 +0100422
Florian Fainelli05c69462009-12-12 17:57:39 +0100423 .has_ohci0 = 1,
424 .has_pccard = 1,
425 .has_ehci0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100426};
427
Florian Fainelli2e6ad9a2010-03-01 23:36:22 +0100428static struct board_info __initdata board_rta1025w_16 = {
429 .name = "RTA1025W_16",
430 .expected_cpu_id = 0x6348,
431
432 .has_enet0 = 1,
433 .has_enet1 = 1,
434 .has_pci = 1,
435
436 .enet0 = {
437 .has_phy = 1,
438 .use_internal_phy = 1,
439 },
440 .enet1 = {
441 .force_speed_100 = 1,
442 .force_duplex_full = 1,
443 },
444};
445
446
Maxime Bizone7300d02009-08-18 13:23:37 +0100447static struct board_info __initdata board_DV201AMR = {
448 .name = "DV201AMR",
449 .expected_cpu_id = 0x6348,
450
Maxime Bizon524ef292010-01-30 18:34:55 +0100451 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100452 .has_pci = 1,
453 .has_ohci0 = 1,
454
455 .has_enet0 = 1,
456 .has_enet1 = 1,
457 .enet0 = {
458 .has_phy = 1,
459 .use_internal_phy = 1,
460 },
461 .enet1 = {
462 .force_speed_100 = 1,
463 .force_duplex_full = 1,
464 },
465};
466
467static struct board_info __initdata board_96348gw_a = {
468 .name = "96348GW-A",
469 .expected_cpu_id = 0x6348,
470
Maxime Bizon524ef292010-01-30 18:34:55 +0100471 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100472 .has_enet0 = 1,
473 .has_enet1 = 1,
474 .has_pci = 1,
475
476 .enet0 = {
477 .has_phy = 1,
478 .use_internal_phy = 1,
479 },
480 .enet1 = {
481 .force_speed_100 = 1,
482 .force_duplex_full = 1,
483 },
484
485 .has_ohci0 = 1,
486};
487#endif
488
489/*
490 * known 6358 boards
491 */
492#ifdef CONFIG_BCM63XX_CPU_6358
493static struct board_info __initdata board_96358vw = {
494 .name = "96358VW",
495 .expected_cpu_id = 0x6358,
496
Maxime Bizon524ef292010-01-30 18:34:55 +0100497 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100498 .has_enet0 = 1,
499 .has_enet1 = 1,
500 .has_pci = 1,
501
502 .enet0 = {
503 .has_phy = 1,
504 .use_internal_phy = 1,
505 },
506
507 .enet1 = {
508 .force_speed_100 = 1,
509 .force_duplex_full = 1,
510 },
511
512
513 .has_ohci0 = 1,
514 .has_pccard = 1,
515 .has_ehci0 = 1,
516
517 .leds = {
518 {
519 .name = "adsl-fail",
520 .gpio = 15,
521 .active_low = 1,
522 },
523 {
524 .name = "ppp",
525 .gpio = 22,
526 .active_low = 1,
527 },
528 {
529 .name = "ppp-fail",
530 .gpio = 23,
531 .active_low = 1,
532 },
533 {
534 .name = "power",
535 .gpio = 4,
536 .default_trigger = "default-on",
537 },
538 {
539 .name = "stop",
540 .gpio = 5,
541 },
542 },
543};
544
545static struct board_info __initdata board_96358vw2 = {
546 .name = "96358VW2",
547 .expected_cpu_id = 0x6358,
548
Maxime Bizon524ef292010-01-30 18:34:55 +0100549 .has_uart0 = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100550 .has_enet0 = 1,
551 .has_enet1 = 1,
552 .has_pci = 1,
553
554 .enet0 = {
555 .has_phy = 1,
556 .use_internal_phy = 1,
557 },
558
559 .enet1 = {
560 .force_speed_100 = 1,
561 .force_duplex_full = 1,
562 },
563
564
565 .has_ohci0 = 1,
566 .has_pccard = 1,
567 .has_ehci0 = 1,
568
569 .leds = {
570 {
571 .name = "adsl",
572 .gpio = 22,
573 .active_low = 1,
574 },
575 {
576 .name = "ppp-fail",
577 .gpio = 23,
578 },
579 {
580 .name = "power",
581 .gpio = 5,
582 .active_low = 1,
583 .default_trigger = "default-on",
584 },
585 {
586 .name = "stop",
587 .gpio = 4,
588 .active_low = 1,
589 },
590 },
591};
592
593static struct board_info __initdata board_AGPFS0 = {
Ralf Baechle70342282013-01-22 12:59:30 +0100594 .name = "AGPF-S0",
595 .expected_cpu_id = 0x6358,
Maxime Bizone7300d02009-08-18 13:23:37 +0100596
Maxime Bizon524ef292010-01-30 18:34:55 +0100597 .has_uart0 = 1,
Ralf Baechle70342282013-01-22 12:59:30 +0100598 .has_enet0 = 1,
599 .has_enet1 = 1,
600 .has_pci = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100601
602 .enet0 = {
Ralf Baechle70342282013-01-22 12:59:30 +0100603 .has_phy = 1,
604 .use_internal_phy = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100605 },
606
607 .enet1 = {
Ralf Baechle70342282013-01-22 12:59:30 +0100608 .force_speed_100 = 1,
609 .force_duplex_full = 1,
Maxime Bizone7300d02009-08-18 13:23:37 +0100610 },
611
612 .has_ohci0 = 1,
613 .has_ehci0 = 1,
614};
Florian Fainellif29b7ca2010-03-01 23:36:27 +0100615
616static struct board_info __initdata board_DWVS0 = {
617 .name = "DWV-S0",
618 .expected_cpu_id = 0x6358,
619
620 .has_enet0 = 1,
621 .has_enet1 = 1,
622 .has_pci = 1,
623
624 .enet0 = {
625 .has_phy = 1,
626 .use_internal_phy = 1,
627 },
628
629 .enet1 = {
630 .force_speed_100 = 1,
631 .force_duplex_full = 1,
632 },
633
634 .has_ohci0 = 1,
635};
Maxime Bizone7300d02009-08-18 13:23:37 +0100636#endif
637
638/*
639 * all boards
640 */
Andi Kleen3cf5ae62012-10-04 17:11:35 -0700641static const struct board_info __initconst *bcm963xx_boards[] = {
Jonas Gorski2f74b772012-07-24 16:33:14 +0200642#ifdef CONFIG_BCM63XX_CPU_6328
643 &board_96328avng,
644#endif
Maxime Bizone7300d02009-08-18 13:23:37 +0100645#ifdef CONFIG_BCM63XX_CPU_6338
646 &board_96338gw,
647 &board_96338w,
648#endif
649#ifdef CONFIG_BCM63XX_CPU_6345
650 &board_96345gw2,
651#endif
652#ifdef CONFIG_BCM63XX_CPU_6348
653 &board_96348r,
654 &board_96348gw,
655 &board_96348gw_10,
656 &board_96348gw_11,
657 &board_FAST2404,
658 &board_DV201AMR,
659 &board_96348gw_a,
Florian Fainelli2e6ad9a2010-03-01 23:36:22 +0100660 &board_rta1025w_16,
Maxime Bizone7300d02009-08-18 13:23:37 +0100661#endif
662
663#ifdef CONFIG_BCM63XX_CPU_6358
664 &board_96358vw,
665 &board_96358vw2,
666 &board_AGPFS0,
Florian Fainellif29b7ca2010-03-01 23:36:27 +0100667 &board_DWVS0,
Maxime Bizone7300d02009-08-18 13:23:37 +0100668#endif
669};
670
671/*
Florian Fainelli5e3644a2010-03-23 10:30:08 +0100672 * Register a sane SPROMv2 to make the on-board
673 * bcm4318 WLAN work
674 */
675#ifdef CONFIG_SSB_PCIHOST
676static struct ssb_sprom bcm63xx_sprom = {
677 .revision = 0x02,
678 .board_rev = 0x17,
679 .country_code = 0x0,
Ralf Baechle70342282013-01-22 12:59:30 +0100680 .ant_available_bg = 0x3,
Florian Fainelli5e3644a2010-03-23 10:30:08 +0100681 .pa0b0 = 0x15ae,
682 .pa0b1 = 0xfa85,
683 .pa0b2 = 0xfe8d,
684 .pa1b0 = 0xffff,
685 .pa1b1 = 0xffff,
686 .pa1b2 = 0xffff,
687 .gpio0 = 0xff,
688 .gpio1 = 0xff,
689 .gpio2 = 0xff,
690 .gpio3 = 0xff,
691 .maxpwr_bg = 0x004c,
692 .itssi_bg = 0x00,
693 .boardflags_lo = 0x2848,
694 .boardflags_hi = 0x0000,
695};
Hauke Mehrtensb3ae52b2011-05-10 23:31:30 +0200696
697int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
698{
699 if (bus->bustype == SSB_BUSTYPE_PCI) {
700 memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
701 return 0;
702 } else {
703 printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
704 return -EINVAL;
705 }
706}
Florian Fainelli5e3644a2010-03-23 10:30:08 +0100707#endif
708
709/*
710 * return board name for /proc/cpuinfo
711 */
712const char *board_get_name(void)
713{
714 return board.name;
715}
716
717/*
Maxime Bizone7300d02009-08-18 13:23:37 +0100718 * early init callback, read nvram data from flash and checksum it
719 */
720void __init board_prom_init(void)
721{
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000722 unsigned int i;
723 u8 *boot_addr, *cfe;
Maxime Bizone7300d02009-08-18 13:23:37 +0100724 char cfe_version[32];
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000725 char *board_name;
Maxime Bizone7300d02009-08-18 13:23:37 +0100726 u32 val;
727
Jonas Gorskie5766ae2012-07-24 16:33:12 +0200728 /* read base address of boot chip select (0)
Jonas Gorski2c8aaf72013-03-21 14:03:17 +0000729 * 6328/6362 do not have MPI but boot from a fixed address
Jonas Gorskie5766ae2012-07-24 16:33:12 +0200730 */
Jonas Gorski2c8aaf72013-03-21 14:03:17 +0000731 if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
Jonas Gorskie5766ae2012-07-24 16:33:12 +0200732 val = 0x18000000;
Jonas Gorski2c8aaf72013-03-21 14:03:17 +0000733 } else {
Jonas Gorskie5766ae2012-07-24 16:33:12 +0200734 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
735 val &= MPI_CSBASE_BASE_MASK;
736 }
Maxime Bizone7300d02009-08-18 13:23:37 +0100737 boot_addr = (u8 *)KSEG1ADDR(val);
738
739 /* dump cfe version */
740 cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
741 if (!memcmp(cfe, "cfe-v", 5))
742 snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
743 cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
744 else
745 strcpy(cfe_version, "unknown");
746 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
747
Jonas Gorski97367512013-03-19 13:08:27 +0000748 bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
Maxime Bizone7300d02009-08-18 13:23:37 +0100749
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000750 board_name = bcm63xx_nvram_get_name();
Maxime Bizone7300d02009-08-18 13:23:37 +0100751 /* find board by name */
752 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000753 if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
Maxime Bizone7300d02009-08-18 13:23:37 +0100754 continue;
755 /* copy, board desc array is marked initdata */
756 memcpy(&board, bcm963xx_boards[i], sizeof(board));
757 break;
758 }
759
760 /* bail out if board is not found, will complain later */
761 if (!board.name[0]) {
762 char name[17];
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000763 memcpy(name, board_name, 16);
Maxime Bizone7300d02009-08-18 13:23:37 +0100764 name[16] = 0;
765 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
766 name);
767 return;
768 }
769
770 /* setup pin multiplexing depending on board enabled device,
771 * this has to be done this early since PCI init is done
772 * inside arch_initcall */
773 val = 0;
774
775#ifdef CONFIG_PCI
776 if (board.has_pci) {
777 bcm63xx_pci_enabled = 1;
778 if (BCMCPU_IS_6348())
779 val |= GPIO_MODE_6348_G2_PCI;
780 }
781#endif
782
783 if (board.has_pccard) {
784 if (BCMCPU_IS_6348())
785 val |= GPIO_MODE_6348_G1_MII_PCCARD;
786 }
787
788 if (board.has_enet0 && !board.enet0.use_internal_phy) {
789 if (BCMCPU_IS_6348())
790 val |= GPIO_MODE_6348_G3_EXT_MII |
791 GPIO_MODE_6348_G0_EXT_MII;
792 }
793
794 if (board.has_enet1 && !board.enet1.use_internal_phy) {
795 if (BCMCPU_IS_6348())
796 val |= GPIO_MODE_6348_G3_EXT_MII |
797 GPIO_MODE_6348_G0_EXT_MII;
798 }
799
800 bcm_gpio_writel(val, GPIO_MODE_REG);
801}
802
803/*
804 * second stage init callback, good time to panic if we couldn't
805 * identify on which board we're running since early printk is working
806 */
807void __init board_setup(void)
808{
809 if (!board.name[0])
810 panic("unable to detect bcm963xx board");
811 printk(KERN_INFO PFX "board name: %s\n", board.name);
812
813 /* make sure we're running on expected cpu */
814 if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
815 panic("unexpected CPU for bcm963xx board");
816}
817
Maxime Bizone7300d02009-08-18 13:23:37 +0100818static struct gpio_led_platform_data bcm63xx_led_data;
819
820static struct platform_device bcm63xx_gpio_leds = {
821 .name = "leds-gpio",
822 .id = 0,
823 .dev.platform_data = &bcm63xx_led_data,
824};
825
826/*
827 * third stage init callback, register all board devices.
828 */
829int __init board_register_devices(void)
830{
Maxime Bizon524ef292010-01-30 18:34:55 +0100831 if (board.has_uart0)
832 bcm63xx_uart_register(0);
833
834 if (board.has_uart1)
835 bcm63xx_uart_register(1);
836
Maxime Bizon553d6d52009-09-28 14:49:43 +0200837 if (board.has_pccard)
838 bcm63xx_pcmcia_register();
839
Maxime Bizone7300d02009-08-18 13:23:37 +0100840 if (board.has_enet0 &&
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000841 !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
Maxime Bizone7300d02009-08-18 13:23:37 +0100842 bcm63xx_enet_register(0, &board.enet0);
843
844 if (board.has_enet1 &&
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000845 !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
Maxime Bizone7300d02009-08-18 13:23:37 +0100846 bcm63xx_enet_register(1, &board.enet1);
847
Maxime Bizon6f00a022013-06-04 22:53:35 +0100848 if (board.has_enetsw &&
849 !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr))
850 bcm63xx_enetsw_register(&board.enetsw);
851
Kevin Cernekee22df90f2012-07-14 18:01:09 +0000852 if (board.has_usbd)
853 bcm63xx_usbd_register(&board.usbd);
854
Maxime Bizone7300d02009-08-18 13:23:37 +0100855 if (board.has_dsp)
856 bcm63xx_dsp_register(&board.dsp);
857
Florian Fainellib15a6d62011-11-16 19:49:58 +0100858 /* Generate MAC address for WLAN and register our SPROM,
859 * do this after registering enet devices
860 */
861#ifdef CONFIG_SSB_PCIHOST
Jonas Gorskie7e333c2012-11-07 08:25:28 +0000862 if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
Florian Fainellib15a6d62011-11-16 19:49:58 +0100863 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
864 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
865 if (ssb_arch_register_fallback_sprom(
866 &bcm63xx_get_fallback_sprom) < 0)
867 pr_err(PFX "failed to register fallback SPROM\n");
Maxime Bizone7300d02009-08-18 13:23:37 +0100868 }
Florian Fainellib15a6d62011-11-16 19:49:58 +0100869#endif
870
Florian Fainelli76ca4e12012-07-04 16:58:37 +0200871 bcm63xx_spi_register();
872
Jonas Gorski4b897d52012-07-24 16:33:11 +0200873 bcm63xx_flash_register();
Maxime Bizone7300d02009-08-18 13:23:37 +0100874
875 bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
876 bcm63xx_led_data.leds = board.leds;
877
878 platform_device_register(&bcm63xx_gpio_leds);
879
880 return 0;
881}