aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTomasz Figa <t.figa@samsung.com>2012-12-10 23:58:43 -0500
committerKukjin Kim <kgene.kim@samsung.com>2013-04-08 12:52:30 -0400
commitbeddf63fc8e01f06799bd6d7a2dd879885bbc9c6 (patch)
tree449ab2a2f4298d7c79285d3830a2cdb73833a040 /arch
parent41de89860baf8e62fd74e83338058575398ad21f (diff)
ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up
Boards using secure firmware must use different CPU boot registers and call secure firmware to boot the CPU. Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Tomasz Figa <t.figa@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-exynos/platsmp.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 60f7c5be057d..a083e0591a56 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -25,6 +25,7 @@
25#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
26#include <asm/smp_plat.h> 26#include <asm/smp_plat.h>
27#include <asm/smp_scu.h> 27#include <asm/smp_scu.h>
28#include <asm/firmware.h>
28 29
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30#include <mach/regs-clock.h> 31#include <mach/regs-clock.h>
@@ -145,10 +146,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
145 146
146 timeout = jiffies + (1 * HZ); 147 timeout = jiffies + (1 * HZ);
147 while (time_before(jiffies, timeout)) { 148 while (time_before(jiffies, timeout)) {
149 unsigned long boot_addr;
150
148 smp_rmb(); 151 smp_rmb();
149 152
150 __raw_writel(virt_to_phys(exynos4_secondary_startup), 153 boot_addr = virt_to_phys(exynos4_secondary_startup);
151 cpu_boot_reg(phys_cpu)); 154
155 /*
156 * Try to set boot address using firmware first
157 * and fall back to boot register if it fails.
158 */
159 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
160 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
161
162 call_firmware_op(cpu_boot, phys_cpu);
163
152 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 164 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
153 165
154 if (pen_release == -1) 166 if (pen_release == -1)
@@ -204,10 +216,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
204 * system-wide flags register. The boot monitor waits 216 * system-wide flags register. The boot monitor waits
205 * until it receives a soft interrupt, and then the 217 * until it receives a soft interrupt, and then the
206 * secondary CPU branches to this address. 218 * secondary CPU branches to this address.
219 *
220 * Try using firmware operation first and fall back to
221 * boot register if it fails.
207 */ 222 */
208 for (i = 1; i < max_cpus; ++i) 223 for (i = 1; i < max_cpus; ++i) {
209 __raw_writel(virt_to_phys(exynos4_secondary_startup), 224 unsigned long phys_cpu;
210 cpu_boot_reg(cpu_logical_map(i))); 225 unsigned long boot_addr;
226
227 phys_cpu = cpu_logical_map(i);
228 boot_addr = virt_to_phys(exynos4_secondary_startup);
229
230 if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
231 __raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
232 }
211} 233}
212 234
213struct smp_operations exynos_smp_ops __initdata = { 235struct smp_operations exynos_smp_ops __initdata = {