aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 17:50:38 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-10 17:50:38 -0500
commite773202e227c8ebbf369b9b924e15cca4d93824b (patch)
tree623a15fe0593e7ff2e79f0a5918fb4b3e739e2ee /arch
parentabf8792d0e1b203e303ed1c02437e0e10a39dcda (diff)
parentd2a40972ec70bd2060d3c46050a101a9678d2991 (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')
-rw-r--r--arch/arm/configs/u8500_defconfig4
-rw-r--r--arch/arm/mach-ux500/Kconfig26
-rw-r--r--arch/arm/mach-ux500/Makefile5
-rw-r--r--arch/arm/mach-ux500/clock.c14
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c18
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c105
-rw-r--r--arch/arm/mach-ux500/cpu.c78
-rw-r--r--arch/arm/mach-ux500/id.c107
-rw-r--r--arch/arm/mach-ux500/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-ux500/include/mach/entry-macro.S5
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h108
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h80
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h2
-rw-r--r--arch/arm/mach-ux500/modem-irq-db5500.c5
-rw-r--r--arch/arm/mach-ux500/platsmp.c37
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
11CONFIG_ARCH_U8500=y 11CONFIG_ARCH_U8500=y
12CONFIG_UX500_SOC_DB5500=y
13CONFIG_UX500_SOC_DB8500=y
14CONFIG_MACH_U8500=y
15CONFIG_MACH_U5500=y
12CONFIG_SMP=y 16CONFIG_SMP=y
13CONFIG_NR_CPUS=2 17CONFIG_NR_CPUS=2
14CONFIG_PREEMPT=y 18CONFIG_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
10config UX500_SOC_DB8500 10menu "Ux500 SoC"
11 bool
12 11
13config UX500_SOC_DB5500 12config UX500_SOC_DB5500
14 bool 13 bool "DB5500"
14
15config UX500_SOC_DB8500
16 bool "DB8500"
17
18endmenu
15 19
16choice 20menu "Ux500 target platform"
17 prompt "Ux500 target platform"
18 default MACH_U8500_MOP
19 21
20config MACH_U8500_MOP 22config 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
26config MACH_U5500 28config 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.
31endchoice 33endmenu
32 34
33config UX500_DEBUG_UART 35config 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
40config U5500_MODEM_IRQ 42config 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
47config U5500_MBOX 49config 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
5obj-y := clock.o cpu.o devices.o devices-common.o 5obj-y := clock.o cpu.o devices.o devices-common.o \
6 id.o
6obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o 7obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
7obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o 8obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
8obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \ 9obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \
9 board-mop500-keypads.o 10 board-mop500-keypads.o
10obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o 11obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
11obj-$(CONFIG_SMP) += platsmp.o headsmp.o 12obj-$(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 */
137static unsigned long clk_mtu_get_rate(struct clk *clk) 137static 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
24static 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
24static struct map_desc u5500_io_desc[] __initdata = { 29static 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
144void __init u5500_map_io(void) 157void __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 */
32static 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
32static struct map_desc u8500_io_desc[] __initdata = { 37static 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
41static struct map_desc u8500_ed_io_desc[] __initdata = { 59static 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 */
78struct db8500_asic_id {
79 u8 process;
80 u16 partnumber;
81 u8 revision;
82};
83
84/* This isn't going to change at runtime */
85static struct db8500_asic_id db8500_id;
86
87static 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
103bool cpu_is_u8500v10(void)
104{
105 return (db8500_id.revision == U8500_ASIC_REV_V10);
106}
107
108bool cpu_is_u8500v11(void)
109{
110 return (db8500_id.revision == U8500_ASIC_REV_V11);
111}
112
113bool cpu_is_u8500v20(void)
114{
115 return (db8500_id.revision == U8500_ASIC_REV_V20);
116}
117
118void __init u8500_map_io(void) 73void __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
135static resource_size_t __initdata db8500_gpio_base[] = { 92static resource_size_t __initdata db8500_gpio_base[] = {
@@ -159,20 +116,6 @@ static void __init db8500_add_gpios(void)
159 */ 116 */
160void __init u8500_init_devices(void) 117void __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
26static struct map_desc ux500_io_desc[] __initdata = { 26#ifdef CONFIG_CACHE_L2X0
27 __IO_DEV_DESC(UX500_UART0_BASE, SZ_4K), 27static 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
48void __init ux500_map_io(void)
49{
50 iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
51}
52 29
53void __init ux500_init_irq(void) 30void __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
75static inline void ux500_cache_sync(void) 63static 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 */
97static void ux500_l2x0_inv_all(void) 86static 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
108static int ux500_l2x0_init(void) 97static 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
20struct dbx500_asic_id dbx500_id;
21
22static 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
41static 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
57static 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
71void __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
98static 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
111static inline bool cpu_is_u8500ed(void)
112{
113 return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED);
114}
115
116static inline bool cpu_is_u8500v1(void)
117{
118 return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1);
119}
120
121static 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
127bool cpu_is_u8500v10(void);
128bool cpu_is_u8500v11(void);
129bool cpu_is_u8500v20(void);
130#else
131static inline bool cpu_is_u8500v10(void) { return false; }
132static inline bool cpu_is_u8500v11(void) { return false; }
133static inline bool cpu_is_u8500v20(void) { return false; }
134#endif
135
136static 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 */
17struct dbx500_asic_id {
18 u16 partnumber;
19 u8 revision;
20 u8 process;
21};
22
23extern struct dbx500_asic_id dbx500_id;
24
25static inline unsigned int __attribute_const__ dbx500_partnumber(void)
26{
27 return dbx500_id.partnumber;
28}
29
30static inline unsigned int __attribute_const__ dbx500_revision(void)
31{
32 return dbx500_id.revision;
33}
34
35/*
36 * SOCs
37 */
38
39static inline bool __attribute_const__ cpu_is_u8500(void)
40{
41 return dbx500_partnumber() == 0x8500;
42}
43
44static inline bool __attribute_const__ cpu_is_u5500(void)
45{
46 return dbx500_partnumber() == 0x5500;
47}
48
49/*
50 * 8500 revisions
51 */
52
53static inline bool __attribute_const__ cpu_is_u8500ed(void)
54{
55 return cpu_is_u8500() && dbx500_revision() == 0x00;
56}
57
58static inline bool __attribute_const__ cpu_is_u8500v1(void)
59{
60 return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0;
61}
62
63static inline bool __attribute_const__ cpu_is_u8500v10(void)
64{
65 return cpu_is_u8500() && dbx500_revision() == 0xA0;
66}
67
68static inline bool __attribute_const__ cpu_is_u8500v11(void)
69{
70 return cpu_is_u8500() && dbx500_revision() == 0xA1;
71}
72
73static 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
17extern void __init ux500_map_io(void); 17void __init ux500_map_io(void);
18extern void __init u5500_map_io(void); 18extern void __init u5500_map_io(void);
19extern void __init u8500_map_io(void); 19extern 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
44static 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
43static DEFINE_SPINLOCK(boot_lock); 56static DEFINE_SPINLOCK(boot_lock);
44 57
45void __cpuinit platform_secondary_init(unsigned int cpu) 58void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -100,21 +113,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
100 113
101static void __init wakeup_secondary(void) 114static 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 */
127void __init smp_init_cpus(void) 147void __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}