diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 17:50:38 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 17:50:38 -0500 |
commit | e773202e227c8ebbf369b9b924e15cca4d93824b (patch) | |
tree | 623a15fe0593e7ff2e79f0a5918fb4b3e739e2ee /arch/arm | |
parent | abf8792d0e1b203e303ed1c02437e0e10a39dcda (diff) | |
parent | d2a40972ec70bd2060d3c46050a101a9678d2991 (diff) |
Merge branch 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson
* 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
ux500: allow 5500 and 8500 to be built together
ux500: modem_irq is only for 5500
ux500: dynamic SOC detection
ux500: rename MOP board Kconfig
ux500: remove build-time changing macros
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/configs/u8500_defconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-ux500/Kconfig | 26 | ||||
-rw-r--r-- | arch/arm/mach-ux500/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-ux500/clock.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu-db5500.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu-db8500.c | 105 | ||||
-rw-r--r-- | arch/arm/mach-ux500/cpu.c | 78 | ||||
-rw-r--r-- | arch/arm/mach-ux500/id.c | 107 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/debug-macro.S | 19 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/entry-macro.S | 5 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/hardware.h | 108 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/id.h | 80 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/irqs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/setup.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/modem-irq-db5500.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-ux500/platsmp.c | 37 |
16 files changed, 354 insertions, 261 deletions
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index be80f037f85a..52d86c4485bf 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig | |||
@@ -9,6 +9,10 @@ CONFIG_MODULE_UNLOAD=y | |||
9 | # CONFIG_LBDAF is not set | 9 | # CONFIG_LBDAF is not set |
10 | # CONFIG_BLK_DEV_BSG is not set | 10 | # CONFIG_BLK_DEV_BSG is not set |
11 | CONFIG_ARCH_U8500=y | 11 | CONFIG_ARCH_U8500=y |
12 | CONFIG_UX500_SOC_DB5500=y | ||
13 | CONFIG_UX500_SOC_DB8500=y | ||
14 | CONFIG_MACH_U8500=y | ||
15 | CONFIG_MACH_U5500=y | ||
12 | CONFIG_SMP=y | 16 | CONFIG_SMP=y |
13 | CONFIG_NR_CPUS=2 | 17 | CONFIG_NR_CPUS=2 |
14 | CONFIG_PREEMPT=y | 18 | CONFIG_PREEMPT=y |
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 2dd44a0b4615..247caa3400d0 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -7,28 +7,30 @@ config UX500_SOC_COMMON | |||
7 | select HAS_MTU | 7 | select HAS_MTU |
8 | select NOMADIK_GPIO | 8 | select NOMADIK_GPIO |
9 | 9 | ||
10 | config UX500_SOC_DB8500 | 10 | menu "Ux500 SoC" |
11 | bool | ||
12 | 11 | ||
13 | config UX500_SOC_DB5500 | 12 | config UX500_SOC_DB5500 |
14 | bool | 13 | bool "DB5500" |
14 | |||
15 | config UX500_SOC_DB8500 | ||
16 | bool "DB8500" | ||
17 | |||
18 | endmenu | ||
15 | 19 | ||
16 | choice | 20 | menu "Ux500 target platform" |
17 | prompt "Ux500 target platform" | ||
18 | default MACH_U8500_MOP | ||
19 | 21 | ||
20 | config MACH_U8500_MOP | 22 | config MACH_U8500 |
21 | bool "U8500 Development platform" | 23 | bool "U8500 Development platform" |
22 | select UX500_SOC_DB8500 | 24 | depends on UX500_SOC_DB8500 |
23 | help | 25 | help |
24 | Include support for the mop500 development platform. | 26 | Include support for the mop500 development platform. |
25 | 27 | ||
26 | config MACH_U5500 | 28 | config MACH_U5500 |
27 | bool "U5500 Development platform" | 29 | bool "U5500 Development platform" |
28 | select UX500_SOC_DB5500 | 30 | depends on UX500_SOC_DB5500 |
29 | help | 31 | help |
30 | Include support for the U5500 development platform. | 32 | Include support for the U5500 development platform. |
31 | endchoice | 33 | endmenu |
32 | 34 | ||
33 | config UX500_DEBUG_UART | 35 | config UX500_DEBUG_UART |
34 | int "Ux500 UART to use for low-level debug" | 36 | int "Ux500 UART to use for low-level debug" |
@@ -39,14 +41,14 @@ config UX500_DEBUG_UART | |||
39 | 41 | ||
40 | config U5500_MODEM_IRQ | 42 | config U5500_MODEM_IRQ |
41 | bool "Modem IRQ support" | 43 | bool "Modem IRQ support" |
42 | depends on MACH_U5500 | 44 | depends on UX500_SOC_DB5500 |
43 | default y | 45 | default y |
44 | help | 46 | help |
45 | Add support for handling IRQ:s from modem side | 47 | Add support for handling IRQ:s from modem side |
46 | 48 | ||
47 | config U5500_MBOX | 49 | config U5500_MBOX |
48 | bool "Mailbox support" | 50 | bool "Mailbox support" |
49 | depends on MACH_U5500 && U5500_MODEM_IRQ | 51 | depends on U5500_MODEM_IRQ |
50 | default y | 52 | default y |
51 | help | 53 | help |
52 | Add support for U5500 mailbox communication with modem side | 54 | Add support for U5500 mailbox communication with modem side |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 12052e8e064c..53ebb429e971 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -2,10 +2,11 @@ | |||
2 | # Makefile for the linux kernel, U8500 machine. | 2 | # Makefile for the linux kernel, U8500 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := clock.o cpu.o devices.o devices-common.o | 5 | obj-y := clock.o cpu.o devices.o devices-common.o \ |
6 | id.o | ||
6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o | 7 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o |
7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ |
9 | board-mop500-keypads.o | 10 | board-mop500-keypads.o |
10 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o | 11 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o |
11 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 12 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index ccff2dae167f..b2b0a3b9be8f 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -136,8 +136,7 @@ EXPORT_SYMBOL(clk_disable); | |||
136 | */ | 136 | */ |
137 | static unsigned long clk_mtu_get_rate(struct clk *clk) | 137 | static unsigned long clk_mtu_get_rate(struct clk *clk) |
138 | { | 138 | { |
139 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) | 139 | void __iomem *addr; |
140 | + PRCM_TCR; | ||
141 | u32 tcr; | 140 | u32 tcr; |
142 | int mtu = (int) clk->data; | 141 | int mtu = (int) clk->data; |
143 | /* | 142 | /* |
@@ -149,13 +148,20 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
149 | unsigned long mturate; | 148 | unsigned long mturate; |
150 | unsigned long retclk; | 149 | unsigned long retclk; |
151 | 150 | ||
151 | if (cpu_is_u5500()) | ||
152 | addr = __io_address(U5500_PRCMU_BASE); | ||
153 | else if (cpu_is_u8500()) | ||
154 | addr = __io_address(U8500_PRCMU_BASE); | ||
155 | else | ||
156 | ux500_unknown_soc(); | ||
157 | |||
152 | /* | 158 | /* |
153 | * On a startup, always conifgure the TCR to the doze mode; | 159 | * On a startup, always conifgure the TCR to the doze mode; |
154 | * bootloaders do it for us. Do this in the kernel too. | 160 | * bootloaders do it for us. Do this in the kernel too. |
155 | */ | 161 | */ |
156 | writel(PRCM_TCR_DOZE_MODE, addr); | 162 | writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR); |
157 | 163 | ||
158 | tcr = readl(addr); | 164 | tcr = readl(addr + PRCM_TCR); |
159 | 165 | ||
160 | /* Get the rate from the parent as a default */ | 166 | /* Get the rate from the parent as a default */ |
161 | if (clk->parent_periph) | 167 | if (clk->parent_periph) |
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index acc841e48de4..af04e0891a78 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c | |||
@@ -21,7 +21,20 @@ | |||
21 | 21 | ||
22 | #include "devices-db5500.h" | 22 | #include "devices-db5500.h" |
23 | 23 | ||
24 | static struct map_desc u5500_uart_io_desc[] __initdata = { | ||
25 | __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K), | ||
26 | __IO_DEV_DESC(U5500_UART2_BASE, SZ_4K), | ||
27 | }; | ||
28 | |||
24 | static struct map_desc u5500_io_desc[] __initdata = { | 29 | static struct map_desc u5500_io_desc[] __initdata = { |
30 | __IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K), | ||
31 | __IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K), | ||
32 | __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K), | ||
33 | __IO_DEV_DESC(U5500_TWD_BASE, SZ_4K), | ||
34 | __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K), | ||
35 | __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K), | ||
36 | __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K), | ||
37 | |||
25 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), | 38 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), |
26 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), | 39 | __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K), |
27 | __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K), | 40 | __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K), |
@@ -143,6 +156,11 @@ static void __init db5500_add_gpios(void) | |||
143 | 156 | ||
144 | void __init u5500_map_io(void) | 157 | void __init u5500_map_io(void) |
145 | { | 158 | { |
159 | /* | ||
160 | * Map the UARTs early so that the DEBUG_LL stuff continues to work. | ||
161 | */ | ||
162 | iotable_init(u5500_uart_io_desc, ARRAY_SIZE(u5500_uart_io_desc)); | ||
163 | |||
146 | ux500_map_io(); | 164 | ux500_map_io(); |
147 | 165 | ||
148 | iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); | 166 | iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index c0f34a404c53..1748fbc58530 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -29,13 +29,31 @@ static struct platform_device *platform_devs[] __initdata = { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* minimum static i/o mapping required to boot U8500 platforms */ | 31 | /* minimum static i/o mapping required to boot U8500 platforms */ |
32 | static struct map_desc u8500_uart_io_desc[] __initdata = { | ||
33 | __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), | ||
34 | __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K), | ||
35 | }; | ||
36 | |||
32 | static struct map_desc u8500_io_desc[] __initdata = { | 37 | static struct map_desc u8500_io_desc[] __initdata = { |
38 | __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), | ||
39 | __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), | ||
40 | __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), | ||
41 | __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), | ||
42 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | ||
43 | __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), | ||
44 | __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), | ||
45 | |||
46 | __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K), | ||
47 | __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K), | ||
48 | __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K), | ||
49 | __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K), | ||
50 | __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K), | ||
51 | |||
33 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), | 52 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
34 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), | 53 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
35 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), | 54 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
36 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | 55 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), |
37 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), | 56 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), |
38 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), | ||
39 | }; | 57 | }; |
40 | 58 | ||
41 | static struct map_desc u8500_ed_io_desc[] __initdata = { | 59 | static struct map_desc u8500_ed_io_desc[] __initdata = { |
@@ -52,71 +70,13 @@ static struct map_desc u8500_v2_io_desc[] __initdata = { | |||
52 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | 70 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), |
53 | }; | 71 | }; |
54 | 72 | ||
55 | /* | ||
56 | * Functions to differentiate between later ASICs | ||
57 | * We look into the end of the ROM to locate the hardcoded ASIC ID. | ||
58 | * This is only needed to differentiate between minor revisions and | ||
59 | * process variants of an ASIC, the major revisions are encoded in | ||
60 | * the cpuid. | ||
61 | */ | ||
62 | #define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4) | ||
63 | #define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4) | ||
64 | #define U8500_ASIC_REV_ED 0x01 | ||
65 | #define U8500_ASIC_REV_V10 0xA0 | ||
66 | #define U8500_ASIC_REV_V11 0xA1 | ||
67 | #define U8500_ASIC_REV_V20 0xB0 | ||
68 | |||
69 | /** | ||
70 | * struct db8500_asic_id - fields of the ASIC ID | ||
71 | * @process: the manufacturing process, 0x40 is 40 nm | ||
72 | * 0x00 is "standard" | ||
73 | * @partnumber: hithereto 0x8500 for DB8500 | ||
74 | * @revision: version code in the series | ||
75 | * This field definion is not formally defined but makes | ||
76 | * sense. | ||
77 | */ | ||
78 | struct db8500_asic_id { | ||
79 | u8 process; | ||
80 | u16 partnumber; | ||
81 | u8 revision; | ||
82 | }; | ||
83 | |||
84 | /* This isn't going to change at runtime */ | ||
85 | static struct db8500_asic_id db8500_id; | ||
86 | |||
87 | static void __init get_db8500_asic_id(void) | ||
88 | { | ||
89 | u32 asicid; | ||
90 | |||
91 | if (cpu_is_u8500v1() || cpu_is_u8500ed()) | ||
92 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1)); | ||
93 | else if (cpu_is_u8500v2()) | ||
94 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2)); | ||
95 | else | ||
96 | BUG(); | ||
97 | |||
98 | db8500_id.process = (asicid >> 24); | ||
99 | db8500_id.partnumber = (asicid >> 16) & 0xFFFFU; | ||
100 | db8500_id.revision = asicid & 0xFFU; | ||
101 | } | ||
102 | |||
103 | bool cpu_is_u8500v10(void) | ||
104 | { | ||
105 | return (db8500_id.revision == U8500_ASIC_REV_V10); | ||
106 | } | ||
107 | |||
108 | bool cpu_is_u8500v11(void) | ||
109 | { | ||
110 | return (db8500_id.revision == U8500_ASIC_REV_V11); | ||
111 | } | ||
112 | |||
113 | bool cpu_is_u8500v20(void) | ||
114 | { | ||
115 | return (db8500_id.revision == U8500_ASIC_REV_V20); | ||
116 | } | ||
117 | |||
118 | void __init u8500_map_io(void) | 73 | void __init u8500_map_io(void) |
119 | { | 74 | { |
75 | /* | ||
76 | * Map the UARTs early so that the DEBUG_LL stuff continues to work. | ||
77 | */ | ||
78 | iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc)); | ||
79 | |||
120 | ux500_map_io(); | 80 | ux500_map_io(); |
121 | 81 | ||
122 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); | 82 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); |
@@ -127,9 +87,6 @@ void __init u8500_map_io(void) | |||
127 | iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); | 87 | iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); |
128 | else if (cpu_is_u8500v2()) | 88 | else if (cpu_is_u8500v2()) |
129 | iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); | 89 | iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); |
130 | |||
131 | /* Read out the ASIC ID as early as we can */ | ||
132 | get_db8500_asic_id(); | ||
133 | } | 90 | } |
134 | 91 | ||
135 | static resource_size_t __initdata db8500_gpio_base[] = { | 92 | static resource_size_t __initdata db8500_gpio_base[] = { |
@@ -159,20 +116,6 @@ static void __init db8500_add_gpios(void) | |||
159 | */ | 116 | */ |
160 | void __init u8500_init_devices(void) | 117 | void __init u8500_init_devices(void) |
161 | { | 118 | { |
162 | /* Display some ASIC boilerplate */ | ||
163 | pr_info("DB8500: process: %02x, revision ID: 0x%02x\n", | ||
164 | db8500_id.process, db8500_id.revision); | ||
165 | if (cpu_is_u8500ed()) | ||
166 | pr_info("DB8500: Early Drop (ED)\n"); | ||
167 | else if (cpu_is_u8500v10()) | ||
168 | pr_info("DB8500: version 1.0\n"); | ||
169 | else if (cpu_is_u8500v11()) | ||
170 | pr_info("DB8500: version 1.1\n"); | ||
171 | else if (cpu_is_u8500v20()) | ||
172 | pr_info("DB8500: version 2.0\n"); | ||
173 | else | ||
174 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | ||
175 | |||
176 | if (cpu_is_u8500ed()) | 119 | if (cpu_is_u8500ed()) |
177 | dma40_u8500ed_fixup(); | 120 | dma40_u8500ed_fixup(); |
178 | 121 | ||
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 5730409c0f7d..5a43107c6232 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c | |||
@@ -23,37 +23,25 @@ | |||
23 | 23 | ||
24 | #include "clock.h" | 24 | #include "clock.h" |
25 | 25 | ||
26 | static struct map_desc ux500_io_desc[] __initdata = { | 26 | #ifdef CONFIG_CACHE_L2X0 |
27 | __IO_DEV_DESC(UX500_UART0_BASE, SZ_4K), | 27 | static void __iomem *l2x0_base; |
28 | __IO_DEV_DESC(UX500_UART2_BASE, SZ_4K), | 28 | #endif |
29 | |||
30 | __IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K), | ||
31 | __IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K), | ||
32 | __IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K), | ||
33 | __IO_DEV_DESC(UX500_TWD_BASE, SZ_4K), | ||
34 | __IO_DEV_DESC(UX500_SCU_BASE, SZ_4K), | ||
35 | |||
36 | __IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K), | ||
37 | __IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K), | ||
38 | __IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K), | ||
39 | __IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K), | ||
40 | __IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K), | ||
41 | |||
42 | __IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K), | ||
43 | __IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K), | ||
44 | |||
45 | __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K), | ||
46 | }; | ||
47 | |||
48 | void __init ux500_map_io(void) | ||
49 | { | ||
50 | iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc)); | ||
51 | } | ||
52 | 29 | ||
53 | void __init ux500_init_irq(void) | 30 | void __init ux500_init_irq(void) |
54 | { | 31 | { |
55 | gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE), | 32 | void __iomem *dist_base; |
56 | __io_address(UX500_GIC_CPU_BASE)); | 33 | void __iomem *cpu_base; |
34 | |||
35 | if (cpu_is_u5500()) { | ||
36 | dist_base = __io_address(U5500_GIC_DIST_BASE); | ||
37 | cpu_base = __io_address(U5500_GIC_CPU_BASE); | ||
38 | } else if (cpu_is_u8500()) { | ||
39 | dist_base = __io_address(U8500_GIC_DIST_BASE); | ||
40 | cpu_base = __io_address(U8500_GIC_CPU_BASE); | ||
41 | } else | ||
42 | ux500_unknown_soc(); | ||
43 | |||
44 | gic_init(0, 29, dist_base, cpu_base); | ||
57 | 45 | ||
58 | /* | 46 | /* |
59 | * Init clocks here so that they are available for system timer | 47 | * Init clocks here so that they are available for system timer |
@@ -74,7 +62,8 @@ static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) | |||
74 | 62 | ||
75 | static inline void ux500_cache_sync(void) | 63 | static inline void ux500_cache_sync(void) |
76 | { | 64 | { |
77 | void __iomem *base = __io_address(UX500_L2CC_BASE); | 65 | void __iomem *base = l2x0_base; |
66 | |||
78 | writel_relaxed(0, base + L2X0_CACHE_SYNC); | 67 | writel_relaxed(0, base + L2X0_CACHE_SYNC); |
79 | ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); | 68 | ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); |
80 | } | 69 | } |
@@ -96,20 +85,23 @@ static void ux500_l2x0_disable(void) | |||
96 | */ | 85 | */ |
97 | static void ux500_l2x0_inv_all(void) | 86 | static void ux500_l2x0_inv_all(void) |
98 | { | 87 | { |
99 | void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE); | 88 | void __iomem *base = l2x0_base; |
100 | uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ | 89 | uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ |
101 | 90 | ||
102 | /* invalidate all ways */ | 91 | /* invalidate all ways */ |
103 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); | 92 | writel_relaxed(l2x0_way_mask, base + L2X0_INV_WAY); |
104 | ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); | 93 | ux500_cache_wait(base + L2X0_INV_WAY, l2x0_way_mask); |
105 | ux500_cache_sync(); | 94 | ux500_cache_sync(); |
106 | } | 95 | } |
107 | 96 | ||
108 | static int ux500_l2x0_init(void) | 97 | static int ux500_l2x0_init(void) |
109 | { | 98 | { |
110 | void __iomem *l2x0_base; | 99 | if (cpu_is_u5500()) |
111 | 100 | l2x0_base = __io_address(U5500_L2CC_BASE); | |
112 | l2x0_base = __io_address(UX500_L2CC_BASE); | 101 | else if (cpu_is_u8500()) |
102 | l2x0_base = __io_address(U8500_L2CC_BASE); | ||
103 | else | ||
104 | ux500_unknown_soc(); | ||
113 | 105 | ||
114 | /* 64KB way size, 8 way associativity, force WA */ | 106 | /* 64KB way size, 8 way associativity, force WA */ |
115 | l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); | 107 | l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); |
@@ -127,13 +119,21 @@ static void __init ux500_timer_init(void) | |||
127 | { | 119 | { |
128 | #ifdef CONFIG_LOCAL_TIMERS | 120 | #ifdef CONFIG_LOCAL_TIMERS |
129 | /* Setup the local timer base */ | 121 | /* Setup the local timer base */ |
130 | twd_base = __io_address(UX500_TWD_BASE); | 122 | if (cpu_is_u5500()) |
123 | twd_base = __io_address(U5500_TWD_BASE); | ||
124 | else if (cpu_is_u8500()) | ||
125 | twd_base = __io_address(U8500_TWD_BASE); | ||
126 | else | ||
127 | ux500_unknown_soc(); | ||
131 | #endif | 128 | #endif |
132 | /* Setup the MTU base */ | 129 | if (cpu_is_u5500()) |
133 | if (cpu_is_u8500ed()) | 130 | mtu_base = __io_address(U5500_MTU0_BASE); |
131 | else if (cpu_is_u8500ed()) | ||
134 | mtu_base = __io_address(U8500_MTU0_BASE_ED); | 132 | mtu_base = __io_address(U8500_MTU0_BASE_ED); |
133 | else if (cpu_is_u8500()) | ||
134 | mtu_base = __io_address(U8500_MTU0_BASE); | ||
135 | else | 135 | else |
136 | mtu_base = __io_address(UX500_MTU0_BASE); | 136 | ux500_unknown_soc(); |
137 | 137 | ||
138 | nmdk_timer_init(); | 138 | nmdk_timer_init(); |
139 | } | 139 | } |
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c new file mode 100644 index 000000000000..d35122ebc67b --- /dev/null +++ b/arch/arm/mach-ux500/id.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/io.h> | ||
11 | |||
12 | #include <asm/cputype.h> | ||
13 | #include <asm/tlbflush.h> | ||
14 | #include <asm/cacheflush.h> | ||
15 | #include <asm/mach/map.h> | ||
16 | |||
17 | #include <mach/hardware.h> | ||
18 | #include <mach/setup.h> | ||
19 | |||
20 | struct dbx500_asic_id dbx500_id; | ||
21 | |||
22 | static unsigned int ux500_read_asicid(phys_addr_t addr) | ||
23 | { | ||
24 | phys_addr_t base = addr & ~0xfff; | ||
25 | struct map_desc desc = { | ||
26 | .virtual = IO_ADDRESS(base), | ||
27 | .pfn = __phys_to_pfn(base), | ||
28 | .length = SZ_16K, | ||
29 | .type = MT_DEVICE, | ||
30 | }; | ||
31 | |||
32 | iotable_init(&desc, 1); | ||
33 | |||
34 | /* As in devicemaps_init() */ | ||
35 | local_flush_tlb_all(); | ||
36 | flush_cache_all(); | ||
37 | |||
38 | return readl(__io_address(addr)); | ||
39 | } | ||
40 | |||
41 | static void ux500_print_soc_info(unsigned int asicid) | ||
42 | { | ||
43 | unsigned int rev = dbx500_revision(); | ||
44 | |||
45 | pr_info("DB%4x ", dbx500_partnumber()); | ||
46 | |||
47 | if (rev == 0x01) | ||
48 | pr_cont("Early Drop"); | ||
49 | else if (rev >= 0xA0) | ||
50 | pr_cont("v%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf); | ||
51 | else | ||
52 | pr_cont("Unknown"); | ||
53 | |||
54 | pr_cont(" [%#010x]\n", asicid); | ||
55 | } | ||
56 | |||
57 | static unsigned int partnumber(unsigned int asicid) | ||
58 | { | ||
59 | return (asicid >> 8) & 0xffff; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * SOC MIDR ASICID ADDRESS ASICID VALUE | ||
64 | * DB8500ed 0x410fc090 0x9001FFF4 0x00850001 | ||
65 | * DB8500v1 0x411fc091 0x9001FFF4 0x008500A0 | ||
66 | * DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1 | ||
67 | * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0 | ||
68 | * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0 | ||
69 | */ | ||
70 | |||
71 | void __init ux500_map_io(void) | ||
72 | { | ||
73 | unsigned int cpuid = read_cpuid_id(); | ||
74 | unsigned int asicid = 0; | ||
75 | phys_addr_t addr = 0; | ||
76 | |||
77 | switch (cpuid) { | ||
78 | case 0x410fc090: /* DB8500ed */ | ||
79 | case 0x411fc091: /* DB8500v1 */ | ||
80 | addr = 0x9001FFF4; | ||
81 | break; | ||
82 | |||
83 | case 0x412fc091: /* DB8500v2 / DB5500v1 */ | ||
84 | asicid = ux500_read_asicid(0x9001DBF4); | ||
85 | if (partnumber(asicid) == 0x8500) | ||
86 | /* DB8500v2 */ | ||
87 | break; | ||
88 | |||
89 | /* DB5500v1 */ | ||
90 | addr = 0x9001FFF4; | ||
91 | break; | ||
92 | } | ||
93 | |||
94 | if (addr) | ||
95 | asicid = ux500_read_asicid(addr); | ||
96 | |||
97 | if (!asicid) { | ||
98 | pr_err("Unable to identify SoC\n"); | ||
99 | ux500_unknown_soc(); | ||
100 | } | ||
101 | |||
102 | dbx500_id.process = asicid >> 24; | ||
103 | dbx500_id.partnumber = partnumber(asicid); | ||
104 | dbx500_id.revision = asicid & 0xff; | ||
105 | |||
106 | ux500_print_soc_info(asicid); | ||
107 | } | ||
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S index be7c0f14e310..700fb05ee815 100644 --- a/arch/arm/mach-ux500/include/mach/debug-macro.S +++ b/arch/arm/mach-ux500/include/mach/debug-macro.S | |||
@@ -14,7 +14,24 @@ | |||
14 | #error Invalid Ux500 debug UART | 14 | #error Invalid Ux500 debug UART |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | #define __UX500_UART(n) UX500_UART##n##_BASE | 17 | /* |
18 | * DEBUG_LL only works if only one SOC is built in. We don't use #else below | ||
19 | * in order to get "__UX500_UART redefined" warnings if more than one SOC is | ||
20 | * built, so that there's some hint during the build that something is wrong. | ||
21 | */ | ||
22 | |||
23 | #ifdef CONFIG_UX500_SOC_DB5500 | ||
24 | #define __UX500_UART(n) U5500_UART##n##_BASE | ||
25 | #endif | ||
26 | |||
27 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
28 | #define __UX500_UART(n) U8500_UART##n##_BASE | ||
29 | #endif | ||
30 | |||
31 | #ifndef __UX500_UART | ||
32 | #error Unknown SOC | ||
33 | #endif | ||
34 | |||
18 | #define UX500_UART(n) __UX500_UART(n) | 35 | #define UX500_UART(n) __UX500_UART(n) |
19 | #define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART) | 36 | #define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART) |
20 | 37 | ||
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S index a37f585a3ecb..071bba94f727 100644 --- a/arch/arm/mach-ux500/include/mach/entry-macro.S +++ b/arch/arm/mach-ux500/include/mach/entry-macro.S | |||
@@ -11,15 +11,10 @@ | |||
11 | * warranty of any kind, whether express or implied. | 11 | * warranty of any kind, whether express or implied. |
12 | */ | 12 | */ |
13 | #include <mach/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #define HAVE_GET_IRQNR_PREAMBLE | ||
15 | #include <asm/hardware/entry-macro-gic.S> | 14 | #include <asm/hardware/entry-macro-gic.S> |
16 | 15 | ||
17 | .macro disable_fiq | 16 | .macro disable_fiq |
18 | .endm | 17 | .endm |
19 | 18 | ||
20 | .macro get_irqnr_preamble, base, tmp | ||
21 | ldr \base, =IO_ADDRESS(UX500_GIC_CPU_BASE) | ||
22 | .endm | ||
23 | |||
24 | .macro arch_ret_to_user, tmp1, tmp2 | 19 | .macro arch_ret_to_user, tmp1, tmp2 |
25 | .endm | 20 | .endm |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 6295cc581355..bf63f2631ba0 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -29,118 +29,12 @@ | |||
29 | #include <mach/db8500-regs.h> | 29 | #include <mach/db8500-regs.h> |
30 | #include <mach/db5500-regs.h> | 30 | #include <mach/db5500-regs.h> |
31 | 31 | ||
32 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
33 | #define UX500(periph) U8500_##periph##_BASE | ||
34 | #elif defined(CONFIG_UX500_SOC_DB5500) | ||
35 | #define UX500(periph) U5500_##periph##_BASE | ||
36 | #endif | ||
37 | |||
38 | #define UX500_BACKUPRAM0_BASE UX500(BACKUPRAM0) | ||
39 | #define UX500_BACKUPRAM1_BASE UX500(BACKUPRAM1) | ||
40 | #define UX500_B2R2_BASE UX500(B2R2) | ||
41 | |||
42 | #define UX500_CLKRST1_BASE UX500(CLKRST1) | ||
43 | #define UX500_CLKRST2_BASE UX500(CLKRST2) | ||
44 | #define UX500_CLKRST3_BASE UX500(CLKRST3) | ||
45 | #define UX500_CLKRST5_BASE UX500(CLKRST5) | ||
46 | #define UX500_CLKRST6_BASE UX500(CLKRST6) | ||
47 | |||
48 | #define UX500_DMA_BASE UX500(DMA) | ||
49 | #define UX500_FSMC_BASE UX500(FSMC) | ||
50 | |||
51 | #define UX500_GIC_CPU_BASE UX500(GIC_CPU) | ||
52 | #define UX500_GIC_DIST_BASE UX500(GIC_DIST) | ||
53 | |||
54 | #define UX500_I2C1_BASE UX500(I2C1) | ||
55 | #define UX500_I2C2_BASE UX500(I2C2) | ||
56 | #define UX500_I2C3_BASE UX500(I2C3) | ||
57 | |||
58 | #define UX500_L2CC_BASE UX500(L2CC) | ||
59 | #define UX500_MCDE_BASE UX500(MCDE) | ||
60 | #define UX500_MTU0_BASE UX500(MTU0) | ||
61 | #define UX500_MTU1_BASE UX500(MTU1) | ||
62 | #define UX500_PRCMU_BASE UX500(PRCMU) | ||
63 | |||
64 | #define UX500_RNG_BASE UX500(RNG) | ||
65 | #define UX500_RTC_BASE UX500(RTC) | ||
66 | |||
67 | #define UX500_SCU_BASE UX500(SCU) | ||
68 | |||
69 | #define UX500_SDI0_BASE UX500(SDI0) | ||
70 | #define UX500_SDI1_BASE UX500(SDI1) | ||
71 | #define UX500_SDI2_BASE UX500(SDI2) | ||
72 | #define UX500_SDI3_BASE UX500(SDI3) | ||
73 | #define UX500_SDI4_BASE UX500(SDI4) | ||
74 | |||
75 | #define UX500_SPI0_BASE UX500(SPI0) | ||
76 | #define UX500_SPI1_BASE UX500(SPI1) | ||
77 | #define UX500_SPI2_BASE UX500(SPI2) | ||
78 | #define UX500_SPI3_BASE UX500(SPI3) | ||
79 | |||
80 | #define UX500_SIA_BASE UX500(SIA) | ||
81 | #define UX500_SVA_BASE UX500(SVA) | ||
82 | |||
83 | #define UX500_TWD_BASE UX500(TWD) | ||
84 | |||
85 | #define UX500_UART0_BASE UX500(UART0) | ||
86 | #define UX500_UART1_BASE UX500(UART1) | ||
87 | #define UX500_UART2_BASE UX500(UART2) | ||
88 | |||
89 | #define UX500_USBOTG_BASE UX500(USBOTG) | ||
90 | |||
91 | /* ST-Ericsson modified pl022 id */ | 32 | /* ST-Ericsson modified pl022 id */ |
92 | #define SSP_PER_ID 0x01080022 | 33 | #define SSP_PER_ID 0x01080022 |
93 | 34 | ||
94 | #ifndef __ASSEMBLY__ | 35 | #ifndef __ASSEMBLY__ |
95 | 36 | ||
96 | #include <asm/cputype.h> | 37 | #include <mach/id.h> |
97 | |||
98 | static inline bool cpu_is_u8500(void) | ||
99 | { | ||
100 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
101 | return 1; | ||
102 | #else | ||
103 | return 0; | ||
104 | #endif | ||
105 | } | ||
106 | |||
107 | #define CPUID_DB8500ED 0x410fc090 | ||
108 | #define CPUID_DB8500V1 0x411fc091 | ||
109 | #define CPUID_DB8500V2 0x412fc091 | ||
110 | |||
111 | static inline bool cpu_is_u8500ed(void) | ||
112 | { | ||
113 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED); | ||
114 | } | ||
115 | |||
116 | static inline bool cpu_is_u8500v1(void) | ||
117 | { | ||
118 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1); | ||
119 | } | ||
120 | |||
121 | static inline bool cpu_is_u8500v2(void) | ||
122 | { | ||
123 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2); | ||
124 | } | ||
125 | |||
126 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
127 | bool cpu_is_u8500v10(void); | ||
128 | bool cpu_is_u8500v11(void); | ||
129 | bool cpu_is_u8500v20(void); | ||
130 | #else | ||
131 | static inline bool cpu_is_u8500v10(void) { return false; } | ||
132 | static inline bool cpu_is_u8500v11(void) { return false; } | ||
133 | static inline bool cpu_is_u8500v20(void) { return false; } | ||
134 | #endif | ||
135 | |||
136 | static inline bool cpu_is_u5500(void) | ||
137 | { | ||
138 | #ifdef CONFIG_UX500_SOC_DB5500 | ||
139 | return 1; | ||
140 | #else | ||
141 | return 0; | ||
142 | #endif | ||
143 | } | ||
144 | 38 | ||
145 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) | 39 | #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) |
146 | 40 | ||
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h new file mode 100644 index 000000000000..f1288d10b6ab --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/id.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #ifndef __MACH_UX500_ID | ||
9 | #define __MACH_UX500_ID | ||
10 | |||
11 | /** | ||
12 | * struct dbx500_asic_id - fields of the ASIC ID | ||
13 | * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard" | ||
14 | * @partnumber: hithereto 0x8500 for DB8500 | ||
15 | * @revision: version code in the series | ||
16 | */ | ||
17 | struct dbx500_asic_id { | ||
18 | u16 partnumber; | ||
19 | u8 revision; | ||
20 | u8 process; | ||
21 | }; | ||
22 | |||
23 | extern struct dbx500_asic_id dbx500_id; | ||
24 | |||
25 | static inline unsigned int __attribute_const__ dbx500_partnumber(void) | ||
26 | { | ||
27 | return dbx500_id.partnumber; | ||
28 | } | ||
29 | |||
30 | static inline unsigned int __attribute_const__ dbx500_revision(void) | ||
31 | { | ||
32 | return dbx500_id.revision; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * SOCs | ||
37 | */ | ||
38 | |||
39 | static inline bool __attribute_const__ cpu_is_u8500(void) | ||
40 | { | ||
41 | return dbx500_partnumber() == 0x8500; | ||
42 | } | ||
43 | |||
44 | static inline bool __attribute_const__ cpu_is_u5500(void) | ||
45 | { | ||
46 | return dbx500_partnumber() == 0x5500; | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * 8500 revisions | ||
51 | */ | ||
52 | |||
53 | static inline bool __attribute_const__ cpu_is_u8500ed(void) | ||
54 | { | ||
55 | return cpu_is_u8500() && dbx500_revision() == 0x00; | ||
56 | } | ||
57 | |||
58 | static inline bool __attribute_const__ cpu_is_u8500v1(void) | ||
59 | { | ||
60 | return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0; | ||
61 | } | ||
62 | |||
63 | static inline bool __attribute_const__ cpu_is_u8500v10(void) | ||
64 | { | ||
65 | return cpu_is_u8500() && dbx500_revision() == 0xA0; | ||
66 | } | ||
67 | |||
68 | static inline bool __attribute_const__ cpu_is_u8500v11(void) | ||
69 | { | ||
70 | return cpu_is_u8500() && dbx500_revision() == 0xA1; | ||
71 | } | ||
72 | |||
73 | static inline bool __attribute_const__ cpu_is_u8500v2(void) | ||
74 | { | ||
75 | return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0); | ||
76 | } | ||
77 | |||
78 | #define ux500_unknown_soc() BUG() | ||
79 | |||
80 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 880ae45bc235..ba1294c13c4d 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h | |||
@@ -36,7 +36,7 @@ | |||
36 | /* This will be overridden by board-specific irq headers */ | 36 | /* This will be overridden by board-specific irq headers */ |
37 | #define IRQ_BOARD_END IRQ_BOARD_START | 37 | #define IRQ_BOARD_END IRQ_BOARD_START |
38 | 38 | ||
39 | #ifdef CONFIG_MACH_U8500_MOP | 39 | #ifdef CONFIG_MACH_U8500 |
40 | #include <mach/irqs-board-mop500.h> | 40 | #include <mach/irqs-board-mop500.h> |
41 | #endif | 41 | #endif |
42 | 42 | ||
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 469877e0de90..a7d363fdb4cd 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <asm/mach/time.h> | 14 | #include <asm/mach/time.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | 16 | ||
17 | extern void __init ux500_map_io(void); | 17 | void __init ux500_map_io(void); |
18 | extern void __init u5500_map_io(void); | 18 | extern void __init u5500_map_io(void); |
19 | extern void __init u8500_map_io(void); | 19 | extern void __init u8500_map_io(void); |
20 | 20 | ||
diff --git a/arch/arm/mach-ux500/modem-irq-db5500.c b/arch/arm/mach-ux500/modem-irq-db5500.c index 3187f8871169..e1296a7447c8 100644 --- a/arch/arm/mach-ux500/modem-irq-db5500.c +++ b/arch/arm/mach-ux500/modem-irq-db5500.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | 14 | ||
15 | #include <mach/id.h> | ||
16 | |||
15 | #define MODEM_INTCON_BASE_ADDR 0xBFFD3000 | 17 | #define MODEM_INTCON_BASE_ADDR 0xBFFD3000 |
16 | #define MODEM_INTCON_SIZE 0xFFF | 18 | #define MODEM_INTCON_SIZE 0xFFF |
17 | 19 | ||
@@ -101,6 +103,9 @@ static int modem_irq_init(void) | |||
101 | static struct irq_chip modem_irq_chip; | 103 | static struct irq_chip modem_irq_chip; |
102 | struct modem_irq *mi; | 104 | struct modem_irq *mi; |
103 | 105 | ||
106 | if (!cpu_is_u5500()) | ||
107 | return -ENODEV; | ||
108 | |||
104 | pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n", | 109 | pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n", |
105 | IRQ_DB5500_MODEM); | 110 | IRQ_DB5500_MODEM); |
106 | 111 | ||
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index d77e76cb7edd..4fff4d408417 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
21 | #include <asm/smp_scu.h> | 21 | #include <asm/smp_scu.h> |
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <mach/setup.h> | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * control for which core is the next to come out of the secondary | 26 | * control for which core is the next to come out of the secondary |
@@ -40,6 +41,18 @@ static void write_pen_release(int val) | |||
40 | outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); | 41 | outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); |
41 | } | 42 | } |
42 | 43 | ||
44 | static void __iomem *scu_base_addr(void) | ||
45 | { | ||
46 | if (cpu_is_u5500()) | ||
47 | return __io_address(U5500_SCU_BASE); | ||
48 | else if (cpu_is_u8500()) | ||
49 | return __io_address(U8500_SCU_BASE); | ||
50 | else | ||
51 | ux500_unknown_soc(); | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
43 | static DEFINE_SPINLOCK(boot_lock); | 56 | static DEFINE_SPINLOCK(boot_lock); |
44 | 57 | ||
45 | void __cpuinit platform_secondary_init(unsigned int cpu) | 58 | void __cpuinit platform_secondary_init(unsigned int cpu) |
@@ -100,21 +113,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
100 | 113 | ||
101 | static void __init wakeup_secondary(void) | 114 | static void __init wakeup_secondary(void) |
102 | { | 115 | { |
116 | void __iomem *backupram; | ||
117 | |||
118 | if (cpu_is_u5500()) | ||
119 | backupram = __io_address(U5500_BACKUPRAM0_BASE); | ||
120 | else if (cpu_is_u8500()) | ||
121 | backupram = __io_address(U8500_BACKUPRAM0_BASE); | ||
122 | else | ||
123 | ux500_unknown_soc(); | ||
124 | |||
103 | /* | 125 | /* |
104 | * write the address of secondary startup into the backup ram register | 126 | * write the address of secondary startup into the backup ram register |
105 | * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the | 127 | * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the |
106 | * backup ram register at offset 0x1FF0, which is what boot rom code | 128 | * backup ram register at offset 0x1FF0, which is what boot rom code |
107 | * is waiting for. This would wake up the secondary core from WFE | 129 | * is waiting for. This would wake up the secondary core from WFE |
108 | */ | 130 | */ |
109 | #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4 | 131 | #define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4 |
110 | __raw_writel(virt_to_phys(u8500_secondary_startup), | 132 | __raw_writel(virt_to_phys(u8500_secondary_startup), |
111 | __io_address(UX500_BACKUPRAM0_BASE) + | 133 | backupram + UX500_CPU1_JUMPADDR_OFFSET); |
112 | U8500_CPU1_JUMPADDR_OFFSET); | ||
113 | 134 | ||
114 | #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 | 135 | #define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 |
115 | __raw_writel(0xA1FEED01, | 136 | __raw_writel(0xA1FEED01, |
116 | __io_address(UX500_BACKUPRAM0_BASE) + | 137 | backupram + UX500_CPU1_WAKEMAGIC_OFFSET); |
117 | U8500_CPU1_WAKEMAGIC_OFFSET); | ||
118 | 138 | ||
119 | /* make sure write buffer is drained */ | 139 | /* make sure write buffer is drained */ |
120 | mb(); | 140 | mb(); |
@@ -126,9 +146,10 @@ static void __init wakeup_secondary(void) | |||
126 | */ | 146 | */ |
127 | void __init smp_init_cpus(void) | 147 | void __init smp_init_cpus(void) |
128 | { | 148 | { |
149 | void __iomem *scu_base = scu_base_addr(); | ||
129 | unsigned int i, ncores; | 150 | unsigned int i, ncores; |
130 | 151 | ||
131 | ncores = scu_get_core_count(__io_address(UX500_SCU_BASE)); | 152 | ncores = scu_base ? scu_get_core_count(scu_base) : 1; |
132 | 153 | ||
133 | /* sanity check */ | 154 | /* sanity check */ |
134 | if (ncores > NR_CPUS) { | 155 | if (ncores > NR_CPUS) { |
@@ -154,6 +175,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus) | |||
154 | for (i = 0; i < max_cpus; i++) | 175 | for (i = 0; i < max_cpus; i++) |
155 | set_cpu_present(i, true); | 176 | set_cpu_present(i, true); |
156 | 177 | ||
157 | scu_enable(__io_address(UX500_SCU_BASE)); | 178 | scu_enable(scu_base_addr()); |
158 | wakeup_secondary(); | 179 | wakeup_secondary(); |
159 | } | 180 | } |