diff options
author | Will Deacon <will.deacon@arm.com> | 2011-02-28 11:01:04 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-20 05:32:21 -0400 |
commit | 80b5efbd43f0a21e9fc6db87823be32fcfe3e7ce (patch) | |
tree | 12a213968fa7c0bac41ff539f82ba64f0e979c4c /arch/arm/mach-vexpress | |
parent | 196f020fbbb83d246960548e73a40fd08f3e7866 (diff) |
ARM: 6771/1: vexpress: add support for multiple core tiles
The current Versatile Express BSP defines the MACHINE_START macro
in the core tile code.
This patch moves this into the generic board code and introduces a
method for determining the current tile at runtime, allowing the
Kernel to have support for multiple tiles compiled in. Tile-specific
functions are executed via a descriptor struct containing the correct
implementations for the current tile.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-vexpress')
-rw-r--r-- | arch/arm/mach-vexpress/core.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/ct-ca9x4.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/motherboard.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/platsmp.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 65 |
6 files changed, 110 insertions, 61 deletions
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index e0312a1dce3a..f4397159c173 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h | |||
@@ -17,9 +17,3 @@ struct amba_device name##_device = { \ | |||
17 | .irq = IRQ_##base, \ | 17 | .irq = IRQ_##base, \ |
18 | /* .dma = DMA_##base,*/ \ | 18 | /* .dma = DMA_##base,*/ \ |
19 | } | 19 | } |
20 | |||
21 | struct map_desc; | ||
22 | |||
23 | void v2m_map_io(struct map_desc *tile, size_t num); | ||
24 | void v2m_init_early(void); | ||
25 | extern struct sys_timer v2m_timer; | ||
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 30d5a5b0ac21..ebc22e759325 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -10,19 +10,17 @@ | |||
10 | #include <linux/amba/clcd.h> | 10 | #include <linux/amba/clcd.h> |
11 | #include <linux/clkdev.h> | 11 | #include <linux/clkdev.h> |
12 | 12 | ||
13 | #include <asm/pgtable.h> | ||
14 | #include <asm/hardware/arm_timer.h> | 13 | #include <asm/hardware/arm_timer.h> |
15 | #include <asm/hardware/cache-l2x0.h> | 14 | #include <asm/hardware/cache-l2x0.h> |
16 | #include <asm/hardware/gic.h> | 15 | #include <asm/hardware/gic.h> |
17 | #include <asm/mach-types.h> | ||
18 | #include <asm/pmu.h> | 16 | #include <asm/pmu.h> |
17 | #include <asm/smp_scu.h> | ||
19 | #include <asm/smp_twd.h> | 18 | #include <asm/smp_twd.h> |
20 | 19 | ||
21 | #include <mach/ct-ca9x4.h> | 20 | #include <mach/ct-ca9x4.h> |
22 | 21 | ||
23 | #include <asm/hardware/timer-sp.h> | 22 | #include <asm/hardware/timer-sp.h> |
24 | 23 | ||
25 | #include <asm/mach/arch.h> | ||
26 | #include <asm/mach/map.h> | 24 | #include <asm/mach/map.h> |
27 | #include <asm/mach/time.h> | 25 | #include <asm/mach/time.h> |
28 | 26 | ||
@@ -58,7 +56,7 @@ static void __init ct_ca9x4_map_io(void) | |||
58 | #ifdef CONFIG_LOCAL_TIMERS | 56 | #ifdef CONFIG_LOCAL_TIMERS |
59 | twd_base = MMIO_P2V(A9_MPCORE_TWD); | 57 | twd_base = MMIO_P2V(A9_MPCORE_TWD); |
60 | #endif | 58 | #endif |
61 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); | 59 | iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); |
62 | } | 60 | } |
63 | 61 | ||
64 | static void __init ct_ca9x4_init_irq(void) | 62 | static void __init ct_ca9x4_init_irq(void) |
@@ -183,8 +181,6 @@ static struct platform_device pmu_device = { | |||
183 | static void __init ct_ca9x4_init_early(void) | 181 | static void __init ct_ca9x4_init_early(void) |
184 | { | 182 | { |
185 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 183 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
186 | |||
187 | v2m_init_early(); | ||
188 | } | 184 | } |
189 | 185 | ||
190 | static void __init ct_ca9x4_init(void) | 186 | static void __init ct_ca9x4_init(void) |
@@ -207,15 +203,34 @@ static void __init ct_ca9x4_init(void) | |||
207 | platform_device_register(&pmu_device); | 203 | platform_device_register(&pmu_device); |
208 | } | 204 | } |
209 | 205 | ||
210 | MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") | 206 | #ifdef CONFIG_SMP |
211 | .boot_params = PLAT_PHYS_OFFSET + 0x00000100, | 207 | static void ct_ca9x4_init_cpu_map(void) |
208 | { | ||
209 | int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); | ||
210 | |||
211 | for (i = 0; i < ncores; ++i) | ||
212 | set_cpu_possible(i, true); | ||
213 | } | ||
214 | |||
215 | static void ct_ca9x4_smp_enable(unsigned int max_cpus) | ||
216 | { | ||
217 | int i; | ||
218 | for (i = 0; i < max_cpus; i++) | ||
219 | set_cpu_present(i, true); | ||
220 | |||
221 | scu_enable(MMIO_P2V(A9_MPCORE_SCU)); | ||
222 | } | ||
223 | #endif | ||
224 | |||
225 | struct ct_desc ct_ca9x4_desc __initdata = { | ||
226 | .id = V2M_CT_ID_CA9, | ||
227 | .name = "CA9x4", | ||
212 | .map_io = ct_ca9x4_map_io, | 228 | .map_io = ct_ca9x4_map_io, |
213 | .init_irq = ct_ca9x4_init_irq, | ||
214 | .init_early = ct_ca9x4_init_early, | 229 | .init_early = ct_ca9x4_init_early, |
215 | #if 0 | 230 | .init_irq = ct_ca9x4_init_irq, |
216 | .timer = &ct_ca9x4_timer, | 231 | .init_tile = ct_ca9x4_init, |
217 | #else | 232 | #ifdef CONFIG_SMP |
218 | .timer = &v2m_timer, | 233 | .init_cpu_map = ct_ca9x4_init_cpu_map, |
234 | .smp_enable = ct_ca9x4_smp_enable, | ||
219 | #endif | 235 | #endif |
220 | .init_machine = ct_ca9x4_init, | 236 | }; |
221 | MACHINE_END | ||
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h index f9e2f8d22962..a34d3d4faae1 100644 --- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | |||
@@ -45,4 +45,6 @@ | |||
45 | #define IRQ_CT_CA9X4_PMU_CPU2 94 | 45 | #define IRQ_CT_CA9X4_PMU_CPU2 94 |
46 | #define IRQ_CT_CA9X4_PMU_CPU3 95 | 46 | #define IRQ_CT_CA9X4_PMU_CPU3 95 |
47 | 47 | ||
48 | extern struct ct_desc ct_ca9x4_desc; | ||
49 | |||
48 | #endif | 50 | #endif |
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h index 98a8ded055bf..0a3a37518405 100644 --- a/arch/arm/mach-vexpress/include/mach/motherboard.h +++ b/arch/arm/mach-vexpress/include/mach/motherboard.h | |||
@@ -118,4 +118,26 @@ | |||
118 | int v2m_cfg_write(u32 devfn, u32 data); | 118 | int v2m_cfg_write(u32 devfn, u32 data); |
119 | int v2m_cfg_read(u32 devfn, u32 *data); | 119 | int v2m_cfg_read(u32 devfn, u32 *data); |
120 | 120 | ||
121 | /* | ||
122 | * Core tile IDs | ||
123 | */ | ||
124 | #define V2M_CT_ID_CA9 0x0c000191 | ||
125 | #define V2M_CT_ID_UNSUPPORTED 0xff000191 | ||
126 | #define V2M_CT_ID_MASK 0xff000fff | ||
127 | |||
128 | struct ct_desc { | ||
129 | u32 id; | ||
130 | const char *name; | ||
131 | void (*map_io)(void); | ||
132 | void (*init_early)(void); | ||
133 | void (*init_irq)(void); | ||
134 | void (*init_tile)(void); | ||
135 | #ifdef CONFIG_SMP | ||
136 | void (*init_cpu_map)(void); | ||
137 | void (*smp_enable)(unsigned int); | ||
138 | #endif | ||
139 | }; | ||
140 | |||
141 | extern struct ct_desc *ct_desc; | ||
142 | |||
121 | #endif | 143 | #endif |
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 18927023c2cc..2b5f7ac001a3 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c | |||
@@ -13,10 +13,8 @@ | |||
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | 15 | ||
16 | #include <asm/smp_scu.h> | ||
17 | #include <asm/unified.h> | 16 | #include <asm/unified.h> |
18 | 17 | ||
19 | #include <mach/ct-ca9x4.h> | ||
20 | #include <mach/motherboard.h> | 18 | #include <mach/motherboard.h> |
21 | #define V2M_PA_CS7 0x10000000 | 19 | #define V2M_PA_CS7 0x10000000 |
22 | 20 | ||
@@ -24,47 +22,22 @@ | |||
24 | 22 | ||
25 | extern void versatile_secondary_startup(void); | 23 | extern void versatile_secondary_startup(void); |
26 | 24 | ||
27 | static void __iomem *scu_base_addr(void) | ||
28 | { | ||
29 | return MMIO_P2V(A9_MPCORE_SCU); | ||
30 | } | ||
31 | |||
32 | /* | 25 | /* |
33 | * Initialise the CPU possible map early - this describes the CPUs | 26 | * Initialise the CPU possible map early - this describes the CPUs |
34 | * which may be present or become present in the system. | 27 | * which may be present or become present in the system. |
35 | */ | 28 | */ |
36 | void __init smp_init_cpus(void) | 29 | void __init smp_init_cpus(void) |
37 | { | 30 | { |
38 | void __iomem *scu_base = scu_base_addr(); | 31 | ct_desc->init_cpu_map(); |
39 | unsigned int i, ncores; | ||
40 | |||
41 | ncores = scu_base ? scu_get_core_count(scu_base) : 1; | ||
42 | |||
43 | /* sanity check */ | ||
44 | if (ncores > NR_CPUS) { | ||
45 | printk(KERN_WARNING | ||
46 | "vexpress: no. of cores (%d) greater than configured " | ||
47 | "maximum of %d - clipping\n", | ||
48 | ncores, NR_CPUS); | ||
49 | ncores = NR_CPUS; | ||
50 | } | ||
51 | |||
52 | for (i = 0; i < ncores; i++) | ||
53 | set_cpu_possible(i, true); | ||
54 | } | 32 | } |
55 | 33 | ||
56 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 34 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
57 | { | 35 | { |
58 | int i; | ||
59 | |||
60 | /* | 36 | /* |
61 | * Initialise the present map, which describes the set of CPUs | 37 | * Initialise the present map, which describes the set of CPUs |
62 | * actually populated at the present time. | 38 | * actually populated at the present time. |
63 | */ | 39 | */ |
64 | for (i = 0; i < max_cpus; i++) | 40 | ct_desc->smp_enable(max_cpus); |
65 | set_cpu_present(i, true); | ||
66 | |||
67 | scu_enable(scu_base_addr()); | ||
68 | 41 | ||
69 | /* | 42 | /* |
70 | * Write the address of secondary startup into the | 43 | * Write the address of secondary startup into the |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 63ef663fb0be..ba46e8e07437 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -14,7 +14,9 @@ | |||
14 | #include <linux/usb/isp1760.h> | 14 | #include <linux/usb/isp1760.h> |
15 | #include <linux/clkdev.h> | 15 | #include <linux/clkdev.h> |
16 | 16 | ||
17 | #include <asm/mach-types.h> | ||
17 | #include <asm/sizes.h> | 18 | #include <asm/sizes.h> |
19 | #include <asm/mach/arch.h> | ||
18 | #include <asm/mach/flash.h> | 20 | #include <asm/mach/flash.h> |
19 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
20 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
@@ -22,6 +24,7 @@ | |||
22 | #include <asm/hardware/timer-sp.h> | 24 | #include <asm/hardware/timer-sp.h> |
23 | #include <asm/hardware/sp810.h> | 25 | #include <asm/hardware/sp810.h> |
24 | 26 | ||
27 | #include <mach/ct-ca9x4.h> | ||
25 | #include <mach/motherboard.h> | 28 | #include <mach/motherboard.h> |
26 | 29 | ||
27 | #include <plat/sched_clock.h> | 30 | #include <plat/sched_clock.h> |
@@ -43,14 +46,9 @@ static struct map_desc v2m_io_desc[] __initdata = { | |||
43 | }, | 46 | }, |
44 | }; | 47 | }; |
45 | 48 | ||
46 | void __init v2m_map_io(struct map_desc *tile, size_t num) | 49 | static void __init v2m_init_early(void) |
47 | { | ||
48 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); | ||
49 | iotable_init(tile, num); | ||
50 | } | ||
51 | |||
52 | void __init v2m_init_early(void) | ||
53 | { | 50 | { |
51 | ct_desc->init_early(); | ||
54 | versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); | 52 | versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); |
55 | } | 53 | } |
56 | 54 | ||
@@ -71,7 +69,7 @@ static void __init v2m_timer_init(void) | |||
71 | sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); | 69 | sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0); |
72 | } | 70 | } |
73 | 71 | ||
74 | struct sys_timer v2m_timer = { | 72 | static struct sys_timer v2m_timer = { |
75 | .init = v2m_timer_init, | 73 | .init = v2m_timer_init, |
76 | }; | 74 | }; |
77 | 75 | ||
@@ -380,7 +378,44 @@ static void v2m_restart(char str, const char *cmd) | |||
380 | printk(KERN_EMERG "Unable to reboot\n"); | 378 | printk(KERN_EMERG "Unable to reboot\n"); |
381 | } | 379 | } |
382 | 380 | ||
383 | static int __init v2m_init(void) | 381 | struct ct_desc *ct_desc; |
382 | |||
383 | static struct ct_desc *ct_descs[] __initdata = { | ||
384 | #ifdef CONFIG_ARCH_VEXPRESS_CA9X4 | ||
385 | &ct_ca9x4_desc, | ||
386 | #endif | ||
387 | }; | ||
388 | |||
389 | static void __init v2m_populate_ct_desc(void) | ||
390 | { | ||
391 | int i; | ||
392 | u32 current_tile_id; | ||
393 | |||
394 | ct_desc = NULL; | ||
395 | current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK; | ||
396 | |||
397 | for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) | ||
398 | if (ct_descs[i]->id == current_tile_id) | ||
399 | ct_desc = ct_descs[i]; | ||
400 | |||
401 | if (!ct_desc) | ||
402 | panic("vexpress: failed to populate core tile description " | ||
403 | "for tile ID 0x%8x\n", current_tile_id); | ||
404 | } | ||
405 | |||
406 | static void __init v2m_map_io(void) | ||
407 | { | ||
408 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); | ||
409 | v2m_populate_ct_desc(); | ||
410 | ct_desc->map_io(); | ||
411 | } | ||
412 | |||
413 | static void __init v2m_init_irq(void) | ||
414 | { | ||
415 | ct_desc->init_irq(); | ||
416 | } | ||
417 | |||
418 | static void __init v2m_init(void) | ||
384 | { | 419 | { |
385 | int i; | 420 | int i; |
386 | 421 | ||
@@ -399,6 +434,14 @@ static int __init v2m_init(void) | |||
399 | pm_power_off = v2m_power_off; | 434 | pm_power_off = v2m_power_off; |
400 | arm_pm_restart = v2m_restart; | 435 | arm_pm_restart = v2m_restart; |
401 | 436 | ||
402 | return 0; | 437 | ct_desc->init_tile(); |
403 | } | 438 | } |
404 | arch_initcall(v2m_init); | 439 | |
440 | MACHINE_START(VEXPRESS, "ARM-Versatile Express") | ||
441 | .boot_params = PLAT_PHYS_OFFSET + 0x00000100, | ||
442 | .map_io = v2m_map_io, | ||
443 | .init_early = v2m_init_early, | ||
444 | .init_irq = v2m_init_irq, | ||
445 | .timer = &v2m_timer, | ||
446 | .init_machine = v2m_init, | ||
447 | MACHINE_END | ||