ARM: tegra: Add suspend support
authorColin Cross <ccross@android.com>
Mon, 29 Nov 2010 06:36:08 +0000 (22:36 -0800)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 07:46:50 +0000 (00:46 -0700)
commit45593c20a5f6752f9bed1d69c67c04b1832dadd4
tree60e3eab709df021c84d2c6e4be4d776a72488fa9
parent82b7dc5d12a7d7cfa75a0bdcdeea670fdf658125
ARM: tegra: Add suspend support

Tegra supports three low power modes that involve powering down the CPU.

LP2 powers down both CPU cores and the GICs, but leaves the core
peripherals, including the memory controller and the legacy
interrupt controller, enabled.  The legacy interrupt controller
is used as the wakeup source, and any interrupt can wake the device.
LP2 can be used in idle.

LP1 is the same as LP2, but in addition turns off the memory
controller and puts the DDR memory in self-refresh.  Any interrupt
can wake the device. LP1 could be used in idle if no peripherals
are doing DMA.

LP0 turns off everything in the SoC except the RTC and a power
management controller, both of which run off a 32 kHz clock.
The power management controller has 32 wake sources, all other
interrupts can not be used to wake from LP0.

These low power modes power-gate the main CPU complex, requiring a
full processor state save and restore from a reset vector.

Platform-specific data (power good times, PMU capabilities, etc.) must be
specified when registering the suspend operations to ensure that platform
power sequencing restrictions are maintained.

In both LP0 and LP1, SDRAM is placed into self-refresh. in order to safely
perform this transition, the final shutdown procedure responsible for

  * turning off the MMU and L1 data cache
  * putting memory into self-refresh
  * setting the DDR pads to the lowest power state
  * and turning off PLLs

is copied into IRAM (at the address TEGRA_IRAM_BASE + SZ_4K) at the
start of the suspend process.

In LP1 mode (like LP2), the CPU is reset and executes the code specified
at the EVP reset vector.  Since SDRAM is in self-refresh, this code must
also be located in IRAM, and it must re-enable DRAM before restoring the
full context.  In this implementation, it enables the CPU on PLLP, enables
PLLC and PLLM, restores the SCLK burst policy, and jumps to the LP2 reset
vector to restore the rest of the system (MMU, PLLX, coresite, etc.).  The
LP2 reset vector is expected to be found in PMC_SCRATCH1, and is
initialized during system-bootup.

In LP0 mode, the core voltage domain is also shutoff.  As a result, all
of the volatile state in the core voltage domain (e.g., pinmux registers,
clock registers, etc.) must be saved to memory so that it can be restored
after the system resumes.  A limited set of wakeups are available from LP0,
and the correct levels for the wakeups must be programmed into the PMC
wakepad configuration register prior to system shutdown.  On resume, the
system resets into the boot ROM, and the boot ROM restores SDRAM and other
system state using values saved during kernel initialization in the PMC
scratch registers.

Resuming from LP0 requires the boot ROM to supply a signed recovery codeblob
to the kernel; the kernel expects that the length and address of this blob
is supplied with the lp0_vec= command line argument; if not present, suspend-
to-LP0 will be disabled

For simplicity, the outer cache is shutdown for both LP0 and LP1; it
is possible to optimize the LP1 routine to bypass outer cache shutdown
and restart.

Includes fixes from:
Scott Williams <scwilliams@nvidia.com>
Aleksandr Frid <afrid@nvidia.com>
Vik Kasivajhula <tkasivajhula@nvidia.com>
Bharat Nihalani <Kbnihalani@nvidia.com>
James Wylder <james.wylder@motorola.com>
Allen Martin <amartin@nvidia.com>

Change-Id: I9e4e61c2fbb8c7bb5a29b1832ea38e7ea0524c52
Original-author: Gary King <gking@nvidia.com>
Signed-off-by: Gary King <gking@nvidia.com>
Signed-off-by: Colin Cross <ccross@android.com>
DW: Split sleep.S to sleep-t20.S
Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

Rebase-Id: R092fd9c11253416a13efb37740e961389f56dbbc
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/flowctrl.h
arch/arm/mach-tegra/pm-t2.c [new file with mode: 0644]
arch/arm/mach-tegra/pm.c [new file with mode: 0644]
arch/arm/mach-tegra/pm.h [new file with mode: 0644]
arch/arm/mach-tegra/sleep-t20.S
arch/arm/mach-tegra/sleep.S
arch/arm/mach-tegra/sleep.h