diff options
Diffstat (limited to 'arch/arm/mach-realview/platsmp.c')
-rw-r--r-- | arch/arm/mach-realview/platsmp.c | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index de2b7159557d..3e57428affee 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
@@ -15,11 +15,14 @@ | |||
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | 16 | ||
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include <asm/hardware/arm_scu.h> | ||
19 | #include <asm/hardware.h> | 18 | #include <asm/hardware.h> |
20 | #include <asm/io.h> | 19 | #include <asm/io.h> |
21 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
22 | 21 | ||
22 | #include <asm/arch/board-eb.h> | ||
23 | #include <asm/arch/board-pb11mp.h> | ||
24 | #include <asm/arch/scu.h> | ||
25 | |||
23 | extern void realview_secondary_startup(void); | 26 | extern void realview_secondary_startup(void); |
24 | 27 | ||
25 | /* | 28 | /* |
@@ -31,9 +34,15 @@ volatile int __cpuinitdata pen_release = -1; | |||
31 | static unsigned int __init get_core_count(void) | 34 | static unsigned int __init get_core_count(void) |
32 | { | 35 | { |
33 | unsigned int ncores; | 36 | unsigned int ncores; |
37 | void __iomem *scu_base = 0; | ||
38 | |||
39 | if (machine_is_realview_eb() && core_tile_eb11mp()) | ||
40 | scu_base = __io_address(REALVIEW_EB11MP_SCU_BASE); | ||
41 | else if (machine_is_realview_pb11mp()) | ||
42 | scu_base = __io_address(REALVIEW_TC11MP_SCU_BASE); | ||
34 | 43 | ||
35 | if (machine_is_realview_eb() && core_tile_eb11mp()) { | 44 | if (scu_base) { |
36 | ncores = __raw_readl(__io_address(REALVIEW_EB11MP_SCU_BASE) + SCU_CONFIG); | 45 | ncores = __raw_readl(scu_base + SCU_CONFIG); |
37 | ncores = (ncores & 0x03) + 1; | 46 | ncores = (ncores & 0x03) + 1; |
38 | } else | 47 | } else |
39 | ncores = 1; | 48 | ncores = 1; |
@@ -41,6 +50,26 @@ static unsigned int __init get_core_count(void) | |||
41 | return ncores; | 50 | return ncores; |
42 | } | 51 | } |
43 | 52 | ||
53 | /* | ||
54 | * Setup the SCU | ||
55 | */ | ||
56 | static void scu_enable(void) | ||
57 | { | ||
58 | u32 scu_ctrl; | ||
59 | void __iomem *scu_base; | ||
60 | |||
61 | if (machine_is_realview_eb() && core_tile_eb11mp()) | ||
62 | scu_base = __io_address(REALVIEW_EB11MP_SCU_BASE); | ||
63 | else if (machine_is_realview_pb11mp()) | ||
64 | scu_base = __io_address(REALVIEW_TC11MP_SCU_BASE); | ||
65 | else | ||
66 | BUG(); | ||
67 | |||
68 | scu_ctrl = __raw_readl(scu_base + SCU_CTRL); | ||
69 | scu_ctrl |= 1; | ||
70 | __raw_writel(scu_ctrl, scu_base + SCU_CTRL); | ||
71 | } | ||
72 | |||
44 | static DEFINE_SPINLOCK(boot_lock); | 73 | static DEFINE_SPINLOCK(boot_lock); |
45 | 74 | ||
46 | void __cpuinit platform_secondary_init(unsigned int cpu) | 75 | void __cpuinit platform_secondary_init(unsigned int cpu) |
@@ -57,7 +86,10 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | |||
57 | * core (e.g. timer irq), then they will not have been enabled | 86 | * core (e.g. timer irq), then they will not have been enabled |
58 | * for us: do so | 87 | * for us: do so |
59 | */ | 88 | */ |
60 | gic_cpu_init(0, __io_address(REALVIEW_EB11MP_GIC_CPU_BASE)); | 89 | if (machine_is_realview_eb() && core_tile_eb11mp()) |
90 | gic_cpu_init(0, __io_address(REALVIEW_EB11MP_GIC_CPU_BASE)); | ||
91 | else if (machine_is_realview_pb11mp()) | ||
92 | gic_cpu_init(0, __io_address(REALVIEW_TC11MP_GIC_CPU_BASE)); | ||
61 | 93 | ||
62 | /* | 94 | /* |
63 | * let the primary processor know we're out of the | 95 | * let the primary processor know we're out of the |
@@ -198,7 +230,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
198 | * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in | 230 | * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in |
199 | * realview_timer_init | 231 | * realview_timer_init |
200 | */ | 232 | */ |
201 | if (machine_is_realview_eb() && core_tile_eb11mp()) | 233 | if ((machine_is_realview_eb() && core_tile_eb11mp()) || |
234 | machine_is_realview_pb11mp()) | ||
202 | local_timer_setup(cpu); | 235 | local_timer_setup(cpu); |
203 | #endif | 236 | #endif |
204 | 237 | ||
@@ -210,11 +243,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
210 | cpu_set(i, cpu_present_map); | 243 | cpu_set(i, cpu_present_map); |
211 | 244 | ||
212 | /* | 245 | /* |
213 | * Do we need any more CPUs? If so, then let them know where | 246 | * Initialise the SCU if there are more than one CPU and let |
214 | * to start. Note that, on modern versions of MILO, the "poke" | 247 | * them know where to start. Note that, on modern versions of |
215 | * doesn't actually do anything until each individual core is | 248 | * MILO, the "poke" doesn't actually do anything until each |
216 | * sent a soft interrupt to get it out of WFI | 249 | * individual core is sent a soft interrupt to get it out of |
250 | * WFI | ||
217 | */ | 251 | */ |
218 | if (max_cpus > 1) | 252 | if (max_cpus > 1) { |
253 | scu_enable(); | ||
219 | poke_milo(); | 254 | poke_milo(); |
255 | } | ||
220 | } | 256 | } |