ACPI System Sleep States and Wake up events

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:

  1. OSPM decides (through a policy scheme) to place the system into a sleeping state

  2. _TTS(Sx) is run, where Sx is the desired sleep state to enter

  3. OSPM notifies all native device drivers of the sleep state transition

  4. _PTS is run

  5. OSPM readies system for the sleep state transition

  6. 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.

  7. System Wakes up

  8. OSPM readies system for the return from the sleep state transition

  9. _WAK is run

  10. OSPM notifies all native device drivers of the return from the sleep state transition

  11. _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.

 

PSCI_CPU_SUSPEND API has a power_state parameter and some of the bits are vendor-specific and this is typically defined in the DT. How do we derive this for ACPI?

Linux commands to test ACPI suspend states

Disable console suspend to get full suspend traces

echo N > /sys/module/printk/parameters/console_suspend

S1

echo standby > /sys/power/state

S3

echo deep > /sys/power/mem_sleep echo mem > /sys/power/state

S4

S2Idle

Linux testing status for ACPI suspend using PSCI

Suspend State

Wake Up event

Status

Notes

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