Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
minLevel1
maxLevel7

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:

  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, _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

Image Added

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