U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Charles Perry <charles.perry@microchip.com>
To: <u-boot@lists.denx.de>
Cc: Rahul Pathak <rahul@summations.net>,
	Anup Patel <anup@brainfault.org>,
	Charles Perry <charles.perry@microchip.com>,
	Simon Glass <sjg@chromium.org>, Tom Rini <trini@konsulko.com>,
	Mattijs Korpershoek <mkorpershoek@kernel.org>,
	 Marek Vasut <marek.vasut+renesas@mailbox.org>,
	Heiko Schocher <hs@nabladev.com>,
	Svyatoslav Ryhel <clamor95@gmail.com>,
	"Markus Schneider-Pargmann (TI.com)" <msp@baylibre.com>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Lucien.Jheng <lucienzx159@gmail.com>,
	"Martin Schwan" <m.schwan@phytec.de>,
	Michal Simek <michal.simek@amd.com>, Peng Fan <peng.fan@nxp.com>,
	Pieter Van Trappen <pieter.van.trappen@cern.ch>,
	"Dinesh Maniyam" <dinesh.maniyam@altera.com>
Subject: [PATCH 7/7] firmware: rpmi: add a test and sandbox for device power
Date: Fri, 26 Jun 2026 13:15:48 -0700	[thread overview]
Message-ID: <20260626201613.1035208-8-charles.perry@microchip.com> (raw)
In-Reply-To: <20260626201613.1035208-1-charles.perry@microchip.com>

Add a simulation of the device power service group using code from
librpmi [1] and adapted.

[1]: https://github.com/riscv-software-src/librpmi/blob/3f3c4ca47339a8795432e260f17e1fc5091c9a3a/lib/rpmi_service_group_device_power.c

Signed-off-by: Charles Perry <charles.perry@microchip.com>
---
 arch/sandbox/dts/test.dts                  |  11 ++
 configs/sandbox_defconfig                  |   1 +
 drivers/firmware/rpmi/Makefile             |   2 +-
 drivers/firmware/rpmi/rpmi-sandbox-power.c | 174 +++++++++++++++++++++
 drivers/firmware/rpmi/rpmi-sandbox.c       |   2 +
 drivers/firmware/rpmi/rpmi-sandbox.h       |   1 +
 test/dm/rpmi.c                             |  21 +++
 7 files changed, 211 insertions(+), 1 deletion(-)
 create mode 100644 drivers/firmware/rpmi/rpmi-sandbox-power.c

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index e5d6f398fb35..7e25053851f4 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -886,6 +886,12 @@
 			#clock-cells = <1>;
 			clocks = <&rpmi_clock 0>, <&rpmi_clock 1>, <&rpmi_clock 2>, <&rpmi_clock 3>;
 		};
+
+		rpmi_dpwr: rpmi-power-domain {
+			compatible = "riscv,rpmi-device-power";
+			mboxes = <&rpmi 0x9>;
+			#power-domain-cells = <1>;
+		};
 	};
 
 	fpga {
@@ -1927,6 +1933,11 @@
 		regul1-supply = <&regul1_scmi>;
 	};
 
+	rpmi-power-domain-test {
+		compatible = "sandbox,power-domain-test";
+		power-domains = <&rpmi_dpwr 1>;
+	};
+
 	pinctrl {
 		compatible = "sandbox,pinctrl";
 
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index f1637e1ff09c..59967bd2ee0f 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -289,6 +289,7 @@ CONFIG_PINCONF=y
 CONFIG_PINCTRL_SANDBOX=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_POWER_DOMAIN=y
+CONFIG_RPMI_POWER_DOMAIN=y
 CONFIG_SANDBOX_POWER_DOMAIN=y
 CONFIG_SCMI_POWER_DOMAIN=y
 CONFIG_DM_PMIC=y
diff --git a/drivers/firmware/rpmi/Makefile b/drivers/firmware/rpmi/Makefile
index 150e98a72df9..c73ad92baec1 100644
--- a/drivers/firmware/rpmi/Makefile
+++ b/drivers/firmware/rpmi/Makefile
@@ -1,4 +1,4 @@
 obj-y	+= rpmi-uclass.o
 obj-$(CONFIG_RPMI_SBI_MPXY) += rpmi-sbi-mpxy.o
 obj-$(CONFIG_RPMI_SHMEM) += rpmi-shmem.o
-obj-$(CONFIG_SANDBOX)	+= rpmi-sandbox.o rpmi-sandbox-clock.o
+obj-$(CONFIG_SANDBOX)	+= rpmi-sandbox.o rpmi-sandbox-clock.o rpmi-sandbox-power.o
diff --git a/drivers/firmware/rpmi/rpmi-sandbox-power.c b/drivers/firmware/rpmi/rpmi-sandbox-power.c
new file mode 100644
index 000000000000..aba0ecdda0a6
--- /dev/null
+++ b/drivers/firmware/rpmi/rpmi-sandbox-power.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Ventana Micro Systems Inc.
+ * Copyright (C) 2026 Microchip Technology Inc. All rights reserved.
+ */
+
+#define LOG_CATEGORY UCLASS_RPMI
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <rpmi.h>
+#include "rpmi-sandbox.h"
+
+struct rpmi_dpwr {
+	const char *name;
+	u32 trans_latency;
+	enum rpmi_dpwr_state state;
+};
+
+struct rpmi_dpwr dpwr_simulation[] = {
+	{ "DPWR0", 0, RPMI_DPWR_STATE_ON },
+	{ "DPWR1", 0, RPMI_DPWR_STATE_OFF },
+};
+
+static u32 dpwr_count = ARRAY_SIZE(dpwr_simulation);
+
+static struct rpmi_dpwr *rpmi_get_dpwr(u32 dpwrid)
+{
+	if (dpwrid >= ARRAY_SIZE(dpwr_simulation))
+		return NULL;
+
+	return &dpwr_simulation[dpwrid];
+}
+
+static enum rpmi_error_codes
+rpmi_dpwr_get_num_domains(struct rpmi_transport *trans, u16 request_datalen,
+			  const u8 *request_data, u16 *response_datalen,
+			  u8 *response_data)
+{
+	u32 *resp = (void *)response_data;
+
+	resp[1] = cpu_to_le32(dpwr_count);
+	resp[0] = cpu_to_le32((u32)RPMI_SUCCESS);
+
+	*response_datalen = 2 * sizeof(*resp);
+
+	return RPMI_SUCCESS;
+}
+
+static enum rpmi_error_codes
+rpmi_dpwr_get_attributes(struct rpmi_transport *trans, u16 request_datalen,
+			 const u8 *request_data, u16 *response_datalen,
+			 u8 *response_data)
+{
+	u16 resp_dlen = sizeof(u32);
+	u32 *resp = (void *)response_data;
+	struct rpmi_dpwr *dpwr;
+
+	u32 dpwrid = cpu_to_le32(((const u32 *)request_data)[0]);
+
+	dpwr = rpmi_get_dpwr(dpwrid);
+	if (!dpwr) {
+		resp[0] = cpu_to_le32((u32)RPMI_ERR_INVALID_PARAM);
+		goto done;
+	}
+
+	if (dpwr->name)
+		strlcpy((char *)&resp[3], dpwr->name, RPMI_DPWR_NAME_LEN);
+
+	resp[2] = cpu_to_le32(dpwr->trans_latency);
+	resp[1] = cpu_to_le32((u32)0x0);
+	resp[0] = cpu_to_le32((u32)RPMI_SUCCESS);
+
+	resp_dlen = 3 * sizeof(*resp) + RPMI_DPWR_NAME_LEN;
+
+done:
+	*response_datalen = resp_dlen;
+
+	return RPMI_SUCCESS;
+}
+
+static enum rpmi_error_codes rpmi_dpwr_get_state(struct rpmi_transport *trans,
+						 u16 request_datalen,
+						 const u8 *request_data,
+						 u16 *response_datalen,
+						 u8 *response_data)
+{
+	u16 resp_dlen = sizeof(u32);
+	u32 *resp = (void *)response_data;
+	u32 dpwr_state = 0;
+	struct rpmi_dpwr *dpwr;
+
+	u32 dpwrid = cpu_to_le32(((const u32 *)request_data)[0]);
+
+	dpwr = rpmi_get_dpwr(dpwrid);
+	if (!dpwr) {
+		resp[0] = cpu_to_le32((u32)RPMI_ERR_INVALID_PARAM);
+		goto done;
+	}
+
+	dpwr_state = dpwr->state;
+
+	resp[1] = cpu_to_le32((u32)dpwr_state);
+	resp[0] = cpu_to_le32((u32)RPMI_SUCCESS);
+
+	resp_dlen = 2 * sizeof(*resp);
+
+done:
+	*response_datalen = resp_dlen;
+	return RPMI_SUCCESS;
+}
+
+static enum rpmi_error_codes rpmi_dpwr_set_state(struct rpmi_transport *trans,
+						 u16 request_datalen,
+						 const u8 *request_data,
+						 u16 *response_datalen,
+						 u8 *response_data)
+{
+	u16 resp_dlen = sizeof(u32);
+	u32 *resp = (void *)response_data;
+	struct rpmi_dpwr *dpwr;
+
+	u32 dpwrid = cpu_to_le32(((const u32 *)request_data)[0]);
+	u32 dpwr_state = cpu_to_le32(((const u32 *)request_data)[1]);
+
+	dpwr = rpmi_get_dpwr(dpwrid);
+	if (!dpwr) {
+		resp[0] = cpu_to_le32((u32)RPMI_ERR_INVALID_PARAM);
+		goto done;
+	}
+
+	dpwr->state = dpwr_state;
+
+	resp[0] = cpu_to_le32((u32)RPMI_SUCCESS);
+
+	resp_dlen = sizeof(*resp);
+
+done:
+	*response_datalen = resp_dlen;
+	return RPMI_SUCCESS;
+}
+
+static struct rpmi_service rpmi_dpwr_services[RPMI_DPWR_SRV_ID_MAX] = {
+	[RPMI_DPWR_SRV_GET_NUM_DOMAINS] = {
+		.service_id = RPMI_DPWR_SRV_GET_NUM_DOMAINS,
+		.min_a2p_request_datalen = 0,
+		.process_a2p_request = rpmi_dpwr_get_num_domains,
+	},
+	[RPMI_DPWR_SRV_GET_ATTRIBUTES] = {
+		.service_id = RPMI_DPWR_SRV_GET_ATTRIBUTES,
+		.min_a2p_request_datalen = 4,
+		.process_a2p_request = rpmi_dpwr_get_attributes,
+	},
+	[RPMI_DPWR_SRV_SET_DPWR_STATE] = {
+		.service_id = RPMI_DPWR_SRV_SET_DPWR_STATE,
+		.min_a2p_request_datalen = 8,
+		.process_a2p_request = rpmi_dpwr_set_state,
+	},
+	[RPMI_DPWR_SRV_GET_DPWR_STATE] = {
+		.service_id = RPMI_DPWR_SRV_GET_DPWR_STATE,
+		.min_a2p_request_datalen = 4,
+		.process_a2p_request = rpmi_dpwr_get_state,
+	},
+};
+
+const struct rpmi_service_group rpmi_sandbox_dpwr_sg = {
+	.name = "dpwr",
+	.max_service_id = RPMI_DPWR_SRV_GET_DPWR_STATE,
+	.servicegroup_version = RPMI_MKVER(1, 0),
+	.services = rpmi_dpwr_services,
+};
diff --git a/drivers/firmware/rpmi/rpmi-sandbox.c b/drivers/firmware/rpmi/rpmi-sandbox.c
index 5597c27067eb..c34c61da5d9e 100644
--- a/drivers/firmware/rpmi/rpmi-sandbox.c
+++ b/drivers/firmware/rpmi/rpmi-sandbox.c
@@ -29,6 +29,8 @@ const struct rpmi_service_group *rpmi_sandbox_sg(u32 servicegroup_id)
 	switch (servicegroup_id) {
 	case RPMI_SRVGRP_CLOCK:
 		return &rpmi_sandbox_clock_sg;
+	case RPMI_SRVGRP_DEVICE_POWER:
+		return &rpmi_sandbox_dpwr_sg;
 	default:
 		return NULL;
 	}
diff --git a/drivers/firmware/rpmi/rpmi-sandbox.h b/drivers/firmware/rpmi/rpmi-sandbox.h
index 132d1e9e8be6..7dea5035929e 100644
--- a/drivers/firmware/rpmi/rpmi-sandbox.h
+++ b/drivers/firmware/rpmi/rpmi-sandbox.h
@@ -43,5 +43,6 @@ struct rpmi_service_group {
 };
 
 extern const struct rpmi_service_group rpmi_sandbox_clock_sg;
+extern const struct rpmi_service_group rpmi_sandbox_dpwr_sg;
 
 #endif
diff --git a/test/dm/rpmi.c b/test/dm/rpmi.c
index 1ea29780a480..e886b9ab2da4 100644
--- a/test/dm/rpmi.c
+++ b/test/dm/rpmi.c
@@ -9,6 +9,7 @@
 #include <stdio.h>
 #include <dm/device-internal.h>
 #include <dm/test.h>
+#include <asm/power-domain.h>
 #include <test/ut.h>
 
 static int dm_test_rpmi_clock(struct unit_test_state *uts)
@@ -46,3 +47,23 @@ static int dm_test_rpmi_clock(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_rpmi_clock, UTF_SCAN_FDT);
+
+static int dm_test_rpmi_dpwr(struct unit_test_state *uts)
+{
+	struct udevice *rpmi_dev, *dpwr_dev, *dpwr_consumer;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_RPMI, "rpmi", &rpmi_dev));
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN,
+					      "rpmi-power-domain", &dpwr_dev));
+
+	ut_assertok(uclass_get_device_by_name(
+		UCLASS_MISC, "rpmi-power-domain-test", &dpwr_consumer));
+
+	ut_assertok(sandbox_power_domain_test_get(dpwr_consumer));
+	ut_assertok(sandbox_power_domain_test_on(dpwr_consumer));
+	ut_assertok(sandbox_power_domain_test_off(dpwr_consumer));
+
+	return 0;
+}
+DM_TEST(dm_test_rpmi_dpwr, UTF_SCAN_FDT);
-- 
2.47.3


      parent reply	other threads:[~2026-06-26 21:21 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-26 20:15 [PATCH 0/7] Add support for RPMI to U-Boot Charles Perry
2026-06-26 20:15 ` [PATCH 1/7] firmware: add support for RPMI Charles Perry
2026-06-27  1:09   ` Yao Zi
2026-06-26 20:15 ` [PATCH 2/7] firmware: rpmi: add support for the SBI MPXY transport Charles Perry
2026-06-27  1:30   ` Yao Zi
2026-06-26 20:15 ` [PATCH 3/7] firmware: rpmi: add support for shared memory transport Charles Perry
2026-06-26 20:15 ` [PATCH 4/7] drivers: clk: add support for RPMI clocks Charles Perry
2026-06-27  1:47   ` Yao Zi
2026-06-26 20:15 ` [PATCH 5/7] drivers: power: add support for RPMI power domains Charles Perry
2026-06-26 20:15 ` [PATCH 6/7] firmware: rpmi: add a test and a sandbox driver Charles Perry
2026-06-26 20:15 ` Charles Perry [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260626201613.1035208-8-charles.perry@microchip.com \
    --to=charles.perry@microchip.com \
    --cc=anup@brainfault.org \
    --cc=clamor95@gmail.com \
    --cc=dinesh.maniyam@altera.com \
    --cc=hs@nabladev.com \
    --cc=lucienzx159@gmail.com \
    --cc=m.schwan@phytec.de \
    --cc=marek.vasut+renesas@mailbox.org \
    --cc=michal.simek@amd.com \
    --cc=mkorpershoek@kernel.org \
    --cc=msp@baylibre.com \
    --cc=neil.armstrong@linaro.org \
    --cc=peng.fan@nxp.com \
    --cc=pieter.van.trappen@cern.ch \
    --cc=rahul@summations.net \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox