diff options
| author | Valentin Caron <[email protected]> | 2025-05-27 15:27:43 +0200 |
|---|---|---|
| committer | Patrice Chotard <[email protected]> | 2025-06-11 09:42:55 +0200 |
| commit | ae7e0330ce22d580990cf40d648c809b5093b252 (patch) | |
| tree | e97169e0f11c74b61316b5d37f91269a8387611e /drivers | |
| parent | 59d00e20fced23e6463aa09db889dd548baee677 (diff) | |
clk: scmi: add compatibility with clock protocol 2.0
Since clock protocol 2.0, SCMI specification add an option field
"clock_enable_delay" to CLOCK_ATTRIBUTES command.
scmi_read_resp_from_smt() will return an error ("Buffer too small") as
the message length coming from the SCMI server is not the same as expected.
So implement a condition to SCMI clock protocol version to change the
length of the expected message.
Signed-off-by: Valentin Caron <[email protected]>
Signed-off-by: Patrice Chotard <[email protected]>
Cc: Lukasz Majewski <[email protected]>
Cc: Sean Anderson <[email protected]>
Reviewed-by: Patrick Delaunay <[email protected]>
Reviewed-by: Patrice Chotard <[email protected]>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/clk/clk_scmi.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/clk/clk_scmi.c b/drivers/clk/clk_scmi.c index af69850cdd8..e323a948780 100644 --- a/drivers/clk/clk_scmi.c +++ b/drivers/clk/clk_scmi.c @@ -84,26 +84,47 @@ static int scmi_clk_get_num_clock(struct udevice *dev, size_t *num_clocks) static int scmi_clk_get_attibute(struct udevice *dev, int clkid, char **name, u32 *attr) { + struct scmi_clock_priv *priv = dev_get_priv(dev); 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; + if (priv->version >= 0x20000) { + struct scmi_clk_attribute_out_v2 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), + }; + + ret = devm_scmi_process_msg(dev, &msg); + if (ret) + return ret; - *name = strdup(out.clock_name); - *attr = out.attributes; + *name = strdup(out.clock_name); + *attr = out.attributes; + } else { + 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), + }; + + ret = devm_scmi_process_msg(dev, &msg); + if (ret) + return ret; + + *name = strdup(out.clock_name); + *attr = out.attributes; + } return 0; } @@ -257,6 +278,9 @@ static int scmi_clk_probe(struct udevice *dev) if (!CONFIG_IS_ENABLED(CLK_CCF)) return 0; + ret = scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_CLOCK, + &priv->version); + /* register CCF children: CLK UCLASS, no probed again */ if (device_get_uclass_id(dev->parent) == UCLASS_CLK) return 0; |
