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 latency to enter sleep states entry/exit latency and power savings. ACPI also provides a mechanism to specify devices that can wake up the system from sleep states and related control methods and bindings to specify how the transition to sleep and wake up are performed.
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 stored.
System Control Methods
Add 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, _WAKDefine , _SWS (System Wake Source)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.
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
...
.
...
System Wakes up
...
...
_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
...
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.”
\_Sx (System States)
Code Block |
---|
Name (_S0, Package (0x04) // _S0_: S0 System State
{
Zero,
Zero,
Zero,
Zero
})
If (SS3)
{
Name (_S3, Package (0x04) // _S3_: S3 System State
{
0x05,
Zero,
Zero,
Zero
})
}
If (SS4)
{
Name (_S4, Package (0x04) // _S4_: S4 System State
{
0x06,
Zero,
Zero,
Zero
})
}
Name (_S5, Package (0x04) // _S5_: S5 System State
{
0x07,
Zero,
Zero,
Zero
})
Method (PTS, 1, NotSerialized)
{
If (Arg0)
{
\_SB.PCI0.LPCB.EC0.ECPS (Arg0)
\_SB.PCI0.LPCB.SPTS (Arg0)
\_SB.PCI0.NPTS (Arg0)
}
}
Method (WAK, 1, NotSerialized)
{
\_SB.PCI0.LPCB.SWAK (Arg0)
\_SB.PCI0.NWAK (Arg0)
}
}
Method (SWAK, 1, NotSerialized)
{
SLPE = Zero
If (RTCX){}
Else
{
Notify (PWRB, 0x02) // Device Wake
}
}
Scope (_SB)
{
Device (PWRB)
{
Name (_HID, EisaId ("PNP0C0C") /* Power Button Device */) // _HID: Hardware ID
Name (_PRW, Package (0x02) // _PRW: Power Resources for Wake
{
0x1E,
0x04
})
Method (_STA, 0, NotSerialized) // _STA: Status
{
If ((ECON == One))
{
Return (0x0F)
}
Return (Zero)
}
}
}
|
Surface 3
Code Block |
---|
Method (_WAK, 1, NotSerialized) // _WAK: Wake
{
PWAK (Arg0)
Return (WAKP) /* \WAKP */
}
Method (_PTS, 1, NotSerialized) // _PTS: Prepare To Sleep
{
If (Arg0)
{
PPTS (Arg0)
}
}
|
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.
...
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.
...
5.2.9 Fixed ACPI Description Table (FADT)
Code Block |
---|
[0F4h 0244 12] Sleep Control Register : [Generic Address Structure]
[0F4h 0244 1] Space ID : 01 [SystemIO]
[0F5h 0245 1] Bit Width : 08
[0F6h 0246 1] Bit Offset : 00
[0F7h 0247 1] Encoded Access Width : 01 [Byte Access:8]
[0F8h 0248 8] Address : 0000000000000405
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
[100h 0256 1] Space ID : 01 [SystemIO]
[101h 0257 1] Bit Width : 08
[102h 0258 1] Bit Offset : 00
[103h 0259 1] Encoded Access Width : 01 [Byte Access:8]
[104h 0260 8] Address : 0000000000000401
|
TODO
Add Sleep Control and status register to FADT
Define _S1, _S2, _S3, _S4 and _S5 states to DSDT
Define _PTS, _TTS, _WAK
For Devices with wake-up capabilities:
Define _SxD (S-state to D-State Mapping)
Define _SxW
_PRW or _PSW
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
Questions
Check how we can flush the cache on Arm platforms - WBINVD
No
16.1.6 Transitioning from the Working to the Sleeping State
...
Flushing the Caches
OSPM is responsible for flushing the system caches before entering sleep states.
...
FLUSH_SIZE. Indicates twice the size of the largest cache in bytes.
•FLUSHFLUSH_STRIDE. Indicates the smallest line size of the caches in bytes. The cache flush size value is typically twice the size of the largest cache size, and the cache flush stride value is typically the size of the smallest cache line size in the platform. OSPM will flush the system caches by reading a contiguous block of memory indicated by the cache flush size.
As mentioned previously, waking from an S4 state is treated the same as a cold boot: the platform boot firmware runs POST and then initializes memory to contain the ACPI system description tables. After it has finished this, it can call OSPM loader, and control is passed to OSPM. When waking from S4 (either S4OS or S4BIOS), the platform boot firmware may optionally set SCI_EN bit before passing control to OSPM. In this case, interrupts must be disabled (for IA-32 processors, disabled CLI instruction) until the control is passed to OSPM and the chipset must be configured in ACPI mode
Linux possible known gaps
ACPI System Low Power States
This work as is since it's directly PSCI linked. However, this is not
connected remotely to existing ACPI methods (7.4.2 _Sx (System
States)). It could be problematic without that as wakeup events need
to be linked to appropriate states as per specification.
Wake Events/Sources
...
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
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