[PATCH v3 0/3] Add RISC-V RPMI voltage service support
From: Joshua Yeong
Date: Tue Oct 06 2026 - 04:34:15 EST
The RISC-V Platform Management Interface (RPMI) specification defines a
modular and extensible messaging protocol between the supervisor software
and a platform microcontroller (PuC). Among the service groups it defines
is the voltage service group (service group ID 0x00007), which allows the
supervisor to enumerate the voltage domains managed by the PuC, query
their attributes and supported levels, switch them on and off, and
get/set their voltage level.
This series adds supervisor-side support for that service group:
- DT bindings for the regulator controller exposed to the supervisor
("riscv,rpmi-voltage") and for the SBI MPXY channel that the SBI
implementation uses to expose the service group to the supervisor
("riscv,rpmi-mpxy-voltage"). The name, level format, supported
levels and always-on capability of each domain are discovered at
runtime, so none of them is described in DT. A consumer names a
domain through a "<name>-supply" phandle to a child of the optional
"regulators" container, whose "reg" is the RPMI DOMAIN_ID. A child
may also give the board's regulator-min-microvolt and
regulator-max-microvolt, which the PuC has no way to express.
- A regulator driver, drivers/regulator/riscv-rpmi-regulator.c, which
talks to the PuC over an SBI MPXY mailbox channel. At probe it
checks the RPMI and service group versions, queries
VOLT_GET_NUM_DOMAINS, then for each domain VOLT_GET_ATTRIBUTES and
VOLT_GET_SUPPORTED_LEVELS and registers it as a regulator. Both
level formats the specification defines are supported: discrete
levels become a voltage table and linear (min, max, step) ranges
become linear ranges. The constraints are built from the discovered
levels and the always-on flag, with the transition latency as the
settling time, and a DT child can only narrow them. Enable and
disable go through VOLT_SET_CONFIG and voltage selection through
VOLT_SET_LEVEL and VOLT_GET_LEVEL.
- A MAINTAINERS update adding the driver and its bindings to the RPMI
device power entry, renamed "RISC-V RPMI DEVICE POWER AND VOLTAGE
DRIVERS".
The series has a prerequisite: the RPMI device power series ("Add
RISC-V RPMI device power service support"), which has been applied for
next:
https://lists.infradead.org/pipermail/linux-riscv/2026-September/099498.html
Patch 2 needs it for include/linux/mailbox/riscv-rpmi-message.h, where
the voltage service group definitions are added next to the device
power ones that series introduces. Patch 3 also extends the MAINTAINERS
entry it adds. The base-commit and prerequisite-patch-id lines below
identify the tree the series applies to.
Changes in v3:
- Drop "#voltage-domain-cells" and naming a domain by DOMAIN_ID through
"voltage-domains". A consumer now names a domain only through a
"<name>-supply" phandle to its child in the "regulators" container.
The regulator core and fw_devlink already follow that phandle, so
such a consumer is also ordered after the provider without any help
from the driver. With it go devm_rpmi_voltage_supply_alias(), the
provider list it searched, the per-domain supply name it aliased to,
and include/linux/regulator/riscv-rpmi-regulator.h together with its
MAINTAINERS entry.
- Make the driver depend on "RISCV || COMPILE_TEST" and on MAILBOX
separately, as the RPMI device power driver does, so a COMPILE_TEST
build no longer selects it without MAILBOX.
- Rebase onto v7.3-rc6.
v1: https://lore.kernel.org/r/20260922161156.1088153-1-joshua.yeong@xxxxxxxxxxxxxxxx
v2: https://lore.kernel.org/r/20260923070014.1340761-1-joshua.yeong@xxxxxxxxxxxxxxxx
Testing
=======
The series was tested under QEMU with the RPMI voltage service
implemented in firmware.
Components:
- OpenSBI: v1.9
https://github.com/riscv-software-src/opensbi
- QEMU: the RPMI-enabled tree at
https://github.com/yeongjoshua/qemu/tree/rpmi-v11.1.0
Kernel config: enable CONFIG_REGULATOR_RISCV_RPMI (default y on RISC-V
when MAILBOX is enabled) along with the SBI MPXY mailbox driver.
Run with:
qemu-system-riscv64 \
-M virt -m 2G -smp 4 \
-bios fw_dynamic.bin \
-kernel Image \
-M rpmi=true \
-nographic \
-initrd rootfs-busybox.cpio \
-append "root=/dev/ram rw console=ttyS0,115200 no_console_suspend mem=2048M earlycon=uart8250,mmio,0x10000000"
The emulated PuC advertises eight voltage domains, covering both level
formats, always-on and switchable domains, and domains the board
constrains in DT. They show up under /sys/class/regulator/ and in
/sys/kernel/debug/regulator/regulator_summary. Consumer test drivers,
kept out of this series, walked each domain to its highest and lowest
level, switched the switchable ones off and back on, and checked board
ranges and requests from several consumers sharing a rail, each naming
it through "<name>-supply", including requests carried by an OPP table.
All checks passed.
Joshua Yeong (3):
dt-bindings: regulator: Add RPMI voltage service bindings
regulator: Add RPMI voltage service
MAINTAINERS: Add RISC-V RPMI voltage driver
.../regulator/riscv,rpmi-mpxy-voltage.yaml | 65 ++
.../regulator/riscv,rpmi-voltage.yaml | 130 +++
MAINTAINERS | 5 +-
drivers/regulator/Kconfig | 14 +
drivers/regulator/Makefile | 1 +
drivers/regulator/riscv-rpmi-regulator.c | 893 ++++++++++++++++++
include/linux/mailbox/riscv-rpmi-message.h | 14 +
7 files changed, 1121 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/regulator/riscv,rpmi-mpxy-voltage.yaml
create mode 100644 Documentation/devicetree/bindings/regulator/riscv,rpmi-voltage.yaml
create mode 100644 drivers/regulator/riscv-rpmi-regulator.c
base-commit: a90ee4305c4a5df72c11b31dacfdc76e00fcf78a
prerequisite-patch-id: 907ffadca74a65c93ad38f428e002d2b34341067
prerequisite-patch-id: 5a4df94e66de2f63697891a0f1382fabd9df7b6f
prerequisite-patch-id: 0827a7050d08fea7deaab8e82f2dd16acdca507d
--
2.43.0