Commit b7806dc7 authored by Santosh Shilimkar's avatar Santosh Shilimkar Committed by Kevin Hilman

ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method

While waking up CPU from off state using clock domain force wakeup, restore
the CPU power state to ON state before putting CPU clock domain under
hardware control. Otherwise CPU wakeup might fail. The change is recommended
for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
devices first.

As a result of weakness, lock-up is observed inside the hardware state
machine of local CPU PRCM and results are UN-predictable as per designers.
In software testing, we have seen hard-locks most of the time where system
gets frozen. With power domain state restored, system behaves correctly.

So update the code accordingly.
Acked-by: default avatarNishanth Menon <nm@ti.com>
Signed-off-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: default avatarKevin Hilman <khilman@linaro.org>
parent c309f7f4
...@@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev, ...@@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
/* Wakeup CPU1 only if it is not offlined */ /* Wakeup CPU1 only if it is not offlined */
if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
clkdm_wakeup(cpu_clkdm[1]); clkdm_wakeup(cpu_clkdm[1]);
omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
clkdm_allow_idle(cpu_clkdm[1]); clkdm_allow_idle(cpu_clkdm[1]);
} }
......
...@@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * ...@@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
{ {
static struct clockdomain *cpu1_clkdm; static struct clockdomain *cpu1_clkdm;
static bool booted; static bool booted;
static struct powerdomain *cpu1_pwrdm;
void __iomem *base = omap_get_wakeupgen_base(); void __iomem *base = omap_get_wakeupgen_base();
/* /*
...@@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * ...@@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
else else
__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
if (!cpu1_clkdm) if (!cpu1_clkdm && !cpu1_pwrdm) {
cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
}
/* /*
* The SGI(Software Generated Interrupts) are not wakeup capable * The SGI(Software Generated Interrupts) are not wakeup capable
...@@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * ...@@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
* Section : * Section :
* 4.3.4.2 Power States of CPU0 and CPU1 * 4.3.4.2 Power States of CPU0 and CPU1
*/ */
if (booted) { if (booted && cpu1_pwrdm && cpu1_clkdm) {
/* /*
* GIC distributor control register has changed between * GIC distributor control register has changed between
* CortexA9 r1pX and r2pX. The Control Register secure * CortexA9 r1pX and r2pX. The Control Register secure
...@@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct * ...@@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
gic_dist_disable(); gic_dist_disable();
} }
/*
* Ensure that CPU power state is set to ON to avoid CPU
* powerdomain transition on wfi
*/
clkdm_wakeup(cpu1_clkdm); clkdm_wakeup(cpu1_clkdm);
omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
clkdm_allow_idle(cpu1_clkdm); clkdm_allow_idle(cpu1_clkdm);
if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
......
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