diff options
author | Tom Rini <trini@konsulko.com> | 2022-03-03 14:16:14 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-03-03 14:16:14 -0500 |
commit | 09cb77d22e8b87f02718a2e8f8ec7952f7673622 (patch) | |
tree | b4a584688949e49d22e1daac341666c93b720d87 | |
parent | 2dfdba4a5a48de33a3cedc908c183b86b6ff7bd5 (diff) | |
parent | 7c33f78983c344c46d46d857fd1d5e2b5b95ad40 (diff) | |
download | u-boot-09cb77d22e8b87f02718a2e8f8ec7952f7673622.zip u-boot-09cb77d22e8b87f02718a2e8f8ec7952f7673622.tar.gz u-boot-09cb77d22e8b87f02718a2e8f8ec7952f7673622.tar.bz2 |
Merge branch '2022-03-02-scmi-updates' into next
- A small set of scmi updates
-rw-r--r-- | arch/sandbox/dts/test.dts | 37 | ||||
-rw-r--r-- | arch/sandbox/include/asm/scmi_test.h | 13 | ||||
-rw-r--r-- | doc/device-tree-bindings/arm/arm,scmi.txt | 236 | ||||
-rw-r--r-- | drivers/clk/clk_scmi.c | 96 | ||||
-rw-r--r-- | drivers/firmware/scmi/sandbox-scmi_agent.c | 228 | ||||
-rw-r--r-- | drivers/firmware/scmi/sandbox-scmi_devices.c | 4 | ||||
-rw-r--r-- | drivers/firmware/scmi/scmi_agent-uclass.c | 17 | ||||
-rw-r--r-- | drivers/power/regulator/scmi_regulator.c | 10 | ||||
-rw-r--r-- | drivers/reset/reset-scmi.c | 4 | ||||
-rw-r--r-- | include/scmi_agent.h | 2 | ||||
-rw-r--r-- | include/scmi_protocols.h | 43 | ||||
-rw-r--r-- | test/dm/scmi.c | 119 |
12 files changed, 345 insertions, 464 deletions
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 48ca3e1..3d206fd 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -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 = <®ul0_scmi0>; - regul1-supply = <®ul1_scmi0>; + clocks = <&clk_scmi 2>, <&clk_scmi 0>; + resets = <&reset_scmi 3>; + regul0-supply = <®ul0_scmi>; + regul1-supply = <®ul1_scmi>; }; pinctrl { diff --git a/arch/sandbox/include/asm/scmi_test.h b/arch/sandbox/include/asm/scmi_test.h index 2930e68..c72ec1e 100644 --- a/arch/sandbox/include/asm/scmi_test.h +++ b/arch/sandbox/include/asm/scmi_test.h @@ -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 */ diff --git a/doc/device-tree-bindings/arm/arm,scmi.txt b/doc/device-tree-bindings/arm/arm,scmi.txt index 92572ea..0a7886d 100644 --- a/doc/device-tree-bindings/arm/arm,scmi.txt +++ b/doc/device-tree-bindings/arm/arm,scmi.txt @@ -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 diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c index 9a0a6f6..5702268 100644 --- a/drivers/clk/clk_scmi.c +++ b/drivers/clk/clk_scmi.c @@ -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, }; diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c index 4b96820..c555164 100644 --- a/drivers/firmware/scmi/sandbox-scmi_agent.c +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c @@ -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; - - 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; - } + + if (sandbox_scmi_service_ctx()->agent) + return -EINVAL; + + *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; }; diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c index 66a6792..9baeb46 100644 --- a/drivers/firmware/scmi/sandbox-scmi_devices.c +++ b/drivers/firmware/scmi/sandbox-scmi_devices.c @@ -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, }; diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 4f5870b..3819f2f 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -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; } diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c index 3ddeaf4..2966bdc 100644 --- a/drivers/power/regulator/scmi_regulator.c +++ b/drivers/power/regulator/scmi_regulator.c @@ -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); diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c index ca0135a..850cb18 100644 --- a/drivers/reset/reset-scmi.c +++ b/drivers/reset/reset-scmi.c @@ -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; diff --git a/include/scmi_agent.h b/include/scmi_agent.h index 5015c06..18bcd48 100644 --- a/include/scmi_agent.h +++ b/include/scmi_agent.h @@ -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 */ diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h index ef26e72..a220cb2 100644 --- a/include/scmi_protocols.h +++ b/include/scmi_protocols.h @@ -41,21 +41,64 @@ enum scmi_status_code { }; /* + * 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 diff --git a/test/dm/scmi.c b/test/dm/scmi.c index c938e6d..795f207 100644 --- a/test/dm/scmi.c +++ b/test/dm/scmi.c @@ -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); } |