aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/sleep-tegra20.S
diff options
context:
space:
mode:
authorJoseph Lo <josephl@nvidia.com>2013-01-16 12:33:55 -0500
committerStephen Warren <swarren@nvidia.com>2013-01-28 13:20:38 -0500
commit1d328606c66b9bb1c0552f585943d596f37ae3b9 (patch)
treeebb8a6e60de7b5b96100ffbcda57445116a906ef /arch/arm/mach-tegra/sleep-tegra20.S
parentafec581c4b53e03a97d9ef1b7a746a67967573cf (diff)
ARM: tegra20: cpuidle: apply coupled cpuidle for powered-down mode
The "powered-down" cpuidle mode of Tegra20 needs the CPU0 be the last one core to go into this mode before other core. The coupled cpuidle framework can help to sync the MPCore to coupled state then go into "powered-down" idle mode together. The driver can just assume the MPCore come into "powered-down" mode at the same time. No need to take care if the CPU_0 goes into this mode along and only can put it into safe idle mode (WFI). The powered-down state of Tegra20 requires power gating both CPU cores. When the secondary CPU requests to enter powered-down state, it saves its own contexts and then enters WFI for waiting CPU0 in the same state. When the CPU0 requests powered-down state, it attempts to put the secondary CPU into reset to prevent it from waking up. Then power down both CPUs together and power off the cpu rail. Be aware of that, you may see the legacy power state "LP2" in the code which is exactly the same meaning of "CPU power down". Based on the work by: Colin Cross <ccross@android.com> Gary King <gking@nvidia.com> Signed-off-by: Joseph Lo <josephl@nvidia.com> Acked-by: Colin Cross <ccross@android.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/sleep-tegra20.S')
-rw-r--r--arch/arm/mach-tegra/sleep-tegra20.S53
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 1074364e77ee..9f6bfafdd512 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -57,6 +57,9 @@ ENDPROC(tegra20_hotplug_shutdown)
57ENTRY(tegra20_cpu_shutdown) 57ENTRY(tegra20_cpu_shutdown)
58 cmp r0, #0 58 cmp r0, #0
59 moveq pc, lr @ must not be called for CPU 0 59 moveq pc, lr @ must not be called for CPU 0
60 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
61 mov r12, #CPU_RESETTABLE
62 str r12, [r1]
60 63
61 cpu_to_halt_reg r1, r0 64 cpu_to_halt_reg r1, r0
62 ldr r3, =TEGRA_FLOW_CTRL_VIRT 65 ldr r3, =TEGRA_FLOW_CTRL_VIRT
@@ -163,6 +166,21 @@ ENTRY(tegra20_cpu_set_resettable_soon)
163ENDPROC(tegra20_cpu_set_resettable_soon) 166ENDPROC(tegra20_cpu_set_resettable_soon)
164 167
165/* 168/*
169 * tegra20_cpu_is_resettable_soon(void)
170 *
171 * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
172 * set because it is expected that the secondary CPU will be idle soon.
173 */
174ENTRY(tegra20_cpu_is_resettable_soon)
175 mov32 r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
176 ldr r12, [r1]
177 cmp r12, #CPU_RESETTABLE_SOON
178 moveq r0, #1
179 movne r0, #0
180 mov pc, lr
181ENDPROC(tegra20_cpu_is_resettable_soon)
182
183/*
166 * tegra20_sleep_cpu_secondary_finish(unsigned long v2p) 184 * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
167 * 185 *
168 * Enters WFI on secondary CPU by exiting coherency. 186 * Enters WFI on secondary CPU by exiting coherency.
@@ -221,4 +239,39 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
221 239
222 ldmfd sp!, {r4 - r11, pc} 240 ldmfd sp!, {r4 - r11, pc}
223ENDPROC(tegra20_sleep_cpu_secondary_finish) 241ENDPROC(tegra20_sleep_cpu_secondary_finish)
242
243/*
244 * tegra20_tear_down_cpu
245 *
246 * Switches the CPU cluster to PLL-P and enters sleep.
247 */
248ENTRY(tegra20_tear_down_cpu)
249 bl tegra_switch_cpu_to_pllp
250 b tegra20_enter_sleep
251ENDPROC(tegra20_tear_down_cpu)
252
253/*
254 * tegra20_enter_sleep
255 *
256 * uses flow controller to enter sleep state
257 * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
258 * executes from SDRAM with target state is LP2
259 */
260tegra20_enter_sleep:
261 mov32 r6, TEGRA_FLOW_CTRL_BASE
262
263 mov r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
264 orr r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
265 cpu_id r1
266 cpu_to_halt_reg r1, r1
267 str r0, [r6, r1]
268 dsb
269 ldr r0, [r6, r1] /* memory barrier */
270
271halted:
272 dsb
273 wfe /* CPU should be power gated here */
274 isb
275 b halted
276
224#endif 277#endif