[PATCH v4 2/2] clk: scmi: add compatibility for clock version 3.0 and onwards

Kamlesh Gurudasani
2025-11-04T11:19:55Z

Clock version 3.0 specified in ARM SCMI Platform design document
v3.2, adds extended_config_val parameter in CLOCK_CONFIG_SET and
CLOCK_CONFIG_GET. Add support for that.

Signed-off-by: Kamlesh Gurudasani <kamlesh@ti.com>
---
drivers/clk/clk_scmi.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
include/scmi_protocols.h | 6 ++++++
2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index 83ea7bb4286..6d47cc6cd01 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -131,19 +131,45 @@ static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name,

static int scmi_clk_gate(struct clk *clk, int enable)
{
- struct scmi_clk_state_in in = {
- .clock_id = clk_get_id(clk),
- .attributes = enable,
- };
+ struct scmi_clock_priv *priv;
struct scmi_clk_state_out out;
- struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
- SCMI_CLOCK_CONFIG_SET,
- in, out);
int ret;

- ret = devm_scmi_process_msg(clk->dev, &msg);
- if (ret)
- return ret;
+ if (CONFIG_IS_ENABLED(CLK_CCF)) {
+ /* CCF: version info is in parent device */
+ priv = dev_get_priv(clk->dev->parent);
+ } else {
+ /* Non-CCF: version info is in current device */
+ priv = dev_get_priv(clk->dev);
+ }
+
+ if (priv->version >= CLOCK_PROTOCOL_VERSION_3_0) {
+ struct scmi_clk_state_in_v2 in = {
+ .clock_id = clk->id,
+ .attributes = enable,
+ .extended_config_val = 0,
+ };
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in, out);
+
+ ret = devm_scmi_process_msg(clk->dev, &msg);
+ if (ret)
+ return ret;
+
+ } else {
+ struct scmi_clk_state_in in = {
+ .clock_id = clk->id,
+ .attributes = enable,
+ };
+ struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in, out);
+
+ ret = devm_scmi_process_msg(clk->dev, &msg);
+ if (ret)
+ return ret;
+ }

return scmi_to_linux_errno(out.status);
}
@@ -275,12 +301,12 @@ static int scmi_clk_probe(struct udevice *dev)
if (ret)
return ret;

- if (!CONFIG_IS_ENABLED(CLK_CCF))
- return 0;
-
ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK,
&priv->version);

+ 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;
diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h
index 762a1032c37..a4d1a4c80c8 100644
--- a/include/scmi_protocols.h
+++ b/include/scmi_protocols.h
@@ -807,6 +807,12 @@ struct scmi_clk_state_in {
u32 attributes;
};

+struct scmi_clk_state_in_v2 {
+ u32 clock_id;
+ u32 attributes;
+ u32 extended_config_val;
+};
+
/**
* struct scmi_clk_state_out - Response payload for CLOCK_CONFIG_SET command
* @status: SCMI command status

--
2.34.1