856 lines
30 KiB
YAML
856 lines
30 KiB
YAML
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||
|
%YAML 1.2
|
||
|
---
|
||
|
$id: http://devicetree.org/schemas/cpu/idle-states.yaml#
|
||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||
|
|
||
|
title: Idle states binding description
|
||
|
|
||
|
maintainers:
|
||
|
- Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
||
|
- Anup Patel <anup@brainfault.org>
|
||
|
|
||
|
description: |+
|
||
|
==========================================
|
||
|
1 - Introduction
|
||
|
==========================================
|
||
|
|
||
|
ARM and RISC-V 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.
|
||
|
|
||
|
==========================================
|
||
|
2 - ARM idle states
|
||
|
==========================================
|
||
|
|
||
|
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 (e.g. 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.
|
||
|
|
||
|
==========================================
|
||
|
3 - RISC-V idle states
|
||
|
==========================================
|
||
|
|
||
|
On RISC-V systems, the HARTs (or CPUs) [6] can be put in platform specific
|
||
|
suspend (or idle) states (ranging from simple WFI, power gating, etc). The
|
||
|
RISC-V SBI v0.3 (or higher) [7] hart state management extension provides a
|
||
|
standard mechanism for OS to request HART state transitions.
|
||
|
|
||
|
The platform specific suspend (or idle) states of a hart can be either
|
||
|
retentive or non-rententive in nature. A retentive suspend state will
|
||
|
preserve HART registers and CSR values for all privilege modes whereas
|
||
|
a non-retentive suspend state will not preserve HART registers and CSR
|
||
|
values.
|
||
|
|
||
|
===========================================
|
||
|
4 - 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
|
||
|
(i.e. 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, e.g.:
|
||
|
|
||
|
wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0)
|
||
|
|
||
|
In other words, the scheduler can make its scheduling decision by selecting
|
||
|
(e.g. waking-up) the CPU with the shortest wake-up delay.
|
||
|
The wake-up delay 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, i.e. caches
|
||
|
state).
|
||
|
|
||
|
An OS has to reliably probe the wakeup-latency since some devices can enforce
|
||
|
latency constraint 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 while 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 (i.e. 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 (i.e. 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.
|
||
|
|
||
|
===========================================
|
||
|
5 - idle-states node
|
||
|
===========================================
|
||
|
|
||
|
The 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.
|
||
|
|
||
|
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.
|
||
|
|
||
|
===========================================
|
||
|
6 - References
|
||
|
===========================================
|
||
|
|
||
|
[1] ARM Linux Kernel documentation - CPUs bindings
|
||
|
Documentation/devicetree/bindings/arm/cpus.yaml
|
||
|
|
||
|
[2] ARM Linux Kernel documentation - PSCI bindings
|
||
|
Documentation/devicetree/bindings/arm/psci.yaml
|
||
|
|
||
|
[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] ARM Linux Kernel documentation - Booting AArch64 Linux
|
||
|
Documentation/arm64/booting.rst
|
||
|
|
||
|
[6] RISC-V Linux Kernel documentation - CPUs bindings
|
||
|
Documentation/devicetree/bindings/riscv/cpus.yaml
|
||
|
|
||
|
[7] RISC-V Supervisor Binary Interface (SBI)
|
||
|
http://github.com/riscv/riscv-sbi-doc/riscv-sbi.adoc
|
||
|
|
||
|
properties:
|
||
|
$nodename:
|
||
|
const: idle-states
|
||
|
|
||
|
entry-method:
|
||
|
description: |
|
||
|
Usage and definition depend on ARM architecture version.
|
||
|
|
||
|
On ARM v8 64-bit this property is required.
|
||
|
On ARM 32-bit systems this property is optional
|
||
|
|
||
|
This assumes that the "enable-method" property is set to "psci" in the cpu
|
||
|
node[5] that is responsible for setting up CPU idle management in the OS
|
||
|
implementation.
|
||
|
const: psci
|
||
|
|
||
|
patternProperties:
|
||
|
"^(cpu|cluster)-":
|
||
|
type: object
|
||
|
description: |
|
||
|
Each state node represents an idle state description and must be defined
|
||
|
as follows.
|
||
|
|
||
|
The idle state entered by executing the wfi instruction (idle_standby
|
||
|
SBSA,[3][4]) is considered standard on all ARM and RISC-V platforms and
|
||
|
therefore must not be listed.
|
||
|
|
||
|
In addition to the properties listed above, a state node may require
|
||
|
additional properties specific to the entry-method defined in the
|
||
|
idle-states node. Please refer to the entry-method bindings
|
||
|
documentation for properties definitions.
|
||
|
|
||
|
properties:
|
||
|
compatible:
|
||
|
enum:
|
||
|
- arm,idle-state
|
||
|
- riscv,idle-state
|
||
|
|
||
|
arm,psci-suspend-param:
|
||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||
|
description: |
|
||
|
power_state parameter to pass to the ARM PSCI suspend call.
|
||
|
|
||
|
Device tree nodes that require usage of PSCI CPU_SUSPEND function
|
||
|
(i.e. idle states node with entry-method property is set to "psci")
|
||
|
must specify this property.
|
||
|
|
||
|
riscv,sbi-suspend-param:
|
||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||
|
description: |
|
||
|
suspend_type parameter to pass to the RISC-V SBI HSM suspend call.
|
||
|
|
||
|
This property is required in idle state nodes of device tree meant
|
||
|
for RISC-V systems. For more details on the suspend_type parameter
|
||
|
refer the SBI specifiation v0.3 (or higher) [7].
|
||
|
|
||
|
local-timer-stop:
|
||
|
description:
|
||
|
If present the CPU local timer control logic is
|
||
|
lost on state entry, otherwise it is retained.
|
||
|
type: boolean
|
||
|
|
||
|
entry-latency-us:
|
||
|
description:
|
||
|
Worst case latency in microseconds required to enter the idle state.
|
||
|
|
||
|
exit-latency-us:
|
||
|
description:
|
||
|
Worst case latency in microseconds required to exit the idle state.
|
||
|
The exit-latency-us duration may be guaranteed only after
|
||
|
entry-latency-us has passed.
|
||
|
|
||
|
min-residency-us:
|
||
|
description:
|
||
|
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:
|
||
|
description: |
|
||
|
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.
|
||
|
|
||
|
idle-state-name:
|
||
|
$ref: /schemas/types.yaml#/definitions/string
|
||
|
description:
|
||
|
A string used as a descriptive name for the idle state.
|
||
|
|
||
|
additionalProperties: false
|
||
|
|
||
|
required:
|
||
|
- compatible
|
||
|
- entry-latency-us
|
||
|
- exit-latency-us
|
||
|
- min-residency-us
|
||
|
|
||
|
additionalProperties: false
|
||
|
|
||
|
examples:
|
||
|
- |
|
||
|
|
||
|
cpus {
|
||
|
#size-cells = <0>;
|
||
|
#address-cells = <2>;
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
|
||
|
cpu@0 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a15";
|
||
|
reg = <0x0>;
|
||
|
cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
|
||
|
};
|
||
|
|
||
|
cpu@1 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a15";
|
||
|
reg = <0x1>;
|
||
|
cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
|
||
|
};
|
||
|
|
||
|
cpu@2 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a15";
|
||
|
reg = <0x2>;
|
||
|
cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
|
||
|
};
|
||
|
|
||
|
cpu@3 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a15";
|
||
|
reg = <0x3>;
|
||
|
cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>;
|
||
|
};
|
||
|
|
||
|
cpu@100 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a7";
|
||
|
reg = <0x100>;
|
||
|
cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
|
||
|
};
|
||
|
|
||
|
cpu@101 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a7";
|
||
|
reg = <0x101>;
|
||
|
cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
|
||
|
};
|
||
|
|
||
|
cpu@102 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "arm,cortex-a7";
|
||
|
reg = <0x102>;
|
||
|
cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>;
|
||
|
};
|
||
|
|
||
|
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>;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
- |
|
||
|
// Example 3 (RISC-V 64-bit, 4-cpu systems, two clusters):
|
||
|
|
||
|
cpus {
|
||
|
#size-cells = <0>;
|
||
|
#address-cells = <1>;
|
||
|
|
||
|
cpu@0 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "riscv";
|
||
|
reg = <0x0>;
|
||
|
riscv,isa = "rv64imafdc";
|
||
|
mmu-type = "riscv,sv48";
|
||
|
cpu-idle-states = <&CPU_RET_0_0>, <&CPU_NONRET_0_0>,
|
||
|
<&CLUSTER_RET_0>, <&CLUSTER_NONRET_0>;
|
||
|
|
||
|
cpu_intc0: interrupt-controller {
|
||
|
#interrupt-cells = <1>;
|
||
|
compatible = "riscv,cpu-intc";
|
||
|
interrupt-controller;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
cpu@1 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "riscv";
|
||
|
reg = <0x1>;
|
||
|
riscv,isa = "rv64imafdc";
|
||
|
mmu-type = "riscv,sv48";
|
||
|
cpu-idle-states = <&CPU_RET_0_0>, <&CPU_NONRET_0_0>,
|
||
|
<&CLUSTER_RET_0>, <&CLUSTER_NONRET_0>;
|
||
|
|
||
|
cpu_intc1: interrupt-controller {
|
||
|
#interrupt-cells = <1>;
|
||
|
compatible = "riscv,cpu-intc";
|
||
|
interrupt-controller;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
cpu@10 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "riscv";
|
||
|
reg = <0x10>;
|
||
|
riscv,isa = "rv64imafdc";
|
||
|
mmu-type = "riscv,sv48";
|
||
|
cpu-idle-states = <&CPU_RET_1_0>, <&CPU_NONRET_1_0>,
|
||
|
<&CLUSTER_RET_1>, <&CLUSTER_NONRET_1>;
|
||
|
|
||
|
cpu_intc10: interrupt-controller {
|
||
|
#interrupt-cells = <1>;
|
||
|
compatible = "riscv,cpu-intc";
|
||
|
interrupt-controller;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
cpu@11 {
|
||
|
device_type = "cpu";
|
||
|
compatible = "riscv";
|
||
|
reg = <0x11>;
|
||
|
riscv,isa = "rv64imafdc";
|
||
|
mmu-type = "riscv,sv48";
|
||
|
cpu-idle-states = <&CPU_RET_1_0>, <&CPU_NONRET_1_0>,
|
||
|
<&CLUSTER_RET_1>, <&CLUSTER_NONRET_1>;
|
||
|
|
||
|
cpu_intc11: interrupt-controller {
|
||
|
#interrupt-cells = <1>;
|
||
|
compatible = "riscv,cpu-intc";
|
||
|
interrupt-controller;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
idle-states {
|
||
|
CPU_RET_0_0: cpu-retentive-0-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x10000000>;
|
||
|
entry-latency-us = <20>;
|
||
|
exit-latency-us = <40>;
|
||
|
min-residency-us = <80>;
|
||
|
};
|
||
|
|
||
|
CPU_NONRET_0_0: cpu-nonretentive-0-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x90000000>;
|
||
|
entry-latency-us = <250>;
|
||
|
exit-latency-us = <500>;
|
||
|
min-residency-us = <950>;
|
||
|
};
|
||
|
|
||
|
CLUSTER_RET_0: cluster-retentive-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x11000000>;
|
||
|
local-timer-stop;
|
||
|
entry-latency-us = <50>;
|
||
|
exit-latency-us = <100>;
|
||
|
min-residency-us = <250>;
|
||
|
wakeup-latency-us = <130>;
|
||
|
};
|
||
|
|
||
|
CLUSTER_NONRET_0: cluster-nonretentive-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x91000000>;
|
||
|
local-timer-stop;
|
||
|
entry-latency-us = <600>;
|
||
|
exit-latency-us = <1100>;
|
||
|
min-residency-us = <2700>;
|
||
|
wakeup-latency-us = <1500>;
|
||
|
};
|
||
|
|
||
|
CPU_RET_1_0: cpu-retentive-1-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x10000010>;
|
||
|
entry-latency-us = <20>;
|
||
|
exit-latency-us = <40>;
|
||
|
min-residency-us = <80>;
|
||
|
};
|
||
|
|
||
|
CPU_NONRET_1_0: cpu-nonretentive-1-0 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x90000010>;
|
||
|
entry-latency-us = <250>;
|
||
|
exit-latency-us = <500>;
|
||
|
min-residency-us = <950>;
|
||
|
};
|
||
|
|
||
|
CLUSTER_RET_1: cluster-retentive-1 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x11000010>;
|
||
|
local-timer-stop;
|
||
|
entry-latency-us = <50>;
|
||
|
exit-latency-us = <100>;
|
||
|
min-residency-us = <250>;
|
||
|
wakeup-latency-us = <130>;
|
||
|
};
|
||
|
|
||
|
CLUSTER_NONRET_1: cluster-nonretentive-1 {
|
||
|
compatible = "riscv,idle-state";
|
||
|
riscv,sbi-suspend-param = <0x91000010>;
|
||
|
local-timer-stop;
|
||
|
entry-latency-us = <600>;
|
||
|
exit-latency-us = <1100>;
|
||
|
min-residency-us = <2700>;
|
||
|
wakeup-latency-us = <1500>;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
...
|