Skip to content

Commit bee7fbc

Browse files
RISC-V CPU Idle Support
This series adds RISC-V CPU Idle support using SBI HSM suspend function. The RISC-V SBI CPU idle driver added by this series is highly inspired from the ARM PSCI CPU idle driver. Special thanks Sandeep Tripathy for providing early feeback on SBI HSM support in all above projects (RISC-V SBI specification, OpenSBI, and Linux RISC-V). * palmer/riscv-idle: RISC-V: Enable RISC-V SBI CPU Idle driver for QEMU virt machine dt-bindings: Add common bindings for ARM and RISC-V idle states cpuidle: Add RISC-V SBI CPU idle driver cpuidle: Factor-out power domain related code from PSCI domain driver RISC-V: Add SBI HSM suspend related defines RISC-V: Add arch functions for non-retentive suspend entry/exit RISC-V: Rename relocate() and make it global RISC-V: Enable CPU_IDLE drivers
2 parents fdecfea + c5179ef commit bee7fbc

27 files changed

Lines changed: 1458 additions & 178 deletions

Documentation/devicetree/bindings/arm/msm/qcom,idle-state.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,4 @@ Example:
8181
};
8282
};
8383

84-
[1]. Documentation/devicetree/bindings/arm/idle-states.yaml
84+
[1]. Documentation/devicetree/bindings/cpu/idle-states.yaml

Documentation/devicetree/bindings/arm/psci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ properties:
101101
bindings in [1]) must specify this property.
102102
103103
[1] Kernel documentation - ARM idle states bindings
104-
Documentation/devicetree/bindings/arm/idle-states.yaml
104+
Documentation/devicetree/bindings/cpu/idle-states.yaml
105105
106106
patternProperties:
107107
"^power-domain-":

Documentation/devicetree/bindings/arm/idle-states.yaml renamed to Documentation/devicetree/bindings/cpu/idle-states.yaml

Lines changed: 211 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22
%YAML 1.2
33
---
4-
$id: http://devicetree.org/schemas/arm/idle-states.yaml#
4+
$id: http://devicetree.org/schemas/cpu/idle-states.yaml#
55
$schema: http://devicetree.org/meta-schemas/core.yaml#
66

7-
title: ARM idle states binding description
7+
title: Idle states binding description
88

99
maintainers:
1010
- Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
11+
- Anup Patel <anup@brainfault.org>
1112

1213
description: |+
1314
==========================================
1415
1 - Introduction
1516
==========================================
1617
17-
ARM systems contain HW capable of managing power consumption dynamically,
18-
where cores can be put in different low-power states (ranging from simple wfi
19-
to power gating) according to OS PM policies. The CPU states representing the
20-
range of dynamic idle states that a processor can enter at run-time, can be
21-
specified through device tree bindings representing the parameters required to
22-
enter/exit specific idle states on a given processor.
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+
==========================================
2328
2429
According to the Server Base System Architecture document (SBSA, [3]), the
2530
power states an ARM CPU can be put into are identified by the following list:
@@ -43,8 +48,23 @@ description: |+
4348
The device tree binding definition for ARM idle states is the subject of this
4449
document.
4550
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+
4666
===========================================
47-
2 - idle-states definitions
67+
4 - idle-states definitions
4868
===========================================
4969
5070
Idle states are characterized for a specific system through a set of
@@ -211,10 +231,10 @@ description: |+
211231
properties specification that is the subject of the following sections.
212232
213233
===========================================
214-
3 - idle-states node
234+
5 - idle-states node
215235
===========================================
216236
217-
ARM processor idle states are defined within the idle-states node, which is
237+
The processor idle states are defined within the idle-states node, which is
218238
a direct child of the cpus node [1] and provides a container where the
219239
processor idle states, defined as device tree nodes, are listed.
220240
@@ -223,7 +243,7 @@ description: |+
223243
just supports idle_standby, an idle-states node is not required.
224244
225245
===========================================
226-
4 - References
246+
6 - References
227247
===========================================
228248
229249
[1] ARM Linux Kernel documentation - CPUs bindings
@@ -238,9 +258,15 @@ description: |+
238258
[4] ARM Architecture Reference Manuals
239259
http://infocenter.arm.com/help/index.jsp
240260
241-
[6] ARM Linux Kernel documentation - Booting AArch64 Linux
261+
[5] ARM Linux Kernel documentation - Booting AArch64 Linux
242262
Documentation/arm64/booting.rst
243263
264+
[6] RISC-V Linux Kernel documentation - CPUs bindings
265+
Documentation/devicetree/bindings/riscv/cpus.yaml
266+
267+
[7] RISC-V Supervisor Binary Interface (SBI)
268+
http://github.com/riscv/riscv-sbi-doc/riscv-sbi.adoc
269+
244270
properties:
245271
$nodename:
246272
const: idle-states
@@ -253,7 +279,7 @@ properties:
253279
On ARM 32-bit systems this property is optional
254280
255281
This assumes that the "enable-method" property is set to "psci" in the cpu
256-
node[6] that is responsible for setting up CPU idle management in the OS
282+
node[5] that is responsible for setting up CPU idle management in the OS
257283
implementation.
258284
const: psci
259285

@@ -265,8 +291,8 @@ patternProperties:
265291
as follows.
266292
267293
The idle state entered by executing the wfi instruction (idle_standby
268-
SBSA,[3][4]) is considered standard on all ARM platforms and therefore
269-
must not be listed.
294+
SBSA,[3][4]) is considered standard on all ARM and RISC-V platforms and
295+
therefore must not be listed.
270296
271297
In addition to the properties listed above, a state node may require
272298
additional properties specific to the entry-method defined in the
@@ -275,7 +301,27 @@ patternProperties:
275301
276302
properties:
277303
compatible:
278-
const: arm,idle-state
304+
enum:
305+
- arm,idle-state
306+
- riscv,idle-state
307+
308+
arm,psci-suspend-param:
309+
$ref: /schemas/types.yaml#/definitions/uint32
310+
description: |
311+
power_state parameter to pass to the ARM PSCI suspend call.
312+
313+
Device tree nodes that require usage of PSCI CPU_SUSPEND function
314+
(i.e. idle states node with entry-method property is set to "psci")
315+
must specify this property.
316+
317+
riscv,sbi-suspend-param:
318+
$ref: /schemas/types.yaml#/definitions/uint32
319+
description: |
320+
suspend_type parameter to pass to the RISC-V SBI HSM suspend call.
321+
322+
This property is required in idle state nodes of device tree meant
323+
for RISC-V systems. For more details on the suspend_type parameter
324+
refer the SBI specifiation v0.3 (or higher) [7].
279325
280326
local-timer-stop:
281327
description:
@@ -317,6 +363,8 @@ patternProperties:
317363
description:
318364
A string used as a descriptive name for the idle state.
319365

366+
additionalProperties: false
367+
320368
required:
321369
- compatible
322370
- entry-latency-us
@@ -658,4 +706,150 @@ examples:
658706
};
659707
};
660708
709+
- |
710+
// Example 3 (RISC-V 64-bit, 4-cpu systems, two clusters):
711+
712+
cpus {
713+
#size-cells = <0>;
714+
#address-cells = <1>;
715+
716+
cpu@0 {
717+
device_type = "cpu";
718+
compatible = "riscv";
719+
reg = <0x0>;
720+
riscv,isa = "rv64imafdc";
721+
mmu-type = "riscv,sv48";
722+
cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
723+
&CLUSTER_RET_0 &CLUSTER_NONRET_0>;
724+
725+
cpu_intc0: interrupt-controller {
726+
#interrupt-cells = <1>;
727+
compatible = "riscv,cpu-intc";
728+
interrupt-controller;
729+
};
730+
};
731+
732+
cpu@1 {
733+
device_type = "cpu";
734+
compatible = "riscv";
735+
reg = <0x1>;
736+
riscv,isa = "rv64imafdc";
737+
mmu-type = "riscv,sv48";
738+
cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
739+
&CLUSTER_RET_0 &CLUSTER_NONRET_0>;
740+
741+
cpu_intc1: interrupt-controller {
742+
#interrupt-cells = <1>;
743+
compatible = "riscv,cpu-intc";
744+
interrupt-controller;
745+
};
746+
};
747+
748+
cpu@10 {
749+
device_type = "cpu";
750+
compatible = "riscv";
751+
reg = <0x10>;
752+
riscv,isa = "rv64imafdc";
753+
mmu-type = "riscv,sv48";
754+
cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
755+
&CLUSTER_RET_1 &CLUSTER_NONRET_1>;
756+
757+
cpu_intc10: interrupt-controller {
758+
#interrupt-cells = <1>;
759+
compatible = "riscv,cpu-intc";
760+
interrupt-controller;
761+
};
762+
};
763+
764+
cpu@11 {
765+
device_type = "cpu";
766+
compatible = "riscv";
767+
reg = <0x11>;
768+
riscv,isa = "rv64imafdc";
769+
mmu-type = "riscv,sv48";
770+
cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
771+
&CLUSTER_RET_1 &CLUSTER_NONRET_1>;
772+
773+
cpu_intc11: interrupt-controller {
774+
#interrupt-cells = <1>;
775+
compatible = "riscv,cpu-intc";
776+
interrupt-controller;
777+
};
778+
};
779+
780+
idle-states {
781+
CPU_RET_0_0: cpu-retentive-0-0 {
782+
compatible = "riscv,idle-state";
783+
riscv,sbi-suspend-param = <0x10000000>;
784+
entry-latency-us = <20>;
785+
exit-latency-us = <40>;
786+
min-residency-us = <80>;
787+
};
788+
789+
CPU_NONRET_0_0: cpu-nonretentive-0-0 {
790+
compatible = "riscv,idle-state";
791+
riscv,sbi-suspend-param = <0x90000000>;
792+
entry-latency-us = <250>;
793+
exit-latency-us = <500>;
794+
min-residency-us = <950>;
795+
};
796+
797+
CLUSTER_RET_0: cluster-retentive-0 {
798+
compatible = "riscv,idle-state";
799+
riscv,sbi-suspend-param = <0x11000000>;
800+
local-timer-stop;
801+
entry-latency-us = <50>;
802+
exit-latency-us = <100>;
803+
min-residency-us = <250>;
804+
wakeup-latency-us = <130>;
805+
};
806+
807+
CLUSTER_NONRET_0: cluster-nonretentive-0 {
808+
compatible = "riscv,idle-state";
809+
riscv,sbi-suspend-param = <0x91000000>;
810+
local-timer-stop;
811+
entry-latency-us = <600>;
812+
exit-latency-us = <1100>;
813+
min-residency-us = <2700>;
814+
wakeup-latency-us = <1500>;
815+
};
816+
817+
CPU_RET_1_0: cpu-retentive-1-0 {
818+
compatible = "riscv,idle-state";
819+
riscv,sbi-suspend-param = <0x10000010>;
820+
entry-latency-us = <20>;
821+
exit-latency-us = <40>;
822+
min-residency-us = <80>;
823+
};
824+
825+
CPU_NONRET_1_0: cpu-nonretentive-1-0 {
826+
compatible = "riscv,idle-state";
827+
riscv,sbi-suspend-param = <0x90000010>;
828+
entry-latency-us = <250>;
829+
exit-latency-us = <500>;
830+
min-residency-us = <950>;
831+
};
832+
833+
CLUSTER_RET_1: cluster-retentive-1 {
834+
compatible = "riscv,idle-state";
835+
riscv,sbi-suspend-param = <0x11000010>;
836+
local-timer-stop;
837+
entry-latency-us = <50>;
838+
exit-latency-us = <100>;
839+
min-residency-us = <250>;
840+
wakeup-latency-us = <130>;
841+
};
842+
843+
CLUSTER_NONRET_1: cluster-nonretentive-1 {
844+
compatible = "riscv,idle-state";
845+
riscv,sbi-suspend-param = <0x91000010>;
846+
local-timer-stop;
847+
entry-latency-us = <600>;
848+
exit-latency-us = <1100>;
849+
min-residency-us = <2700>;
850+
wakeup-latency-us = <1500>;
851+
};
852+
};
853+
};
854+
661855
...

Documentation/devicetree/bindings/riscv/cpus.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ properties:
9999
- compatible
100100
- interrupt-controller
101101

102+
cpu-idle-states:
103+
$ref: '/schemas/types.yaml#/definitions/phandle-array'
104+
description: |
105+
List of phandles to idle state nodes supported
106+
by this hart (see ./idle-states.yaml).
107+
102108
required:
103109
- riscv,isa
104110
- interrupt-controller

MAINTAINERS

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5069,6 +5069,20 @@ S: Supported
50695069
F: drivers/cpuidle/cpuidle-psci.h
50705070
F: drivers/cpuidle/cpuidle-psci-domain.c
50715071

5072+
CPUIDLE DRIVER - DT IDLE PM DOMAIN
5073+
M: Ulf Hansson <ulf.hansson@linaro.org>
5074+
L: linux-pm@vger.kernel.org
5075+
S: Supported
5076+
F: drivers/cpuidle/dt_idle_genpd.c
5077+
F: drivers/cpuidle/dt_idle_genpd.h
5078+
5079+
CPUIDLE DRIVER - RISC-V SBI
5080+
M: Anup Patel <anup@brainfault.org>
5081+
L: linux-pm@vger.kernel.org
5082+
L: linux-riscv@lists.infradead.org
5083+
S: Maintained
5084+
F: drivers/cpuidle/cpuidle-riscv-sbi.c
5085+
50725086
CRAMFS FILESYSTEM
50735087
M: Nicolas Pitre <nico@fluxnic.net>
50745088
S: Maintained

arch/riscv/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ config RISCV
4848
select CLONE_BACKWARDS
4949
select CLINT_TIMER if !MMU
5050
select COMMON_CLK
51+
select CPU_PM if CPU_IDLE
5152
select EDAC_SUPPORT
5253
select GENERIC_ARCH_TOPOLOGY if SMP
5354
select GENERIC_ATOMIC64 if !64BIT
@@ -534,4 +535,10 @@ source "kernel/power/Kconfig"
534535

535536
endmenu
536537

538+
menu "CPU Power Management"
539+
540+
source "drivers/cpuidle/Kconfig"
541+
542+
endmenu
543+
537544
source "arch/riscv/kvm/Kconfig"

arch/riscv/Kconfig.socs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ config SOC_VIRT
3636
select GOLDFISH
3737
select RTC_DRV_GOLDFISH if RTC_CLASS
3838
select SIFIVE_PLIC
39+
select PM_GENERIC_DOMAINS if PM
40+
select PM_GENERIC_DOMAINS_OF if PM && OF
41+
select RISCV_SBI_CPUIDLE if CPU_IDLE
3942
help
4043
This enables support for QEMU Virt Machine.
4144

arch/riscv/configs/defconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ CONFIG_SOC_SIFIVE=y
2020
CONFIG_SOC_VIRT=y
2121
CONFIG_SMP=y
2222
CONFIG_HOTPLUG_CPU=y
23+
CONFIG_PM=y
24+
CONFIG_CPU_IDLE=y
2325
CONFIG_VIRTUALIZATION=y
2426
CONFIG_KVM=m
2527
CONFIG_JUMP_LABEL=y

0 commit comments

Comments
 (0)