diff options
Diffstat (limited to 'arch/mips/bcm63xx')
-rw-r--r-- | arch/mips/bcm63xx/Makefile | 7 | ||||
-rw-r--r-- | arch/mips/bcm63xx/boards/board_bcm963xx.c | 71 | ||||
-rw-r--r-- | arch/mips/bcm63xx/clk.c | 34 | ||||
-rw-r--r-- | arch/mips/bcm63xx/nvram.c | 107 | ||||
-rw-r--r-- | arch/mips/bcm63xx/reset.c | 223 |
5 files changed, 365 insertions, 77 deletions
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile index 9bbb30a9dc20..ac2807397c1c 100644 --- a/arch/mips/bcm63xx/Makefile +++ b/arch/mips/bcm63xx/Makefile | |||
@@ -1,6 +1,7 @@ | |||
1 | obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ | 1 | obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \ |
2 | dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ | 2 | setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \ |
3 | dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o | 3 | dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \ |
4 | dev-usb-usbd.o | ||
4 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 5 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
5 | 6 | ||
6 | obj-y += boards/ | 7 | obj-y += boards/ |
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index 1cd4d73f23c7..73be9b349690 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <bcm63xx_dev_uart.h> | 18 | #include <bcm63xx_dev_uart.h> |
19 | #include <bcm63xx_regs.h> | 19 | #include <bcm63xx_regs.h> |
20 | #include <bcm63xx_io.h> | 20 | #include <bcm63xx_io.h> |
21 | #include <bcm63xx_nvram.h> | ||
21 | #include <bcm63xx_dev_pci.h> | 22 | #include <bcm63xx_dev_pci.h> |
22 | #include <bcm63xx_dev_enet.h> | 23 | #include <bcm63xx_dev_enet.h> |
23 | #include <bcm63xx_dev_dsp.h> | 24 | #include <bcm63xx_dev_dsp.h> |
@@ -29,8 +30,6 @@ | |||
29 | 30 | ||
30 | #define PFX "board_bcm963xx: " | 31 | #define PFX "board_bcm963xx: " |
31 | 32 | ||
32 | static struct bcm963xx_nvram nvram; | ||
33 | static unsigned int mac_addr_used; | ||
34 | static struct board_info board; | 33 | static struct board_info board; |
35 | 34 | ||
36 | /* | 35 | /* |
@@ -716,50 +715,14 @@ const char *board_get_name(void) | |||
716 | } | 715 | } |
717 | 716 | ||
718 | /* | 717 | /* |
719 | * register & return a new board mac address | ||
720 | */ | ||
721 | static int board_get_mac_address(u8 *mac) | ||
722 | { | ||
723 | u8 *oui; | ||
724 | int count; | ||
725 | |||
726 | if (mac_addr_used >= nvram.mac_addr_count) { | ||
727 | printk(KERN_ERR PFX "not enough mac address\n"); | ||
728 | return -ENODEV; | ||
729 | } | ||
730 | |||
731 | memcpy(mac, nvram.mac_addr_base, ETH_ALEN); | ||
732 | oui = mac + ETH_ALEN/2 - 1; | ||
733 | count = mac_addr_used; | ||
734 | |||
735 | while (count--) { | ||
736 | u8 *p = mac + ETH_ALEN - 1; | ||
737 | |||
738 | do { | ||
739 | (*p)++; | ||
740 | if (*p != 0) | ||
741 | break; | ||
742 | p--; | ||
743 | } while (p != oui); | ||
744 | |||
745 | if (p == oui) { | ||
746 | printk(KERN_ERR PFX "unable to fetch mac address\n"); | ||
747 | return -ENODEV; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | mac_addr_used++; | ||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | /* | ||
756 | * early init callback, read nvram data from flash and checksum it | 718 | * early init callback, read nvram data from flash and checksum it |
757 | */ | 719 | */ |
758 | void __init board_prom_init(void) | 720 | void __init board_prom_init(void) |
759 | { | 721 | { |
760 | unsigned int check_len, i; | 722 | unsigned int i; |
761 | u8 *boot_addr, *cfe, *p; | 723 | u8 *boot_addr, *cfe; |
762 | char cfe_version[32]; | 724 | char cfe_version[32]; |
725 | char *board_name; | ||
763 | u32 val; | 726 | u32 val; |
764 | 727 | ||
765 | /* read base address of boot chip select (0) | 728 | /* read base address of boot chip select (0) |
@@ -782,27 +745,15 @@ void __init board_prom_init(void) | |||
782 | strcpy(cfe_version, "unknown"); | 745 | strcpy(cfe_version, "unknown"); |
783 | printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); | 746 | printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); |
784 | 747 | ||
785 | /* extract nvram data */ | 748 | if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { |
786 | memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); | ||
787 | |||
788 | /* check checksum before using data */ | ||
789 | if (nvram.version <= 4) | ||
790 | check_len = offsetof(struct bcm963xx_nvram, checksum_old); | ||
791 | else | ||
792 | check_len = sizeof(nvram); | ||
793 | val = 0; | ||
794 | p = (u8 *)&nvram; | ||
795 | while (check_len--) | ||
796 | val += *p; | ||
797 | if (val) { | ||
798 | printk(KERN_ERR PFX "invalid nvram checksum\n"); | 749 | printk(KERN_ERR PFX "invalid nvram checksum\n"); |
799 | return; | 750 | return; |
800 | } | 751 | } |
801 | 752 | ||
753 | board_name = bcm63xx_nvram_get_name(); | ||
802 | /* find board by name */ | 754 | /* find board by name */ |
803 | for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { | 755 | for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { |
804 | if (strncmp(nvram.name, bcm963xx_boards[i]->name, | 756 | if (strncmp(board_name, bcm963xx_boards[i]->name, 16)) |
805 | sizeof(nvram.name))) | ||
806 | continue; | 757 | continue; |
807 | /* copy, board desc array is marked initdata */ | 758 | /* copy, board desc array is marked initdata */ |
808 | memcpy(&board, bcm963xx_boards[i], sizeof(board)); | 759 | memcpy(&board, bcm963xx_boards[i], sizeof(board)); |
@@ -812,7 +763,7 @@ void __init board_prom_init(void) | |||
812 | /* bail out if board is not found, will complain later */ | 763 | /* bail out if board is not found, will complain later */ |
813 | if (!board.name[0]) { | 764 | if (!board.name[0]) { |
814 | char name[17]; | 765 | char name[17]; |
815 | memcpy(name, nvram.name, 16); | 766 | memcpy(name, board_name, 16); |
816 | name[16] = 0; | 767 | name[16] = 0; |
817 | printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", | 768 | printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", |
818 | name); | 769 | name); |
@@ -890,11 +841,11 @@ int __init board_register_devices(void) | |||
890 | bcm63xx_pcmcia_register(); | 841 | bcm63xx_pcmcia_register(); |
891 | 842 | ||
892 | if (board.has_enet0 && | 843 | if (board.has_enet0 && |
893 | !board_get_mac_address(board.enet0.mac_addr)) | 844 | !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) |
894 | bcm63xx_enet_register(0, &board.enet0); | 845 | bcm63xx_enet_register(0, &board.enet0); |
895 | 846 | ||
896 | if (board.has_enet1 && | 847 | if (board.has_enet1 && |
897 | !board_get_mac_address(board.enet1.mac_addr)) | 848 | !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) |
898 | bcm63xx_enet_register(1, &board.enet1); | 849 | bcm63xx_enet_register(1, &board.enet1); |
899 | 850 | ||
900 | if (board.has_usbd) | 851 | if (board.has_usbd) |
@@ -907,7 +858,7 @@ int __init board_register_devices(void) | |||
907 | * do this after registering enet devices | 858 | * do this after registering enet devices |
908 | */ | 859 | */ |
909 | #ifdef CONFIG_SSB_PCIHOST | 860 | #ifdef CONFIG_SSB_PCIHOST |
910 | if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { | 861 | if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { |
911 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); | 862 | memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
912 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); | 863 | memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); |
913 | if (ssb_arch_register_fallback_sprom( | 864 | if (ssb_arch_register_fallback_sprom( |
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index dff79ab6005e..b9e948d59430 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <bcm63xx_cpu.h> | 14 | #include <bcm63xx_cpu.h> |
15 | #include <bcm63xx_io.h> | 15 | #include <bcm63xx_io.h> |
16 | #include <bcm63xx_regs.h> | 16 | #include <bcm63xx_regs.h> |
17 | #include <bcm63xx_reset.h> | ||
17 | #include <bcm63xx_clk.h> | 18 | #include <bcm63xx_clk.h> |
18 | 19 | ||
19 | static DEFINE_MUTEX(clocks_mutex); | 20 | static DEFINE_MUTEX(clocks_mutex); |
@@ -124,15 +125,10 @@ static void enetsw_set(struct clk *clk, int enable) | |||
124 | CKCTL_6368_SWPKT_USB_EN | | 125 | CKCTL_6368_SWPKT_USB_EN | |
125 | CKCTL_6368_SWPKT_SAR_EN, enable); | 126 | CKCTL_6368_SWPKT_SAR_EN, enable); |
126 | if (enable) { | 127 | if (enable) { |
127 | u32 val; | ||
128 | |||
129 | /* reset switch core afer clock change */ | 128 | /* reset switch core afer clock change */ |
130 | val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); | 129 | bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1); |
131 | val &= ~SOFTRESET_6368_ENETSW_MASK; | ||
132 | bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); | ||
133 | msleep(10); | 130 | msleep(10); |
134 | val |= SOFTRESET_6368_ENETSW_MASK; | 131 | bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0); |
135 | bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); | ||
136 | msleep(10); | 132 | msleep(10); |
137 | } | 133 | } |
138 | } | 134 | } |
@@ -222,15 +218,10 @@ static void xtm_set(struct clk *clk, int enable) | |||
222 | CKCTL_6368_SWPKT_SAR_EN, enable); | 218 | CKCTL_6368_SWPKT_SAR_EN, enable); |
223 | 219 | ||
224 | if (enable) { | 220 | if (enable) { |
225 | u32 val; | ||
226 | |||
227 | /* reset sar core afer clock change */ | 221 | /* reset sar core afer clock change */ |
228 | val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); | 222 | bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1); |
229 | val &= ~SOFTRESET_6368_SAR_MASK; | ||
230 | bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); | ||
231 | mdelay(1); | 223 | mdelay(1); |
232 | val |= SOFTRESET_6368_SAR_MASK; | 224 | bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0); |
233 | bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); | ||
234 | mdelay(1); | 225 | mdelay(1); |
235 | } | 226 | } |
236 | } | 227 | } |
@@ -253,6 +244,19 @@ static struct clk clk_ipsec = { | |||
253 | }; | 244 | }; |
254 | 245 | ||
255 | /* | 246 | /* |
247 | * PCIe clock | ||
248 | */ | ||
249 | |||
250 | static void pcie_set(struct clk *clk, int enable) | ||
251 | { | ||
252 | bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable); | ||
253 | } | ||
254 | |||
255 | static struct clk clk_pcie = { | ||
256 | .set = pcie_set, | ||
257 | }; | ||
258 | |||
259 | /* | ||
256 | * Internal peripheral clock | 260 | * Internal peripheral clock |
257 | */ | 261 | */ |
258 | static struct clk clk_periph = { | 262 | static struct clk clk_periph = { |
@@ -313,6 +317,8 @@ struct clk *clk_get(struct device *dev, const char *id) | |||
313 | return &clk_pcm; | 317 | return &clk_pcm; |
314 | if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) | 318 | if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) |
315 | return &clk_ipsec; | 319 | return &clk_ipsec; |
320 | if (BCMCPU_IS_6328() && !strcmp(id, "pcie")) | ||
321 | return &clk_pcie; | ||
316 | return ERR_PTR(-ENOENT); | 322 | return ERR_PTR(-ENOENT); |
317 | } | 323 | } |
318 | 324 | ||
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c new file mode 100644 index 000000000000..620611680839 --- /dev/null +++ b/arch/mips/bcm63xx/nvram.c | |||
@@ -0,0 +1,107 @@ | |||
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 | */ | ||
24 | struct 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 | |||
38 | static struct bcm963xx_nvram nvram; | ||
39 | static int mac_addr_used; | ||
40 | |||
41 | int __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 | |||
68 | u8 *bcm63xx_nvram_get_name(void) | ||
69 | { | ||
70 | return nvram.name; | ||
71 | } | ||
72 | EXPORT_SYMBOL(bcm63xx_nvram_get_name); | ||
73 | |||
74 | int 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 | } | ||
107 | EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); | ||
diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c new file mode 100644 index 000000000000..68a31bb90cbf --- /dev/null +++ b/arch/mips/bcm63xx/reset.c | |||
@@ -0,0 +1,223 @@ | |||
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 | */ | ||
106 | static const u32 bcm6328_reset_bits[] = { | ||
107 | __GEN_RESET_BITS_TABLE(6328) | ||
108 | }; | ||
109 | |||
110 | static const u32 bcm6338_reset_bits[] = { | ||
111 | __GEN_RESET_BITS_TABLE(6338) | ||
112 | }; | ||
113 | |||
114 | static const u32 bcm6348_reset_bits[] = { | ||
115 | __GEN_RESET_BITS_TABLE(6348) | ||
116 | }; | ||
117 | |||
118 | static const u32 bcm6358_reset_bits[] = { | ||
119 | __GEN_RESET_BITS_TABLE(6358) | ||
120 | }; | ||
121 | |||
122 | static const u32 bcm6368_reset_bits[] = { | ||
123 | __GEN_RESET_BITS_TABLE(6368) | ||
124 | }; | ||
125 | |||
126 | const u32 *bcm63xx_reset_bits; | ||
127 | static int reset_reg; | ||
128 | |||
129 | static 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 | ||
153 | static 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 | ||
160 | static 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 | ||
167 | static const u32 bcm63xx_reset_bits[] = { }; | ||
168 | #define reset_reg 0 | ||
169 | #endif | ||
170 | |||
171 | #ifdef CONFIG_BCM63XX_CPU_6348 | ||
172 | static 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 | ||
179 | static 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 | ||
186 | static const u32 bcm63xx_reset_bits[] = { | ||
187 | __GEN_RESET_BITS_TABLE(6368) | ||
188 | }; | ||
189 | #define reset_reg PERF_SOFTRESET_6368_REG | ||
190 | #endif | ||
191 | |||
192 | static int __init bcm63xx_reset_bits_init(void) { return 0; } | ||
193 | #endif | ||
194 | |||
195 | static DEFINE_SPINLOCK(reset_mutex); | ||
196 | |||
197 | static 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 | |||
217 | void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset) | ||
218 | { | ||
219 | __bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset); | ||
220 | } | ||
221 | EXPORT_SYMBOL(bcm63xx_core_set_reset); | ||
222 | |||
223 | postcore_initcall(bcm63xx_reset_bits_init); | ||