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