Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+27 −5
Original line number Original line Diff line number Diff line
@@ -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


	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)
	 * 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 = {