diff options
-rw-r--r-- | arch/arm/mach-omap2/omap-headsmp.S | 35 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-smp.c | 24 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/smp.h | 2 |
3 files changed, 37 insertions, 24 deletions
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 4afadba09477..aa3f65c2ac97 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S | |||
@@ -27,20 +27,39 @@ | |||
27 | * OMAP4 specific entry point for secondary CPU to jump from ROM | 27 | * OMAP4 specific entry point for secondary CPU to jump from ROM |
28 | * code. This routine also provides a holding flag into which | 28 | * code. This routine also provides a holding flag into which |
29 | * secondary core is held until we're ready for it to initialise. | 29 | * secondary core is held until we're ready for it to initialise. |
30 | * The primary core will update the this flag using a hardware | 30 | * The primary core will update this flag using a hardware |
31 | * register AuxCoreBoot1. | 31 | * register AuxCoreBoot0. |
32 | */ | 32 | */ |
33 | ENTRY(omap_secondary_startup) | 33 | ENTRY(omap_secondary_startup) |
34 | mrc p15, 0, r0, c0, c0, 5 | 34 | hold: ldr r12,=0x103 |
35 | and r0, r0, #0x0f | 35 | dsb |
36 | hold: ldr r1, =OMAP4_AUX_CORE_BOOT1_PA @ read from AuxCoreBoot1 | 36 | smc @ read from AuxCoreBoot0 |
37 | ldr r2, [r1] | 37 | mov r0, r0, lsr #9 |
38 | cmp r2, r0 | 38 | mrc p15, 0, r4, c0, c0, 5 |
39 | and r4, r4, #0x0f | ||
40 | cmp r0, r4 | ||
39 | bne hold | 41 | bne hold |
40 | 42 | ||
41 | /* | 43 | /* |
42 | * we've been released from the cpu_release,secondary_stack | 44 | * we've been released from the wait loop,secondary_stack |
43 | * should now contain the SVC stack for this core | 45 | * should now contain the SVC stack for this core |
44 | */ | 46 | */ |
45 | b secondary_startup | 47 | b secondary_startup |
48 | END(omap_secondary_startup) | ||
46 | 49 | ||
50 | |||
51 | ENTRY(omap_modify_auxcoreboot0) | ||
52 | stmfd sp!, {r1-r12, lr} | ||
53 | ldr r12, =0x104 | ||
54 | dsb | ||
55 | smc | ||
56 | ldmfd sp!, {r1-r12, pc} | ||
57 | END(omap_modify_auxcoreboot0) | ||
58 | |||
59 | ENTRY(omap_auxcoreboot_addr) | ||
60 | stmfd sp!, {r2-r12, lr} | ||
61 | ldr r12, =0x105 | ||
62 | dsb | ||
63 | smc | ||
64 | ldmfd sp!, {r2-r12, pc} | ||
65 | END(omap_auxcoreboot_addr) | ||
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 4890bcf4dadd..59e847843af5 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -21,15 +21,12 @@ | |||
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | 23 | ||
24 | #include <asm/cacheflush.h> | ||
24 | #include <asm/localtimer.h> | 25 | #include <asm/localtimer.h> |
25 | #include <asm/smp_scu.h> | 26 | #include <asm/smp_scu.h> |
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | #include <plat/common.h> | 28 | #include <plat/common.h> |
28 | 29 | ||
29 | /* Registers used for communicating startup information */ | ||
30 | static void __iomem *omap4_auxcoreboot_reg0; | ||
31 | static void __iomem *omap4_auxcoreboot_reg1; | ||
32 | |||
33 | /* SCU base address */ | 30 | /* SCU base address */ |
34 | static void __iomem *scu_base; | 31 | static void __iomem *scu_base; |
35 | 32 | ||
@@ -74,12 +71,13 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
74 | spin_lock(&boot_lock); | 71 | spin_lock(&boot_lock); |
75 | 72 | ||
76 | /* | 73 | /* |
77 | * Update the AuxCoreBoot1 with boot state for secondary core. | 74 | * Update the AuxCoreBoot0 with boot state for secondary core. |
78 | * omap_secondary_startup() routine will hold the secondary core till | 75 | * omap_secondary_startup() routine will hold the secondary core till |
79 | * the AuxCoreBoot1 register is updated with cpu state | 76 | * the AuxCoreBoot1 register is updated with cpu state |
80 | * A barrier is added to ensure that write buffer is drained | 77 | * A barrier is added to ensure that write buffer is drained |
81 | */ | 78 | */ |
82 | __raw_writel(cpu, omap4_auxcoreboot_reg1); | 79 | omap_modify_auxcoreboot0(0x200, 0x0); |
80 | flush_cache_all(); | ||
83 | smp_wmb(); | 81 | smp_wmb(); |
84 | 82 | ||
85 | timeout = jiffies + (1 * HZ); | 83 | timeout = jiffies + (1 * HZ); |
@@ -99,17 +97,18 @@ static void __init wakeup_secondary(void) | |||
99 | { | 97 | { |
100 | /* | 98 | /* |
101 | * Write the address of secondary startup routine into the | 99 | * Write the address of secondary startup routine into the |
102 | * AuxCoreBoot0 where ROM code will jump and start executing | 100 | * AuxCoreBoot1 where ROM code will jump and start executing |
103 | * on secondary core once out of WFE | 101 | * on secondary core once out of WFE |
104 | * A barrier is added to ensure that write buffer is drained | 102 | * A barrier is added to ensure that write buffer is drained |
105 | */ | 103 | */ |
106 | __raw_writel(virt_to_phys(omap_secondary_startup), \ | 104 | omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup)); |
107 | omap4_auxcoreboot_reg0); | ||
108 | smp_wmb(); | 105 | smp_wmb(); |
109 | 106 | ||
110 | /* | 107 | /* |
111 | * Send a 'sev' to wake the secondary core from WFE. | 108 | * Send a 'sev' to wake the secondary core from WFE. |
109 | * Drain the outstanding writes to memory | ||
112 | */ | 110 | */ |
111 | dsb(); | ||
113 | set_event(); | 112 | set_event(); |
114 | mb(); | 113 | mb(); |
115 | } | 114 | } |
@@ -136,7 +135,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
136 | { | 135 | { |
137 | unsigned int ncores = get_core_count(); | 136 | unsigned int ncores = get_core_count(); |
138 | unsigned int cpu = smp_processor_id(); | 137 | unsigned int cpu = smp_processor_id(); |
139 | void __iomem *omap4_wkupgen_base; | ||
140 | int i; | 138 | int i; |
141 | 139 | ||
142 | /* sanity check */ | 140 | /* sanity check */ |
@@ -168,12 +166,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
168 | for (i = 0; i < max_cpus; i++) | 166 | for (i = 0; i < max_cpus; i++) |
169 | set_cpu_present(i, true); | 167 | set_cpu_present(i, true); |
170 | 168 | ||
171 | /* Never released */ | ||
172 | omap4_wkupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); | ||
173 | BUG_ON(!omap4_wkupgen_base); | ||
174 | omap4_auxcoreboot_reg0 = omap4_wkupgen_base + 0x800; | ||
175 | omap4_auxcoreboot_reg1 = omap4_wkupgen_base + 0x804; | ||
176 | |||
177 | if (max_cpus > 1) { | 169 | if (max_cpus > 1) { |
178 | /* | 170 | /* |
179 | * Enable the local timer or broadcast device for the | 171 | * Enable the local timer or broadcast device for the |
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index dcaa8fde7063..8983d54c4fd2 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | /* Needed for secondary core boot */ | 29 | /* Needed for secondary core boot */ |
30 | extern void omap_secondary_startup(void); | 30 | extern void omap_secondary_startup(void); |
31 | extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); | ||
32 | extern void omap_auxcoreboot_addr(u32 cpu_addr); | ||
31 | 33 | ||
32 | /* | 34 | /* |
33 | * We use Soft IRQ1 as the IPI | 35 | * We use Soft IRQ1 as the IPI |