From: Chanwoo Choi Date: Thu, 10 Jul 2014 04:48:32 +0000 (+0900) Subject: ARM: EXYNOS: Fix the sequence of secondary CPU boot for Exynos3250 X-Git-Tag: submit/tizen/20141121.110247~457 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d5becdd8c2fa5776a7a4695fc702abb620b3b801;p=platform%2Fkernel%2Flinux-3.10.git ARM: EXYNOS: Fix the sequence of secondary CPU boot for Exynos3250 This patch set AUTOWAKEUP_EN bit to ARM_CORE_CONFIGURATION register because Exynos3250 removes WFE in secure mode so that turn on automatically after setting CORE_LOCAL_PWR_EN. Also, This patch use dbs_sev() macro to guarantee the data synchronization of command instead of IPI_WAKEUP because Exynos3250 don't have WFE mode in secue mode. Signed-off-by: Chanwoo Choi Acked-by: Kyungmin Park --- diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h index 1b888cd..9320e10 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h @@ -161,6 +161,7 @@ #define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 #define S5P_CORE_LOCAL_PWR_EN 0x3 #define S5P_INT_LOCAL_PWR_EN 0x7 +#define S5P_CORE_AUTOWAKEUP_EN (1 << 31) #define S5P_CHECK_SLEEP 0x00000BAD @@ -231,6 +232,9 @@ #define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034) #define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038) +/* For EXYNOS3 */ +#define EXYNOS3_COREPORESET(cpu) ((1 << 4) << cpu) + /* For EXYNOS5 */ #define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234) diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 3525597..cfbc410 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -111,8 +111,12 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct if (!(__raw_readl(S5P_ARM_CORE_STATUS(phys_cpu)) & S5P_CORE_LOCAL_PWR_EN)) { - __raw_writel(S5P_CORE_LOCAL_PWR_EN, - S5P_ARM_CORE_CONFIGURATION(phys_cpu)); + u32 core_conf = 0; + + core_conf |= S5P_CORE_LOCAL_PWR_EN; + if (soc_is_exynos3250()) + core_conf |= S5P_CORE_AUTOWAKEUP_EN; + __raw_writel(core_conf, S5P_ARM_CORE_CONFIGURATION(phys_cpu)); timeout = 10; @@ -131,6 +135,24 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct return -ETIMEDOUT; } } + + /* HACK: Turn on secondary CPUs */ + if (soc_is_exynos3250()) { + unsigned int tmp; + + /* FIXME: 0x0908 is hidden register */ + while(!__raw_readl(S5P_PMUREG(0x0908))) + udelay(10); + udelay(10); + + tmp = __raw_readl(S5P_ARM_CORE_STATUS(phys_cpu)); + tmp |= (S5P_CORE_LOCAL_PWR_EN << 8); + __raw_writel(tmp, S5P_ARM_CORE_STATUS(phys_cpu)); + } + + if (soc_is_exynos3250()) + __raw_writel(EXYNOS3_COREPORESET(phys_cpu), EXYNOS_SWRESET); + /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, @@ -154,7 +176,10 @@ static int __cpuinit exynos_boot_secondary(unsigned int cpu, struct task_struct call_firmware_op(cpu_boot, phys_cpu); - arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + if (soc_is_exynos3250()) + dsb_sev(); + else + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); if (pen_release == -1) break;