ARM: tegra: power: Power off multiple CPUs on-line
authorAlex Frid <afrid@nvidia.com>
Fri, 3 Feb 2012 00:21:02 +0000 (16:21 -0800)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 07:59:22 +0000 (00:59 -0700)
commitd9dd580bf54f8a67c824c9dabb7799d334522c18
tree66abb61031fd61e09548b5a92e9a05a97dd37e40
parent97d33af21c99748b62dd690bf4ae7e718b8419ef
ARM: tegra: power: Power off multiple CPUs on-line

Currently on Tegra3 cpu complex is powered off in idle (enters CPU0
LP2 state) only if all secondary CPUs are off-line. This commit adds
an option for CPU0 to enter LP2 while secondary CPUs are still on-line
but have been power gated and entered LP2 state by themselves.

The critical race: secondary CPU is waking up from LP2, while CPU0 is
turning common CPU rail off, is addressed as follows.

1. When entering LP2 state on CPU0:
a) disable GIC distributor
b) check that CPU1-3 are all power-gated (i.e., either off-lined or
have entered LP2)
c) if (b) passes - set all interrupts affinity to CPU0, then
re-enable distributor and continue with CPU complex powering off
d) if (b) fails - re-enable distributor and enter clock-gated (LP3)
state on CPU0
This procedure prevents waking secondary CPUs by GIC SPIs.

2. We still need to make sure that no CPU1-3 PPIs from legacy IRQ/FIQ
or private timers would happen. This is achieved by disabling timers
and legacy interrupts if CPU1-3 enters LP2 state with external timers
selected as wake sources. Respectively, establish dependency between
turning rail off and LP2 wake timers configuration options.

3. Finally, no IPIs is sent by CPU0 entering LP2.

There are no special changes in wake up procedures - whenever CPU0
is awaken by external interrupt or wake timer, cpu complex is powered
on by h/w, and secondary CPUs that were in LP2 state are ungated by
the same interrupt (off-line CPUs are kept power gated). Hence, there
is no need for CPU1-3 external wake timers to run while the rail is
off, and these timers are stopped. To make sure that none of secondary
CPUs over-sleeps its LP2 time, CPU0 wake timer is set to minimum sleep
interval of all CPUs.

By default configuration option for powering off multiple on-line CPUs
is disabled on Tegra3.

Change-Id: I4920d0df375536b2b8ebd9e6738c5fe4f92b92a0
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/83547
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

Rebase-Id: Rc518e98ddce9152f0eeb086a49c31e1c252fe9eb
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/cpuidle-t3.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/timer-t3.c