Table of Contents | ||||
---|---|---|---|---|
|
ACPI defines system sleep states (S-States, S1 to S5) within the global system power state (G-States, G0 to G1). S0 is the working state in which actual work is being done and S1 to S5 are different sleep states with varying entry/exit latency and power savings. ACPI also provides a mechanism to specify devices that can wake up the system and related control methods and bindings.
Hardware can provide multiple system states that have different power and exit latencies and OSPM picks a sleeping state most appropriate based on the OS policies and device capabilities to wake up the system etc.
ACPI System States
S0: The processors are either running, or in a C-state, or in an LPI state. Processor context, Cache, Memory, etc are retained. Devices can be in any of the power states.
S1: Processor context is maintained, memory context is maintained. Devices are in a compatible state. Devices enabled for wake from S1 can wake up the system.
S2: Processor context is not maintained and memory context is maintained.
S3: Similar to S2, but deeper sleeping state and better power saving.
S4: Processor context and memory context are not maintained. Processor state and memory is saved to disk and restored on wakeup.
S5: Soft off, similar to S4 but no context is saved.
Sleep / Wake-up Flow
OSPM will invoke _PTS, _TTS, and _WAK in the following order:
OSPM decides (through a policy scheme) to place the system into a sleeping state
_TTS(Sx) is run, where Sx is the desired sleep state to enter
OSPM notifies all native device drivers of the sleep state transition
_PTS is run
OSPM readies system for the sleep state transition
OSPM writes the HW-reduced Sleep Type value to the Sleep Control Register and spins waiting for the WAK_STS bit of the Sleep Status Register to be set, indicating a platform transition to the Working state.
System Wakes up
OSPM readies system for the return from the sleep state transition
_WAK is run
OSPM notifies all native device drivers of the return from the sleep state transition
_TTS(0) is run to indicate the return to the S0 state
Required Sleep Object and Control Methods
Define Sleep Control and status register to FADT
Define _S1, _S2, _S3, _S4 and _S5 states to DSDT as appropriate.
Define _PTS, _TTS, _WAK, _SWS control methods
_PTS (Prepare To Sleep)
The _PTS control method is executed by the OS during the sleep transition process for S1, S2, S3, S4, and for orderly S5 shutdown.
_SWS (System Wake Source)
This object provides a means for OSPM to definitively determine the source of an event that caused the system to enter the S0 state
_TTS (Transition To State)
The _TTS control method is executed by the OSPM at the beginning of the sleep transition process for S1, S2, S3, S4, and orderly S5 shutdown
_WAK (System Wake)
After the system wakes from a sleeping state, it will invoke the \_WAK method and pass the sleeping state value that has ended.
Device Wake-Up Capabilities
When controlling power to devices that must wake the system during a system sleeping state:
The device must declare its ability to wake the system by declaring either the _PRW or _PSW object.
After OSPM has called _PTS, it must call the device’s _PSW to enable wake.
OSPM must transition a device into a D-state that is deeper than or equal to that specified by the device’s _SxD object (if present) to enable entry into Sx, but shallower than or equal to that specified by the device’s _SxW object so that it can still wake the system.
OSPM may transition the system to the specified sleep state.
_DSW (Device Sleep Wake) In addition to _PRW, this control method can be used to enable or disable the device’s ability to wake a sleeping system.
_SxW (Sx Device Wake State) This object evaluates to an integer that conveys to OSPM the deepest D-state supported by this device in the Sx system sleeping state where the device can wake itself.
_SxD: These methods tell OSPM for S-state “x”, the shallowest D-state supported by the device is “y.”
Sleep Control and Status Register
The optional ACPI sleep registers (SLEEP_CONTROL_REG and SLEEP_STATUS_REG) specify a standard mechanism for system sleep state entry on HW-Reduced ACPI systems.
Use of these registers is at the discretion of OSPM. OSPM can decide whether to enter sleep states on the platform based on the LOW_POWER_S0_IDLE_CAPABLE flag. Even when implemented, OSPM may use other provided options for hibernate and shutdown (e.g. UEFI ResetSystem()).
The HW-reduced Sleep mechanism is implemented via two 8-bit registers described by SLEEP_CONTROL_REG and SLEEP_STATUS_REG in the FADT (always accessed via the natural alignment and size described in SLEEP_*_REG). To put the system into a sleep state, software will write the HW-reduced Sleep Type value (obtained from the \_Sx object in the DSDT) and the SLP_EN bit to the sleep control register. The OSPM then polls the WAK_STS bit of the SLEEP_STATUS_REG waiting for it to be one (1), indicating that the system has been transitioned back to the Working state.
Flushing the Caches
OSPM is responsible for flushing the system caches before entering sleep states.
The manual cache-flushing mechanism relies on the two FADT fields:
FLUSH_SIZE. Indicates twice the size of the largest cache in bytes.
FLUSH_STRIDE. Indicates the smallest line size of the caches in bytes.
Low Power Idle (LPI)
ACPI v6.0 introduced Low Power Idle mode in S0. S0 Idle could achieve savings similar to or better than those typically achieved in S3. OSPM can keep the system in S0 idle for its low-latency response rather than transitioning to a system sleep state.
Linux ACPI Suspend Flow
acpi_enter_sleep_state
uses hardware sleep control and status register to put the system to sleep and wake up.
PSCI-based suspend for Arm platforms
Arm platforms implement PSCI standards (mandated by BSA spec) and rather than introducing the sleep control and status register could make use of the PSCI standard for putting CPU and platform to suspend state.
Linux commands to test ACPI suspend states
Disable console suspend to get full suspend traces
Code Block |
---|
echo N > /sys/module/printk/parameters/console_suspend |
S1
Code Block |
---|
echo standby > /sys/power/state |
S3
Code Block |
---|
echo deep > /sys/power/mem_sleep echo mem > /sys/power/state |
S4
Code Block |
---|
echo disk > /sys/power/state |
S2Idle
Code Block |
---|
echo freeze > /sys/power/state |
Linux testing status for ACPI suspend using PSCI
Suspend State | Wake Up event | Status | Notes |
---|---|---|---|
S2Idle | Lid | OK | |
S2Idle | RTC Alarm | OK | Linux kernel uses few ACPI GPE functions to determine if the device can wake up. They return wrong values for Arm64 implementation and had to be disabled during the testing. |
S1 | Lid | OK | |
S1 | RTC Alarm | OK | |
S3 | TF-A hack to wake up immediately after suspend | OK | This works only with single processor suspend, for SMP the wake up sequence crashes. The same behaviour is observed for DT as well. |
Gaps in existing Linux implementation
Linux kernel uses a few ACPI GPE functions to determine if the device can wake up and set appropriate flags. GPE is not present in HW-reduced platforms.
Linux ACPI suspend does not have PSCI bindings