aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/mips/bcm63xx
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/mips/bcm63xx')
-rw-r--r--arch/mips/bcm63xx/Kconfig8
-rw-r--r--arch/mips/bcm63xx/Makefile6
-rw-r--r--arch/mips/bcm63xx/boards/Makefile2
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c205
-rw-r--r--arch/mips/bcm63xx/clk.c115
-rw-r--r--arch/mips/bcm63xx/cpu.c306
-rw-r--r--arch/mips/bcm63xx/dev-dsp.c2
-rw-r--r--arch/mips/bcm63xx/dev-flash.c123
-rw-r--r--arch/mips/bcm63xx/dev-pcmcia.c4
-rw-r--r--arch/mips/bcm63xx/dev-rng.c40
-rw-r--r--arch/mips/bcm63xx/dev-spi.c123
-rw-r--r--arch/mips/bcm63xx/dev-uart.c2
-rw-r--r--arch/mips/bcm63xx/dev-usb-usbd.c65
-rw-r--r--arch/mips/bcm63xx/dev-wdt.c2
-rw-r--r--arch/mips/bcm63xx/gpio.c41
-rw-r--r--arch/mips/bcm63xx/irq.c436
-rw-r--r--arch/mips/bcm63xx/nvram.c107
-rw-r--r--arch/mips/bcm63xx/prom.c11
-rw-r--r--arch/mips/bcm63xx/reset.c223
-rw-r--r--arch/mips/bcm63xx/setup.c53
20 files changed, 390 insertions, 1484 deletions
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
index d03e8799d1c..fb177d6df06 100644
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -1,10 +1,6 @@
1menu "CPU support" 1menu "CPU support"
2 depends on BCM63XX 2 depends on BCM63XX
3 3
4config BCM63XX_CPU_6328
5 bool "support 6328 CPU"
6 select HW_HAS_PCI
7
8config BCM63XX_CPU_6338 4config BCM63XX_CPU_6338
9 bool "support 6338 CPU" 5 bool "support 6338 CPU"
10 select HW_HAS_PCI 6 select HW_HAS_PCI
@@ -24,10 +20,6 @@ config BCM63XX_CPU_6348
24config BCM63XX_CPU_6358 20config BCM63XX_CPU_6358
25 bool "support 6358 CPU" 21 bool "support 6358 CPU"
26 select HW_HAS_PCI 22 select HW_HAS_PCI
27
28config BCM63XX_CPU_6368
29 bool "support 6368 CPU"
30 select HW_HAS_PCI
31endmenu 23endmenu
32 24
33source "arch/mips/bcm63xx/boards/Kconfig" 25source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index ac2807397c1..6dfdc69928a 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,7 +1,5 @@
1obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \ 1obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
2 setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \ 2 dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
3 dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
4 dev-usb-usbd.o
5obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 3obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
6 4
7obj-y += boards/ 5obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
index af07c1aa202..9f64fb41407 100644
--- a/arch/mips/bcm63xx/boards/Makefile
+++ b/arch/mips/bcm63xx/boards/Makefile
@@ -1 +1,3 @@
1obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o 1obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
2
3ccflags-y := -Werror
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 73be9b34969..40b223b603b 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -11,6 +11,9 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/platform_device.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>
14#include <linux/ssb/ssb.h> 17#include <linux/ssb/ssb.h>
15#include <asm/addrspace.h> 18#include <asm/addrspace.h>
16#include <bcm63xx_board.h> 19#include <bcm63xx_board.h>
@@ -18,69 +21,19 @@
18#include <bcm63xx_dev_uart.h> 21#include <bcm63xx_dev_uart.h>
19#include <bcm63xx_regs.h> 22#include <bcm63xx_regs.h>
20#include <bcm63xx_io.h> 23#include <bcm63xx_io.h>
21#include <bcm63xx_nvram.h>
22#include <bcm63xx_dev_pci.h> 24#include <bcm63xx_dev_pci.h>
23#include <bcm63xx_dev_enet.h> 25#include <bcm63xx_dev_enet.h>
24#include <bcm63xx_dev_dsp.h> 26#include <bcm63xx_dev_dsp.h>
25#include <bcm63xx_dev_flash.h>
26#include <bcm63xx_dev_pcmcia.h> 27#include <bcm63xx_dev_pcmcia.h>
27#include <bcm63xx_dev_spi.h>
28#include <bcm63xx_dev_usb_usbd.h>
29#include <board_bcm963xx.h> 28#include <board_bcm963xx.h>
30 29
31#define PFX "board_bcm963xx: " 30#define PFX "board_bcm963xx: "
32 31
32static struct bcm963xx_nvram nvram;
33static unsigned int mac_addr_used;
33static struct board_info board; 34static struct board_info board;
34 35
35/* 36/*
36 * 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,
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 37 * known 6338 boards
85 */ 38 */
86#ifdef CONFIG_BCM63XX_CPU_6338 39#ifdef CONFIG_BCM63XX_CPU_6338
@@ -638,10 +591,7 @@ static struct board_info __initdata board_DWVS0 = {
638/* 591/*
639 * all boards 592 * all boards
640 */ 593 */
641static const struct board_info __initconst *bcm963xx_boards[] = { 594static const struct board_info __initdata *bcm963xx_boards[] = {
642#ifdef CONFIG_BCM63XX_CPU_6328
643 &board_96328avng,
644#endif
645#ifdef CONFIG_BCM63XX_CPU_6338 595#ifdef CONFIG_BCM63XX_CPU_6338
646 &board_96338gw, 596 &board_96338gw,
647 &board_96338w, 597 &board_96338w,
@@ -715,21 +665,55 @@ const char *board_get_name(void)
715} 665}
716 666
717/* 667/*
668 * register & return a new board mac address
669 */
670static int board_get_mac_address(u8 *mac)
671{
672 u8 *p;
673 int count;
674
675 if (mac_addr_used >= nvram.mac_addr_count) {
676 printk(KERN_ERR PFX "not enough mac address\n");
677 return -ENODEV;
678 }
679
680 memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
681 p = mac + ETH_ALEN - 1;
682 count = mac_addr_used;
683
684 while (count--) {
685 do {
686 (*p)++;
687 if (*p != 0)
688 break;
689 p--;
690 } while (p != mac);
691 }
692
693 if (p == mac) {
694 printk(KERN_ERR PFX "unable to fetch mac address\n");
695 return -ENODEV;
696 }
697
698 mac_addr_used++;
699 return 0;
700}
701
702/*
718 * early init callback, read nvram data from flash and checksum it 703 * early init callback, read nvram data from flash and checksum it
719 */ 704 */
720void __init board_prom_init(void) 705void __init board_prom_init(void)
721{ 706{
722 unsigned int i; 707 unsigned int check_len, i;
723 u8 *boot_addr, *cfe; 708 u8 *boot_addr, *cfe, *p;
724 char cfe_version[32]; 709 char cfe_version[32];
725 char *board_name;
726 u32 val; 710 u32 val;
727 711
728 /* read base address of boot chip select (0) 712 /* read base address of boot chip select (0)
729 * 6328 does not have MPI but boots from a fixed address 713 * 6345 does not have MPI but boots from standard
730 */ 714 * MIPS Flash address */
731 if (BCMCPU_IS_6328()) 715 if (BCMCPU_IS_6345())
732 val = 0x18000000; 716 val = 0x1fc00000;
733 else { 717 else {
734 val = bcm_mpi_readl(MPI_CSBASE_REG(0)); 718 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
735 val &= MPI_CSBASE_BASE_MASK; 719 val &= MPI_CSBASE_BASE_MASK;
@@ -745,15 +729,27 @@ void __init board_prom_init(void)
745 strcpy(cfe_version, "unknown"); 729 strcpy(cfe_version, "unknown");
746 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); 730 printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
747 731
748 if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { 732 /* extract nvram data */
733 memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
734
735 /* check checksum before using data */
736 if (nvram.version <= 4)
737 check_len = offsetof(struct bcm963xx_nvram, checksum_old);
738 else
739 check_len = sizeof(nvram);
740 val = 0;
741 p = (u8 *)&nvram;
742 while (check_len--)
743 val += *p;
744 if (val) {
749 printk(KERN_ERR PFX "invalid nvram checksum\n"); 745 printk(KERN_ERR PFX "invalid nvram checksum\n");
750 return; 746 return;
751 } 747 }
752 748
753 board_name = bcm63xx_nvram_get_name();
754 /* find board by name */ 749 /* find board by name */
755 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { 750 for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
756 if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) 751 if (strncmp(nvram.name, bcm963xx_boards[i]->name,
752 sizeof(nvram.name)))
757 continue; 753 continue;
758 /* copy, board desc array is marked initdata */ 754 /* copy, board desc array is marked initdata */
759 memcpy(&board, bcm963xx_boards[i], sizeof(board)); 755 memcpy(&board, bcm963xx_boards[i], sizeof(board));
@@ -763,7 +759,7 @@ void __init board_prom_init(void)
763 /* bail out if board is not found, will complain later */ 759 /* bail out if board is not found, will complain later */
764 if (!board.name[0]) { 760 if (!board.name[0]) {
765 char name[17]; 761 char name[17];
766 memcpy(name, board_name, 16); 762 memcpy(name, nvram.name, 16);
767 name[16] = 0; 763 name[16] = 0;
768 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", 764 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
769 name); 765 name);
@@ -801,6 +797,18 @@ void __init board_prom_init(void)
801 } 797 }
802 798
803 bcm_gpio_writel(val, GPIO_MODE_REG); 799 bcm_gpio_writel(val, GPIO_MODE_REG);
800
801 /* Generate MAC address for WLAN and
802 * register our SPROM */
803#ifdef CONFIG_SSB_PCIHOST
804 if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
805 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
806 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
807 if (ssb_arch_register_fallback_sprom(
808 &bcm63xx_get_fallback_sprom) < 0)
809 printk(KERN_ERR PFX "failed to register fallback SPROM\n");
810 }
811#endif
804} 812}
805 813
806/* 814/*
@@ -818,6 +826,37 @@ void __init board_setup(void)
818 panic("unexpected CPU for bcm963xx board"); 826 panic("unexpected CPU for bcm963xx board");
819} 827}
820 828
829static struct mtd_partition mtd_partitions[] = {
830 {
831 .name = "cfe",
832 .offset = 0x0,
833 .size = 0x40000,
834 }
835};
836
837static struct physmap_flash_data flash_data = {
838 .width = 2,
839 .nr_parts = ARRAY_SIZE(mtd_partitions),
840 .parts = mtd_partitions,
841};
842
843static struct resource mtd_resources[] = {
844 {
845 .start = 0, /* filled at runtime */
846 .end = 0, /* filled at runtime */
847 .flags = IORESOURCE_MEM,
848 }
849};
850
851static struct platform_device mtd_dev = {
852 .name = "physmap-flash",
853 .resource = mtd_resources,
854 .num_resources = ARRAY_SIZE(mtd_resources),
855 .dev = {
856 .platform_data = &flash_data,
857 },
858};
859
821static struct gpio_led_platform_data bcm63xx_led_data; 860static struct gpio_led_platform_data bcm63xx_led_data;
822 861
823static struct platform_device bcm63xx_gpio_leds = { 862static struct platform_device bcm63xx_gpio_leds = {
@@ -831,6 +870,8 @@ static struct platform_device bcm63xx_gpio_leds = {
831 */ 870 */
832int __init board_register_devices(void) 871int __init board_register_devices(void)
833{ 872{
873 u32 val;
874
834 if (board.has_uart0) 875 if (board.has_uart0)
835 bcm63xx_uart_register(0); 876 bcm63xx_uart_register(0);
836 877
@@ -841,35 +882,27 @@ int __init board_register_devices(void)
841 bcm63xx_pcmcia_register(); 882 bcm63xx_pcmcia_register();
842 883
843 if (board.has_enet0 && 884 if (board.has_enet0 &&
844 !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) 885 !board_get_mac_address(board.enet0.mac_addr))
845 bcm63xx_enet_register(0, &board.enet0); 886 bcm63xx_enet_register(0, &board.enet0);
846 887
847 if (board.has_enet1 && 888 if (board.has_enet1 &&
848 !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) 889 !board_get_mac_address(board.enet1.mac_addr))
849 bcm63xx_enet_register(1, &board.enet1); 890 bcm63xx_enet_register(1, &board.enet1);
850 891
851 if (board.has_usbd)
852 bcm63xx_usbd_register(&board.usbd);
853
854 if (board.has_dsp) 892 if (board.has_dsp)
855 bcm63xx_dsp_register(&board.dsp); 893 bcm63xx_dsp_register(&board.dsp);
856 894
857 /* Generate MAC address for WLAN and register our SPROM, 895 /* read base address of boot chip select (0) */
858 * do this after registering enet devices 896 if (BCMCPU_IS_6345())
859 */ 897 val = 0x1fc00000;
860#ifdef CONFIG_SSB_PCIHOST 898 else {
861 if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { 899 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
862 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); 900 val &= MPI_CSBASE_BASE_MASK;
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 } 901 }
868#endif 902 mtd_resources[0].start = val;
869 903 mtd_resources[0].end = 0x1FFFFFFF;
870 bcm63xx_spi_register();
871 904
872 bcm63xx_flash_register(); 905 platform_device_register(&mtd_dev);
873 906
874 bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); 907 bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
875 bcm63xx_led_data.leds = board.leds; 908 bcm63xx_led_data.leds = board.leds;
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index b9e948d5943..2c68ee9ccee 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -10,11 +10,9 @@
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11#include <linux/err.h> 11#include <linux/err.h>
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <bcm63xx_cpu.h> 13#include <bcm63xx_cpu.h>
15#include <bcm63xx_io.h> 14#include <bcm63xx_io.h>
16#include <bcm63xx_regs.h> 15#include <bcm63xx_regs.h>
17#include <bcm63xx_reset.h>
18#include <bcm63xx_clk.h> 16#include <bcm63xx_clk.h>
19 17
20static DEFINE_MUTEX(clocks_mutex); 18static DEFINE_MUTEX(clocks_mutex);
@@ -115,29 +113,6 @@ static struct clk clk_ephy = {
115}; 113};
116 114
117/* 115/*
118 * Ethernet switch clock
119 */
120static void enetsw_set(struct clk *clk, int enable)
121{
122 if (!BCMCPU_IS_6368())
123 return;
124 bcm_hwclock_set(CKCTL_6368_ROBOSW_EN |
125 CKCTL_6368_SWPKT_USB_EN |
126 CKCTL_6368_SWPKT_SAR_EN, enable);
127 if (enable) {
128 /* reset switch core afer clock change */
129 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
130 msleep(10);
131 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
132 msleep(10);
133 }
134}
135
136static struct clk clk_enetsw = {
137 .set = enetsw_set,
138};
139
140/*
141 * PCM clock 116 * PCM clock
142 */ 117 */
143static void pcm_set(struct clk *clk, int enable) 118static void pcm_set(struct clk *clk, int enable)
@@ -156,12 +131,9 @@ static struct clk clk_pcm = {
156 */ 131 */
157static void usbh_set(struct clk *clk, int enable) 132static void usbh_set(struct clk *clk, int enable)
158{ 133{
159 if (BCMCPU_IS_6328()) 134 if (!BCMCPU_IS_6348())
160 bcm_hwclock_set(CKCTL_6328_USBH_EN, enable); 135 return;
161 else if (BCMCPU_IS_6348()) 136 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
162 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
163 else if (BCMCPU_IS_6368())
164 bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
165} 137}
166 138
167static struct clk clk_usbh = { 139static struct clk clk_usbh = {
@@ -169,21 +141,6 @@ static struct clk clk_usbh = {
169}; 141};
170 142
171/* 143/*
172 * USB device clock
173 */
174static void usbd_set(struct clk *clk, int enable)
175{
176 if (BCMCPU_IS_6328())
177 bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
178 else if (BCMCPU_IS_6368())
179 bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
180}
181
182static struct clk clk_usbd = {
183 .set = usbd_set,
184};
185
186/*
187 * SPI clock 144 * SPI clock
188 */ 145 */
189static void spi_set(struct clk *clk, int enable) 146static void spi_set(struct clk *clk, int enable)
@@ -194,11 +151,9 @@ static void spi_set(struct clk *clk, int enable)
194 mask = CKCTL_6338_SPI_EN; 151 mask = CKCTL_6338_SPI_EN;
195 else if (BCMCPU_IS_6348()) 152 else if (BCMCPU_IS_6348())
196 mask = CKCTL_6348_SPI_EN; 153 mask = CKCTL_6348_SPI_EN;
197 else if (BCMCPU_IS_6358())
198 mask = CKCTL_6358_SPI_EN;
199 else 154 else
200 /* BCMCPU_IS_6368 */ 155 /* BCMCPU_IS_6358 */
201 mask = CKCTL_6368_SPI_EN; 156 mask = CKCTL_6358_SPI_EN;
202 bcm_hwclock_set(mask, enable); 157 bcm_hwclock_set(mask, enable);
203} 158}
204 159
@@ -207,56 +162,6 @@ static struct clk clk_spi = {
207}; 162};
208 163
209/* 164/*
210 * XTM clock
211 */
212static void xtm_set(struct clk *clk, int enable)
213{
214 if (!BCMCPU_IS_6368())
215 return;
216
217 bcm_hwclock_set(CKCTL_6368_SAR_EN |
218 CKCTL_6368_SWPKT_SAR_EN, enable);
219
220 if (enable) {
221 /* reset sar core afer clock change */
222 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
223 mdelay(1);
224 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
225 mdelay(1);
226 }
227}
228
229
230static struct clk clk_xtm = {
231 .set = xtm_set,
232};
233
234/*
235 * IPsec clock
236 */
237static void ipsec_set(struct clk *clk, int enable)
238{
239 bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
240}
241
242static struct clk clk_ipsec = {
243 .set = ipsec_set,
244};
245
246/*
247 * PCIe clock
248 */
249
250static void pcie_set(struct clk *clk, int enable)
251{
252 bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
253}
254
255static struct clk clk_pcie = {
256 .set = pcie_set,
257};
258
259/*
260 * Internal peripheral clock 165 * Internal peripheral clock
261 */ 166 */
262static struct clk clk_periph = { 167static struct clk clk_periph = {
@@ -299,26 +204,16 @@ struct clk *clk_get(struct device *dev, const char *id)
299 return &clk_enet0; 204 return &clk_enet0;
300 if (!strcmp(id, "enet1")) 205 if (!strcmp(id, "enet1"))
301 return &clk_enet1; 206 return &clk_enet1;
302 if (!strcmp(id, "enetsw"))
303 return &clk_enetsw;
304 if (!strcmp(id, "ephy")) 207 if (!strcmp(id, "ephy"))
305 return &clk_ephy; 208 return &clk_ephy;
306 if (!strcmp(id, "usbh")) 209 if (!strcmp(id, "usbh"))
307 return &clk_usbh; 210 return &clk_usbh;
308 if (!strcmp(id, "usbd"))
309 return &clk_usbd;
310 if (!strcmp(id, "spi")) 211 if (!strcmp(id, "spi"))
311 return &clk_spi; 212 return &clk_spi;
312 if (!strcmp(id, "xtm"))
313 return &clk_xtm;
314 if (!strcmp(id, "periph")) 213 if (!strcmp(id, "periph"))
315 return &clk_periph; 214 return &clk_periph;
316 if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) 215 if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
317 return &clk_pcm; 216 return &clk_pcm;
318 if (BCMCPU_IS_6368() && !strcmp(id, "ipsec"))
319 return &clk_ipsec;
320 if (BCMCPU_IS_6328() && !strcmp(id, "pcie"))
321 return &clk_pcie;
322 return ERR_PTR(-ENOENT); 217 return ERR_PTR(-ENOENT);
323} 218}
324 219
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index a7afb289b15..7c7e4d4486c 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -29,55 +29,166 @@ static u16 bcm63xx_cpu_rev;
29static unsigned int bcm63xx_cpu_freq; 29static unsigned int bcm63xx_cpu_freq;
30static unsigned int bcm63xx_memory_size; 30static unsigned int bcm63xx_memory_size;
31 31
32static const unsigned long bcm6328_regs_base[] = { 32/*
33 __GEN_CPU_REGS_TABLE(6328) 33 * 6338 register sets and irqs
34}; 34 */
35 35static const unsigned long bcm96338_regs_base[] = {
36static const int bcm6328_irqs[] = { 36 [RSET_DSL_LMEM] = BCM_6338_DSL_LMEM_BASE,
37 __GEN_CPU_IRQ_TABLE(6328) 37 [RSET_PERF] = BCM_6338_PERF_BASE,
38}; 38 [RSET_TIMER] = BCM_6338_TIMER_BASE,
39 39 [RSET_WDT] = BCM_6338_WDT_BASE,
40static const unsigned long bcm6338_regs_base[] = { 40 [RSET_UART0] = BCM_6338_UART0_BASE,
41 __GEN_CPU_REGS_TABLE(6338) 41 [RSET_UART1] = BCM_6338_UART1_BASE,
42}; 42 [RSET_GPIO] = BCM_6338_GPIO_BASE,
43 43 [RSET_SPI] = BCM_6338_SPI_BASE,
44static const int bcm6338_irqs[] = { 44 [RSET_OHCI0] = BCM_6338_OHCI0_BASE,
45 __GEN_CPU_IRQ_TABLE(6338) 45 [RSET_OHCI_PRIV] = BCM_6338_OHCI_PRIV_BASE,
46}; 46 [RSET_USBH_PRIV] = BCM_6338_USBH_PRIV_BASE,
47 47 [RSET_UDC0] = BCM_6338_UDC0_BASE,
48static const unsigned long bcm6345_regs_base[] = { 48 [RSET_MPI] = BCM_6338_MPI_BASE,
49 __GEN_CPU_REGS_TABLE(6345) 49 [RSET_PCMCIA] = BCM_6338_PCMCIA_BASE,
50 [RSET_SDRAM] = BCM_6338_SDRAM_BASE,
51 [RSET_DSL] = BCM_6338_DSL_BASE,
52 [RSET_ENET0] = BCM_6338_ENET0_BASE,
53 [RSET_ENET1] = BCM_6338_ENET1_BASE,
54 [RSET_ENETDMA] = BCM_6338_ENETDMA_BASE,
55 [RSET_MEMC] = BCM_6338_MEMC_BASE,
56 [RSET_DDR] = BCM_6338_DDR_BASE,
50}; 57};
51 58
52static const int bcm6345_irqs[] = { 59static const int bcm96338_irqs[] = {
53 __GEN_CPU_IRQ_TABLE(6345) 60 [IRQ_TIMER] = BCM_6338_TIMER_IRQ,
61 [IRQ_UART0] = BCM_6338_UART0_IRQ,
62 [IRQ_DSL] = BCM_6338_DSL_IRQ,
63 [IRQ_ENET0] = BCM_6338_ENET0_IRQ,
64 [IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ,
65 [IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ,
66 [IRQ_ENET0_TXDMA] = BCM_6338_ENET0_TXDMA_IRQ,
54}; 67};
55 68
56static const unsigned long bcm6348_regs_base[] = { 69/*
57 __GEN_CPU_REGS_TABLE(6348) 70 * 6345 register sets and irqs
71 */
72static const unsigned long bcm96345_regs_base[] = {
73 [RSET_DSL_LMEM] = BCM_6345_DSL_LMEM_BASE,
74 [RSET_PERF] = BCM_6345_PERF_BASE,
75 [RSET_TIMER] = BCM_6345_TIMER_BASE,
76 [RSET_WDT] = BCM_6345_WDT_BASE,
77 [RSET_UART0] = BCM_6345_UART0_BASE,
78 [RSET_UART1] = BCM_6345_UART1_BASE,
79 [RSET_GPIO] = BCM_6345_GPIO_BASE,
80 [RSET_SPI] = BCM_6345_SPI_BASE,
81 [RSET_UDC0] = BCM_6345_UDC0_BASE,
82 [RSET_OHCI0] = BCM_6345_OHCI0_BASE,
83 [RSET_OHCI_PRIV] = BCM_6345_OHCI_PRIV_BASE,
84 [RSET_USBH_PRIV] = BCM_6345_USBH_PRIV_BASE,
85 [RSET_MPI] = BCM_6345_MPI_BASE,
86 [RSET_PCMCIA] = BCM_6345_PCMCIA_BASE,
87 [RSET_DSL] = BCM_6345_DSL_BASE,
88 [RSET_ENET0] = BCM_6345_ENET0_BASE,
89 [RSET_ENET1] = BCM_6345_ENET1_BASE,
90 [RSET_ENETDMA] = BCM_6345_ENETDMA_BASE,
91 [RSET_EHCI0] = BCM_6345_EHCI0_BASE,
92 [RSET_SDRAM] = BCM_6345_SDRAM_BASE,
93 [RSET_MEMC] = BCM_6345_MEMC_BASE,
94 [RSET_DDR] = BCM_6345_DDR_BASE,
58}; 95};
59 96
60static const int bcm6348_irqs[] = { 97static const int bcm96345_irqs[] = {
61 __GEN_CPU_IRQ_TABLE(6348) 98 [IRQ_TIMER] = BCM_6345_TIMER_IRQ,
62 99 [IRQ_UART0] = BCM_6345_UART0_IRQ,
100 [IRQ_DSL] = BCM_6345_DSL_IRQ,
101 [IRQ_ENET0] = BCM_6345_ENET0_IRQ,
102 [IRQ_ENET_PHY] = BCM_6345_ENET_PHY_IRQ,
103 [IRQ_ENET0_RXDMA] = BCM_6345_ENET0_RXDMA_IRQ,
104 [IRQ_ENET0_TXDMA] = BCM_6345_ENET0_TXDMA_IRQ,
63}; 105};
64 106
65static const unsigned long bcm6358_regs_base[] = { 107/*
66 __GEN_CPU_REGS_TABLE(6358) 108 * 6348 register sets and irqs
109 */
110static const unsigned long bcm96348_regs_base[] = {
111 [RSET_DSL_LMEM] = BCM_6348_DSL_LMEM_BASE,
112 [RSET_PERF] = BCM_6348_PERF_BASE,
113 [RSET_TIMER] = BCM_6348_TIMER_BASE,
114 [RSET_WDT] = BCM_6348_WDT_BASE,
115 [RSET_UART0] = BCM_6348_UART0_BASE,
116 [RSET_UART1] = BCM_6348_UART1_BASE,
117 [RSET_GPIO] = BCM_6348_GPIO_BASE,
118 [RSET_SPI] = BCM_6348_SPI_BASE,
119 [RSET_OHCI0] = BCM_6348_OHCI0_BASE,
120 [RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE,
121 [RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE,
122 [RSET_MPI] = BCM_6348_MPI_BASE,
123 [RSET_PCMCIA] = BCM_6348_PCMCIA_BASE,
124 [RSET_SDRAM] = BCM_6348_SDRAM_BASE,
125 [RSET_DSL] = BCM_6348_DSL_BASE,
126 [RSET_ENET0] = BCM_6348_ENET0_BASE,
127 [RSET_ENET1] = BCM_6348_ENET1_BASE,
128 [RSET_ENETDMA] = BCM_6348_ENETDMA_BASE,
129 [RSET_MEMC] = BCM_6348_MEMC_BASE,
130 [RSET_DDR] = BCM_6348_DDR_BASE,
67}; 131};
68 132
69static const int bcm6358_irqs[] = { 133static const int bcm96348_irqs[] = {
70 __GEN_CPU_IRQ_TABLE(6358) 134 [IRQ_TIMER] = BCM_6348_TIMER_IRQ,
71 135 [IRQ_UART0] = BCM_6348_UART0_IRQ,
136 [IRQ_DSL] = BCM_6348_DSL_IRQ,
137 [IRQ_ENET0] = BCM_6348_ENET0_IRQ,
138 [IRQ_ENET1] = BCM_6348_ENET1_IRQ,
139 [IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ,
140 [IRQ_OHCI0] = BCM_6348_OHCI0_IRQ,
141 [IRQ_PCMCIA] = BCM_6348_PCMCIA_IRQ,
142 [IRQ_ENET0_RXDMA] = BCM_6348_ENET0_RXDMA_IRQ,
143 [IRQ_ENET0_TXDMA] = BCM_6348_ENET0_TXDMA_IRQ,
144 [IRQ_ENET1_RXDMA] = BCM_6348_ENET1_RXDMA_IRQ,
145 [IRQ_ENET1_TXDMA] = BCM_6348_ENET1_TXDMA_IRQ,
146 [IRQ_PCI] = BCM_6348_PCI_IRQ,
72}; 147};
73 148
74static const unsigned long bcm6368_regs_base[] = { 149/*
75 __GEN_CPU_REGS_TABLE(6368) 150 * 6358 register sets and irqs
151 */
152static const unsigned long bcm96358_regs_base[] = {
153 [RSET_DSL_LMEM] = BCM_6358_DSL_LMEM_BASE,
154 [RSET_PERF] = BCM_6358_PERF_BASE,
155 [RSET_TIMER] = BCM_6358_TIMER_BASE,
156 [RSET_WDT] = BCM_6358_WDT_BASE,
157 [RSET_UART0] = BCM_6358_UART0_BASE,
158 [RSET_UART1] = BCM_6358_UART1_BASE,
159 [RSET_GPIO] = BCM_6358_GPIO_BASE,
160 [RSET_SPI] = BCM_6358_SPI_BASE,
161 [RSET_OHCI0] = BCM_6358_OHCI0_BASE,
162 [RSET_EHCI0] = BCM_6358_EHCI0_BASE,
163 [RSET_OHCI_PRIV] = BCM_6358_OHCI_PRIV_BASE,
164 [RSET_USBH_PRIV] = BCM_6358_USBH_PRIV_BASE,
165 [RSET_MPI] = BCM_6358_MPI_BASE,
166 [RSET_PCMCIA] = BCM_6358_PCMCIA_BASE,
167 [RSET_SDRAM] = BCM_6358_SDRAM_BASE,
168 [RSET_DSL] = BCM_6358_DSL_BASE,
169 [RSET_ENET0] = BCM_6358_ENET0_BASE,
170 [RSET_ENET1] = BCM_6358_ENET1_BASE,
171 [RSET_ENETDMA] = BCM_6358_ENETDMA_BASE,
172 [RSET_MEMC] = BCM_6358_MEMC_BASE,
173 [RSET_DDR] = BCM_6358_DDR_BASE,
76}; 174};
77 175
78static const int bcm6368_irqs[] = { 176static const int bcm96358_irqs[] = {
79 __GEN_CPU_IRQ_TABLE(6368) 177 [IRQ_TIMER] = BCM_6358_TIMER_IRQ,
80 178 [IRQ_UART0] = BCM_6358_UART0_IRQ,
179 [IRQ_UART1] = BCM_6358_UART1_IRQ,
180 [IRQ_DSL] = BCM_6358_DSL_IRQ,
181 [IRQ_ENET0] = BCM_6358_ENET0_IRQ,
182 [IRQ_ENET1] = BCM_6358_ENET1_IRQ,
183 [IRQ_ENET_PHY] = BCM_6358_ENET_PHY_IRQ,
184 [IRQ_OHCI0] = BCM_6358_OHCI0_IRQ,
185 [IRQ_EHCI0] = BCM_6358_EHCI0_IRQ,
186 [IRQ_PCMCIA] = BCM_6358_PCMCIA_IRQ,
187 [IRQ_ENET0_RXDMA] = BCM_6358_ENET0_RXDMA_IRQ,
188 [IRQ_ENET0_TXDMA] = BCM_6358_ENET0_TXDMA_IRQ,
189 [IRQ_ENET1_RXDMA] = BCM_6358_ENET1_RXDMA_IRQ,
190 [IRQ_ENET1_TXDMA] = BCM_6358_ENET1_TXDMA_IRQ,
191 [IRQ_PCI] = BCM_6358_PCI_IRQ,
81}; 192};
82 193
83u16 __bcm63xx_get_cpu_id(void) 194u16 __bcm63xx_get_cpu_id(void)
@@ -106,46 +217,20 @@ unsigned int bcm63xx_get_memory_size(void)
106 217
107static unsigned int detect_cpu_clock(void) 218static unsigned int detect_cpu_clock(void)
108{ 219{
109 switch (bcm63xx_get_cpu_id()) { 220 unsigned int tmp, n1 = 0, n2 = 0, m1 = 0;
110 case BCM6328_CPU_ID:
111 {
112 unsigned int tmp, mips_pll_fcvo;
113
114 tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
115 mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
116 >> STRAPBUS_6328_FCVO_SHIFT;
117
118 switch (mips_pll_fcvo) {
119 case 0x12:
120 case 0x14:
121 case 0x19:
122 return 160000000;
123 case 0x1c:
124 return 192000000;
125 case 0x13:
126 case 0x15:
127 return 200000000;
128 case 0x1a:
129 return 384000000;
130 case 0x16:
131 return 400000000;
132 default:
133 return 320000000;
134 }
135 221
136 } 222 /* BCM6338 has a fixed 240 Mhz frequency */
137 case BCM6338_CPU_ID: 223 if (BCMCPU_IS_6338())
138 /* BCM6338 has a fixed 240 Mhz frequency */
139 return 240000000; 224 return 240000000;
140 225
141 case BCM6345_CPU_ID: 226 /* BCM6345 has a fixed 140Mhz frequency */
142 /* BCM6345 has a fixed 140Mhz frequency */ 227 if (BCMCPU_IS_6345())
143 return 140000000; 228 return 140000000;
144 229
145 case BCM6348_CPU_ID: 230 /*
146 { 231 * frequency depends on PLL configuration:
147 unsigned int tmp, n1, n2, m1; 232 */
148 233 if (BCMCPU_IS_6348()) {
149 /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */ 234 /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
150 tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG); 235 tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
151 n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT; 236 n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
@@ -154,47 +239,17 @@ static unsigned int detect_cpu_clock(void)
154 n1 += 1; 239 n1 += 1;
155 n2 += 2; 240 n2 += 2;
156 m1 += 1; 241 m1 += 1;
157 return (16 * 1000000 * n1 * n2) / m1;
158 } 242 }
159 243
160 case BCM6358_CPU_ID: 244 if (BCMCPU_IS_6358()) {
161 {
162 unsigned int tmp, n1, n2, m1;
163
164 /* 16MHz * N1 * N2 / M1_CPU */ 245 /* 16MHz * N1 * N2 / M1_CPU */
165 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG); 246 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
166 n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT; 247 n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
167 n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT; 248 n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
168 m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT; 249 m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
169 return (16 * 1000000 * n1 * n2) / m1;
170 } 250 }
171 251
172 case BCM6368_CPU_ID: 252 return (16 * 1000000 * n1 * n2) / m1;
173 {
174 unsigned int tmp, p1, p2, ndiv, m1;
175
176 /* (64MHz / P1) * P2 * NDIV / M1_CPU */
177 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
178
179 p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
180 DMIPSPLLCFG_6368_P1_SHIFT;
181
182 p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
183 DMIPSPLLCFG_6368_P2_SHIFT;
184
185 ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
186 DMIPSPLLCFG_6368_NDIV_SHIFT;
187
188 tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
189 m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
190 DMIPSPLLDIV_6368_MDIV_SHIFT;
191
192 return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
193 }
194
195 default:
196 BUG();
197 }
198} 253}
199 254
200/* 255/*
@@ -205,13 +260,8 @@ static unsigned int detect_memory_size(void)
205 unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; 260 unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
206 u32 val; 261 u32 val;
207 262
208 if (BCMCPU_IS_6328()) 263 if (BCMCPU_IS_6345())
209 return bcm_ddr_readl(DDR_CSEND_REG) << 24; 264 return (8 * 1024 * 1024);
210
211 if (BCMCPU_IS_6345()) {
212 val = bcm_sdram_readl(SDRAM_MBASE_REG);
213 return (val * 8 * 1024 * 1024);
214 }
215 265
216 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { 266 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
217 val = bcm_sdram_readl(SDRAM_CFG_REG); 267 val = bcm_sdram_readl(SDRAM_CFG_REG);
@@ -221,7 +271,7 @@ static unsigned int detect_memory_size(void)
221 banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; 271 banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
222 } 272 }
223 273
224 if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { 274 if (BCMCPU_IS_6358()) {
225 val = bcm_memc_readl(MEMC_CFG_REG); 275 val = bcm_memc_readl(MEMC_CFG_REG);
226 rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; 276 rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
227 cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; 277 cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
@@ -251,42 +301,24 @@ void __init bcm63xx_cpu_init(void)
251 case CPU_BMIPS3300: 301 case CPU_BMIPS3300:
252 if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) { 302 if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
253 expected_cpu_id = BCM6348_CPU_ID; 303 expected_cpu_id = BCM6348_CPU_ID;
254 bcm63xx_regs_base = bcm6348_regs_base; 304 bcm63xx_regs_base = bcm96348_regs_base;
255 bcm63xx_irqs = bcm6348_irqs; 305 bcm63xx_irqs = bcm96348_irqs;
256 } else { 306 } else {
257 __cpu_name[cpu] = "Broadcom BCM6338"; 307 __cpu_name[cpu] = "Broadcom BCM6338";
258 expected_cpu_id = BCM6338_CPU_ID; 308 expected_cpu_id = BCM6338_CPU_ID;
259 bcm63xx_regs_base = bcm6338_regs_base; 309 bcm63xx_regs_base = bcm96338_regs_base;
260 bcm63xx_irqs = bcm6338_irqs; 310 bcm63xx_irqs = bcm96338_irqs;
261 } 311 }
262 break; 312 break;
263 case CPU_BMIPS32: 313 case CPU_BMIPS32:
264 expected_cpu_id = BCM6345_CPU_ID; 314 expected_cpu_id = BCM6345_CPU_ID;
265 bcm63xx_regs_base = bcm6345_regs_base; 315 bcm63xx_regs_base = bcm96345_regs_base;
266 bcm63xx_irqs = bcm6345_irqs; 316 bcm63xx_irqs = bcm96345_irqs;
267 break; 317 break;
268 case CPU_BMIPS4350: 318 case CPU_BMIPS4350:
269 if ((read_c0_prid() & 0xf0) == 0x10) { 319 expected_cpu_id = BCM6358_CPU_ID;
270 expected_cpu_id = BCM6358_CPU_ID; 320 bcm63xx_regs_base = bcm96358_regs_base;
271 bcm63xx_regs_base = bcm6358_regs_base; 321 bcm63xx_irqs = bcm96358_irqs;
272 bcm63xx_irqs = bcm6358_irqs;
273 } else {
274 /* all newer chips have the same chip id location */
275 u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
276
277 switch (chip_id) {
278 case BCM6328_CPU_ID:
279 expected_cpu_id = BCM6328_CPU_ID;
280 bcm63xx_regs_base = bcm6328_regs_base;
281 bcm63xx_irqs = bcm6328_irqs;
282 break;
283 case BCM6368_CPU_ID:
284 expected_cpu_id = BCM6368_CPU_ID;
285 bcm63xx_regs_base = bcm6368_regs_base;
286 bcm63xx_irqs = bcm6368_irqs;
287 break;
288 }
289 }
290 break; 322 break;
291 } 323 }
292 324
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c
index 5bb5b154c9b..da46d1d3c77 100644
--- a/arch/mips/bcm63xx/dev-dsp.c
+++ b/arch/mips/bcm63xx/dev-dsp.c
@@ -31,7 +31,7 @@ static struct resource voip_dsp_resources[] = {
31 31
32static struct platform_device bcm63xx_voip_dsp_device = { 32static struct platform_device bcm63xx_voip_dsp_device = {
33 .name = "bcm63xx-voip-dsp", 33 .name = "bcm63xx-voip-dsp",
34 .id = -1, 34 .id = 0,
35 .num_resources = ARRAY_SIZE(voip_dsp_resources), 35 .num_resources = ARRAY_SIZE(voip_dsp_resources),
36 .resource = voip_dsp_resources, 36 .resource = voip_dsp_resources,
37}; 37};
diff --git a/arch/mips/bcm63xx/dev-flash.c b/arch/mips/bcm63xx/dev-flash.c
deleted file mode 100644
index 58371c7deac..00000000000
--- a/arch/mips/bcm63xx/dev-flash.c
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Broadcom BCM63xx flash registration
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
9 * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
10 * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
11 */
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/partitions.h>
18#include <linux/mtd/physmap.h>
19
20#include <bcm63xx_cpu.h>
21#include <bcm63xx_dev_flash.h>
22#include <bcm63xx_regs.h>
23#include <bcm63xx_io.h>
24
25static struct mtd_partition mtd_partitions[] = {
26 {
27 .name = "cfe",
28 .offset = 0x0,
29 .size = 0x40000,
30 }
31};
32
33static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
34
35static struct physmap_flash_data flash_data = {
36 .width = 2,
37 .parts = mtd_partitions,
38 .part_probe_types = bcm63xx_part_types,
39};
40
41static struct resource mtd_resources[] = {
42 {
43 .start = 0, /* filled at runtime */
44 .end = 0, /* filled at runtime */
45 .flags = IORESOURCE_MEM,
46 }
47};
48
49static struct platform_device mtd_dev = {
50 .name = "physmap-flash",
51 .resource = mtd_resources,
52 .num_resources = ARRAY_SIZE(mtd_resources),
53 .dev = {
54 .platform_data = &flash_data,
55 },
56};
57
58static int __init bcm63xx_detect_flash_type(void)
59{
60 u32 val;
61
62 switch (bcm63xx_get_cpu_id()) {
63 case BCM6328_CPU_ID:
64 val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
65 if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
66 return BCM63XX_FLASH_TYPE_SERIAL;
67 else
68 return BCM63XX_FLASH_TYPE_NAND;
69 case BCM6338_CPU_ID:
70 case BCM6345_CPU_ID:
71 case BCM6348_CPU_ID:
72 /* no way to auto detect so assume parallel */
73 return BCM63XX_FLASH_TYPE_PARALLEL;
74 case BCM6358_CPU_ID:
75 val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
76 if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
77 return BCM63XX_FLASH_TYPE_PARALLEL;
78 else
79 return BCM63XX_FLASH_TYPE_SERIAL;
80 case BCM6368_CPU_ID:
81 val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
82 switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
83 case STRAPBUS_6368_BOOT_SEL_NAND:
84 return BCM63XX_FLASH_TYPE_NAND;
85 case STRAPBUS_6368_BOOT_SEL_SERIAL:
86 return BCM63XX_FLASH_TYPE_SERIAL;
87 case STRAPBUS_6368_BOOT_SEL_PARALLEL:
88 return BCM63XX_FLASH_TYPE_PARALLEL;
89 }
90 default:
91 return -EINVAL;
92 }
93}
94
95int __init bcm63xx_flash_register(void)
96{
97 int flash_type;
98 u32 val;
99
100 flash_type = bcm63xx_detect_flash_type();
101
102 switch (flash_type) {
103 case BCM63XX_FLASH_TYPE_PARALLEL:
104 /* read base address of boot chip select (0) */
105 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
106 val &= MPI_CSBASE_BASE_MASK;
107
108 mtd_resources[0].start = val;
109 mtd_resources[0].end = 0x1FFFFFFF;
110
111 return platform_device_register(&mtd_dev);
112 case BCM63XX_FLASH_TYPE_SERIAL:
113 pr_warn("unsupported serial flash detected\n");
114 return -ENODEV;
115 case BCM63XX_FLASH_TYPE_NAND:
116 pr_warn("unsupported NAND flash detected\n");
117 return -ENODEV;
118 default:
119 pr_err("flash detection failed for BCM%x: %d\n",
120 bcm63xx_get_cpu_id(), flash_type);
121 return -ENODEV;
122 }
123}
diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c
index a551bab5ecb..de4d917fd54 100644
--- a/arch/mips/bcm63xx/dev-pcmcia.c
+++ b/arch/mips/bcm63xx/dev-pcmcia.c
@@ -79,11 +79,11 @@ static int __init config_pcmcia_cs(unsigned int cs,
79 return ret; 79 return ret;
80} 80}
81 81
82static const struct { 82static const __initdata struct {
83 unsigned int cs; 83 unsigned int cs;
84 unsigned int base; 84 unsigned int base;
85 unsigned int size; 85 unsigned int size;
86} pcmcia_cs[3] __initconst = { 86} pcmcia_cs[3] = {
87 { 87 {
88 .cs = MPI_CS_PCMCIA_COMMON, 88 .cs = MPI_CS_PCMCIA_COMMON,
89 .base = BCM_PCMCIA_COMMON_BASE_PA, 89 .base = BCM_PCMCIA_COMMON_BASE_PA,
diff --git a/arch/mips/bcm63xx/dev-rng.c b/arch/mips/bcm63xx/dev-rng.c
deleted file mode 100644
index d277b4dc6c6..00000000000
--- a/arch/mips/bcm63xx/dev-rng.c
+++ /dev/null
@@ -1,40 +0,0 @@
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) 2011 Florian Fainelli <florian@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12#include <bcm63xx_cpu.h>
13
14static struct resource rng_resources[] = {
15 {
16 .start = -1, /* filled at runtime */
17 .end = -1, /* filled at runtime */
18 .flags = IORESOURCE_MEM,
19 },
20};
21
22static struct platform_device bcm63xx_rng_device = {
23 .name = "bcm63xx-rng",
24 .id = -1,
25 .num_resources = ARRAY_SIZE(rng_resources),
26 .resource = rng_resources,
27};
28
29int __init bcm63xx_rng_register(void)
30{
31 if (!BCMCPU_IS_6368())
32 return -ENODEV;
33
34 rng_resources[0].start = bcm63xx_regset_address(RSET_RNG);
35 rng_resources[0].end = rng_resources[0].start;
36 rng_resources[0].end += RSET_RNG_SIZE - 1;
37
38 return platform_device_register(&bcm63xx_rng_device);
39}
40arch_initcall(bcm63xx_rng_register);
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c
deleted file mode 100644
index f1c9c3e2f67..00000000000
--- a/arch/mips/bcm63xx/dev-spi.c
+++ /dev/null
@@ -1,123 +0,0 @@
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) 2009-2011 Florian Fainelli <florian@openwrt.org>
7 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
8 */
9
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/export.h>
13#include <linux/platform_device.h>
14#include <linux/err.h>
15#include <linux/clk.h>
16
17#include <bcm63xx_cpu.h>
18#include <bcm63xx_dev_spi.h>
19#include <bcm63xx_regs.h>
20
21#ifdef BCMCPU_RUNTIME_DETECT
22/*
23 * register offsets
24 */
25static const unsigned long bcm6338_regs_spi[] = {
26 __GEN_SPI_REGS_TABLE(6338)
27};
28
29static const unsigned long bcm6348_regs_spi[] = {
30 __GEN_SPI_REGS_TABLE(6348)
31};
32
33static const unsigned long bcm6358_regs_spi[] = {
34 __GEN_SPI_REGS_TABLE(6358)
35};
36
37static const unsigned long bcm6368_regs_spi[] = {
38 __GEN_SPI_REGS_TABLE(6368)
39};
40
41const unsigned long *bcm63xx_regs_spi;
42EXPORT_SYMBOL(bcm63xx_regs_spi);
43
44static __init void bcm63xx_spi_regs_init(void)
45{
46 if (BCMCPU_IS_6338())
47 bcm63xx_regs_spi = bcm6338_regs_spi;
48 if (BCMCPU_IS_6348())
49 bcm63xx_regs_spi = bcm6348_regs_spi;
50 if (BCMCPU_IS_6358())
51 bcm63xx_regs_spi = bcm6358_regs_spi;
52 if (BCMCPU_IS_6368())
53 bcm63xx_regs_spi = bcm6368_regs_spi;
54}
55#else
56static __init void bcm63xx_spi_regs_init(void) { }
57#endif
58
59static struct resource spi_resources[] = {
60 {
61 .start = -1, /* filled at runtime */
62 .end = -1, /* filled at runtime */
63 .flags = IORESOURCE_MEM,
64 },
65 {
66 .start = -1, /* filled at runtime */
67 .flags = IORESOURCE_IRQ,
68 },
69};
70
71static struct bcm63xx_spi_pdata spi_pdata = {
72 .bus_num = 0,
73 .num_chipselect = 8,
74};
75
76static struct platform_device bcm63xx_spi_device = {
77 .name = "bcm63xx-spi",
78 .id = -1,
79 .num_resources = ARRAY_SIZE(spi_resources),
80 .resource = spi_resources,
81 .dev = {
82 .platform_data = &spi_pdata,
83 },
84};
85
86int __init bcm63xx_spi_register(void)
87{
88 struct clk *periph_clk;
89
90 if (BCMCPU_IS_6328() || BCMCPU_IS_6345())
91 return -ENODEV;
92
93 periph_clk = clk_get(NULL, "periph");
94 if (IS_ERR(periph_clk)) {
95 pr_err("unable to get periph clock\n");
96 return -ENODEV;
97 }
98
99 /* Set bus frequency */
100 spi_pdata.speed_hz = clk_get_rate(periph_clk);
101
102 spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
103 spi_resources[0].end = spi_resources[0].start;
104 spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
105
106 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
107 spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
108 spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
109 spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT;
110 spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH;
111 }
112
113 if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
114 spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
115 spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
116 spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT;
117 spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH;
118 }
119
120 bcm63xx_spi_regs_init();
121
122 return platform_device_register(&bcm63xx_spi_device);
123}
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index d6e42c60832..c2963da0253 100644
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -54,7 +54,7 @@ int __init bcm63xx_uart_register(unsigned int id)
54 if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) 54 if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
55 return -ENODEV; 55 return -ENODEV;
56 56
57 if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())) 57 if (id == 1 && !BCMCPU_IS_6358())
58 return -ENODEV; 58 return -ENODEV;
59 59
60 if (id == 0) { 60 if (id == 0) {
diff --git a/arch/mips/bcm63xx/dev-usb-usbd.c b/arch/mips/bcm63xx/dev-usb-usbd.c
deleted file mode 100644
index 508bd9d8df2..00000000000
--- a/arch/mips/bcm63xx/dev-usb-usbd.c
+++ /dev/null
@@ -1,65 +0,0 @@
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) 2012 Kevin Cernekee <cernekee@gmail.com>
8 * Copyright (C) 2012 Broadcom Corporation
9 */
10
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <bcm63xx_cpu.h>
16#include <bcm63xx_dev_usb_usbd.h>
17
18#define NUM_MMIO 2
19#define NUM_IRQ 7
20
21static struct resource usbd_resources[NUM_MMIO + NUM_IRQ];
22
23static u64 usbd_dmamask = DMA_BIT_MASK(32);
24
25static struct platform_device bcm63xx_usbd_device = {
26 .name = "bcm63xx_udc",
27 .id = -1,
28 .num_resources = ARRAY_SIZE(usbd_resources),
29 .resource = usbd_resources,
30 .dev = {
31 .dma_mask = &usbd_dmamask,
32 .coherent_dma_mask = DMA_BIT_MASK(32),
33 },
34};
35
36int __init bcm63xx_usbd_register(const struct bcm63xx_usbd_platform_data *pd)
37{
38 const int irq_list[NUM_IRQ] = { IRQ_USBD,
39 IRQ_USBD_RXDMA0, IRQ_USBD_TXDMA0,
40 IRQ_USBD_RXDMA1, IRQ_USBD_TXDMA1,
41 IRQ_USBD_RXDMA2, IRQ_USBD_TXDMA2 };
42 int i;
43
44 if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368())
45 return 0;
46
47 usbd_resources[0].start = bcm63xx_regset_address(RSET_USBD);
48 usbd_resources[0].end = usbd_resources[0].start + RSET_USBD_SIZE - 1;
49 usbd_resources[0].flags = IORESOURCE_MEM;
50
51 usbd_resources[1].start = bcm63xx_regset_address(RSET_USBDMA);
52 usbd_resources[1].end = usbd_resources[1].start + RSET_USBDMA_SIZE - 1;
53 usbd_resources[1].flags = IORESOURCE_MEM;
54
55 for (i = 0; i < NUM_IRQ; i++) {
56 struct resource *r = &usbd_resources[NUM_MMIO + i];
57
58 r->start = r->end = bcm63xx_get_irq_number(irq_list[i]);
59 r->flags = IORESOURCE_IRQ;
60 }
61
62 platform_device_add_data(&bcm63xx_usbd_device, pd, sizeof(*pd));
63
64 return platform_device_register(&bcm63xx_usbd_device);
65}
diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
index 2a2346a99bc..3e6c716a4c1 100644
--- a/arch/mips/bcm63xx/dev-wdt.c
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -21,7 +21,7 @@ static struct resource wdt_resources[] = {
21 21
22static struct platform_device bcm63xx_wdt_device = { 22static struct platform_device bcm63xx_wdt_device = {
23 .name = "bcm63xx-wdt", 23 .name = "bcm63xx-wdt",
24 .id = -1, 24 .id = 0,
25 .num_resources = ARRAY_SIZE(wdt_resources), 25 .num_resources = ARRAY_SIZE(wdt_resources),
26 .resource = wdt_resources, 26 .resource = wdt_resources,
27}; 27};
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
index a6c2135dbf3..f560fe7d38d 100644
--- a/arch/mips/bcm63xx/gpio.c
+++ b/arch/mips/bcm63xx/gpio.c
@@ -4,7 +4,7 @@
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> 6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 * Copyright (C) 2008-2011 Florian Fainelli <florian@openwrt.org> 7 * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -18,34 +18,6 @@
18#include <bcm63xx_io.h> 18#include <bcm63xx_io.h>
19#include <bcm63xx_regs.h> 19#include <bcm63xx_regs.h>
20 20
21#ifndef BCMCPU_RUNTIME_DETECT
22#define gpio_out_low_reg GPIO_DATA_LO_REG
23#ifdef CONFIG_BCM63XX_CPU_6345
24#ifdef gpio_out_low_reg
25#undef gpio_out_low_reg
26#define gpio_out_low_reg GPIO_DATA_LO_REG_6345
27#endif /* gpio_out_low_reg */
28#endif /* CONFIG_BCM63XX_CPU_6345 */
29
30static inline void bcm63xx_gpio_out_low_reg_init(void)
31{
32}
33#else /* ! BCMCPU_RUNTIME_DETECT */
34static u32 gpio_out_low_reg;
35
36static void bcm63xx_gpio_out_low_reg_init(void)
37{
38 switch (bcm63xx_get_cpu_id()) {
39 case BCM6345_CPU_ID:
40 gpio_out_low_reg = GPIO_DATA_LO_REG_6345;
41 break;
42 default:
43 gpio_out_low_reg = GPIO_DATA_LO_REG;
44 break;
45 }
46}
47#endif /* ! BCMCPU_RUNTIME_DETECT */
48
49static DEFINE_SPINLOCK(bcm63xx_gpio_lock); 21static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
50static u32 gpio_out_low, gpio_out_high; 22static u32 gpio_out_low, gpio_out_high;
51 23
@@ -61,7 +33,7 @@ static void bcm63xx_gpio_set(struct gpio_chip *chip,
61 BUG(); 33 BUG();
62 34
63 if (gpio < 32) { 35 if (gpio < 32) {
64 reg = gpio_out_low_reg; 36 reg = GPIO_DATA_LO_REG;
65 mask = 1 << gpio; 37 mask = 1 << gpio;
66 v = &gpio_out_low; 38 v = &gpio_out_low;
67 } else { 39 } else {
@@ -88,7 +60,7 @@ static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
88 BUG(); 60 BUG();
89 61
90 if (gpio < 32) { 62 if (gpio < 32) {
91 reg = gpio_out_low_reg; 63 reg = GPIO_DATA_LO_REG;
92 mask = 1 << gpio; 64 mask = 1 << gpio;
93 } else { 65 } else {
94 reg = GPIO_DATA_HI_REG; 66 reg = GPIO_DATA_HI_REG;
@@ -153,11 +125,8 @@ static struct gpio_chip bcm63xx_gpio_chip = {
153 125
154int __init bcm63xx_gpio_init(void) 126int __init bcm63xx_gpio_init(void)
155{ 127{
156 bcm63xx_gpio_out_low_reg_init(); 128 gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
157 129 gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
158 gpio_out_low = bcm_gpio_readl(gpio_out_low_reg);
159 if (!BCMCPU_IS_6345())
160 gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
161 bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count(); 130 bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
162 pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio); 131 pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
163 132
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index da24c2bd9b7..162e11b4ed7 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -19,212 +19,19 @@
19#include <bcm63xx_io.h> 19#include <bcm63xx_io.h>
20#include <bcm63xx_irq.h> 20#include <bcm63xx_irq.h>
21 21
22static void __dispatch_internal(void) __maybe_unused;
23static void __dispatch_internal_64(void) __maybe_unused;
24static void __internal_irq_mask_32(unsigned int irq) __maybe_unused;
25static void __internal_irq_mask_64(unsigned int irq) __maybe_unused;
26static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
27static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
28
29#ifndef BCMCPU_RUNTIME_DETECT
30#ifdef CONFIG_BCM63XX_CPU_6328
31#define irq_stat_reg PERF_IRQSTAT_6328_REG
32#define irq_mask_reg PERF_IRQMASK_6328_REG
33#define irq_bits 64
34#define is_ext_irq_cascaded 1
35#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
36#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
37#define ext_irq_count 4
38#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
39#define ext_irq_cfg_reg2 0
40#endif
41#ifdef CONFIG_BCM63XX_CPU_6338
42#define irq_stat_reg PERF_IRQSTAT_6338_REG
43#define irq_mask_reg PERF_IRQMASK_6338_REG
44#define irq_bits 32
45#define is_ext_irq_cascaded 0
46#define ext_irq_start 0
47#define ext_irq_end 0
48#define ext_irq_count 4
49#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6338
50#define ext_irq_cfg_reg2 0
51#endif
52#ifdef CONFIG_BCM63XX_CPU_6345
53#define irq_stat_reg PERF_IRQSTAT_6345_REG
54#define irq_mask_reg PERF_IRQMASK_6345_REG
55#define irq_bits 32
56#define is_ext_irq_cascaded 0
57#define ext_irq_start 0
58#define ext_irq_end 0
59#define ext_irq_count 4
60#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345
61#define ext_irq_cfg_reg2 0
62#endif
63#ifdef CONFIG_BCM63XX_CPU_6348
64#define irq_stat_reg PERF_IRQSTAT_6348_REG
65#define irq_mask_reg PERF_IRQMASK_6348_REG
66#define irq_bits 32
67#define is_ext_irq_cascaded 0
68#define ext_irq_start 0
69#define ext_irq_end 0
70#define ext_irq_count 4
71#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6348
72#define ext_irq_cfg_reg2 0
73#endif
74#ifdef CONFIG_BCM63XX_CPU_6358
75#define irq_stat_reg PERF_IRQSTAT_6358_REG
76#define irq_mask_reg PERF_IRQMASK_6358_REG
77#define irq_bits 32
78#define is_ext_irq_cascaded 1
79#define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE)
80#define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE)
81#define ext_irq_count 4
82#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358
83#define ext_irq_cfg_reg2 0
84#endif
85#ifdef CONFIG_BCM63XX_CPU_6368
86#define irq_stat_reg PERF_IRQSTAT_6368_REG
87#define irq_mask_reg PERF_IRQMASK_6368_REG
88#define irq_bits 64
89#define is_ext_irq_cascaded 1
90#define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE)
91#define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE)
92#define ext_irq_count 6
93#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368
94#define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368
95#endif
96
97#if irq_bits == 32
98#define dispatch_internal __dispatch_internal
99#define internal_irq_mask __internal_irq_mask_32
100#define internal_irq_unmask __internal_irq_unmask_32
101#else
102#define dispatch_internal __dispatch_internal_64
103#define internal_irq_mask __internal_irq_mask_64
104#define internal_irq_unmask __internal_irq_unmask_64
105#endif
106
107#define irq_stat_addr (bcm63xx_regset_address(RSET_PERF) + irq_stat_reg)
108#define irq_mask_addr (bcm63xx_regset_address(RSET_PERF) + irq_mask_reg)
109
110static inline void bcm63xx_init_irq(void)
111{
112}
113#else /* ! BCMCPU_RUNTIME_DETECT */
114
115static u32 irq_stat_addr, irq_mask_addr;
116static void (*dispatch_internal)(void);
117static int is_ext_irq_cascaded;
118static unsigned int ext_irq_count;
119static unsigned int ext_irq_start, ext_irq_end;
120static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2;
121static void (*internal_irq_mask)(unsigned int irq);
122static void (*internal_irq_unmask)(unsigned int irq);
123
124static void bcm63xx_init_irq(void)
125{
126 int irq_bits;
127
128 irq_stat_addr = bcm63xx_regset_address(RSET_PERF);
129 irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
130
131 switch (bcm63xx_get_cpu_id()) {
132 case BCM6328_CPU_ID:
133 irq_stat_addr += PERF_IRQSTAT_6328_REG;
134 irq_mask_addr += PERF_IRQMASK_6328_REG;
135 irq_bits = 64;
136 ext_irq_count = 4;
137 is_ext_irq_cascaded = 1;
138 ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
139 ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
140 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
141 break;
142 case BCM6338_CPU_ID:
143 irq_stat_addr += PERF_IRQSTAT_6338_REG;
144 irq_mask_addr += PERF_IRQMASK_6338_REG;
145 irq_bits = 32;
146 ext_irq_count = 4;
147 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
148 break;
149 case BCM6345_CPU_ID:
150 irq_stat_addr += PERF_IRQSTAT_6345_REG;
151 irq_mask_addr += PERF_IRQMASK_6345_REG;
152 irq_bits = 32;
153 ext_irq_count = 4;
154 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
155 break;
156 case BCM6348_CPU_ID:
157 irq_stat_addr += PERF_IRQSTAT_6348_REG;
158 irq_mask_addr += PERF_IRQMASK_6348_REG;
159 irq_bits = 32;
160 ext_irq_count = 4;
161 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
162 break;
163 case BCM6358_CPU_ID:
164 irq_stat_addr += PERF_IRQSTAT_6358_REG;
165 irq_mask_addr += PERF_IRQMASK_6358_REG;
166 irq_bits = 32;
167 ext_irq_count = 4;
168 is_ext_irq_cascaded = 1;
169 ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
170 ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
171 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
172 break;
173 case BCM6368_CPU_ID:
174 irq_stat_addr += PERF_IRQSTAT_6368_REG;
175 irq_mask_addr += PERF_IRQMASK_6368_REG;
176 irq_bits = 64;
177 ext_irq_count = 6;
178 is_ext_irq_cascaded = 1;
179 ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
180 ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
181 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
182 ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
183 break;
184 default:
185 BUG();
186 }
187
188 if (irq_bits == 32) {
189 dispatch_internal = __dispatch_internal;
190 internal_irq_mask = __internal_irq_mask_32;
191 internal_irq_unmask = __internal_irq_unmask_32;
192 } else {
193 dispatch_internal = __dispatch_internal_64;
194 internal_irq_mask = __internal_irq_mask_64;
195 internal_irq_unmask = __internal_irq_unmask_64;
196 }
197}
198#endif /* ! BCMCPU_RUNTIME_DETECT */
199
200static inline u32 get_ext_irq_perf_reg(int irq)
201{
202 if (irq < 4)
203 return ext_irq_cfg_reg1;
204 return ext_irq_cfg_reg2;
205}
206
207static inline void handle_internal(int intbit)
208{
209 if (is_ext_irq_cascaded &&
210 intbit >= ext_irq_start && intbit <= ext_irq_end)
211 do_IRQ(intbit - ext_irq_start + IRQ_EXTERNAL_BASE);
212 else
213 do_IRQ(intbit + IRQ_INTERNAL_BASE);
214}
215
216/* 22/*
217 * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not 23 * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
218 * prioritize any interrupt relatively to another. the static counter 24 * prioritize any interrupt relatively to another. the static counter
219 * will resume the loop where it ended the last time we left this 25 * will resume the loop where it ended the last time we left this
220 * function. 26 * function.
221 */ 27 */
222static void __dispatch_internal(void) 28static void bcm63xx_irq_dispatch_internal(void)
223{ 29{
224 u32 pending; 30 u32 pending;
225 static int i; 31 static int i;
226 32
227 pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr); 33 pending = bcm_perf_readl(PERF_IRQMASK_REG) &
34 bcm_perf_readl(PERF_IRQSTAT_REG);
228 35
229 if (!pending) 36 if (!pending)
230 return ; 37 return ;
@@ -234,28 +41,7 @@ static void __dispatch_internal(void)
234 41
235 i = (i + 1) & 0x1f; 42 i = (i + 1) & 0x1f;
236 if (pending & (1 << to_call)) { 43 if (pending & (1 << to_call)) {
237 handle_internal(to_call); 44 do_IRQ(to_call + IRQ_INTERNAL_BASE);
238 break;
239 }
240 }
241}
242
243static void __dispatch_internal_64(void)
244{
245 u64 pending;
246 static int i;
247
248 pending = bcm_readq(irq_stat_addr) & bcm_readq(irq_mask_addr);
249
250 if (!pending)
251 return ;
252
253 while (1) {
254 int to_call = i;
255
256 i = (i + 1) & 0x3f;
257 if (pending & (1ull << to_call)) {
258 handle_internal(to_call);
259 break; 45 break;
260 } 46 }
261 } 47 }
@@ -274,17 +60,15 @@ asmlinkage void plat_irq_dispatch(void)
274 if (cause & CAUSEF_IP7) 60 if (cause & CAUSEF_IP7)
275 do_IRQ(7); 61 do_IRQ(7);
276 if (cause & CAUSEF_IP2) 62 if (cause & CAUSEF_IP2)
277 dispatch_internal(); 63 bcm63xx_irq_dispatch_internal();
278 if (!is_ext_irq_cascaded) { 64 if (cause & CAUSEF_IP3)
279 if (cause & CAUSEF_IP3) 65 do_IRQ(IRQ_EXT_0);
280 do_IRQ(IRQ_EXT_0); 66 if (cause & CAUSEF_IP4)
281 if (cause & CAUSEF_IP4) 67 do_IRQ(IRQ_EXT_1);
282 do_IRQ(IRQ_EXT_1); 68 if (cause & CAUSEF_IP5)
283 if (cause & CAUSEF_IP5) 69 do_IRQ(IRQ_EXT_2);
284 do_IRQ(IRQ_EXT_2); 70 if (cause & CAUSEF_IP6)
285 if (cause & CAUSEF_IP6) 71 do_IRQ(IRQ_EXT_3);
286 do_IRQ(IRQ_EXT_3);
287 }
288 } while (1); 72 } while (1);
289} 73}
290 74
@@ -292,50 +76,24 @@ asmlinkage void plat_irq_dispatch(void)
292 * internal IRQs operations: only mask/unmask on PERF irq mask 76 * internal IRQs operations: only mask/unmask on PERF irq mask
293 * register. 77 * register.
294 */ 78 */
295static void __internal_irq_mask_32(unsigned int irq) 79static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
296{ 80{
81 unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
297 u32 mask; 82 u32 mask;
298 83
299 mask = bcm_readl(irq_mask_addr); 84 mask = bcm_perf_readl(PERF_IRQMASK_REG);
300 mask &= ~(1 << irq); 85 mask &= ~(1 << irq);
301 bcm_writel(mask, irq_mask_addr); 86 bcm_perf_writel(mask, PERF_IRQMASK_REG);
302}
303
304static void __internal_irq_mask_64(unsigned int irq)
305{
306 u64 mask;
307
308 mask = bcm_readq(irq_mask_addr);
309 mask &= ~(1ull << irq);
310 bcm_writeq(mask, irq_mask_addr);
311} 87}
312 88
313static void __internal_irq_unmask_32(unsigned int irq) 89static void bcm63xx_internal_irq_unmask(struct irq_data *d)
314{ 90{
91 unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
315 u32 mask; 92 u32 mask;
316 93
317 mask = bcm_readl(irq_mask_addr); 94 mask = bcm_perf_readl(PERF_IRQMASK_REG);
318 mask |= (1 << irq); 95 mask |= (1 << irq);
319 bcm_writel(mask, irq_mask_addr); 96 bcm_perf_writel(mask, PERF_IRQMASK_REG);
320}
321
322static void __internal_irq_unmask_64(unsigned int irq)
323{
324 u64 mask;
325
326 mask = bcm_readq(irq_mask_addr);
327 mask |= (1ull << irq);
328 bcm_writeq(mask, irq_mask_addr);
329}
330
331static void bcm63xx_internal_irq_mask(struct irq_data *d)
332{
333 internal_irq_mask(d->irq - IRQ_INTERNAL_BASE);
334}
335
336static void bcm63xx_internal_irq_unmask(struct irq_data *d)
337{
338 internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE);
339} 97}
340 98
341/* 99/*
@@ -344,139 +102,94 @@ static void bcm63xx_internal_irq_unmask(struct irq_data *d)
344 */ 102 */
345static void bcm63xx_external_irq_mask(struct irq_data *d) 103static void bcm63xx_external_irq_mask(struct irq_data *d)
346{ 104{
347 unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; 105 unsigned int irq = d->irq - IRQ_EXT_BASE;
348 u32 reg, regaddr; 106 u32 reg;
349
350 regaddr = get_ext_irq_perf_reg(irq);
351 reg = bcm_perf_readl(regaddr);
352 107
353 if (BCMCPU_IS_6348()) 108 reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
354 reg &= ~EXTIRQ_CFG_MASK_6348(irq % 4); 109 reg &= ~EXTIRQ_CFG_MASK(irq);
355 else 110 bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
356 reg &= ~EXTIRQ_CFG_MASK(irq % 4);
357
358 bcm_perf_writel(reg, regaddr);
359 if (is_ext_irq_cascaded)
360 internal_irq_mask(irq + ext_irq_start);
361} 111}
362 112
363static void bcm63xx_external_irq_unmask(struct irq_data *d) 113static void bcm63xx_external_irq_unmask(struct irq_data *d)
364{ 114{
365 unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; 115 unsigned int irq = d->irq - IRQ_EXT_BASE;
366 u32 reg, regaddr; 116 u32 reg;
367
368 regaddr = get_ext_irq_perf_reg(irq);
369 reg = bcm_perf_readl(regaddr);
370
371 if (BCMCPU_IS_6348())
372 reg |= EXTIRQ_CFG_MASK_6348(irq % 4);
373 else
374 reg |= EXTIRQ_CFG_MASK(irq % 4);
375 117
376 bcm_perf_writel(reg, regaddr); 118 reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
377 119 reg |= EXTIRQ_CFG_MASK(irq);
378 if (is_ext_irq_cascaded) 120 bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
379 internal_irq_unmask(irq + ext_irq_start);
380} 121}
381 122
382static void bcm63xx_external_irq_clear(struct irq_data *d) 123static void bcm63xx_external_irq_clear(struct irq_data *d)
383{ 124{
384 unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; 125 unsigned int irq = d->irq - IRQ_EXT_BASE;
385 u32 reg, regaddr; 126 u32 reg;
386 127
387 regaddr = get_ext_irq_perf_reg(irq); 128 reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
388 reg = bcm_perf_readl(regaddr); 129 reg |= EXTIRQ_CFG_CLEAR(irq);
130 bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
131}
389 132
390 if (BCMCPU_IS_6348()) 133static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
391 reg |= EXTIRQ_CFG_CLEAR_6348(irq % 4); 134{
392 else 135 set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
393 reg |= EXTIRQ_CFG_CLEAR(irq % 4); 136 irq_enable_hazard();
137 bcm63xx_external_irq_unmask(d);
138 return 0;
139}
394 140
395 bcm_perf_writel(reg, regaddr); 141static void bcm63xx_external_irq_shutdown(struct irq_data *d)
142{
143 bcm63xx_external_irq_mask(d);
144 clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
145 irq_disable_hazard();
396} 146}
397 147
398static int bcm63xx_external_irq_set_type(struct irq_data *d, 148static int bcm63xx_external_irq_set_type(struct irq_data *d,
399 unsigned int flow_type) 149 unsigned int flow_type)
400{ 150{
401 unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; 151 unsigned int irq = d->irq - IRQ_EXT_BASE;
402 u32 reg, regaddr; 152 u32 reg;
403 int levelsense, sense, bothedge;
404 153
405 flow_type &= IRQ_TYPE_SENSE_MASK; 154 flow_type &= IRQ_TYPE_SENSE_MASK;
406 155
407 if (flow_type == IRQ_TYPE_NONE) 156 if (flow_type == IRQ_TYPE_NONE)
408 flow_type = IRQ_TYPE_LEVEL_LOW; 157 flow_type = IRQ_TYPE_LEVEL_LOW;
409 158
410 levelsense = sense = bothedge = 0; 159 reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
411 switch (flow_type) { 160 switch (flow_type) {
412 case IRQ_TYPE_EDGE_BOTH: 161 case IRQ_TYPE_EDGE_BOTH:
413 bothedge = 1; 162 reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
163 reg |= EXTIRQ_CFG_BOTHEDGE(irq);
414 break; 164 break;
415 165
416 case IRQ_TYPE_EDGE_RISING: 166 case IRQ_TYPE_EDGE_RISING:
417 sense = 1; 167 reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
168 reg |= EXTIRQ_CFG_SENSE(irq);
169 reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
418 break; 170 break;
419 171
420 case IRQ_TYPE_EDGE_FALLING: 172 case IRQ_TYPE_EDGE_FALLING:
173 reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
174 reg &= ~EXTIRQ_CFG_SENSE(irq);
175 reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
421 break; 176 break;
422 177
423 case IRQ_TYPE_LEVEL_HIGH: 178 case IRQ_TYPE_LEVEL_HIGH:
424 levelsense = 1; 179 reg |= EXTIRQ_CFG_LEVELSENSE(irq);
425 sense = 1; 180 reg |= EXTIRQ_CFG_SENSE(irq);
426 break; 181 break;
427 182
428 case IRQ_TYPE_LEVEL_LOW: 183 case IRQ_TYPE_LEVEL_LOW:
429 levelsense = 1; 184 reg |= EXTIRQ_CFG_LEVELSENSE(irq);
185 reg &= ~EXTIRQ_CFG_SENSE(irq);
430 break; 186 break;
431 187
432 default: 188 default:
433 printk(KERN_ERR "bogus flow type combination given !\n"); 189 printk(KERN_ERR "bogus flow type combination given !\n");
434 return -EINVAL; 190 return -EINVAL;
435 } 191 }
436 192 bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
437 regaddr = get_ext_irq_perf_reg(irq);
438 reg = bcm_perf_readl(regaddr);
439 irq %= 4;
440
441 switch (bcm63xx_get_cpu_id()) {
442 case BCM6348_CPU_ID:
443 if (levelsense)
444 reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
445 else
446 reg &= ~EXTIRQ_CFG_LEVELSENSE_6348(irq);
447 if (sense)
448 reg |= EXTIRQ_CFG_SENSE_6348(irq);
449 else
450 reg &= ~EXTIRQ_CFG_SENSE_6348(irq);
451 if (bothedge)
452 reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
453 else
454 reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
455 break;
456
457 case BCM6328_CPU_ID:
458 case BCM6338_CPU_ID:
459 case BCM6345_CPU_ID:
460 case BCM6358_CPU_ID:
461 case BCM6368_CPU_ID:
462 if (levelsense)
463 reg |= EXTIRQ_CFG_LEVELSENSE(irq);
464 else
465 reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
466 if (sense)
467 reg |= EXTIRQ_CFG_SENSE(irq);
468 else
469 reg &= ~EXTIRQ_CFG_SENSE(irq);
470 if (bothedge)
471 reg |= EXTIRQ_CFG_BOTHEDGE(irq);
472 else
473 reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
474 break;
475 default:
476 BUG();
477 }
478
479 bcm_perf_writel(reg, regaddr);
480 193
481 irqd_set_trigger_type(d, flow_type); 194 irqd_set_trigger_type(d, flow_type);
482 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) 195 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -495,6 +208,9 @@ static struct irq_chip bcm63xx_internal_irq_chip = {
495 208
496static struct irq_chip bcm63xx_external_irq_chip = { 209static struct irq_chip bcm63xx_external_irq_chip = {
497 .name = "bcm63xx_epic", 210 .name = "bcm63xx_epic",
211 .irq_startup = bcm63xx_external_irq_startup,
212 .irq_shutdown = bcm63xx_external_irq_shutdown,
213
498 .irq_ack = bcm63xx_external_irq_clear, 214 .irq_ack = bcm63xx_external_irq_clear,
499 215
500 .irq_mask = bcm63xx_external_irq_mask, 216 .irq_mask = bcm63xx_external_irq_mask,
@@ -509,30 +225,18 @@ static struct irqaction cpu_ip2_cascade_action = {
509 .flags = IRQF_NO_THREAD, 225 .flags = IRQF_NO_THREAD,
510}; 226};
511 227
512static struct irqaction cpu_ext_cascade_action = {
513 .handler = no_action,
514 .name = "cascade_extirq",
515 .flags = IRQF_NO_THREAD,
516};
517
518void __init arch_init_irq(void) 228void __init arch_init_irq(void)
519{ 229{
520 int i; 230 int i;
521 231
522 bcm63xx_init_irq();
523 mips_cpu_irq_init(); 232 mips_cpu_irq_init();
524 for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i) 233 for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
525 irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip, 234 irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
526 handle_level_irq); 235 handle_level_irq);
527 236
528 for (i = IRQ_EXTERNAL_BASE; i < IRQ_EXTERNAL_BASE + ext_irq_count; ++i) 237 for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
529 irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip, 238 irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
530 handle_edge_irq); 239 handle_edge_irq);
531 240
532 if (!is_ext_irq_cascaded) { 241 setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
533 for (i = 3; i < 3 + ext_irq_count; ++i)
534 setup_irq(MIPS_CPU_IRQ_BASE + i, &cpu_ext_cascade_action);
535 }
536
537 setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
538} 242}
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c
deleted file mode 100644
index 62061168083..00000000000
--- a/arch/mips/bcm63xx/nvram.c
+++ /dev/null
@@ -1,107 +0,0 @@
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 * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
9 */
10
11#define pr_fmt(fmt) "bcm63xx_nvram: " fmt
12
13#include <linux/init.h>
14#include <linux/crc32.h>
15#include <linux/export.h>
16#include <linux/kernel.h>
17#include <linux/if_ether.h>
18
19#include <bcm63xx_nvram.h>
20
21/*
22 * nvram structure
23 */
24struct bcm963xx_nvram {
25 u32 version;
26 u8 reserved1[256];
27 u8 name[16];
28 u32 main_tp_number;
29 u32 psi_size;
30 u32 mac_addr_count;
31 u8 mac_addr_base[ETH_ALEN];
32 u8 reserved2[2];
33 u32 checksum_old;
34 u8 reserved3[720];
35 u32 checksum_high;
36};
37
38static struct bcm963xx_nvram nvram;
39static int mac_addr_used;
40
41int __init bcm63xx_nvram_init(void *addr)
42{
43 unsigned int check_len;
44 u32 crc, expected_crc;
45
46 /* extract nvram data */
47 memcpy(&nvram, addr, sizeof(nvram));
48
49 /* check checksum before using data */
50 if (nvram.version <= 4) {
51 check_len = offsetof(struct bcm963xx_nvram, reserved3);
52 expected_crc = nvram.checksum_old;
53 nvram.checksum_old = 0;
54 } else {
55 check_len = sizeof(nvram);
56 expected_crc = nvram.checksum_high;
57 nvram.checksum_high = 0;
58 }
59
60 crc = crc32_le(~0, (u8 *)&nvram, check_len);
61
62 if (crc != expected_crc)
63 return -EINVAL;
64
65 return 0;
66}
67
68u8 *bcm63xx_nvram_get_name(void)
69{
70 return nvram.name;
71}
72EXPORT_SYMBOL(bcm63xx_nvram_get_name);
73
74int bcm63xx_nvram_get_mac_address(u8 *mac)
75{
76 u8 *oui;
77 int count;
78
79 if (mac_addr_used >= nvram.mac_addr_count) {
80 pr_err("not enough mac addresses\n");
81 return -ENODEV;
82 }
83
84 memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
85 oui = mac + ETH_ALEN/2 - 1;
86 count = mac_addr_used;
87
88 while (count--) {
89 u8 *p = mac + ETH_ALEN - 1;
90
91 do {
92 (*p)++;
93 if (*p != 0)
94 break;
95 p--;
96 } while (p != oui);
97
98 if (p == oui) {
99 pr_err("unable to fetch mac address\n");
100 return -ENODEV;
101 }
102 }
103
104 mac_addr_used++;
105 return 0;
106}
107EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address);
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index 10eaff45807..be252efa075 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -26,20 +26,15 @@ void __init prom_init(void)
26 bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); 26 bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
27 27
28 /* disable all hardware blocks clock for now */ 28 /* disable all hardware blocks clock for now */
29 if (BCMCPU_IS_6328()) 29 if (BCMCPU_IS_6338())
30 mask = CKCTL_6328_ALL_SAFE_EN;
31 else if (BCMCPU_IS_6338())
32 mask = CKCTL_6338_ALL_SAFE_EN; 30 mask = CKCTL_6338_ALL_SAFE_EN;
33 else if (BCMCPU_IS_6345()) 31 else if (BCMCPU_IS_6345())
34 mask = CKCTL_6345_ALL_SAFE_EN; 32 mask = CKCTL_6345_ALL_SAFE_EN;
35 else if (BCMCPU_IS_6348()) 33 else if (BCMCPU_IS_6348())
36 mask = CKCTL_6348_ALL_SAFE_EN; 34 mask = CKCTL_6348_ALL_SAFE_EN;
37 else if (BCMCPU_IS_6358())
38 mask = CKCTL_6358_ALL_SAFE_EN;
39 else if (BCMCPU_IS_6368())
40 mask = CKCTL_6368_ALL_SAFE_EN;
41 else 35 else
42 mask = 0; 36 /* BCMCPU_IS_6358() */
37 mask = CKCTL_6358_ALL_SAFE_EN;
43 38
44 reg = bcm_perf_readl(PERF_CKCTL_REG); 39 reg = bcm_perf_readl(PERF_CKCTL_REG);
45 reg &= ~mask; 40 reg &= ~mask;
diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c
deleted file mode 100644
index 68a31bb90cb..00000000000
--- a/arch/mips/bcm63xx/reset.c
+++ /dev/null
@@ -1,223 +0,0 @@
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) 2012 Jonas Gorski <jonas.gorski@gmail.com>
7 */
8
9#include <linux/module.h>
10#include <linux/mutex.h>
11#include <linux/err.h>
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <bcm63xx_cpu.h>
15#include <bcm63xx_io.h>
16#include <bcm63xx_regs.h>
17#include <bcm63xx_reset.h>
18
19#define __GEN_RESET_BITS_TABLE(__cpu) \
20 [BCM63XX_RESET_SPI] = BCM## __cpu ##_RESET_SPI, \
21 [BCM63XX_RESET_ENET] = BCM## __cpu ##_RESET_ENET, \
22 [BCM63XX_RESET_USBH] = BCM## __cpu ##_RESET_USBH, \
23 [BCM63XX_RESET_USBD] = BCM## __cpu ##_RESET_USBD, \
24 [BCM63XX_RESET_DSL] = BCM## __cpu ##_RESET_DSL, \
25 [BCM63XX_RESET_SAR] = BCM## __cpu ##_RESET_SAR, \
26 [BCM63XX_RESET_EPHY] = BCM## __cpu ##_RESET_EPHY, \
27 [BCM63XX_RESET_ENETSW] = BCM## __cpu ##_RESET_ENETSW, \
28 [BCM63XX_RESET_PCM] = BCM## __cpu ##_RESET_PCM, \
29 [BCM63XX_RESET_MPI] = BCM## __cpu ##_RESET_MPI, \
30 [BCM63XX_RESET_PCIE] = BCM## __cpu ##_RESET_PCIE, \
31 [BCM63XX_RESET_PCIE_EXT] = BCM## __cpu ##_RESET_PCIE_EXT,
32
33#define BCM6328_RESET_SPI SOFTRESET_6328_SPI_MASK
34#define BCM6328_RESET_ENET 0
35#define BCM6328_RESET_USBH SOFTRESET_6328_USBH_MASK
36#define BCM6328_RESET_USBD SOFTRESET_6328_USBS_MASK
37#define BCM6328_RESET_DSL 0
38#define BCM6328_RESET_SAR SOFTRESET_6328_SAR_MASK
39#define BCM6328_RESET_EPHY SOFTRESET_6328_EPHY_MASK
40#define BCM6328_RESET_ENETSW SOFTRESET_6328_ENETSW_MASK
41#define BCM6328_RESET_PCM SOFTRESET_6328_PCM_MASK
42#define BCM6328_RESET_MPI 0
43#define BCM6328_RESET_PCIE \
44 (SOFTRESET_6328_PCIE_MASK | \
45 SOFTRESET_6328_PCIE_CORE_MASK | \
46 SOFTRESET_6328_PCIE_HARD_MASK)
47#define BCM6328_RESET_PCIE_EXT SOFTRESET_6328_PCIE_EXT_MASK
48
49#define BCM6338_RESET_SPI SOFTRESET_6338_SPI_MASK
50#define BCM6338_RESET_ENET SOFTRESET_6338_ENET_MASK
51#define BCM6338_RESET_USBH SOFTRESET_6338_USBH_MASK
52#define BCM6338_RESET_USBD SOFTRESET_6338_USBS_MASK
53#define BCM6338_RESET_DSL SOFTRESET_6338_ADSL_MASK
54#define BCM6338_RESET_SAR SOFTRESET_6338_SAR_MASK
55#define BCM6338_RESET_EPHY 0
56#define BCM6338_RESET_ENETSW 0
57#define BCM6338_RESET_PCM 0
58#define BCM6338_RESET_MPI 0
59#define BCM6338_RESET_PCIE 0
60#define BCM6338_RESET_PCIE_EXT 0
61
62#define BCM6348_RESET_SPI SOFTRESET_6348_SPI_MASK
63#define BCM6348_RESET_ENET SOFTRESET_6348_ENET_MASK
64#define BCM6348_RESET_USBH SOFTRESET_6348_USBH_MASK
65#define BCM6348_RESET_USBD SOFTRESET_6348_USBS_MASK
66#define BCM6348_RESET_DSL SOFTRESET_6348_ADSL_MASK
67#define BCM6348_RESET_SAR SOFTRESET_6348_SAR_MASK
68#define BCM6348_RESET_EPHY 0
69#define BCM6348_RESET_ENETSW 0
70#define BCM6348_RESET_PCM 0
71#define BCM6348_RESET_MPI 0
72#define BCM6348_RESET_PCIE 0
73#define BCM6348_RESET_PCIE_EXT 0
74
75#define BCM6358_RESET_SPI SOFTRESET_6358_SPI_MASK
76#define BCM6358_RESET_ENET SOFTRESET_6358_ENET_MASK
77#define BCM6358_RESET_USBH SOFTRESET_6358_USBH_MASK
78#define BCM6358_RESET_USBD 0
79#define BCM6358_RESET_DSL SOFTRESET_6358_ADSL_MASK
80#define BCM6358_RESET_SAR SOFTRESET_6358_SAR_MASK
81#define BCM6358_RESET_EPHY SOFTRESET_6358_EPHY_MASK
82#define BCM6358_RESET_ENETSW 0
83#define BCM6358_RESET_PCM SOFTRESET_6358_PCM_MASK
84#define BCM6358_RESET_MPI SOFTRESET_6358_MPI_MASK
85#define BCM6358_RESET_PCIE 0
86#define BCM6358_RESET_PCIE_EXT 0
87
88#define BCM6368_RESET_SPI SOFTRESET_6368_SPI_MASK
89#define BCM6368_RESET_ENET 0
90#define BCM6368_RESET_USBH SOFTRESET_6368_USBH_MASK
91#define BCM6368_RESET_USBD SOFTRESET_6368_USBS_MASK
92#define BCM6368_RESET_DSL 0
93#define BCM6368_RESET_SAR SOFTRESET_6368_SAR_MASK
94#define BCM6368_RESET_EPHY SOFTRESET_6368_EPHY_MASK
95#define BCM6368_RESET_ENETSW 0
96#define BCM6368_RESET_PCM SOFTRESET_6368_PCM_MASK
97#define BCM6368_RESET_MPI SOFTRESET_6368_MPI_MASK
98#define BCM6368_RESET_PCIE 0
99#define BCM6368_RESET_PCIE_EXT 0
100
101#ifdef BCMCPU_RUNTIME_DETECT
102
103/*
104 * core reset bits
105 */
106static const u32 bcm6328_reset_bits[] = {
107 __GEN_RESET_BITS_TABLE(6328)
108};
109
110static const u32 bcm6338_reset_bits[] = {
111 __GEN_RESET_BITS_TABLE(6338)
112};
113
114static const u32 bcm6348_reset_bits[] = {
115 __GEN_RESET_BITS_TABLE(6348)
116};
117
118static const u32 bcm6358_reset_bits[] = {
119 __GEN_RESET_BITS_TABLE(6358)
120};
121
122static const u32 bcm6368_reset_bits[] = {
123 __GEN_RESET_BITS_TABLE(6368)
124};
125
126const u32 *bcm63xx_reset_bits;
127static int reset_reg;
128
129static int __init bcm63xx_reset_bits_init(void)
130{
131 if (BCMCPU_IS_6328()) {
132 reset_reg = PERF_SOFTRESET_6328_REG;
133 bcm63xx_reset_bits = bcm6328_reset_bits;
134 } else if (BCMCPU_IS_6338()) {
135 reset_reg = PERF_SOFTRESET_REG;
136 bcm63xx_reset_bits = bcm6338_reset_bits;
137 } else if (BCMCPU_IS_6348()) {
138 reset_reg = PERF_SOFTRESET_REG;
139 bcm63xx_reset_bits = bcm6348_reset_bits;
140 } else if (BCMCPU_IS_6358()) {
141 reset_reg = PERF_SOFTRESET_6358_REG;
142 bcm63xx_reset_bits = bcm6358_reset_bits;
143 } else if (BCMCPU_IS_6368()) {
144 reset_reg = PERF_SOFTRESET_6368_REG;
145 bcm63xx_reset_bits = bcm6368_reset_bits;
146 }
147
148 return 0;
149}
150#else
151
152#ifdef CONFIG_BCM63XX_CPU_6328
153static const u32 bcm63xx_reset_bits[] = {
154 __GEN_RESET_BITS_TABLE(6328)
155};
156#define reset_reg PERF_SOFTRESET_6328_REG
157#endif
158
159#ifdef CONFIG_BCM63XX_CPU_6338
160static const u32 bcm63xx_reset_bits[] = {
161 __GEN_RESET_BITS_TABLE(6338)
162};
163#define reset_reg PERF_SOFTRESET_REG
164#endif
165
166#ifdef CONFIG_BCM63XX_CPU_6345
167static const u32 bcm63xx_reset_bits[] = { };
168#define reset_reg 0
169#endif
170
171#ifdef CONFIG_BCM63XX_CPU_6348
172static const u32 bcm63xx_reset_bits[] = {
173 __GEN_RESET_BITS_TABLE(6348)
174};
175#define reset_reg PERF_SOFTRESET_REG
176#endif
177
178#ifdef CONFIG_BCM63XX_CPU_6358
179static const u32 bcm63xx_reset_bits[] = {
180 __GEN_RESET_BITS_TABLE(6358)
181};
182#define reset_reg PERF_SOFTRESET_6358_REG
183#endif
184
185#ifdef CONFIG_BCM63XX_CPU_6368
186static const u32 bcm63xx_reset_bits[] = {
187 __GEN_RESET_BITS_TABLE(6368)
188};
189#define reset_reg PERF_SOFTRESET_6368_REG
190#endif
191
192static int __init bcm63xx_reset_bits_init(void) { return 0; }
193#endif
194
195static DEFINE_SPINLOCK(reset_mutex);
196
197static void __bcm63xx_core_set_reset(u32 mask, int enable)
198{
199 unsigned long flags;
200 u32 val;
201
202 if (!mask)
203 return;
204
205 spin_lock_irqsave(&reset_mutex, flags);
206 val = bcm_perf_readl(reset_reg);
207
208 if (enable)
209 val &= ~mask;
210 else
211 val |= mask;
212
213 bcm_perf_writel(val, reset_reg);
214 spin_unlock_irqrestore(&reset_mutex, flags);
215}
216
217void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset)
218{
219 __bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset);
220}
221EXPORT_SYMBOL(bcm63xx_core_set_reset);
222
223postcore_initcall(bcm63xx_reset_bits_init);
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 314231be788..d0056598fbf 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -33,7 +33,7 @@ static void bcm6348_a1_reboot(void)
33 u32 reg; 33 u32 reg;
34 34
35 /* soft reset all blocks */ 35 /* soft reset all blocks */
36 printk(KERN_INFO "soft-resetting all blocks ...\n"); 36 printk(KERN_INFO "soft-reseting all blocks ...\n");
37 reg = bcm_perf_readl(PERF_SOFTRESET_REG); 37 reg = bcm_perf_readl(PERF_SOFTRESET_REG);
38 reg &= ~SOFTRESET_6348_ALL; 38 reg &= ~SOFTRESET_6348_ALL;
39 bcm_perf_writel(reg, PERF_SOFTRESET_REG); 39 bcm_perf_writel(reg, PERF_SOFTRESET_REG);
@@ -63,54 +63,21 @@ static void bcm6348_a1_reboot(void)
63 63
64void bcm63xx_machine_reboot(void) 64void bcm63xx_machine_reboot(void)
65{ 65{
66 u32 reg, perf_regs[2] = { 0, 0 }; 66 u32 reg;
67 unsigned int i;
68 67
69 /* mask and clear all external irq */ 68 /* mask and clear all external irq */
70 switch (bcm63xx_get_cpu_id()) { 69 reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
71 case BCM6328_CPU_ID: 70 reg &= ~EXTIRQ_CFG_MASK_ALL;
72 perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328; 71 reg |= EXTIRQ_CFG_CLEAR_ALL;
73 break; 72 bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
74 case BCM6338_CPU_ID:
75 perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
76 break;
77 case BCM6345_CPU_ID:
78 perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
79 break;
80 case BCM6348_CPU_ID:
81 perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
82 break;
83 case BCM6358_CPU_ID:
84 perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358;
85 break;
86 }
87
88 for (i = 0; i < 2; i++) {
89 if (!perf_regs[i])
90 break;
91
92 reg = bcm_perf_readl(perf_regs[i]);
93 if (BCMCPU_IS_6348()) {
94 reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
95 reg |= EXTIRQ_CFG_CLEAR_ALL_6348;
96 } else {
97 reg &= ~EXTIRQ_CFG_MASK_ALL;
98 reg |= EXTIRQ_CFG_CLEAR_ALL;
99 }
100 bcm_perf_writel(reg, perf_regs[i]);
101 }
102 73
103 if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1)) 74 if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
104 bcm6348_a1_reboot(); 75 bcm6348_a1_reboot();
105 76
106 printk(KERN_INFO "triggering watchdog soft-reset...\n"); 77 printk(KERN_INFO "triggering watchdog soft-reset...\n");
107 if (BCMCPU_IS_6328()) { 78 reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
108 bcm_wdt_writel(1, WDT_SOFTRESET_REG); 79 reg |= SYS_PLL_SOFT_RESET;
109 } else { 80 bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
110 reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
111 reg |= SYS_PLL_SOFT_RESET;
112 bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
113 }
114 while (1) 81 while (1)
115 ; 82 ;
116} 83}
@@ -157,4 +124,4 @@ int __init bcm63xx_register_devices(void)
157 return board_register_devices(); 124 return board_register_devices();
158} 125}
159 126
160device_initcall(bcm63xx_register_devices); 127arch_initcall(bcm63xx_register_devices);