aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2013-02-08 12:20:58 -0500
committerKevin Hilman <khilman@linaro.org>2013-04-05 17:19:25 -0400
commitb7806dc7cba840ea538706621486475d93a53c55 (patch)
tree934e1b306991d96755cb1babceefa3ed77b3944f
parentc309f7f46167e85d1aae2fd31f23e7d2b5cdfbe0 (diff)
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: Nishanth Menon <nm@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Kevin Hilman <khilman@linaro.org>
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c1
-rw-r--r--arch/arm/mach-omap2/omap-smp.c12
2 files changed, 11 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 944e64aad7e5..9de47a70628f 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
131 /* Wakeup CPU1 only if it is not offlined */ 131 /* Wakeup CPU1 only if it is not offlined */
132 if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { 132 if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
133 clkdm_wakeup(cpu_clkdm[1]); 133 clkdm_wakeup(cpu_clkdm[1]);
134 omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
134 clkdm_allow_idle(cpu_clkdm[1]); 135 clkdm_allow_idle(cpu_clkdm[1]);
135 } 136 }
136 137
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 0cbb677c4df4..e4441cc7aca2 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
83{ 83{
84 static struct clockdomain *cpu1_clkdm; 84 static struct clockdomain *cpu1_clkdm;
85 static bool booted; 85 static bool booted;
86 static struct powerdomain *cpu1_pwrdm;
86 void __iomem *base = omap_get_wakeupgen_base(); 87 void __iomem *base = omap_get_wakeupgen_base();
87 88
88 /* 89 /*
@@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
102 else 103 else
103 __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); 104 __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
104 105
105 if (!cpu1_clkdm) 106 if (!cpu1_clkdm && !cpu1_pwrdm) {
106 cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); 107 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
108 cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
109 }
107 110
108 /* 111 /*
109 * The SGI(Software Generated Interrupts) are not wakeup capable 112 * 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 * Section : 119 * Section :
117 * 4.3.4.2 Power States of CPU0 and CPU1 120 * 4.3.4.2 Power States of CPU0 and CPU1
118 */ 121 */
119 if (booted) { 122 if (booted && cpu1_pwrdm && cpu1_clkdm) {
120 /* 123 /*
121 * GIC distributor control register has changed between 124 * GIC distributor control register has changed between
122 * CortexA9 r1pX and r2pX. The Control Register secure 125 * 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 gic_dist_disable(); 140 gic_dist_disable();
138 } 141 }
139 142
143 /*
144 * Ensure that CPU power state is set to ON to avoid CPU
145 * powerdomain transition on wfi
146 */
140 clkdm_wakeup(cpu1_clkdm); 147 clkdm_wakeup(cpu1_clkdm);
148 omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
141 clkdm_allow_idle(cpu1_clkdm); 149 clkdm_allow_idle(cpu1_clkdm);
142 150
143 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { 151 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {