> -----邮件原件----- > 发件人: U-Boot <[email protected]> 代表 Marek Vasut > 发送时间: 2025年11月5日 11:42 > 收件人: [email protected] > 抄送: Vinh Nguyen <[email protected]>; Marek Vasut > <[email protected]>; Alice Guo <[email protected]>; > Cristian Marussi <[email protected]>; Patrice Chotard > <[email protected]>; Patrick Delaunay > <[email protected]>; Peng Fan <[email protected]>; Sean > Anderson <[email protected]>; Tom Rini <[email protected]>; Valentin > Caron <[email protected]>; Ye Li <[email protected]> > 主题: [PATCH v4] firmware: scmi: Add clock v3.2 CONFIG_SET support > > From: Vinh Nguyen <[email protected]> > > 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. > > Signed-off-by: Vinh Nguyen <[email protected]> > Signed-off-by: Marek Vasut <[email protected]> > [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] > --- > Cc: Alice Guo <[email protected]> > Cc: Cristian Marussi <[email protected]> > Cc: Patrice Chotard <[email protected]> > Cc: Patrick Delaunay <[email protected]> > Cc: Peng Fan <[email protected]> > Cc: Sean Anderson <[email protected]> > Cc: Tom Rini <[email protected]> > Cc: Valentin Caron <[email protected]> > Cc: Vinh Nguyen <[email protected]> > Cc: Ye Li <[email protected]> > Cc: [email protected] > --- > V2: Fix up iMX95 and sandbox after rework > V3: Cache pointer to top-level SCMI clock device in each struct clk_scmi > and use it to extract struct scmi_clock_priv private data which > contain protocol version. This is necessary, because clk_scmi .dev > may not necessarily point to direct subdevice of the top level SCMI > clock device. > V4: Use parent_priv instead to avoid growing memory usage (Alice) > --- > arch/arm/mach-imx/imx9/scmi/clock_scmi.c | 2 +- > drivers/clk/clk_scmi.c | 23 +++++++++++++++++----- > drivers/firmware/scmi/sandbox-scmi_agent.c | 4 ++-- > include/scmi_protocols.h | 17 ++++++++++++++-- > 4 files changed, 36 insertions(+), 10 deletions(-) > > diff --git a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c > b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c > index b6be20ec674..9030dbf600d 100644 > --- a/arch/arm/mach-imx/imx9/scmi/clock_scmi.c > +++ b/arch/arm/mach-imx/imx9/scmi/clock_scmi.c > @@ -10,7 +10,7 @@ > > int imx_clk_scmi_enable(u32 clock_id, bool enable) { > - struct scmi_clk_state_in in = { > + struct scmi_clk_state_in_v1 in = { > .clock_id = clock_id, > .attributes = !!enable, > }; > 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); diff --git > a/include/scmi_protocols.h b/include/scmi_protocols.h index > bcd8e671149..ecab021b472 100644 > --- a/include/scmi_protocols.h > +++ b/include/scmi_protocols.h > @@ -733,6 +733,7 @@ int scmi_pwd_name_get(struct udevice *dev, u32 > domain_id, u8 **name); > /* > * SCMI Clock Protocol > */ > +#define CLOCK_PROTOCOL_VERSION_2_1 0x20001 > #define CLOCK_PROTOCOL_VERSION_3_0 0x30000 > > enum scmi_clock_message_id { > @@ -800,15 +801,27 @@ struct scmi_clk_attribute_out_v2 { }; > > /** > - * struct scmi_clk_state_in - Message payload for CLOCK_CONFIG_SET > command > + * struct scmi_clk_state_in_v1 - Message payload for CLOCK_CONFIG_SET > + command for protocol < 2.1 > * @clock_id: SCMI clock ID > * @attributes: Attributes of the targets clock state > */ > -struct scmi_clk_state_in { > +struct scmi_clk_state_in_v1 { > u32 clock_id; > u32 attributes; > }; > > +/** > + * struct scmi_clk_state_in_v2 - Message payload for CLOCK_CONFIG_SET > command for protocol >= 2.1 > + * @clock_id: SCMI clock ID > + * @attributes: Attributes of the targets clock state > + * @extended_config_val: Extended and OEM specific configuration */ > +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.51.0
Reviewed-by: Alice Guo <[email protected]>

