ARM: EXYNOS: Fix the sequence of secondary CPU boot for Exynos3250
authorChanwoo Choi <cw00.choi@samsung.com>
Thu, 10 Jul 2014 04:48:32 +0000 (13:48 +0900)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 03:00:10 +0000 (12:00 +0900)
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 <cw00.choi@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
arch/arm/mach-exynos/include/mach/regs-pmu.h
arch/arm/mach-exynos/platsmp.c

index 1b888cd..9320e10 100644 (file)
 #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
 
 #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)
index 3525597..cfbc410 100644 (file)
@@ -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;