Commit beddf63f authored by Tomasz Figa's avatar Tomasz Figa Committed by Kukjin Kim

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: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent 41de8986
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/firmware.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
...@@ -145,10 +146,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct ...@@ -145,10 +146,21 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct
timeout = jiffies + (1 * HZ); timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
unsigned long boot_addr;
smp_rmb(); smp_rmb();
__raw_writel(virt_to_phys(exynos4_secondary_startup), boot_addr = virt_to_phys(exynos4_secondary_startup);
cpu_boot_reg(phys_cpu));
/*
* Try to set boot address using firmware first
* and fall back to boot register if it fails.
*/
if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
call_firmware_op(cpu_boot, phys_cpu);
arch_send_wakeup_ipi_mask(cpumask_of(cpu)); arch_send_wakeup_ipi_mask(cpumask_of(cpu));
if (pen_release == -1) if (pen_release == -1)
...@@ -204,10 +216,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) ...@@ -204,10 +216,20 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
* system-wide flags register. The boot monitor waits * system-wide flags register. The boot monitor waits
* until it receives a soft interrupt, and then the * until it receives a soft interrupt, and then the
* secondary CPU branches to this address. * secondary CPU branches to this address.
*
* Try using firmware operation first and fall back to
* boot register if it fails.
*/ */
for (i = 1; i < max_cpus; ++i) for (i = 1; i < max_cpus; ++i) {
__raw_writel(virt_to_phys(exynos4_secondary_startup), unsigned long phys_cpu;
cpu_boot_reg(cpu_logical_map(i))); unsigned long boot_addr;
phys_cpu = cpu_logical_map(i);
boot_addr = virt_to_phys(exynos4_secondary_startup);
if (call_firmware_op(set_cpu_boot_addr, phys_cpu, boot_addr))
__raw_writel(boot_addr, cpu_boot_reg(phys_cpu));
}
} }
struct smp_operations exynos_smp_ops __initdata = { struct smp_operations exynos_smp_ops __initdata = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment