Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[deliverable/linux.git] / arch / mips / bcm63xx / boards / board_bcm963xx.c
1 /*
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>
14 #include <linux/ssb/ssb.h>
15 #include <asm/addrspace.h>
16 #include <bcm63xx_board.h>
17 #include <bcm63xx_cpu.h>
18 #include <bcm63xx_dev_uart.h>
19 #include <bcm63xx_regs.h>
20 #include <bcm63xx_io.h>
21 #include <bcm63xx_nvram.h>
22 #include <bcm63xx_dev_pci.h>
23 #include <bcm63xx_dev_enet.h>
24 #include <bcm63xx_dev_dsp.h>
25 #include <bcm63xx_dev_flash.h>
26 #include <bcm63xx_dev_pcmcia.h>
27 #include <bcm63xx_dev_spi.h>
28 #include <bcm63xx_dev_usb_usbd.h>
29 #include <board_bcm963xx.h>
30
31 #define PFX "board_bcm963xx: "
32
33 static struct board_info board;
34
35 /*
36 * known 6328 boards
37 */
38 #ifdef CONFIG_BCM63XX_CPU_6328
39 static struct board_info __initdata board_96328avng = {
40 .name = "96328avng",
41 .expected_cpu_id = 0x6328,
42
43 .has_uart0 = 1,
44 .has_pci = 1,
45 .has_usbd = 0,
46
47 .usbd = {
48 .use_fullspeed = 0,
49 .port_no = 0,
50 },
51
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 /*
84 * known 6338 boards
85 */
86 #ifdef CONFIG_BCM63XX_CPU_6338
87 static struct board_info __initdata board_96338gw = {
88 .name = "96338GW",
89 .expected_cpu_id = 0x6338,
90
91 .has_uart0 = 1,
92 .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
130 static struct board_info __initdata board_96338w = {
131 .name = "96338W",
132 .expected_cpu_id = 0x6338,
133
134 .has_uart0 = 1,
135 .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
176 static struct board_info __initdata board_96345gw2 = {
177 .name = "96345GW2",
178 .expected_cpu_id = 0x6345,
179
180 .has_uart0 = 1,
181 };
182 #endif
183
184 /*
185 * known 6348 boards
186 */
187 #ifdef CONFIG_BCM63XX_CPU_6348
188 static struct board_info __initdata board_96348r = {
189 .name = "96348R",
190 .expected_cpu_id = 0x6348,
191
192 .has_uart0 = 1,
193 .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
232 static struct board_info __initdata board_96348gw_10 = {
233 .name = "96348GW-10",
234 .expected_cpu_id = 0x6348,
235
236 .has_uart0 = 1,
237 .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
292 static struct board_info __initdata board_96348gw_11 = {
293 .name = "96348GW-11",
294 .expected_cpu_id = 0x6348,
295
296 .has_uart0 = 1,
297 .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
346 static struct board_info __initdata board_96348gw = {
347 .name = "96348GW",
348 .expected_cpu_id = 0x6348,
349
350 .has_uart0 = 1,
351 .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
404 static struct board_info __initdata board_FAST2404 = {
405 .name = "F@ST2404",
406 .expected_cpu_id = 0x6348,
407
408 .has_uart0 = 1,
409 .has_enet0 = 1,
410 .has_enet1 = 1,
411 .has_pci = 1,
412
413 .enet0 = {
414 .has_phy = 1,
415 .use_internal_phy = 1,
416 },
417
418 .enet1 = {
419 .force_speed_100 = 1,
420 .force_duplex_full = 1,
421 },
422
423 .has_ohci0 = 1,
424 .has_pccard = 1,
425 .has_ehci0 = 1,
426 };
427
428 static 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
447 static struct board_info __initdata board_DV201AMR = {
448 .name = "DV201AMR",
449 .expected_cpu_id = 0x6348,
450
451 .has_uart0 = 1,
452 .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
467 static struct board_info __initdata board_96348gw_a = {
468 .name = "96348GW-A",
469 .expected_cpu_id = 0x6348,
470
471 .has_uart0 = 1,
472 .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
493 static struct board_info __initdata board_96358vw = {
494 .name = "96358VW",
495 .expected_cpu_id = 0x6358,
496
497 .has_uart0 = 1,
498 .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
545 static struct board_info __initdata board_96358vw2 = {
546 .name = "96358VW2",
547 .expected_cpu_id = 0x6358,
548
549 .has_uart0 = 1,
550 .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
593 static struct board_info __initdata board_AGPFS0 = {
594 .name = "AGPF-S0",
595 .expected_cpu_id = 0x6358,
596
597 .has_uart0 = 1,
598 .has_enet0 = 1,
599 .has_enet1 = 1,
600 .has_pci = 1,
601
602 .enet0 = {
603 .has_phy = 1,
604 .use_internal_phy = 1,
605 },
606
607 .enet1 = {
608 .force_speed_100 = 1,
609 .force_duplex_full = 1,
610 },
611
612 .has_ohci0 = 1,
613 .has_ehci0 = 1,
614 };
615
616 static 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 };
636 #endif
637
638 /*
639 * all boards
640 */
641 static const struct board_info __initconst *bcm963xx_boards[] = {
642 #ifdef CONFIG_BCM63XX_CPU_6328
643 &board_96328avng,
644 #endif
645 #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,
660 &board_rta1025w_16,
661 #endif
662
663 #ifdef CONFIG_BCM63XX_CPU_6358
664 &board_96358vw,
665 &board_96358vw2,
666 &board_AGPFS0,
667 &board_DWVS0,
668 #endif
669 };
670
671 /*
672 * Register a sane SPROMv2 to make the on-board
673 * bcm4318 WLAN work
674 */
675 #ifdef CONFIG_SSB_PCIHOST
676 static struct ssb_sprom bcm63xx_sprom = {
677 .revision = 0x02,
678 .board_rev = 0x17,
679 .country_code = 0x0,
680 .ant_available_bg = 0x3,
681 .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 };
696
697 int 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 }
707 #endif
708
709 /*
710 * return board name for /proc/cpuinfo
711 */
712 const char *board_get_name(void)
713 {
714 return board.name;
715 }
716
717 /*
718 * early init callback, read nvram data from flash and checksum it
719 */
720 void __init board_prom_init(void)
721 {
722 unsigned int i;
723 u8 *boot_addr, *cfe;
724 char cfe_version[32];
725 char *board_name;
726 u32 val;
727
728 /* read base address of boot chip select (0)
729 * 6328 does not have MPI but boots from a fixed address
730 */
731 if (BCMCPU_IS_6328())
732 val = 0x18000000;
733 else {
734 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
735 val &= MPI_CSBASE_BASE_MASK;
736 }
737 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
748 if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) {
749 printk(KERN_ERR PFX "invalid nvram checksum\n");
750 return;
751 }
752
753 board_name = bcm63xx_nvram_get_name();
754 /* find board by name */
755 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
756 if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
757 continue;
758 /* copy, board desc array is marked initdata */
759 memcpy(&board, bcm963xx_boards[i], sizeof(board));
760 break;
761 }
762
763 /* bail out if board is not found, will complain later */
764 if (!board.name[0]) {
765 char name[17];
766 memcpy(name, board_name, 16);
767 name[16] = 0;
768 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
769 name);
770 return;
771 }
772
773 /* setup pin multiplexing depending on board enabled device,
774 * this has to be done this early since PCI init is done
775 * inside arch_initcall */
776 val = 0;
777
778 #ifdef CONFIG_PCI
779 if (board.has_pci) {
780 bcm63xx_pci_enabled = 1;
781 if (BCMCPU_IS_6348())
782 val |= GPIO_MODE_6348_G2_PCI;
783 }
784 #endif
785
786 if (board.has_pccard) {
787 if (BCMCPU_IS_6348())
788 val |= GPIO_MODE_6348_G1_MII_PCCARD;
789 }
790
791 if (board.has_enet0 && !board.enet0.use_internal_phy) {
792 if (BCMCPU_IS_6348())
793 val |= GPIO_MODE_6348_G3_EXT_MII |
794 GPIO_MODE_6348_G0_EXT_MII;
795 }
796
797 if (board.has_enet1 && !board.enet1.use_internal_phy) {
798 if (BCMCPU_IS_6348())
799 val |= GPIO_MODE_6348_G3_EXT_MII |
800 GPIO_MODE_6348_G0_EXT_MII;
801 }
802
803 bcm_gpio_writel(val, GPIO_MODE_REG);
804 }
805
806 /*
807 * second stage init callback, good time to panic if we couldn't
808 * identify on which board we're running since early printk is working
809 */
810 void __init board_setup(void)
811 {
812 if (!board.name[0])
813 panic("unable to detect bcm963xx board");
814 printk(KERN_INFO PFX "board name: %s\n", board.name);
815
816 /* make sure we're running on expected cpu */
817 if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
818 panic("unexpected CPU for bcm963xx board");
819 }
820
821 static struct gpio_led_platform_data bcm63xx_led_data;
822
823 static struct platform_device bcm63xx_gpio_leds = {
824 .name = "leds-gpio",
825 .id = 0,
826 .dev.platform_data = &bcm63xx_led_data,
827 };
828
829 /*
830 * third stage init callback, register all board devices.
831 */
832 int __init board_register_devices(void)
833 {
834 if (board.has_uart0)
835 bcm63xx_uart_register(0);
836
837 if (board.has_uart1)
838 bcm63xx_uart_register(1);
839
840 if (board.has_pccard)
841 bcm63xx_pcmcia_register();
842
843 if (board.has_enet0 &&
844 !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
845 bcm63xx_enet_register(0, &board.enet0);
846
847 if (board.has_enet1 &&
848 !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
849 bcm63xx_enet_register(1, &board.enet1);
850
851 if (board.has_usbd)
852 bcm63xx_usbd_register(&board.usbd);
853
854 if (board.has_dsp)
855 bcm63xx_dsp_register(&board.dsp);
856
857 /* Generate MAC address for WLAN and register our SPROM,
858 * do this after registering enet devices
859 */
860 #ifdef CONFIG_SSB_PCIHOST
861 if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
862 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
863 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
864 if (ssb_arch_register_fallback_sprom(
865 &bcm63xx_get_fallback_sprom) < 0)
866 pr_err(PFX "failed to register fallback SPROM\n");
867 }
868 #endif
869
870 bcm63xx_spi_register();
871
872 bcm63xx_flash_register();
873
874 bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
875 bcm63xx_led_data.leds = board.leds;
876
877 platform_device_register(&bcm63xx_gpio_leds);
878
879 return 0;
880 }
This page took 0.049029 seconds and 5 git commands to generate.