Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame] | 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
| 2 | %YAML 1.2 |
| 3 | --- |
| 4 | $id: http://devicetree.org/schemas/cpu/idle-states.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | |
| 7 | title: Idle states |
| 8 | |
| 9 | maintainers: |
| 10 | - Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
| 11 | - Anup Patel <anup@brainfault.org> |
| 12 | |
| 13 | description: |+ |
| 14 | ========================================== |
| 15 | 1 - Introduction |
| 16 | ========================================== |
| 17 | |
| 18 | ARM and RISC-V systems contain HW capable of managing power consumption |
| 19 | dynamically, where cores can be put in different low-power states (ranging |
| 20 | from simple wfi to power gating) according to OS PM policies. The CPU states |
| 21 | representing the range of dynamic idle states that a processor can enter at |
| 22 | run-time, can be specified through device tree bindings representing the |
| 23 | parameters required to enter/exit specific idle states on a given processor. |
| 24 | |
| 25 | ========================================== |
| 26 | 2 - ARM idle states |
| 27 | ========================================== |
| 28 | |
| 29 | According to the Server Base System Architecture document (SBSA, [3]), the |
| 30 | power states an ARM CPU can be put into are identified by the following list: |
| 31 | |
| 32 | - Running |
| 33 | - Idle_standby |
| 34 | - Idle_retention |
| 35 | - Sleep |
| 36 | - Off |
| 37 | |
| 38 | The power states described in the SBSA document define the basic CPU states on |
| 39 | top of which ARM platforms implement power management schemes that allow an OS |
| 40 | PM implementation to put the processor in different idle states (which include |
| 41 | states listed above; "off" state is not an idle state since it does not have |
| 42 | wake-up capabilities, hence it is not considered in this document). |
| 43 | |
| 44 | Idle state parameters (e.g. entry latency) are platform specific and need to |
| 45 | be characterized with bindings that provide the required information to OS PM |
| 46 | code so that it can build the required tables and use them at runtime. |
| 47 | |
| 48 | The device tree binding definition for ARM idle states is the subject of this |
| 49 | document. |
| 50 | |
| 51 | ========================================== |
| 52 | 3 - RISC-V idle states |
| 53 | ========================================== |
| 54 | |
| 55 | On RISC-V systems, the HARTs (or CPUs) [6] can be put in platform specific |
| 56 | suspend (or idle) states (ranging from simple WFI, power gating, etc). The |
| 57 | RISC-V SBI v0.3 (or higher) [7] hart state management extension provides a |
| 58 | standard mechanism for OS to request HART state transitions. |
| 59 | |
| 60 | The platform specific suspend (or idle) states of a hart can be either |
| 61 | retentive or non-rententive in nature. A retentive suspend state will |
| 62 | preserve HART registers and CSR values for all privilege modes whereas |
| 63 | a non-retentive suspend state will not preserve HART registers and CSR |
| 64 | values. |
| 65 | |
| 66 | =========================================== |
| 67 | 4 - idle-states definitions |
| 68 | =========================================== |
| 69 | |
| 70 | Idle states are characterized for a specific system through a set of |
| 71 | timing and energy related properties, that underline the HW behaviour |
| 72 | triggered upon idle states entry and exit. |
| 73 | |
| 74 | The following diagram depicts the CPU execution phases and related timing |
| 75 | properties required to enter and exit an idle state: |
| 76 | |
| 77 | ..__[EXEC]__|__[PREP]__|__[ENTRY]__|__[IDLE]__|__[EXIT]__|__[EXEC]__.. |
| 78 | | | | | | |
| 79 | |
| 80 | |<------ entry ------->| |
| 81 | | latency | |
| 82 | |<- exit ->| |
| 83 | | latency | |
| 84 | |<-------- min-residency -------->| |
| 85 | |<------- wakeup-latency ------->| |
| 86 | |
| 87 | Diagram 1: CPU idle state execution phases |
| 88 | |
| 89 | EXEC: Normal CPU execution. |
| 90 | |
| 91 | PREP: Preparation phase before committing the hardware to idle mode |
| 92 | like cache flushing. This is abortable on pending wake-up |
| 93 | event conditions. The abort latency is assumed to be negligible |
| 94 | (i.e. less than the ENTRY + EXIT duration). If aborted, CPU |
| 95 | goes back to EXEC. This phase is optional. If not abortable, |
| 96 | this should be included in the ENTRY phase instead. |
| 97 | |
| 98 | ENTRY: The hardware is committed to idle mode. This period must run |
| 99 | to completion up to IDLE before anything else can happen. |
| 100 | |
| 101 | IDLE: This is the actual energy-saving idle period. This may last |
| 102 | between 0 and infinite time, until a wake-up event occurs. |
| 103 | |
| 104 | EXIT: Period during which the CPU is brought back to operational |
| 105 | mode (EXEC). |
| 106 | |
| 107 | entry-latency: Worst case latency required to enter the idle state. The |
| 108 | exit-latency may be guaranteed only after entry-latency has passed. |
| 109 | |
| 110 | min-residency: Minimum period, including preparation and entry, for a given |
| 111 | idle state to be worthwhile energywise. |
| 112 | |
| 113 | wakeup-latency: Maximum delay between the signaling of a wake-up event and the |
| 114 | CPU being able to execute normal code again. If not specified, this is assumed |
| 115 | to be entry-latency + exit-latency. |
| 116 | |
| 117 | These timing parameters can be used by an OS in different circumstances. |
| 118 | |
| 119 | An idle CPU requires the expected min-residency time to select the most |
| 120 | appropriate idle state based on the expected expiry time of the next IRQ |
| 121 | (i.e. wake-up) that causes the CPU to return to the EXEC phase. |
| 122 | |
| 123 | An operating system scheduler may need to compute the shortest wake-up delay |
| 124 | for CPUs in the system by detecting how long will it take to get a CPU out |
| 125 | of an idle state, e.g.: |
| 126 | |
| 127 | wakeup-delay = exit-latency + max(entry-latency - (now - entry-timestamp), 0) |
| 128 | |
| 129 | In other words, the scheduler can make its scheduling decision by selecting |
| 130 | (e.g. waking-up) the CPU with the shortest wake-up delay. |
| 131 | The wake-up delay must take into account the entry latency if that period |
| 132 | has not expired. The abortable nature of the PREP period can be ignored |
| 133 | if it cannot be relied upon (e.g. the PREP deadline may occur much sooner than |
| 134 | the worst case since it depends on the CPU operating conditions, i.e. caches |
| 135 | state). |
| 136 | |
| 137 | An OS has to reliably probe the wakeup-latency since some devices can enforce |
| 138 | latency constraint guarantees to work properly, so the OS has to detect the |
| 139 | worst case wake-up latency it can incur if a CPU is allowed to enter an |
| 140 | idle state, and possibly to prevent that to guarantee reliable device |
| 141 | functioning. |
| 142 | |
| 143 | The min-residency time parameter deserves further explanation since it is |
| 144 | expressed in time units but must factor in energy consumption coefficients. |
| 145 | |
| 146 | The energy consumption of a cpu when it enters a power state can be roughly |
| 147 | characterised by the following graph: |
| 148 | |
| 149 | | |
| 150 | | |
| 151 | | |
| 152 | e | |
| 153 | n | /--- |
| 154 | e | /------ |
| 155 | r | /------ |
| 156 | g | /----- |
| 157 | y | /------ |
| 158 | | ---- |
| 159 | | /| |
| 160 | | / | |
| 161 | | / | |
| 162 | | / | |
| 163 | | / | |
| 164 | | / | |
| 165 | |/ | |
| 166 | -----|-------+---------------------------------- |
| 167 | 0| 1 time(ms) |
| 168 | |
| 169 | Graph 1: Energy vs time example |
| 170 | |
| 171 | The graph is split in two parts delimited by time 1ms on the X-axis. |
| 172 | The graph curve with X-axis values = { x | 0 < x < 1ms } has a steep slope |
| 173 | and denotes the energy costs incurred while entering and leaving the idle |
| 174 | state. |
| 175 | The graph curve in the area delimited by X-axis values = {x | x > 1ms } has |
| 176 | shallower slope and essentially represents the energy consumption of the idle |
| 177 | state. |
| 178 | |
| 179 | min-residency is defined for a given idle state as the minimum expected |
| 180 | residency time for a state (inclusive of preparation and entry) after |
| 181 | which choosing that state become the most energy efficient option. A good |
| 182 | way to visualise this, is by taking the same graph above and comparing some |
| 183 | states energy consumptions plots. |
| 184 | |
| 185 | For sake of simplicity, let's consider a system with two idle states IDLE1, |
| 186 | and IDLE2: |
| 187 | |
| 188 | | |
| 189 | | |
| 190 | | |
| 191 | | /-- IDLE1 |
| 192 | e | /--- |
| 193 | n | /---- |
| 194 | e | /--- |
| 195 | r | /-----/--------- IDLE2 |
| 196 | g | /-------/--------- |
| 197 | y | ------------ /---| |
| 198 | | / /---- | |
| 199 | | / /--- | |
| 200 | | / /---- | |
| 201 | | / /--- | |
| 202 | | --- | |
| 203 | | / | |
| 204 | | / | |
| 205 | |/ | time |
| 206 | ---/----------------------------+------------------------ |
| 207 | |IDLE1-energy < IDLE2-energy | IDLE2-energy < IDLE1-energy |
| 208 | | |
| 209 | IDLE2-min-residency |
| 210 | |
| 211 | Graph 2: idle states min-residency example |
| 212 | |
| 213 | In graph 2 above, that takes into account idle states entry/exit energy |
| 214 | costs, it is clear that if the idle state residency time (i.e. time till next |
| 215 | wake-up IRQ) is less than IDLE2-min-residency, IDLE1 is the better idle state |
| 216 | choice energywise. |
| 217 | |
| 218 | This is mainly down to the fact that IDLE1 entry/exit energy costs are lower |
| 219 | than IDLE2. |
| 220 | |
| 221 | However, the lower power consumption (i.e. shallower energy curve slope) of |
| 222 | idle state IDLE2 implies that after a suitable time, IDLE2 becomes more energy |
| 223 | efficient. |
| 224 | |
| 225 | The time at which IDLE2 becomes more energy efficient than IDLE1 (and other |
| 226 | shallower states in a system with multiple idle states) is defined |
| 227 | IDLE2-min-residency and corresponds to the time when energy consumption of |
| 228 | IDLE1 and IDLE2 states breaks even. |
| 229 | |
| 230 | The definitions provided in this section underpin the idle states |
| 231 | properties specification that is the subject of the following sections. |
| 232 | |
| 233 | =========================================== |
| 234 | 5 - idle-states node |
| 235 | =========================================== |
| 236 | |
| 237 | The processor idle states are defined within the idle-states node, which is |
| 238 | a direct child of the cpus node [1] and provides a container where the |
| 239 | processor idle states, defined as device tree nodes, are listed. |
| 240 | |
| 241 | On ARM systems, it is a container of processor idle states nodes. If the |
| 242 | system does not provide CPU power management capabilities, or the processor |
| 243 | just supports idle_standby, an idle-states node is not required. |
| 244 | |
| 245 | =========================================== |
Tom Rini | 93743d2 | 2024-04-01 09:08:13 -0400 | [diff] [blame] | 246 | 6 - Qualcomm specific STATES |
Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame] | 247 | =========================================== |
| 248 | |
Tom Rini | 93743d2 | 2024-04-01 09:08:13 -0400 | [diff] [blame] | 249 | Idle states have different enter/exit latency and residency values. |
| 250 | The idle states supported by the QCOM SoC are defined as - |
| 251 | |
| 252 | * Standby |
| 253 | * Retention |
| 254 | * Standalone Power Collapse (Standalone PC or SPC) |
| 255 | * Power Collapse (PC) |
| 256 | |
| 257 | Standby: Standby does a little more in addition to architectural clock gating. |
| 258 | When the WFI instruction is executed the ARM core would gate its internal |
| 259 | clocks. In addition to gating the clocks, QCOM cpus use this instruction as a |
| 260 | trigger to execute the SPM state machine. The SPM state machine waits for the |
| 261 | interrupt to trigger the core back in to active. This triggers the cache |
| 262 | hierarchy to enter standby states, when all cpus are idle. An interrupt brings |
| 263 | the SPM state machine out of its wait, the next step is to ensure that the |
| 264 | cache hierarchy is also out of standby, and then the cpu is allowed to resume |
| 265 | execution. This state is defined as a generic ARM WFI state by the ARM cpuidle |
| 266 | driver and is not defined in the DT. The SPM state machine should be |
| 267 | configured to execute this state by default and after executing every other |
| 268 | state below. |
| 269 | |
| 270 | Retention: Retention is a low power state where the core is clock gated and |
| 271 | the memory and the registers associated with the core are retained. The |
| 272 | voltage may be reduced to the minimum value needed to keep the processor |
| 273 | registers active. The SPM should be configured to execute the retention |
| 274 | sequence and would wait for interrupt, before restoring the cpu to execution |
| 275 | state. Retention may have a slightly higher latency than Standby. |
| 276 | |
| 277 | Standalone PC: A cpu can power down and warmboot if there is a sufficient time |
| 278 | between the time it enters idle and the next known wake up. SPC mode is used |
| 279 | to indicate a core entering a power down state without consulting any other |
| 280 | cpu or the system resources. This helps save power only on that core. The SPM |
| 281 | sequence for this idle state is programmed to power down the supply to the |
| 282 | core, wait for the interrupt, restore power to the core, and ensure the |
| 283 | system state including cache hierarchy is ready before allowing core to |
| 284 | resume. Applying power and resetting the core causes the core to warmboot |
| 285 | back into Elevation Level (EL) which trampolines the control back to the |
| 286 | kernel. Entering a power down state for the cpu, needs to be done by trapping |
| 287 | into a EL. Failing to do so, would result in a crash enforced by the warm boot |
| 288 | code in the EL for the SoC. On SoCs with write-back L1 cache, the cache has to |
| 289 | be flushed in s/w, before powering down the core. |
| 290 | |
| 291 | Power Collapse: This state is similar to the SPC mode, but distinguishes |
| 292 | itself in that the cpu acknowledges and permits the SoC to enter deeper sleep |
| 293 | modes. In a hierarchical power domain SoC, this means L2 and other caches can |
| 294 | be flushed, system bus, clocks - lowered, and SoC main XO clock gated and |
| 295 | voltages reduced, provided all cpus enter this state. Since the span of low |
| 296 | power modes possible at this state is vast, the exit latency and the residency |
| 297 | of this low power mode would be considered high even though at a cpu level, |
| 298 | this essentially is cpu power down. The SPM in this state also may handshake |
| 299 | with the Resource power manager (RPM) processor in the SoC to indicate a |
| 300 | complete application processor subsystem shut down. |
| 301 | |
| 302 | =========================================== |
| 303 | 7 - References |
| 304 | =========================================== |
| 305 | |
Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame] | 306 | [1] ARM Linux Kernel documentation - CPUs bindings |
| 307 | Documentation/devicetree/bindings/arm/cpus.yaml |
| 308 | |
| 309 | [2] ARM Linux Kernel documentation - PSCI bindings |
| 310 | Documentation/devicetree/bindings/arm/psci.yaml |
| 311 | |
| 312 | [3] ARM Server Base System Architecture (SBSA) |
| 313 | http://infocenter.arm.com/help/index.jsp |
| 314 | |
| 315 | [4] ARM Architecture Reference Manuals |
| 316 | http://infocenter.arm.com/help/index.jsp |
| 317 | |
| 318 | [5] ARM Linux Kernel documentation - Booting AArch64 Linux |
| 319 | Documentation/arch/arm64/booting.rst |
| 320 | |
| 321 | [6] RISC-V Linux Kernel documentation - CPUs bindings |
| 322 | Documentation/devicetree/bindings/riscv/cpus.yaml |
| 323 | |
| 324 | [7] RISC-V Supervisor Binary Interface (SBI) |
| 325 | http://github.com/riscv/riscv-sbi-doc/riscv-sbi.adoc |
| 326 | |
| 327 | properties: |
| 328 | $nodename: |
| 329 | const: idle-states |
| 330 | |
| 331 | entry-method: |
| 332 | description: | |
| 333 | Usage and definition depend on ARM architecture version. |
| 334 | |
| 335 | On ARM v8 64-bit this property is required. |
| 336 | On ARM 32-bit systems this property is optional |
| 337 | |
| 338 | This assumes that the "enable-method" property is set to "psci" in the cpu |
| 339 | node[5] that is responsible for setting up CPU idle management in the OS |
| 340 | implementation. |
| 341 | const: psci |
| 342 | |
| 343 | patternProperties: |
| 344 | "^(cpu|cluster)-": |
| 345 | type: object |
| 346 | description: | |
| 347 | Each state node represents an idle state description and must be defined |
| 348 | as follows. |
| 349 | |
| 350 | The idle state entered by executing the wfi instruction (idle_standby |
| 351 | SBSA,[3][4]) is considered standard on all ARM and RISC-V platforms and |
| 352 | therefore must not be listed. |
| 353 | |
| 354 | In addition to the properties listed above, a state node may require |
| 355 | additional properties specific to the entry-method defined in the |
| 356 | idle-states node. Please refer to the entry-method bindings |
| 357 | documentation for properties definitions. |
| 358 | |
| 359 | properties: |
| 360 | compatible: |
Tom Rini | 93743d2 | 2024-04-01 09:08:13 -0400 | [diff] [blame] | 361 | oneOf: |
| 362 | - items: |
| 363 | - enum: |
| 364 | - qcom,idle-state-ret |
| 365 | - qcom,idle-state-spc |
| 366 | - qcom,idle-state-pc |
| 367 | - const: arm,idle-state |
| 368 | - enum: |
| 369 | - arm,idle-state |
| 370 | - riscv,idle-state |
Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame] | 371 | |
| 372 | arm,psci-suspend-param: |
| 373 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 374 | description: | |
| 375 | power_state parameter to pass to the ARM PSCI suspend call. |
| 376 | |
| 377 | Device tree nodes that require usage of PSCI CPU_SUSPEND function |
| 378 | (i.e. idle states node with entry-method property is set to "psci") |
| 379 | must specify this property. |
| 380 | |
| 381 | riscv,sbi-suspend-param: |
| 382 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 383 | description: | |
| 384 | suspend_type parameter to pass to the RISC-V SBI HSM suspend call. |
| 385 | |
| 386 | This property is required in idle state nodes of device tree meant |
| 387 | for RISC-V systems. For more details on the suspend_type parameter |
| 388 | refer the SBI specifiation v0.3 (or higher) [7]. |
| 389 | |
| 390 | local-timer-stop: |
| 391 | description: |
| 392 | If present the CPU local timer control logic is |
| 393 | lost on state entry, otherwise it is retained. |
| 394 | type: boolean |
| 395 | |
| 396 | entry-latency-us: |
| 397 | description: |
| 398 | Worst case latency in microseconds required to enter the idle state. |
| 399 | |
| 400 | exit-latency-us: |
| 401 | description: |
| 402 | Worst case latency in microseconds required to exit the idle state. |
| 403 | The exit-latency-us duration may be guaranteed only after |
| 404 | entry-latency-us has passed. |
| 405 | |
| 406 | min-residency-us: |
| 407 | description: |
| 408 | Minimum residency duration in microseconds, inclusive of preparation |
| 409 | and entry, for this idle state to be considered worthwhile energy wise |
| 410 | (refer to section 2 of this document for a complete description). |
| 411 | |
| 412 | wakeup-latency-us: |
| 413 | description: | |
| 414 | Maximum delay between the signaling of a wake-up event and the CPU |
| 415 | being able to execute normal code again. If omitted, this is assumed |
| 416 | to be equal to: |
| 417 | |
| 418 | entry-latency-us + exit-latency-us |
| 419 | |
| 420 | It is important to supply this value on systems where the duration of |
| 421 | PREP phase (see diagram 1, section 2) is non-neglibigle. In such |
| 422 | systems entry-latency-us + exit-latency-us will exceed |
| 423 | wakeup-latency-us by this duration. |
| 424 | |
| 425 | idle-state-name: |
| 426 | $ref: /schemas/types.yaml#/definitions/string |
| 427 | description: |
| 428 | A string used as a descriptive name for the idle state. |
| 429 | |
| 430 | additionalProperties: false |
| 431 | |
| 432 | required: |
| 433 | - compatible |
| 434 | - entry-latency-us |
| 435 | - exit-latency-us |
| 436 | - min-residency-us |
| 437 | |
| 438 | additionalProperties: false |
| 439 | |
| 440 | examples: |
| 441 | - | |
| 442 | |
| 443 | cpus { |
| 444 | #size-cells = <0>; |
| 445 | #address-cells = <2>; |
| 446 | |
| 447 | cpu@0 { |
| 448 | device_type = "cpu"; |
| 449 | compatible = "arm,cortex-a57"; |
| 450 | reg = <0x0 0x0>; |
| 451 | enable-method = "psci"; |
| 452 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 453 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 454 | }; |
| 455 | |
| 456 | cpu@1 { |
| 457 | device_type = "cpu"; |
| 458 | compatible = "arm,cortex-a57"; |
| 459 | reg = <0x0 0x1>; |
| 460 | enable-method = "psci"; |
| 461 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 462 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 463 | }; |
| 464 | |
| 465 | cpu@100 { |
| 466 | device_type = "cpu"; |
| 467 | compatible = "arm,cortex-a57"; |
| 468 | reg = <0x0 0x100>; |
| 469 | enable-method = "psci"; |
| 470 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 471 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 472 | }; |
| 473 | |
| 474 | cpu@101 { |
| 475 | device_type = "cpu"; |
| 476 | compatible = "arm,cortex-a57"; |
| 477 | reg = <0x0 0x101>; |
| 478 | enable-method = "psci"; |
| 479 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 480 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 481 | }; |
| 482 | |
| 483 | cpu@10000 { |
| 484 | device_type = "cpu"; |
| 485 | compatible = "arm,cortex-a57"; |
| 486 | reg = <0x0 0x10000>; |
| 487 | enable-method = "psci"; |
| 488 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 489 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 490 | }; |
| 491 | |
| 492 | cpu@10001 { |
| 493 | device_type = "cpu"; |
| 494 | compatible = "arm,cortex-a57"; |
| 495 | reg = <0x0 0x10001>; |
| 496 | enable-method = "psci"; |
| 497 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 498 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 499 | }; |
| 500 | |
| 501 | cpu@10100 { |
| 502 | device_type = "cpu"; |
| 503 | compatible = "arm,cortex-a57"; |
| 504 | reg = <0x0 0x10100>; |
| 505 | enable-method = "psci"; |
| 506 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 507 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 508 | }; |
| 509 | |
| 510 | cpu@10101 { |
| 511 | device_type = "cpu"; |
| 512 | compatible = "arm,cortex-a57"; |
| 513 | reg = <0x0 0x10101>; |
| 514 | enable-method = "psci"; |
| 515 | cpu-idle-states = <&CPU_RETENTION_0_0>, <&CPU_SLEEP_0_0>, |
| 516 | <&CLUSTER_RETENTION_0>, <&CLUSTER_SLEEP_0>; |
| 517 | }; |
| 518 | |
| 519 | cpu@100000000 { |
| 520 | device_type = "cpu"; |
| 521 | compatible = "arm,cortex-a53"; |
| 522 | reg = <0x1 0x0>; |
| 523 | enable-method = "psci"; |
| 524 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 525 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 526 | }; |
| 527 | |
| 528 | cpu@100000001 { |
| 529 | device_type = "cpu"; |
| 530 | compatible = "arm,cortex-a53"; |
| 531 | reg = <0x1 0x1>; |
| 532 | enable-method = "psci"; |
| 533 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 534 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 535 | }; |
| 536 | |
| 537 | cpu@100000100 { |
| 538 | device_type = "cpu"; |
| 539 | compatible = "arm,cortex-a53"; |
| 540 | reg = <0x1 0x100>; |
| 541 | enable-method = "psci"; |
| 542 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 543 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 544 | }; |
| 545 | |
| 546 | cpu@100000101 { |
| 547 | device_type = "cpu"; |
| 548 | compatible = "arm,cortex-a53"; |
| 549 | reg = <0x1 0x101>; |
| 550 | enable-method = "psci"; |
| 551 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 552 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 553 | }; |
| 554 | |
| 555 | cpu@100010000 { |
| 556 | device_type = "cpu"; |
| 557 | compatible = "arm,cortex-a53"; |
| 558 | reg = <0x1 0x10000>; |
| 559 | enable-method = "psci"; |
| 560 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 561 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 562 | }; |
| 563 | |
| 564 | cpu@100010001 { |
| 565 | device_type = "cpu"; |
| 566 | compatible = "arm,cortex-a53"; |
| 567 | reg = <0x1 0x10001>; |
| 568 | enable-method = "psci"; |
| 569 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 570 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 571 | }; |
| 572 | |
| 573 | cpu@100010100 { |
| 574 | device_type = "cpu"; |
| 575 | compatible = "arm,cortex-a53"; |
| 576 | reg = <0x1 0x10100>; |
| 577 | enable-method = "psci"; |
| 578 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 579 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 580 | }; |
| 581 | |
| 582 | cpu@100010101 { |
| 583 | device_type = "cpu"; |
| 584 | compatible = "arm,cortex-a53"; |
| 585 | reg = <0x1 0x10101>; |
| 586 | enable-method = "psci"; |
| 587 | cpu-idle-states = <&CPU_RETENTION_1_0>, <&CPU_SLEEP_1_0>, |
| 588 | <&CLUSTER_RETENTION_1>, <&CLUSTER_SLEEP_1>; |
| 589 | }; |
| 590 | |
| 591 | idle-states { |
| 592 | entry-method = "psci"; |
| 593 | |
| 594 | CPU_RETENTION_0_0: cpu-retention-0-0 { |
| 595 | compatible = "arm,idle-state"; |
| 596 | arm,psci-suspend-param = <0x0010000>; |
| 597 | entry-latency-us = <20>; |
| 598 | exit-latency-us = <40>; |
| 599 | min-residency-us = <80>; |
| 600 | }; |
| 601 | |
| 602 | CLUSTER_RETENTION_0: cluster-retention-0 { |
| 603 | compatible = "arm,idle-state"; |
| 604 | local-timer-stop; |
| 605 | arm,psci-suspend-param = <0x1010000>; |
| 606 | entry-latency-us = <50>; |
| 607 | exit-latency-us = <100>; |
| 608 | min-residency-us = <250>; |
| 609 | wakeup-latency-us = <130>; |
| 610 | }; |
| 611 | |
| 612 | CPU_SLEEP_0_0: cpu-sleep-0-0 { |
| 613 | compatible = "arm,idle-state"; |
| 614 | local-timer-stop; |
| 615 | arm,psci-suspend-param = <0x0010000>; |
| 616 | entry-latency-us = <250>; |
| 617 | exit-latency-us = <500>; |
| 618 | min-residency-us = <950>; |
| 619 | }; |
| 620 | |
| 621 | CLUSTER_SLEEP_0: cluster-sleep-0 { |
| 622 | compatible = "arm,idle-state"; |
| 623 | local-timer-stop; |
| 624 | arm,psci-suspend-param = <0x1010000>; |
| 625 | entry-latency-us = <600>; |
| 626 | exit-latency-us = <1100>; |
| 627 | min-residency-us = <2700>; |
| 628 | wakeup-latency-us = <1500>; |
| 629 | }; |
| 630 | |
| 631 | CPU_RETENTION_1_0: cpu-retention-1-0 { |
| 632 | compatible = "arm,idle-state"; |
| 633 | arm,psci-suspend-param = <0x0010000>; |
| 634 | entry-latency-us = <20>; |
| 635 | exit-latency-us = <40>; |
| 636 | min-residency-us = <90>; |
| 637 | }; |
| 638 | |
| 639 | CLUSTER_RETENTION_1: cluster-retention-1 { |
| 640 | compatible = "arm,idle-state"; |
| 641 | local-timer-stop; |
| 642 | arm,psci-suspend-param = <0x1010000>; |
| 643 | entry-latency-us = <50>; |
| 644 | exit-latency-us = <100>; |
| 645 | min-residency-us = <270>; |
| 646 | wakeup-latency-us = <100>; |
| 647 | }; |
| 648 | |
| 649 | CPU_SLEEP_1_0: cpu-sleep-1-0 { |
| 650 | compatible = "arm,idle-state"; |
| 651 | local-timer-stop; |
| 652 | arm,psci-suspend-param = <0x0010000>; |
| 653 | entry-latency-us = <70>; |
| 654 | exit-latency-us = <100>; |
| 655 | min-residency-us = <300>; |
| 656 | wakeup-latency-us = <150>; |
| 657 | }; |
| 658 | |
| 659 | CLUSTER_SLEEP_1: cluster-sleep-1 { |
| 660 | compatible = "arm,idle-state"; |
| 661 | local-timer-stop; |
| 662 | arm,psci-suspend-param = <0x1010000>; |
| 663 | entry-latency-us = <500>; |
| 664 | exit-latency-us = <1200>; |
| 665 | min-residency-us = <3500>; |
| 666 | wakeup-latency-us = <1300>; |
| 667 | }; |
| 668 | }; |
| 669 | }; |
| 670 | |
| 671 | - | |
| 672 | // Example 2 (ARM 32-bit, 8-cpu system, two clusters): |
| 673 | |
| 674 | cpus { |
| 675 | #size-cells = <0>; |
| 676 | #address-cells = <1>; |
| 677 | |
| 678 | cpu@0 { |
| 679 | device_type = "cpu"; |
| 680 | compatible = "arm,cortex-a15"; |
| 681 | reg = <0x0>; |
| 682 | cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; |
| 683 | }; |
| 684 | |
| 685 | cpu@1 { |
| 686 | device_type = "cpu"; |
| 687 | compatible = "arm,cortex-a15"; |
| 688 | reg = <0x1>; |
| 689 | cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; |
| 690 | }; |
| 691 | |
| 692 | cpu@2 { |
| 693 | device_type = "cpu"; |
| 694 | compatible = "arm,cortex-a15"; |
| 695 | reg = <0x2>; |
| 696 | cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; |
| 697 | }; |
| 698 | |
| 699 | cpu@3 { |
| 700 | device_type = "cpu"; |
| 701 | compatible = "arm,cortex-a15"; |
| 702 | reg = <0x3>; |
| 703 | cpu-idle-states = <&cpu_sleep_0_0>, <&cluster_sleep_0>; |
| 704 | }; |
| 705 | |
| 706 | cpu@100 { |
| 707 | device_type = "cpu"; |
| 708 | compatible = "arm,cortex-a7"; |
| 709 | reg = <0x100>; |
| 710 | cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; |
| 711 | }; |
| 712 | |
| 713 | cpu@101 { |
| 714 | device_type = "cpu"; |
| 715 | compatible = "arm,cortex-a7"; |
| 716 | reg = <0x101>; |
| 717 | cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; |
| 718 | }; |
| 719 | |
| 720 | cpu@102 { |
| 721 | device_type = "cpu"; |
| 722 | compatible = "arm,cortex-a7"; |
| 723 | reg = <0x102>; |
| 724 | cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; |
| 725 | }; |
| 726 | |
| 727 | cpu@103 { |
| 728 | device_type = "cpu"; |
| 729 | compatible = "arm,cortex-a7"; |
| 730 | reg = <0x103>; |
| 731 | cpu-idle-states = <&cpu_sleep_1_0>, <&cluster_sleep_1>; |
| 732 | }; |
| 733 | |
| 734 | idle-states { |
| 735 | cpu_sleep_0_0: cpu-sleep-0-0 { |
| 736 | compatible = "arm,idle-state"; |
| 737 | local-timer-stop; |
| 738 | entry-latency-us = <200>; |
| 739 | exit-latency-us = <100>; |
| 740 | min-residency-us = <400>; |
| 741 | wakeup-latency-us = <250>; |
| 742 | }; |
| 743 | |
| 744 | cluster_sleep_0: cluster-sleep-0 { |
| 745 | compatible = "arm,idle-state"; |
| 746 | local-timer-stop; |
| 747 | entry-latency-us = <500>; |
| 748 | exit-latency-us = <1500>; |
| 749 | min-residency-us = <2500>; |
| 750 | wakeup-latency-us = <1700>; |
| 751 | }; |
| 752 | |
| 753 | cpu_sleep_1_0: cpu-sleep-1-0 { |
| 754 | compatible = "arm,idle-state"; |
| 755 | local-timer-stop; |
| 756 | entry-latency-us = <300>; |
| 757 | exit-latency-us = <500>; |
| 758 | min-residency-us = <900>; |
| 759 | wakeup-latency-us = <600>; |
| 760 | }; |
| 761 | |
| 762 | cluster_sleep_1: cluster-sleep-1 { |
| 763 | compatible = "arm,idle-state"; |
| 764 | local-timer-stop; |
| 765 | entry-latency-us = <800>; |
| 766 | exit-latency-us = <2000>; |
| 767 | min-residency-us = <6500>; |
| 768 | wakeup-latency-us = <2300>; |
| 769 | }; |
| 770 | }; |
| 771 | }; |
| 772 | |
| 773 | - | |
| 774 | // Example 3 (RISC-V 64-bit, 4-cpu systems, two clusters): |
| 775 | |
| 776 | cpus { |
| 777 | #size-cells = <0>; |
| 778 | #address-cells = <1>; |
| 779 | |
| 780 | cpu@0 { |
| 781 | device_type = "cpu"; |
| 782 | compatible = "riscv"; |
| 783 | reg = <0x0>; |
| 784 | riscv,isa = "rv64imafdc"; |
| 785 | mmu-type = "riscv,sv48"; |
| 786 | cpu-idle-states = <&CPU_RET_0_0>, <&CPU_NONRET_0_0>, |
| 787 | <&CLUSTER_RET_0>, <&CLUSTER_NONRET_0>; |
| 788 | |
| 789 | cpu_intc0: interrupt-controller { |
| 790 | #interrupt-cells = <1>; |
| 791 | compatible = "riscv,cpu-intc"; |
| 792 | interrupt-controller; |
| 793 | }; |
| 794 | }; |
| 795 | |
| 796 | cpu@1 { |
| 797 | device_type = "cpu"; |
| 798 | compatible = "riscv"; |
| 799 | reg = <0x1>; |
| 800 | riscv,isa = "rv64imafdc"; |
| 801 | mmu-type = "riscv,sv48"; |
| 802 | cpu-idle-states = <&CPU_RET_0_0>, <&CPU_NONRET_0_0>, |
| 803 | <&CLUSTER_RET_0>, <&CLUSTER_NONRET_0>; |
| 804 | |
| 805 | cpu_intc1: interrupt-controller { |
| 806 | #interrupt-cells = <1>; |
| 807 | compatible = "riscv,cpu-intc"; |
| 808 | interrupt-controller; |
| 809 | }; |
| 810 | }; |
| 811 | |
| 812 | cpu@10 { |
| 813 | device_type = "cpu"; |
| 814 | compatible = "riscv"; |
| 815 | reg = <0x10>; |
| 816 | riscv,isa = "rv64imafdc"; |
| 817 | mmu-type = "riscv,sv48"; |
| 818 | cpu-idle-states = <&CPU_RET_1_0>, <&CPU_NONRET_1_0>, |
| 819 | <&CLUSTER_RET_1>, <&CLUSTER_NONRET_1>; |
| 820 | |
| 821 | cpu_intc10: interrupt-controller { |
| 822 | #interrupt-cells = <1>; |
| 823 | compatible = "riscv,cpu-intc"; |
| 824 | interrupt-controller; |
| 825 | }; |
| 826 | }; |
| 827 | |
| 828 | cpu@11 { |
| 829 | device_type = "cpu"; |
| 830 | compatible = "riscv"; |
| 831 | reg = <0x11>; |
| 832 | riscv,isa = "rv64imafdc"; |
| 833 | mmu-type = "riscv,sv48"; |
| 834 | cpu-idle-states = <&CPU_RET_1_0>, <&CPU_NONRET_1_0>, |
| 835 | <&CLUSTER_RET_1>, <&CLUSTER_NONRET_1>; |
| 836 | |
| 837 | cpu_intc11: interrupt-controller { |
| 838 | #interrupt-cells = <1>; |
| 839 | compatible = "riscv,cpu-intc"; |
| 840 | interrupt-controller; |
| 841 | }; |
| 842 | }; |
| 843 | |
| 844 | idle-states { |
| 845 | CPU_RET_0_0: cpu-retentive-0-0 { |
| 846 | compatible = "riscv,idle-state"; |
| 847 | riscv,sbi-suspend-param = <0x10000000>; |
| 848 | entry-latency-us = <20>; |
| 849 | exit-latency-us = <40>; |
| 850 | min-residency-us = <80>; |
| 851 | }; |
| 852 | |
| 853 | CPU_NONRET_0_0: cpu-nonretentive-0-0 { |
| 854 | compatible = "riscv,idle-state"; |
| 855 | riscv,sbi-suspend-param = <0x90000000>; |
| 856 | entry-latency-us = <250>; |
| 857 | exit-latency-us = <500>; |
| 858 | min-residency-us = <950>; |
| 859 | }; |
| 860 | |
| 861 | CLUSTER_RET_0: cluster-retentive-0 { |
| 862 | compatible = "riscv,idle-state"; |
| 863 | riscv,sbi-suspend-param = <0x11000000>; |
| 864 | local-timer-stop; |
| 865 | entry-latency-us = <50>; |
| 866 | exit-latency-us = <100>; |
| 867 | min-residency-us = <250>; |
| 868 | wakeup-latency-us = <130>; |
| 869 | }; |
| 870 | |
| 871 | CLUSTER_NONRET_0: cluster-nonretentive-0 { |
| 872 | compatible = "riscv,idle-state"; |
| 873 | riscv,sbi-suspend-param = <0x91000000>; |
| 874 | local-timer-stop; |
| 875 | entry-latency-us = <600>; |
| 876 | exit-latency-us = <1100>; |
| 877 | min-residency-us = <2700>; |
| 878 | wakeup-latency-us = <1500>; |
| 879 | }; |
| 880 | |
| 881 | CPU_RET_1_0: cpu-retentive-1-0 { |
| 882 | compatible = "riscv,idle-state"; |
| 883 | riscv,sbi-suspend-param = <0x10000010>; |
| 884 | entry-latency-us = <20>; |
| 885 | exit-latency-us = <40>; |
| 886 | min-residency-us = <80>; |
| 887 | }; |
| 888 | |
| 889 | CPU_NONRET_1_0: cpu-nonretentive-1-0 { |
| 890 | compatible = "riscv,idle-state"; |
| 891 | riscv,sbi-suspend-param = <0x90000010>; |
| 892 | entry-latency-us = <250>; |
| 893 | exit-latency-us = <500>; |
| 894 | min-residency-us = <950>; |
| 895 | }; |
| 896 | |
| 897 | CLUSTER_RET_1: cluster-retentive-1 { |
| 898 | compatible = "riscv,idle-state"; |
| 899 | riscv,sbi-suspend-param = <0x11000010>; |
| 900 | local-timer-stop; |
| 901 | entry-latency-us = <50>; |
| 902 | exit-latency-us = <100>; |
| 903 | min-residency-us = <250>; |
| 904 | wakeup-latency-us = <130>; |
| 905 | }; |
| 906 | |
| 907 | CLUSTER_NONRET_1: cluster-nonretentive-1 { |
| 908 | compatible = "riscv,idle-state"; |
| 909 | riscv,sbi-suspend-param = <0x91000010>; |
| 910 | local-timer-stop; |
| 911 | entry-latency-us = <600>; |
| 912 | exit-latency-us = <1100>; |
| 913 | min-residency-us = <2700>; |
| 914 | wakeup-latency-us = <1500>; |
| 915 | }; |
| 916 | }; |
| 917 | }; |
| 918 | |
Tom Rini | 93743d2 | 2024-04-01 09:08:13 -0400 | [diff] [blame] | 919 | // Example 4 - Qualcomm SPC |
| 920 | idle-states { |
| 921 | cpu_spc: cpu-spc { |
| 922 | compatible = "qcom,idle-state-spc", "arm,idle-state"; |
| 923 | entry-latency-us = <150>; |
| 924 | exit-latency-us = <200>; |
| 925 | min-residency-us = <2000>; |
| 926 | }; |
| 927 | }; |
Tom Rini | 53633a8 | 2024-02-29 12:33:36 -0500 | [diff] [blame] | 928 | ... |