Merge branch '2022-03-02-scmi-updates' into next

- A small set of scmi updates
This commit is contained in:
Tom Rini 2022-03-03 14:16:14 -05:00
commit 09cb77d22e
12 changed files with 343 additions and 462 deletions

View file

@ -574,17 +574,21 @@
compatible = "sandbox,firmware";
};
sandbox-scmi-agent@0 {
scmi {
compatible = "sandbox,scmi-agent";
#address-cells = <1>;
#size-cells = <0>;
clk_scmi0: protocol@14 {
protocol@10 {
reg = <0x10>;
};
clk_scmi: protocol@14 {
reg = <0x14>;
#clock-cells = <1>;
};
reset_scmi0: protocol@16 {
reset_scmi: protocol@16 {
reg = <0x16>;
#reset-cells = <1>;
};
@ -596,13 +600,13 @@
#address-cells = <1>;
#size-cells = <0>;
regul0_scmi0: reg@0 {
regul0_scmi: reg@0 {
reg = <0>;
regulator-name = "sandbox-voltd0";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <3300000>;
};
regul1_scmi0: reg@1 {
regul1_scmi: reg@1 {
reg = <0x1>;
regulator-name = "sandbox-voltd1";
regulator-min-microvolt = <1800000>;
@ -610,21 +614,6 @@
};
};
};
sandbox-scmi-agent@1 {
compatible = "sandbox,scmi-agent";
#address-cells = <1>;
#size-cells = <0>;
clk_scmi1: protocol@14 {
reg = <0x14>;
#clock-cells = <1>;
};
protocol@10 {
reg = <0x10>;
};
};
};
pinctrl-gpio {
@ -1403,10 +1392,10 @@
sandbox_scmi {
compatible = "sandbox,scmi-devices";
clocks = <&clk_scmi0 7>, <&clk_scmi0 3>, <&clk_scmi1 1>;
resets = <&reset_scmi0 3>;
regul0-supply = <&regul0_scmi0>;
regul1-supply = <&regul1_scmi0>;
clocks = <&clk_scmi 2>, <&clk_scmi 0>;
resets = <&reset_scmi 3>;
regul0-supply = <&regul0_scmi>;
regul1-supply = <&regul1_scmi>;
};
pinctrl {

View file

@ -17,7 +17,6 @@ struct sandbox_scmi_service;
* @rate: Clock rate in Hertz
*/
struct sandbox_scmi_clk {
uint id;
bool enabled;
ulong rate;
};
@ -46,7 +45,6 @@ struct sandbox_scmi_voltd {
/**
* struct sandbox_scmi_agent - Simulated SCMI service seen by SCMI agent
* @idx: Identifier for the SCMI agent, its index
* @clk: Simulated clocks
* @clk_count: Simulated clocks array size
* @reset: Simulated reset domains
@ -55,7 +53,6 @@ struct sandbox_scmi_voltd {
* @voltd_count: Simulated voltage domains array size
*/
struct sandbox_scmi_agent {
uint idx;
struct sandbox_scmi_clk *clk;
size_t clk_count;
struct sandbox_scmi_reset *reset;
@ -66,12 +63,10 @@ struct sandbox_scmi_agent {
/**
* struct sandbox_scmi_service - Reference to simutaed SCMI agents/services
* @agent: Pointer to SCMI sandbox agent pointers array
* @agent_count: Number of emulated agents exposed in array @agent.
* @agent: Pointer to SCMI sandbox agent or NULL if not probed
*/
struct sandbox_scmi_service {
struct sandbox_scmi_agent **agent;
size_t agent_count;
struct sandbox_scmi_agent *agent;
};
/**
@ -94,13 +89,13 @@ struct sandbox_scmi_devices {
#ifdef CONFIG_SCMI_FIRMWARE
/**
* sandbox_scmi_service_context - Get the simulated SCMI services context
* sandbox_scmi_service_ctx - Get the simulated SCMI services context
* @return: Reference to backend simulated resources state
*/
struct sandbox_scmi_service *sandbox_scmi_service_ctx(void);
/**
* sandbox_scmi_devices_get_ref - Get references to devices accessed through SCMI
* sandbox_scmi_devices_ctx - Get references to devices accessed through SCMI
* @dev: Reference to the test device used get test resources
* @return: Reference to the devices probed by the SCMI test
*/

View file

@ -1,234 +1,2 @@
System Control and Management Interface (SCMI) Message Protocol
----------------------------------------------------------
The SCMI is intended to allow agents such as OSPM to manage various functions
that are provided by the hardware platform it is running on, including power
and performance functions.
This binding is intended to define the interface the firmware implementing
the SCMI as described in ARM document number ARM DEN 0056A ("ARM System Control
and Management Interface Platform Design Document")[0] provide for OSPM in
the device tree.
Required properties:
The scmi node with the following properties shall be under the /firmware/ node.
- compatible : shall be "arm,scmi" or "arm,scmi-smc" for smc/hvc transports,
or "linaro,scmi-optee" for OP-TEE transport.
- mboxes: List of phandle and mailbox channel specifiers. It should contain
exactly one or two mailboxes, one for transmitting messages("tx")
and another optional for receiving the notifications("rx") if
supported.
- shmem : List of phandle pointing to the shared memory(SHM) area as per
generic mailbox client binding.
- #address-cells : should be '1' if the device has sub-nodes, maps to
protocol identifier for a given sub-node.
- #size-cells : should be '0' as 'reg' property doesn't have any size
associated with it.
- arm,smc-id : SMC id required when using smc or hvc transports
- linaro,optee-channel-id : Channel specifier required when using OP-TEE
transport.
Optional properties:
- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
about the generic mailbox controller and client driver bindings.
Mailbox doorbell is used as a mechanism to alert the presence of a
messages and/or notification.
Each protocol supported shall have a sub-node with corresponding compatible
as described in the following sections. If the platform supports dedicated
communication channel for a particular protocol, properties shall be present
in the sub-node corresponding to that protocol. These properties are:
- mboxes, mbox-names and shmem for mailbox transport
- arm,smc-id and shmem for smc/hvc transport
- linaro,optee-channel-id and possibly shmem for OP-TEE transport
Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol
------------------------------------------------------------
This binding uses the common clock binding[1].
Required properties:
- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands.
Power domain bindings for the power domains based on SCMI Message Protocol
------------------------------------------------------------
This binding for the SCMI power domain providers uses the generic power
domain binding[2].
Required properties:
- #power-domain-cells : Should be 1. Contains the device or the power
domain ID value used by SCMI commands.
Regulator bindings for the SCMI Regulator based on SCMI Message Protocol
------------------------------------------------------------
An SCMI Regulator is permanently bound to a well defined SCMI Voltage Domain,
and should be always positioned as a root regulator.
It does not support any current operation.
SCMI Regulators are grouped under a 'regulators' node which in turn is a child
of the SCMI Voltage protocol node inside the desired SCMI instance node.
This binding uses the common regulator binding[6].
Required properties:
- reg : shall identify an existent SCMI Voltage Domain.
Sensor bindings for the sensors based on SCMI Message Protocol
--------------------------------------------------------------
SCMI provides an API to access the various sensors on the SoC.
Required properties:
- #thermal-sensor-cells: should be set to 1. This property follows the
thermal device tree bindings[3].
Valid cell values are raw identifiers (Sensor ID)
as used by the firmware. Refer to platform details
for your implementation for the IDs to use.
Reset signal bindings for the reset domains based on SCMI Message Protocol
------------------------------------------------------------
This binding for the SCMI reset domain providers uses the generic reset
signal binding[5].
Required properties:
- #reset-cells : Should be 1. Contains the reset domain ID value used
by SCMI commands.
SRAM and Shared Memory for SCMI
-------------------------------
A small area of SRAM is reserved for SCMI communication between application
processors and SCP.
The properties should follow the generic mmio-sram description found in [4]
Each sub-node represents the reserved area for SCMI.
Required sub-node properties:
- reg : The base offset and size of the reserved area with the SRAM
- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based
shared memory
[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Documentation/devicetree/bindings/power/power-domain.yaml
[3] Documentation/devicetree/bindings/thermal/thermal.txt
[4] Documentation/devicetree/bindings/sram/sram.yaml
[5] Documentation/devicetree/bindings/reset/reset.txt
[6] Documentation/devicetree/bindings/regulator/regulator.yaml
Example:
sram@50000000 {
compatible = "mmio-sram";
reg = <0x0 0x50000000 0x0 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x0 0x50000000 0x10000>;
cpu_scp_lpri: scp-shmem@0 {
compatible = "arm,scmi-shmem";
reg = <0x0 0x200>;
};
cpu_scp_hpri: scp-shmem@200 {
compatible = "arm,scmi-shmem";
reg = <0x200 0x200>;
};
};
mailbox@40000000 {
....
#mbox-cells = <1>;
reg = <0x0 0x40000000 0x0 0x10000>;
};
firmware {
...
scmi {
compatible = "arm,scmi";
mboxes = <&mailbox 0 &mailbox 1>;
mbox-names = "tx", "rx";
shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
#address-cells = <1>;
#size-cells = <0>;
scmi_devpd: protocol@11 {
reg = <0x11>;
#power-domain-cells = <1>;
};
scmi_dvfs: protocol@13 {
reg = <0x13>;
#clock-cells = <1>;
};
scmi_clk: protocol@14 {
reg = <0x14>;
#clock-cells = <1>;
};
scmi_sensors0: protocol@15 {
reg = <0x15>;
#thermal-sensor-cells = <1>;
};
scmi_reset: protocol@16 {
reg = <0x16>;
#reset-cells = <1>;
};
scmi_voltage: protocol@17 {
reg = <0x17>;
regulators {
regulator_devX: regulator@0 {
reg = <0x0>;
regulator-max-microvolt = <3300000>;
};
regulator_devY: regulator@9 {
reg = <0x9>;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <4200000>;
};
...
};
};
};
};
cpu@0 {
...
reg = <0 0>;
clocks = <&scmi_dvfs 0>;
};
hdlcd@7ff60000 {
...
reg = <0 0x7ff60000 0 0x1000>;
clocks = <&scmi_clk 4>;
power-domains = <&scmi_devpd 1>;
resets = <&scmi_reset 10>;
};
thermal-zones {
soc_thermal {
polling-delay-passive = <100>;
polling-delay = <1000>;
/* sensor ID */
thermal-sensors = <&scmi_sensors0 3>;
...
};
};
See Binding in Linux documentation:
Documentation/devicetree/bindings/firmware/arm,scmi.yaml

View file

@ -11,6 +11,52 @@
#include <scmi_agent.h>
#include <scmi_protocols.h>
#include <asm/types.h>
#include <linux/clk-provider.h>
static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks)
{
struct scmi_clk_protocol_attr_out out;
struct scmi_msg msg = {
.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
.message_id = SCMI_PROTOCOL_ATTRIBUTES,
.out_msg = (u8 *)&out,
.out_msg_sz = sizeof(out),
};
int ret;
ret = devm_scmi_process_msg(dev, &msg);
if (ret)
return ret;
*num_clocks = out.attributes & SCMI_CLK_PROTO_ATTR_COUNT_MASK;
return 0;
}
static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name)
{
struct scmi_clk_attribute_in in = {
.clock_id = clkid,
};
struct scmi_clk_attribute_out out;
struct scmi_msg msg = {
.protocol_id = SCMI_PROTOCOL_ID_CLOCK,
.message_id = SCMI_CLOCK_ATTRIBUTES,
.in_msg = (u8 *)&in,
.in_msg_sz = sizeof(in),
.out_msg = (u8 *)&out,
.out_msg_sz = sizeof(out),
};
int ret;
ret = devm_scmi_process_msg(dev, &msg);
if (ret)
return ret;
*name = out.clock_name;
return 0;
}
static int scmi_clk_gate(struct clk *clk, int enable)
{
@ -24,7 +70,7 @@ static int scmi_clk_gate(struct clk *clk, int enable)
in, out);
int ret;
ret = devm_scmi_process_msg(clk->dev->parent, &msg);
ret = devm_scmi_process_msg(clk->dev, &msg);
if (ret)
return ret;
@ -52,7 +98,7 @@ static ulong scmi_clk_get_rate(struct clk *clk)
in, out);
int ret;
ret = devm_scmi_process_msg(clk->dev->parent, &msg);
ret = devm_scmi_process_msg(clk->dev, &msg);
if (ret < 0)
return ret;
@ -77,7 +123,7 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
in, out);
int ret;
ret = devm_scmi_process_msg(clk->dev->parent, &msg);
ret = devm_scmi_process_msg(clk->dev, &msg);
if (ret < 0)
return ret;
@ -88,6 +134,49 @@ static ulong scmi_clk_set_rate(struct clk *clk, ulong rate)
return scmi_clk_get_rate(clk);
}
static int scmi_clk_probe(struct udevice *dev)
{
struct clk *clk;
size_t num_clocks, i;
int ret;
if (!CONFIG_IS_ENABLED(CLK_CCF))
return 0;
/* register CCF children: CLK UCLASS, no probed again */
if (device_get_uclass_id(dev->parent) == UCLASS_CLK)
return 0;
ret = scmi_clk_get_num_clock(dev, &num_clocks);
if (ret)
return ret;
for (i = 0; i < num_clocks; i++) {
char *name;
if (!scmi_clk_get_attibute(dev, i, &name)) {
char *clock_name = strdup(name);
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk || !clock_name)
ret = -ENOMEM;
else
ret = clk_register(clk, dev->driver->name,
clock_name, dev->name);
if (ret) {
free(clk);
free(clock_name);
return ret;
}
clk_dm(i, clk);
}
}
return 0;
}
static const struct clk_ops scmi_clk_ops = {
.enable = scmi_clk_enable,
.disable = scmi_clk_disable,
@ -99,4 +188,5 @@ U_BOOT_DRIVER(scmi_clock) = {
.name = "scmi_clk",
.id = UCLASS_CLK,
.ops = &scmi_clk_ops,
.probe = &scmi_clk_probe,
};

View file

@ -19,51 +19,36 @@
* The sandbox SCMI agent driver simulates to some extend a SCMI message
* processing. It simulates few of the SCMI services for some of the
* SCMI protocols embedded in U-Boot. Currently:
* - SCMI clock protocol: emulate 2 agents each exposing few clocks
* - SCMI reset protocol: emulate 1 agent exposing a reset controller
* - SCMI voltage domain protocol: emulate 1 agent exposing 2 regulators
* - SCMI clock protocol emulates an agent exposing 2 clocks
* - SCMI reset protocol emulates an agent exposing a reset controller
* - SCMI voltage domain protocol emulates an agent exposing 2 regulators
*
* Agent #0 simulates 2 clocks, 1 reset domain and 1 voltage domain.
* See IDs in scmi0_clk[]/scmi0_reset[] and "sandbox-scmi-agent@0" in test.dts.
*
* Agent #1 simulates 1 clock.
* See IDs in scmi1_clk[] and "sandbox-scmi-agent@1" in test.dts.
* As per DT bindings, the device node name shall be scmi.
*
* All clocks and regulators are default disabled and reset controller down.
*
* This Driver exports sandbox_scmi_service_ctx() for the test sequence to
* This driver exports sandbox_scmi_service_ctx() for the test sequence to
* get the state of the simulated services (clock state, rate, ...) and
* check back-end device state reflects the request send through the
* various uclass devices, as clocks and reset controllers.
*/
#define SANDBOX_SCMI_AGENT_COUNT 2
static struct sandbox_scmi_clk scmi0_clk[] = {
{ .id = 7, .rate = 1000 },
{ .id = 3, .rate = 333 },
static struct sandbox_scmi_clk scmi_clk[] = {
{ .rate = 333 },
{ .rate = 200 },
{ .rate = 1000 },
};
static struct sandbox_scmi_reset scmi0_reset[] = {
static struct sandbox_scmi_reset scmi_reset[] = {
{ .id = 3 },
};
static struct sandbox_scmi_voltd scmi0_voltd[] = {
static struct sandbox_scmi_voltd scmi_voltd[] = {
{ .id = 0, .voltage_uv = 3300000 },
{ .id = 1, .voltage_uv = 1800000 },
};
static struct sandbox_scmi_clk scmi1_clk[] = {
{ .id = 1, .rate = 44 },
};
/* The list saves to simulted end devices references for test purpose */
struct sandbox_scmi_agent *sandbox_scmi_agent_list[SANDBOX_SCMI_AGENT_COUNT];
static struct sandbox_scmi_service sandbox_scmi_service_state = {
.agent = sandbox_scmi_agent_list,
.agent_count = SANDBOX_SCMI_AGENT_COUNT,
};
static struct sandbox_scmi_service sandbox_scmi_service_state;
struct sandbox_scmi_service *sandbox_scmi_service_ctx(void)
{
@ -74,9 +59,8 @@ static void debug_print_agent_state(struct udevice *dev, char *str)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
dev_dbg(dev, "Dump sandbox_scmi_agent %u: %s\n", agent->idx, str);
dev_dbg(dev, " scmi%u_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n",
agent->idx,
dev_dbg(dev, "Dump sandbox_scmi_agent: %s\n", str);
dev_dbg(dev, " scmi_clk (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n",
agent->clk_count,
agent->clk_count ? agent->clk[0].enabled : -1,
agent->clk_count ? agent->clk[0].rate : -1,
@ -84,13 +68,11 @@ static void debug_print_agent_state(struct udevice *dev, char *str)
agent->clk_count > 1 ? agent->clk[1].rate : -1,
agent->clk_count > 2 ? agent->clk[2].enabled : -1,
agent->clk_count > 2 ? agent->clk[2].rate : -1);
dev_dbg(dev, " scmi%u_reset (%zu): %d, %d, ...\n",
agent->idx,
dev_dbg(dev, " scmi_reset (%zu): %d, %d, ...\n",
agent->reset_count,
agent->reset_count ? agent->reset[0].asserted : -1,
agent->reset_count > 1 ? agent->reset[1].asserted : -1);
dev_dbg(dev, " scmi%u_voltd (%zu): %u/%d, %u/%d, ...\n",
agent->idx,
dev_dbg(dev, " scmi_voltd (%zu): %u/%d, %u/%d, ...\n",
agent->voltd_count,
agent->voltd_count ? agent->voltd[0].enabled : -1,
agent->voltd_count ? agent->voltd[0].voltage_uv : -1,
@ -98,56 +80,32 @@ static void debug_print_agent_state(struct udevice *dev, char *str)
agent->voltd_count ? agent->voltd[1].voltage_uv : -1);
};
static struct sandbox_scmi_clk *get_scmi_clk_state(uint agent_id, uint clock_id)
static struct sandbox_scmi_clk *get_scmi_clk_state(uint clock_id)
{
struct sandbox_scmi_clk *target = NULL;
size_t target_count = 0;
size_t n;
switch (agent_id) {
case 0:
target = scmi0_clk;
target_count = ARRAY_SIZE(scmi0_clk);
break;
case 1:
target = scmi1_clk;
target_count = ARRAY_SIZE(scmi1_clk);
break;
default:
return NULL;
}
for (n = 0; n < target_count; n++)
if (target[n].id == clock_id)
return target + n;
if (clock_id < ARRAY_SIZE(scmi_clk))
return scmi_clk + clock_id;
return NULL;
}
static struct sandbox_scmi_reset *get_scmi_reset_state(uint agent_id,
uint reset_id)
static struct sandbox_scmi_reset *get_scmi_reset_state(uint reset_id)
{
size_t n;
if (agent_id == 0) {
for (n = 0; n < ARRAY_SIZE(scmi0_reset); n++)
if (scmi0_reset[n].id == reset_id)
return scmi0_reset + n;
}
for (n = 0; n < ARRAY_SIZE(scmi_reset); n++)
if (scmi_reset[n].id == reset_id)
return scmi_reset + n;
return NULL;
}
static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint agent_id,
uint domain_id)
static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint domain_id)
{
size_t n;
if (agent_id == 0) {
for (n = 0; n < ARRAY_SIZE(scmi0_voltd); n++)
if (scmi0_voltd[n].id == domain_id)
return scmi0_voltd + n;
}
for (n = 0; n < ARRAY_SIZE(scmi_voltd); n++)
if (scmi_voltd[n].id == domain_id)
return scmi_voltd + n;
return NULL;
}
@ -156,10 +114,58 @@ static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint agent_id,
* Sandbox SCMI agent ops
*/
static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
struct scmi_msg *msg)
{
struct scmi_clk_protocol_attr_out *out = NULL;
if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
return -EINVAL;
out = (struct scmi_clk_protocol_attr_out *)msg->out_msg;
out->attributes = ARRAY_SIZE(scmi_clk);
out->status = SCMI_SUCCESS;
return 0;
}
static int sandbox_scmi_clock_attribs(struct udevice *dev, struct scmi_msg *msg)
{
struct scmi_clk_attribute_in *in = NULL;
struct scmi_clk_attribute_out *out = NULL;
struct sandbox_scmi_clk *clk_state = NULL;
int ret;
if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
return -EINVAL;
in = (struct scmi_clk_attribute_in *)msg->in_msg;
out = (struct scmi_clk_attribute_out *)msg->out_msg;
clk_state = get_scmi_clk_state(in->clock_id);
if (!clk_state) {
dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
out->status = SCMI_NOT_FOUND;
} else {
memset(out, 0, sizeof(*out));
if (clk_state->enabled)
out->attributes = 1;
ret = snprintf(out->clock_name, sizeof(out->clock_name),
"clk%u", in->clock_id);
assert(ret > 0 && ret < sizeof(out->clock_name));
out->status = SCMI_SUCCESS;
}
return 0;
}
static int sandbox_scmi_clock_rate_set(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_clk_rate_set_in *in = NULL;
struct scmi_clk_rate_set_out *out = NULL;
struct sandbox_scmi_clk *clk_state = NULL;
@ -171,7 +177,7 @@ static int sandbox_scmi_clock_rate_set(struct udevice *dev,
in = (struct scmi_clk_rate_set_in *)msg->in_msg;
out = (struct scmi_clk_rate_set_out *)msg->out_msg;
clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
clk_state = get_scmi_clk_state(in->clock_id);
if (!clk_state) {
dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
@ -190,7 +196,6 @@ static int sandbox_scmi_clock_rate_set(struct udevice *dev,
static int sandbox_scmi_clock_rate_get(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_clk_rate_get_in *in = NULL;
struct scmi_clk_rate_get_out *out = NULL;
struct sandbox_scmi_clk *clk_state = NULL;
@ -202,7 +207,7 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev,
in = (struct scmi_clk_rate_get_in *)msg->in_msg;
out = (struct scmi_clk_rate_get_out *)msg->out_msg;
clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
clk_state = get_scmi_clk_state(in->clock_id);
if (!clk_state) {
dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
@ -219,7 +224,6 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev,
static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_clk_state_in *in = NULL;
struct scmi_clk_state_out *out = NULL;
struct sandbox_scmi_clk *clk_state = NULL;
@ -231,7 +235,7 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
in = (struct scmi_clk_state_in *)msg->in_msg;
out = (struct scmi_clk_state_out *)msg->out_msg;
clk_state = get_scmi_clk_state(agent->idx, in->clock_id);
clk_state = get_scmi_clk_state(in->clock_id);
if (!clk_state) {
dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
@ -249,7 +253,6 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_rd_attr_in *in = NULL;
struct scmi_rd_attr_out *out = NULL;
struct sandbox_scmi_reset *reset_state = NULL;
@ -261,7 +264,7 @@ static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
in = (struct scmi_rd_attr_in *)msg->in_msg;
out = (struct scmi_rd_attr_out *)msg->out_msg;
reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
reset_state = get_scmi_reset_state(in->domain_id);
if (!reset_state) {
dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
@ -278,7 +281,6 @@ static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_rd_reset_in *in = NULL;
struct scmi_rd_reset_out *out = NULL;
struct sandbox_scmi_reset *reset_state = NULL;
@ -290,7 +292,7 @@ static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
in = (struct scmi_rd_reset_in *)msg->in_msg;
out = (struct scmi_rd_reset_out *)msg->out_msg;
reset_state = get_scmi_reset_state(agent->idx, in->domain_id);
reset_state = get_scmi_reset_state(in->domain_id);
if (!reset_state) {
dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
@ -321,7 +323,6 @@ static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_voltd_attr_in *in = NULL;
struct scmi_voltd_attr_out *out = NULL;
struct sandbox_scmi_voltd *voltd_state = NULL;
@ -333,7 +334,7 @@ static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg)
in = (struct scmi_voltd_attr_in *)msg->in_msg;
out = (struct scmi_voltd_attr_out *)msg->out_msg;
voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id);
voltd_state = get_scmi_voltd_state(in->domain_id);
if (!voltd_state) {
dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
@ -351,7 +352,6 @@ static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg)
static int sandbox_scmi_voltd_config_set(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_voltd_config_set_in *in = NULL;
struct scmi_voltd_config_set_out *out = NULL;
struct sandbox_scmi_voltd *voltd_state = NULL;
@ -363,7 +363,7 @@ static int sandbox_scmi_voltd_config_set(struct udevice *dev,
in = (struct scmi_voltd_config_set_in *)msg->in_msg;
out = (struct scmi_voltd_config_set_out *)msg->out_msg;
voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id);
voltd_state = get_scmi_voltd_state(in->domain_id);
if (!voltd_state) {
dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
@ -388,7 +388,6 @@ static int sandbox_scmi_voltd_config_set(struct udevice *dev,
static int sandbox_scmi_voltd_config_get(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_voltd_config_get_in *in = NULL;
struct scmi_voltd_config_get_out *out = NULL;
struct sandbox_scmi_voltd *voltd_state = NULL;
@ -400,7 +399,7 @@ static int sandbox_scmi_voltd_config_get(struct udevice *dev,
in = (struct scmi_voltd_config_get_in *)msg->in_msg;
out = (struct scmi_voltd_config_get_out *)msg->out_msg;
voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id);
voltd_state = get_scmi_voltd_state(in->domain_id);
if (!voltd_state) {
dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
@ -420,7 +419,6 @@ static int sandbox_scmi_voltd_config_get(struct udevice *dev,
static int sandbox_scmi_voltd_level_set(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_voltd_level_set_in *in = NULL;
struct scmi_voltd_level_set_out *out = NULL;
struct sandbox_scmi_voltd *voltd_state = NULL;
@ -432,7 +430,7 @@ static int sandbox_scmi_voltd_level_set(struct udevice *dev,
in = (struct scmi_voltd_level_set_in *)msg->in_msg;
out = (struct scmi_voltd_level_set_out *)msg->out_msg;
voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id);
voltd_state = get_scmi_voltd_state(in->domain_id);
if (!voltd_state) {
dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
@ -448,7 +446,6 @@ static int sandbox_scmi_voltd_level_set(struct udevice *dev,
static int sandbox_scmi_voltd_level_get(struct udevice *dev,
struct scmi_msg *msg)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
struct scmi_voltd_level_get_in *in = NULL;
struct scmi_voltd_level_get_out *out = NULL;
struct sandbox_scmi_voltd *voltd_state = NULL;
@ -460,7 +457,7 @@ static int sandbox_scmi_voltd_level_get(struct udevice *dev,
in = (struct scmi_voltd_level_get_in *)msg->in_msg;
out = (struct scmi_voltd_level_get_out *)msg->out_msg;
voltd_state = get_scmi_voltd_state(agent->idx, in->domain_id);
voltd_state = get_scmi_voltd_state(in->domain_id);
if (!voltd_state) {
dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
@ -479,6 +476,10 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev,
switch (msg->protocol_id) {
case SCMI_PROTOCOL_ID_CLOCK:
switch (msg->message_id) {
case SCMI_PROTOCOL_ATTRIBUTES:
return sandbox_scmi_clock_protocol_attribs(dev, msg);
case SCMI_CLOCK_ATTRIBUTES:
return sandbox_scmi_clock_attribs(dev, msg);
case SCMI_CLOCK_RATE_SET:
return sandbox_scmi_clock_rate_set(dev, msg);
case SCMI_CLOCK_RATE_GET:
@ -541,52 +542,37 @@ static int sandbox_scmi_test_remove(struct udevice *dev)
{
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
if (agent != sandbox_scmi_service_ctx()->agent)
return -EINVAL;
debug_print_agent_state(dev, "removed");
/* We only need to dereference the agent in the context */
sandbox_scmi_service_ctx()->agent[agent->idx] = NULL;
sandbox_scmi_service_ctx()->agent = NULL;
return 0;
}
static int sandbox_scmi_test_probe(struct udevice *dev)
{
static const char basename[] = "sandbox-scmi-agent@";
struct sandbox_scmi_agent *agent = dev_get_priv(dev);
const size_t basename_size = sizeof(basename) - 1;
if (strncmp(basename, dev->name, basename_size))
return -ENOENT;
if (sandbox_scmi_service_ctx()->agent)
return -EINVAL;
switch (dev->name[basename_size]) {
case '0':
*agent = (struct sandbox_scmi_agent){
.idx = 0,
.clk = scmi0_clk,
.clk_count = ARRAY_SIZE(scmi0_clk),
.reset = scmi0_reset,
.reset_count = ARRAY_SIZE(scmi0_reset),
.voltd = scmi0_voltd,
.voltd_count = ARRAY_SIZE(scmi0_voltd),
};
break;
case '1':
*agent = (struct sandbox_scmi_agent){
.idx = 1,
.clk = scmi1_clk,
.clk_count = ARRAY_SIZE(scmi1_clk),
};
break;
default:
dev_err(dev, "%s(): Unexpected agent ID %s\n",
__func__, dev->name + basename_size);
return -ENOENT;
}
*agent = (struct sandbox_scmi_agent){
.clk = scmi_clk,
.clk_count = ARRAY_SIZE(scmi_clk),
.reset = scmi_reset,
.reset_count = ARRAY_SIZE(scmi_reset),
.voltd = scmi_voltd,
.voltd_count = ARRAY_SIZE(scmi_voltd),
};
debug_print_agent_state(dev, "probed");
/* Save reference for tests purpose */
sandbox_scmi_service_ctx()->agent[agent->idx] = agent;
sandbox_scmi_service_ctx()->agent = agent;
return 0;
};

View file

@ -23,7 +23,7 @@
* and reset controllers.
*/
#define SCMI_TEST_DEVICES_CLK_COUNT 3
#define SCMI_TEST_DEVICES_CLK_COUNT 2
#define SCMI_TEST_DEVICES_RD_COUNT 1
#define SCMI_TEST_DEVICES_VOLTD_COUNT 2
@ -135,7 +135,7 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = {
.name = "sandbox-scmi_devices",
.id = UCLASS_MISC,
.of_match = sandbox_scmi_devices_ids,
.priv_auto = sizeof(struct sandbox_scmi_device_priv),
.priv_auto = sizeof(struct sandbox_scmi_device_priv),
.remove = sandbox_scmi_devices_remove,
.probe = sandbox_scmi_devices_probe,
};

View file

@ -116,10 +116,23 @@ static const struct scmi_agent_ops *transport_dev_ops(struct udevice *dev)
int devm_scmi_process_msg(struct udevice *dev, struct scmi_msg *msg)
{
const struct scmi_agent_ops *ops = transport_dev_ops(dev);
const struct scmi_agent_ops *ops;
struct udevice *parent = dev;
/* Find related SCMI agent device */
do {
parent = dev_get_parent(parent);
} while (parent && device_get_uclass_id(parent) != UCLASS_SCMI_AGENT);
if (!parent) {
dev_err(dev, "Invalid SCMI device, agent not found\n");
return -ENODEV;
}
ops = transport_dev_ops(parent);
if (ops->process_msg)
return ops->process_msg(dev, msg);
return ops->process_msg(parent, msg);
return -EPROTONOSUPPORT;
}

View file

@ -38,7 +38,7 @@ static int scmi_voltd_set_enable(struct udevice *dev, bool enable)
in, out);
int ret;
ret = devm_scmi_process_msg(dev->parent->parent, &msg);
ret = devm_scmi_process_msg(dev, &msg);
if (ret)
return ret;
@ -61,7 +61,7 @@ static int scmi_voltd_get_enable(struct udevice *dev)
in, out);
int ret;
ret = devm_scmi_process_msg(dev->parent->parent, &msg);
ret = devm_scmi_process_msg(dev, &msg);
if (ret < 0)
return ret;
@ -85,7 +85,7 @@ static int scmi_voltd_set_voltage_level(struct udevice *dev, int uV)
in, out);
int ret;
ret = devm_scmi_process_msg(dev->parent->parent, &msg);
ret = devm_scmi_process_msg(dev, &msg);
if (ret < 0)
return ret;
@ -104,7 +104,7 @@ static int scmi_voltd_get_voltage_level(struct udevice *dev)
in, out);
int ret;
ret = devm_scmi_process_msg(dev->parent->parent, &msg);
ret = devm_scmi_process_msg(dev, &msg);
if (ret < 0)
return ret;
@ -147,7 +147,7 @@ static int scmi_regulator_probe(struct udevice *dev)
/* Check voltage domain is known from SCMI server */
in.domain_id = pdata->domain_id;
ret = devm_scmi_process_msg(dev->parent->parent, &scmi_msg);
ret = devm_scmi_process_msg(dev, &scmi_msg);
if (ret) {
dev_err(dev, "Failed to query voltage domain %u: %d\n",
pdata->domain_id, ret);

View file

@ -26,7 +26,7 @@ static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert)
in, out);
int ret;
ret = devm_scmi_process_msg(rst->dev->parent, &msg);
ret = devm_scmi_process_msg(rst->dev, &msg);
if (ret)
return ret;
@ -58,7 +58,7 @@ static int scmi_reset_request(struct reset_ctl *rst)
* We don't really care about the attribute, just check
* the reset domain exists.
*/
ret = devm_scmi_process_msg(rst->dev->parent, &msg);
ret = devm_scmi_process_msg(rst->dev, &msg);
if (ret)
return ret;

View file

@ -51,7 +51,7 @@ struct scmi_msg {
* Caller sets scmi_msg::out_msg_sz to the output message buffer size.
* On return, scmi_msg::out_msg_sz stores the response payload size.
*
* @dev: SCMI agent device
* @dev: SCMI device
* @msg: Message structure reference
* Return: 0 on success and a negative errno on failure
*/

View file

@ -40,22 +40,65 @@ enum scmi_status_code {
SCMI_PROTOCOL_ERROR = -10,
};
/*
* Generic message IDs
*/
enum scmi_discovery_id {
SCMI_PROTOCOL_VERSION = 0x0,
SCMI_PROTOCOL_ATTRIBUTES = 0x1,
SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2,
};
/*
* SCMI Clock Protocol
*/
enum scmi_clock_message_id {
SCMI_CLOCK_ATTRIBUTES = 0x3,
SCMI_CLOCK_RATE_SET = 0x5,
SCMI_CLOCK_RATE_GET = 0x6,
SCMI_CLOCK_CONFIG_SET = 0x7,
};
#define SCMI_CLK_PROTO_ATTR_COUNT_MASK GENMASK(15, 0)
#define SCMI_CLK_RATE_ASYNC_NOTIFY BIT(0)
#define SCMI_CLK_RATE_ASYNC_NORESP (BIT(0) | BIT(1))
#define SCMI_CLK_RATE_ROUND_DOWN 0
#define SCMI_CLK_RATE_ROUND_UP BIT(2)
#define SCMI_CLK_RATE_ROUND_CLOSEST BIT(3)
#define SCMI_CLOCK_NAME_LENGTH_MAX 16
/**
* struct scmi_clk_get_nb_out - Response for SCMI_PROTOCOL_ATTRIBUTES command
* @status: SCMI command status
* @attributes: Attributes of the clock protocol, mainly number of clocks exposed
*/
struct scmi_clk_protocol_attr_out {
s32 status;
u32 attributes;
};
/**
* struct scmi_clk_attribute_in - Message payload for SCMI_CLOCK_ATTRIBUTES command
* @clock_id: SCMI clock ID
*/
struct scmi_clk_attribute_in {
u32 clock_id;
};
/**
* struct scmi_clk_get_nb_out - Response payload for SCMI_CLOCK_ATTRIBUTES command
* @status: SCMI command status
* @attributes: clock attributes
* @clock_name: name of the clock
*/
struct scmi_clk_attribute_out {
s32 status;
u32 attributes;
char clock_name[SCMI_CLOCK_NAME_LENGTH_MAX];
};
/**
* struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET command
* @clock_id: SCMI clock ID

View file

@ -5,7 +5,7 @@
* Tests scmi_agent uclass and the SCMI drivers implemented in other
* uclass devices probe when a SCMI server exposes resources.
*
* Note in test.dts the protocol@10 node in agent 1. Protocol 0x10 is not
* Note in test.dts the protocol@10 node in scmi node. Protocol 0x10 is not
* implemented in U-Boot SCMI components but the implementation is exepected
* to not complain on unknown protocol IDs, as long as it is not used. Note
* in test.dts tests that SCMI drivers probing does not fail for such an
@ -28,8 +28,7 @@ static int ut_assert_scmi_state_preprobe(struct unit_test_state *uts)
struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx();
ut_assertnonnull(scmi_ctx);
if (scmi_ctx->agent_count)
ut_asserteq(2, scmi_ctx->agent_count);
ut_assertnull(scmi_ctx->agent);
return 0;
}
@ -39,35 +38,26 @@ static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
{
struct sandbox_scmi_devices *scmi_devices;
struct sandbox_scmi_service *scmi_ctx;
struct sandbox_scmi_agent *agent0;
struct sandbox_scmi_agent *agent1;
struct sandbox_scmi_agent *agent;
/* Device references to check context against test sequence */
scmi_devices = sandbox_scmi_devices_ctx(dev);
ut_assertnonnull(scmi_devices);
ut_asserteq(3, scmi_devices->clk_count);
ut_asserteq(2, scmi_devices->clk_count);
ut_asserteq(1, scmi_devices->reset_count);
ut_asserteq(2, scmi_devices->regul_count);
/* State of the simulated SCMI server exposed */
scmi_ctx = sandbox_scmi_service_ctx();
agent0 = scmi_ctx->agent[0];
agent1 = scmi_ctx->agent[1];
ut_asserteq(2, scmi_ctx->agent_count);
ut_assertnonnull(agent0);
ut_asserteq(2, agent0->clk_count);
ut_assertnonnull(agent0->clk);
ut_asserteq(1, agent0->reset_count);
ut_assertnonnull(agent0->reset);
ut_asserteq(2, agent0->voltd_count);
ut_assertnonnull(agent0->voltd);
ut_assertnonnull(agent1);
ut_assertnonnull(agent1->clk);
ut_asserteq(1, agent1->clk_count);
ut_assertnonnull(scmi_ctx);
agent = scmi_ctx->agent;
ut_assertnonnull(agent);
ut_asserteq(3, agent->clk_count);
ut_assertnonnull(agent->clk);
ut_asserteq(1, agent->reset_count);
ut_assertnonnull(agent->reset);
ut_asserteq(2, agent->voltd_count);
ut_assertnonnull(agent->voltd);
return 0;
}
@ -118,9 +108,8 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
{
struct sandbox_scmi_devices *scmi_devices;
struct sandbox_scmi_service *scmi_ctx;
struct sandbox_scmi_agent *agent0;
struct sandbox_scmi_agent *agent1;
struct udevice *dev = NULL;
struct sandbox_scmi_agent *agent;
struct udevice *dev;
int ret_dev;
int ret;
@ -129,48 +118,50 @@ static int dm_test_scmi_clocks(struct unit_test_state *uts)
return ret;
scmi_devices = sandbox_scmi_devices_ctx(dev);
ut_assertnonnull(scmi_devices);
scmi_ctx = sandbox_scmi_service_ctx();
agent0 = scmi_ctx->agent[0];
agent1 = scmi_ctx->agent[1];
ut_assertnonnull(scmi_ctx);
agent = scmi_ctx->agent;
ut_assertnonnull(agent);
/* Test SCMI clocks rate manipulation */
ut_asserteq(333, agent->clk[0].rate);
ut_asserteq(200, agent->clk[1].rate);
ut_asserteq(1000, agent->clk[2].rate);
ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1]));
ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088);
ut_assert(!ret_dev || ret_dev == 1088);
ut_asserteq(1000, agent0->clk[0].rate);
ut_asserteq(1088, agent0->clk[1].rate);
ut_asserteq(44, agent1->clk[0].rate);
ut_asserteq(1088, agent->clk[0].rate);
ut_asserteq(200, agent->clk[1].rate);
ut_asserteq(1000, agent->clk[2].rate);
ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1]));
ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
/* restore original rate for further tests */
ret_dev = clk_set_rate(&scmi_devices->clk[1], 333);
ut_assert(!ret_dev || ret_dev == 333);
/* Test SCMI clocks gating manipulation */
ut_assert(!agent0->clk[0].enabled);
ut_assert(!agent0->clk[1].enabled);
ut_assert(!agent1->clk[0].enabled);
ut_assert(!agent->clk[0].enabled);
ut_assert(!agent->clk[1].enabled);
ut_assert(!agent->clk[2].enabled);
ut_asserteq(0, clk_enable(&scmi_devices->clk[1]));
ut_asserteq(0, clk_enable(&scmi_devices->clk[2]));
ut_assert(!agent0->clk[0].enabled);
ut_assert(agent0->clk[1].enabled);
ut_assert(agent1->clk[0].enabled);
ut_assert(agent->clk[0].enabled);
ut_assert(!agent->clk[1].enabled);
ut_assert(!agent->clk[2].enabled);
ut_assertok(clk_disable(&scmi_devices->clk[1]));
ut_assertok(clk_disable(&scmi_devices->clk[2]));
ut_assert(!agent0->clk[0].enabled);
ut_assert(!agent0->clk[1].enabled);
ut_assert(!agent1->clk[0].enabled);
ut_assert(!agent->clk[0].enabled);
ut_assert(!agent->clk[1].enabled);
ut_assert(!agent->clk[2].enabled);
return release_sandbox_scmi_test_devices(uts, dev);
}
@ -180,7 +171,7 @@ static int dm_test_scmi_resets(struct unit_test_state *uts)
{
struct sandbox_scmi_devices *scmi_devices;
struct sandbox_scmi_service *scmi_ctx;
struct sandbox_scmi_agent *agent0;
struct sandbox_scmi_agent *agent;
struct udevice *dev = NULL;
int ret;
@ -189,17 +180,20 @@ static int dm_test_scmi_resets(struct unit_test_state *uts)
return ret;
scmi_devices = sandbox_scmi_devices_ctx(dev);
ut_assertnonnull(scmi_devices);
scmi_ctx = sandbox_scmi_service_ctx();
agent0 = scmi_ctx->agent[0];
ut_assertnonnull(scmi_ctx);
agent = scmi_ctx->agent;
ut_assertnonnull(agent);
/* Test SCMI resect controller manipulation */
ut_assert(!agent0->reset[0].asserted)
ut_assert(!agent->reset[0].asserted)
ut_assertok(reset_assert(&scmi_devices->reset[0]));
ut_assert(agent0->reset[0].asserted)
ut_assert(agent->reset[0].asserted)
ut_assertok(reset_deassert(&scmi_devices->reset[0]));
ut_assert(!agent0->reset[0].asserted);
ut_assert(!agent->reset[0].asserted);
return release_sandbox_scmi_test_devices(uts, dev);
}
@ -209,7 +203,7 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts)
{
struct sandbox_scmi_devices *scmi_devices;
struct sandbox_scmi_service *scmi_ctx;
struct sandbox_scmi_agent *agent0;
struct sandbox_scmi_agent *agent;
struct dm_regulator_uclass_plat *uc_pdata;
struct udevice *dev;
struct udevice *regul0_dev;
@ -217,8 +211,11 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts)
ut_assertok(load_sandbox_scmi_test_devices(uts, &dev));
scmi_devices = sandbox_scmi_devices_ctx(dev);
ut_assertnonnull(scmi_devices);
scmi_ctx = sandbox_scmi_service_ctx();
agent0 = scmi_ctx->agent[0];
ut_assertnonnull(scmi_ctx);
agent = scmi_ctx->agent;
ut_assertnonnull(agent);
/* Set/Get an SCMI voltage domain level */
regul0_dev = scmi_devices->regul[0];
@ -228,32 +225,32 @@ static int dm_test_scmi_voltage_domains(struct unit_test_state *uts)
ut_assert(uc_pdata);
ut_assertok(regulator_set_value(regul0_dev, uc_pdata->min_uV));
ut_asserteq(agent0->voltd[0].voltage_uv, uc_pdata->min_uV);
ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->min_uV);
ut_assert(regulator_get_value(regul0_dev) == uc_pdata->min_uV);
ut_assertok(regulator_set_value(regul0_dev, uc_pdata->max_uV));
ut_asserteq(agent0->voltd[0].voltage_uv, uc_pdata->max_uV);
ut_asserteq(agent->voltd[0].voltage_uv, uc_pdata->max_uV);
ut_assert(regulator_get_value(regul0_dev) == uc_pdata->max_uV);
/* Enable/disable SCMI voltage domains */
ut_assertok(regulator_set_enable(scmi_devices->regul[0], false));
ut_assertok(regulator_set_enable(scmi_devices->regul[1], false));
ut_assert(!agent0->voltd[0].enabled);
ut_assert(!agent0->voltd[1].enabled);
ut_assert(!agent->voltd[0].enabled);
ut_assert(!agent->voltd[1].enabled);
ut_assertok(regulator_set_enable(scmi_devices->regul[0], true));
ut_assert(agent0->voltd[0].enabled);
ut_assert(!agent0->voltd[1].enabled);
ut_assert(agent->voltd[0].enabled);
ut_assert(!agent->voltd[1].enabled);
ut_assertok(regulator_set_enable(scmi_devices->regul[1], true));
ut_assert(agent0->voltd[0].enabled);
ut_assert(agent0->voltd[1].enabled);
ut_assert(agent->voltd[0].enabled);
ut_assert(agent->voltd[1].enabled);
ut_assertok(regulator_set_enable(scmi_devices->regul[0], false));
ut_assert(!agent0->voltd[0].enabled);
ut_assert(agent0->voltd[1].enabled);
ut_assert(!agent->voltd[0].enabled);
ut_assert(agent->voltd[1].enabled);
return release_sandbox_scmi_test_devices(uts, dev);
}