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 <[email protected]>
---
 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

Reply via email to