summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorVinh Nguyen <[email protected]>2025-11-05 04:42:26 +0100
committerPeng Fan <[email protected]>2025-11-10 20:57:42 +0800
commit0619cb32030b1d78379f3181d3e1103bb86124fb (patch)
tree1db6c99ef95717fe3919e3085868f2b7599e209f /drivers
parenta5a0134570c88cd49a6fc97256764cb7fbb93dff (diff)
firmware: scmi: Add clock v3.2 CONFIG_SET support
SCMI v3.2 introduces a new clock CONFIG_SET message format that can optionally carry also OEM specific configuration values beside the usual clock enable/disable requests. Add support to use such new format when talking to a v3.2 compliant SCMI platform. Support existing enable/disable operations across different clock protocol versions: this patch still does not add protocol operations to support the new OEM specific optional configuration capabilities. No functional change for the SCMI drivers users of the related enable and disable clock operations. [Marek: Remodel after Linux e49e314a2cf7 ("firmware: arm_scmi: Add clock v3.2 CONFIG_SET support") Support both old < 2.1 and new >= 2.1 protocol versions. Update commit message based on Linux one] Signed-off-by: Vinh Nguyen <[email protected]> Signed-off-by: Marek Vasut <[email protected]> Reviewed-by: Alice Guo <[email protected]> Signed-off-by: Peng Fan <[email protected]>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/clk_scmi.c23
-rw-r--r--drivers/firmware/scmi/sandbox-scmi_agent.c4
2 files changed, 20 insertions, 7 deletions
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c
index a7d89f32cd7..54378b4e1ec 100644
--- a/drivers/clk/clk_scmi.c
+++ b/drivers/clk/clk_scmi.c
@@ -8,6 +8,7 @@
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device_compat.h>
+#include <dm/device-internal.h>
#include <scmi_agent.h>
#include <scmi_agent-uclass.h>
#include <scmi_protocols.h>
@@ -134,17 +135,28 @@ 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 = {
+ struct scmi_clock_priv *priv = dev_get_parent_priv(clk->dev);
+ struct scmi_clk_state_in_v1 in_v1 = {
+ .clock_id = clk_get_id(clk),
+ .attributes = enable,
+ };
+ /* Valid only from SCMI clock v2.1 */
+ struct scmi_clk_state_in_v2 in_v2 = {
.clock_id = clk_get_id(clk),
.attributes = enable,
};
struct scmi_clk_state_out out;
- struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
- SCMI_CLOCK_CONFIG_SET,
- in, out);
+ struct scmi_msg msg_v1 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in_v1, out);
+ struct scmi_msg msg_v2 = SCMI_MSG_IN(SCMI_PROTOCOL_ID_CLOCK,
+ SCMI_CLOCK_CONFIG_SET,
+ in_v2, out);
int ret;
- ret = devm_scmi_process_msg(clk->dev, &msg);
+ ret = devm_scmi_process_msg(clk->dev,
+ (priv->version < CLOCK_PROTOCOL_VERSION_2_1) ?
+ &msg_v1 : &msg_v2);
if (ret)
return ret;
@@ -319,6 +331,7 @@ static int scmi_clk_probe(struct udevice *dev)
}
dev_clk_dm(dev, i, &clk_scmi->clk);
+ dev_set_parent_priv(clk_scmi->clk.dev, priv);
if (CLK_HAS_RESTRICTIONS(attributes)) {
u32 perm;
diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c
index 74a87832dcb..5b242a039c2 100644
--- a/drivers/firmware/scmi/sandbox-scmi_agent.c
+++ b/drivers/firmware/scmi/sandbox-scmi_agent.c
@@ -828,7 +828,7 @@ static int sandbox_scmi_clock_rate_get(struct udevice *dev,
static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
{
- struct scmi_clk_state_in *in = NULL;
+ struct scmi_clk_state_in_v1 *in = NULL;
struct scmi_clk_state_out *out = NULL;
struct sandbox_scmi_clk *clk_state = NULL;
@@ -836,7 +836,7 @@ static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
!msg->out_msg || msg->out_msg_sz < sizeof(*out))
return -EINVAL;
- in = (struct scmi_clk_state_in *)msg->in_msg;
+ in = (struct scmi_clk_state_in_v1 *)msg->in_msg;
out = (struct scmi_clk_state_out *)msg->out_msg;
clk_state = get_scmi_clk_state(in->clock_id);