#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)
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;
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,
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;