123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- ==========================================
- ARM idle states binding description
- ==========================================
- ==========================================
- 1 - Introduction
- ==========================================
- ARM systems contain HW capable of managing power consumption dynamically,
- where cores can be put in different low-power states (ranging from simple
- wfi to power gating) according to OS PM policies. The CPU states representing
- the range of dynamic idle states that a processor can enter at run-time, can be
- specified through device tree bindings representing the parameters required
- to enter/exit specific idle states on a given processor.
- According to the Server Base System Architecture document (SBSA, [3]), the
- power states an ARM CPU can be put into are identified by the following list:
- - Running
- - Idle_standby
- - Idle_retention
- - Sleep
- - Off
- The power states described in the SBSA document define the basic CPU states on
- top of which ARM platforms implement power management schemes that allow an OS
- PM implementation to put the processor in different idle states (which include
- states listed above; "off" state is not an idle state since it does not have
- wake-up capabilities, hence it is not considered in this document).
- Idle state parameters (eg entry latency) are platform specific and need to be
- characterized with bindings that provide the required information to OS PM
- code so that it can build the required tables and use them at runtime.
- The device tree binding definition for ARM idle states is the subject of this
- document.
- ===========================================
- 2 - idle-states definitions
- ===========================================
- Idle states are characterized for a specific system through a set of
- timing and energy related properties, that underline the HW behaviour
- triggered upon idle states entry and exit.
- The following diagram depicts the CPU execution phases and related timing
- properties required to enter and exit an idle state:
- ..__[EXEC]__|__[PREP]__|__[ENTRY]__|__[IDLE]__|__[EXIT]__|__[EXEC]__..
- | | | | |
- |<------ entry ------->|
- | latency |
- |<- exit ->|
- | latency |
- |<-------- min-residency -------->|
- |<------- wakeup-latency ------->|
- Diagram 1: CPU idle state execution phases
- EXEC: Normal CPU execution.
- PREP: Preparation phase before committing the hardware to idle mode
- like cache flushing. This is abortable on pending wake-up
- event conditions. The abort latency is assumed to be negligible
- (i.e. less than the ENTRY + EXIT duration). If aborted, CPU
- goes back to EXEC. This phase is optional. If not abortable,
- this should be included in the ENTRY phase instead.
- ENTRY: The hardware is committed to idle mode. This period must run
- to completion up to IDLE before anything else can happen.
- IDLE: This is the actual energy-saving idle period. This may last
- between 0 and infinite time, until a wake-up event occurs.
- EXIT: Period during which the CPU is brought back to operational
- mode (EXEC).
- entry-latency: Worst case latency required to enter the idle state. The
- exit-latency may be guaranteed only after entry-latency has passed.
- min-residency: Minimum period, including preparation and entry, for a given
- idle state to be worthwhile energywise.
- wakeup-latency: Maximum delay between the signaling of a wake-up event and the
- CPU being able to execute normal code again. If not specified, this is assumed
- to be entry-latency + exit-latency.
- These timing parameters can be used by an OS in different circumstances.
- An idle CPU requires the expected min-residency time to select the most
- appropriate idle state based on the expected expiry time of the next IRQ
- (ie wake-up) that causes the CPU to return to the EXEC phase.
- An operating system scheduler may need to compute the shortest wake-up delay
- for CPUs in the system by detecting how long will it take to get a CPU out
- of an idle state, eg:
- wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0)
- In other words, the scheduler can make its scheduling decision by selecting
- (eg waking-up) the CPU with the shortest wake-up latency.
- The wake-up latency must take into account the entry latency if that period
- has not expired. The abortable nature of the PREP period can be ignored
- if it cannot be relied upon (e.g. the PREP deadline may occur much sooner than
- the worst case since it depends on the CPU operating conditions, ie caches
- state).
- An OS has to reliably probe the wakeup-latency since some devices can enforce
- latency constraints guarantees to work properly, so the OS has to detect the
- worst case wake-up latency it can incur if a CPU is allowed to enter an
- idle state, and possibly to prevent that to guarantee reliable device
- functioning.
- The min-residency time parameter deserves further explanation since it is
- expressed in time units but must factor in energy consumption coefficients.
- The energy consumption of a cpu when it enters a power state can be roughly
- characterised by the following graph:
- |
- |
- |
- e |
- n | /---
- e | /------
- r | /------
- g | /-----
- y | /------
- | ----
- | /|
- | / |
- | / |
- | / |
- | / |
- | / |
- |/ |
- -----|-------+----------------------------------
- 0| 1 time(ms)
- Graph 1: Energy vs time example
- The graph is split in two parts delimited by time 1ms on the X-axis.
- The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope
- and denotes the energy costs incurred whilst entering and leaving the idle
- state.
- The graph curve in the area delimited by X-axis values = {x | x > 1ms } has
- shallower slope and essentially represents the energy consumption of the idle
- state.
- min-residency is defined for a given idle state as the minimum expected
- residency time for a state (inclusive of preparation and entry) after
- which choosing that state become the most energy efficient option. A good
- way to visualise this, is by taking the same graph above and comparing some
- states energy consumptions plots.
- For sake of simplicity, let's consider a system with two idle states IDLE1,
- and IDLE2:
- |
- |
- |
- | /-- IDLE1
- e | /---
- n | /----
- e | /---
- r | /-----/--------- IDLE2
- g | /-------/---------
- y | ------------ /---|
- | / /---- |
- | / /--- |
- | / /---- |
- | / /--- |
- | --- |
- | / |
- | / |
- |/ | time
- ---/----------------------------+------------------------
- |IDLE1-energy < IDLE2-energy | IDLE2-energy < IDLE1-energy
- |
- IDLE2-min-residency
- Graph 2: idle states min-residency example
- In graph 2 above, that takes into account idle states entry/exit energy
- costs, it is clear that if the idle state residency time (ie time till next
- wake-up IRQ) is less than IDLE2-min-residency, IDLE1 is the better idle state
- choice energywise.
- This is mainly down to the fact that IDLE1 entry/exit energy costs are lower
- than IDLE2.
- However, the lower power consumption (ie shallower energy curve slope) of idle
- state IDLE2 implies that after a suitable time, IDLE2 becomes more energy
- efficient.
- The time at which IDLE2 becomes more energy efficient than IDLE1 (and other
- shallower states in a system with multiple idle states) is defined
- IDLE2-min-residency and corresponds to the time when energy consumption of
- IDLE1 and IDLE2 states breaks even.
- The definitions provided in this section underpin the idle states
- properties specification that is the subject of the following sections.
- ===========================================
- 3 - idle-states node
- ===========================================
- ARM processor idle states are defined within the idle-states node, which is
- a direct child of the cpus node [1] and provides a container where the
- processor idle states, defined as device tree nodes, are listed.
- - idle-states node
- Usage: Optional - On ARM systems, it is a container of processor idle
- states nodes. If the system does not provide CPU
- power management capabilities or the processor just
- supports idle_standby an idle-states node is not
- required.
- Description: idle-states node is a container node, where its
- subnodes describe the CPU idle states.
- Node name must be "idle-states".
- The idle-states node's parent node must be the cpus node.
- The idle-states node's child nodes can be:
- - one or more state nodes
- Any other configuration is considered invalid.
- An idle-states node defines the following properties:
- - entry-method
- Value type: <stringlist>
- Usage and definition depend on ARM architecture version.
- # On ARM v8 64-bit this property is required and must
- be one of:
- - "psci" (see bindings in [2])
- # On ARM 32-bit systems this property is optional
- The nodes describing the idle states (state) can only be defined within the
- idle-states node, any other configuration is considered invalid and therefore
- must be ignored.
- ===========================================
- 4 - state node
- ===========================================
- A state node represents an idle state description and must be defined as
- follows:
- - state node
- Description: must be child of the idle-states node
- The state node name shall follow standard device tree naming
- rules ([5], 2.2.1 "Node names"), in particular state nodes which
- are siblings within a single common parent must be given a unique name.
- The idle state entered by executing the wfi instruction (idle_standby
- SBSA,[3][4]) is considered standard on all ARM platforms and therefore
- must not be listed.
- With the definitions provided above, the following list represents
- the valid properties for a state node:
- - compatible
- Usage: Required
- Value type: <stringlist>
- Definition: Must be "arm,idle-state".
- - local-timer-stop
- Usage: See definition
- Value type: <none>
- Definition: if present the CPU local timer control logic is
- lost on state entry, otherwise it is retained.
- - entry-latency-us
- Usage: Required
- Value type: <prop-encoded-array>
- Definition: u32 value representing worst case latency in
- microseconds required to enter the idle state.
- The exit-latency-us duration may be guaranteed
- only after entry-latency-us has passed.
- - exit-latency-us
- Usage: Required
- Value type: <prop-encoded-array>
- Definition: u32 value representing worst case latency
- in microseconds required to exit the idle state.
- - min-residency-us
- Usage: Required
- Value type: <prop-encoded-array>
- Definition: u32 value representing minimum residency duration
- in microseconds, inclusive of preparation and
- entry, for this idle state to be considered
- worthwhile energy wise (refer to section 2 of
- this document for a complete description).
- - wakeup-latency-us:
- Usage: Optional
- Value type: <prop-encoded-array>
- Definition: u32 value representing maximum delay between the
- signaling of a wake-up event and the CPU being
- able to execute normal code again. If omitted,
- this is assumed to be equal to:
- entry-latency-us + exit-latency-us
- It is important to supply this value on systems
- where the duration of PREP phase (see diagram 1,
- section 2) is non-neglibigle.
- In such systems entry-latency-us + exit-latency-us
- will exceed wakeup-latency-us by this duration.
- - status:
- Usage: Optional
- Value type: <string>
- Definition: A standard device tree property [5] that indicates
- the operational status of an idle-state.
- If present, it shall be:
- "okay": to indicate that the idle state is
- operational.
- "disabled": to indicate that the idle state has
- been disabled in firmware so it is not
- operational.
- If the property is not present the idle-state must
- be considered operational.
- - idle-state-name:
- Usage: Optional
- Value type: <string>
- Definition: A string used as a descriptive name for the idle
- state.
- In addition to the properties listed above, a state node may require
- additional properties specifics to the entry-method defined in the
- idle-states node, please refer to the entry-method bindings
- documentation for properties definitions.
- ===========================================
- 4 - Examples
- ===========================================
- Example 1 (ARM 64-bit, 16-cpu system, PSCI enable-method):
- cpus {
- #size-cells = <0>;
- #address-cells = <2>;
- CPU0: cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x0>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU1: cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x1>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU2: cpu@100 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x100>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU3: cpu@101 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x101>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU4: cpu@10000 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x10000>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU5: cpu@10001 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x10001>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU6: cpu@10100 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x10100>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU7: cpu@10101 {
- device_type = "cpu";
- compatible = "arm,cortex-a57";
- reg = <0x0 0x10101>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_0_0 &CPU_SLEEP_0_0
- &CLUSTER_RETENTION_0 &CLUSTER_SLEEP_0>;
- };
- CPU8: cpu@100000000 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x0>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU9: cpu@100000001 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x1>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU10: cpu@100000100 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x100>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU11: cpu@100000101 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x101>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU12: cpu@100010000 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x10000>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU13: cpu@100010001 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x10001>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU14: cpu@100010100 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x10100>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- CPU15: cpu@100010101 {
- device_type = "cpu";
- compatible = "arm,cortex-a53";
- reg = <0x1 0x10101>;
- enable-method = "psci";
- cpu-idle-states = <&CPU_RETENTION_1_0 &CPU_SLEEP_1_0
- &CLUSTER_RETENTION_1 &CLUSTER_SLEEP_1>;
- };
- idle-states {
- entry-method = "psci";
- CPU_RETENTION_0_0: cpu-retention-0-0 {
- compatible = "arm,idle-state";
- arm,psci-suspend-param = <0x0010000>;
- entry-latency-us = <20>;
- exit-latency-us = <40>;
- min-residency-us = <80>;
- };
- CLUSTER_RETENTION_0: cluster-retention-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x1010000>;
- entry-latency-us = <50>;
- exit-latency-us = <100>;
- min-residency-us = <250>;
- wakeup-latency-us = <130>;
- };
- CPU_SLEEP_0_0: cpu-sleep-0-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x0010000>;
- entry-latency-us = <250>;
- exit-latency-us = <500>;
- min-residency-us = <950>;
- };
- CLUSTER_SLEEP_0: cluster-sleep-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x1010000>;
- entry-latency-us = <600>;
- exit-latency-us = <1100>;
- min-residency-us = <2700>;
- wakeup-latency-us = <1500>;
- };
- CPU_RETENTION_1_0: cpu-retention-1-0 {
- compatible = "arm,idle-state";
- arm,psci-suspend-param = <0x0010000>;
- entry-latency-us = <20>;
- exit-latency-us = <40>;
- min-residency-us = <90>;
- };
- CLUSTER_RETENTION_1: cluster-retention-1 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x1010000>;
- entry-latency-us = <50>;
- exit-latency-us = <100>;
- min-residency-us = <270>;
- wakeup-latency-us = <100>;
- };
- CPU_SLEEP_1_0: cpu-sleep-1-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x0010000>;
- entry-latency-us = <70>;
- exit-latency-us = <100>;
- min-residency-us = <300>;
- wakeup-latency-us = <150>;
- };
- CLUSTER_SLEEP_1: cluster-sleep-1 {
- compatible = "arm,idle-state";
- local-timer-stop;
- arm,psci-suspend-param = <0x1010000>;
- entry-latency-us = <500>;
- exit-latency-us = <1200>;
- min-residency-us = <3500>;
- wakeup-latency-us = <1300>;
- };
- };
- };
- Example 2 (ARM 32-bit, 8-cpu system, two clusters):
- cpus {
- #size-cells = <0>;
- #address-cells = <1>;
- CPU0: cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a15";
- reg = <0x0>;
- cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
- };
- CPU1: cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a15";
- reg = <0x1>;
- cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
- };
- CPU2: cpu@2 {
- device_type = "cpu";
- compatible = "arm,cortex-a15";
- reg = <0x2>;
- cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
- };
- CPU3: cpu@3 {
- device_type = "cpu";
- compatible = "arm,cortex-a15";
- reg = <0x3>;
- cpu-idle-states = <&CPU_SLEEP_0_0 &CLUSTER_SLEEP_0>;
- };
- CPU4: cpu@100 {
- device_type = "cpu";
- compatible = "arm,cortex-a7";
- reg = <0x100>;
- cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
- };
- CPU5: cpu@101 {
- device_type = "cpu";
- compatible = "arm,cortex-a7";
- reg = <0x101>;
- cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
- };
- CPU6: cpu@102 {
- device_type = "cpu";
- compatible = "arm,cortex-a7";
- reg = <0x102>;
- cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
- };
- CPU7: cpu@103 {
- device_type = "cpu";
- compatible = "arm,cortex-a7";
- reg = <0x103>;
- cpu-idle-states = <&CPU_SLEEP_1_0 &CLUSTER_SLEEP_1>;
- };
- idle-states {
- CPU_SLEEP_0_0: cpu-sleep-0-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- entry-latency-us = <200>;
- exit-latency-us = <100>;
- min-residency-us = <400>;
- wakeup-latency-us = <250>;
- };
- CLUSTER_SLEEP_0: cluster-sleep-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- entry-latency-us = <500>;
- exit-latency-us = <1500>;
- min-residency-us = <2500>;
- wakeup-latency-us = <1700>;
- };
- CPU_SLEEP_1_0: cpu-sleep-1-0 {
- compatible = "arm,idle-state";
- local-timer-stop;
- entry-latency-us = <300>;
- exit-latency-us = <500>;
- min-residency-us = <900>;
- wakeup-latency-us = <600>;
- };
- CLUSTER_SLEEP_1: cluster-sleep-1 {
- compatible = "arm,idle-state";
- local-timer-stop;
- entry-latency-us = <800>;
- exit-latency-us = <2000>;
- min-residency-us = <6500>;
- wakeup-latency-us = <2300>;
- };
- };
- };
- ===========================================
- 5 - References
- ===========================================
- [1] ARM Linux Kernel documentation - CPUs bindings
- Documentation/devicetree/bindings/arm/cpus.txt
- [2] ARM Linux Kernel documentation - PSCI bindings
- Documentation/devicetree/bindings/arm/psci.txt
- [3] ARM Server Base System Architecture (SBSA)
- http://infocenter.arm.com/help/index.jsp
- [4] ARM Architecture Reference Manuals
- http://infocenter.arm.com/help/index.jsp
- [5] ePAPR standard
- https://www.power.org/documentation/epapr-version-1-1/
|