Hi all,
this small series introduces support for the new Clock CONFIG features
added by SCMI v3.2 specification [1].
It does NOT add support, still, for the SCMI v3.2 Clock reparenting
features added in v3.2 too.
After a small refactoring in [1/6], support for the new CONFIG_SET message
format is added in [2/6]: this is just internal rework to support new and
legacy (pre-v3.2) message formats.
Patch [3/6] adds support for the new v3.2 CONFIG_GET command and adds a new
related Clock operation .state_get() to retrieve the enabled state of one
clock when talking to a v3.2 compliant server.
Patch [4/6] extend .state_get() support to legacy SCMI platforms implementing
pre-v3.2 SCMI stacks: in such a scenario we can use the old CLOCK_ATTRIBUTES
command to retrieve the clock state.
Patch [5/6] finally wires up this new .state_get() clock operation to the
Linux Clock framework .is_enabled() callback, AS-LONG-AS the underlying
configured SCMI stack supports atomic operations. (since .is_enabled() is
required not to sleep)
This *should* ease unused clocks management by the Linux Clock framework.
Last but not least, patch [6/6] exposes a couple more SCMI Clock operations
in order to be able to set/get OEM specific clock configuration values as
described in SCMI v3.2 specification.
Tested on JUNO and on an SCMI emulation setup.
Based on v6.5-rc5.
Any feedback welcome,
Thanks,
Cristian
[1]: https://developer.arm.com/documentation/den0056/e
----
v1 --> v2
- more descriptive commit message for 1/6
- add and use more descriptive defines to name boolean arguments in clk-scmi.c
- dropped RFC from 6/6
Cristian Marussi (6):
firmware: arm_scmi: Simplify enable/disable Clock operations
firmware: arm_scmi: Add Clock v3.2 CONFIG_SET support
firmware: arm_scmi: Add v3.2 Clock CONFIG_GET support
firmware: arm_scmi: Add Clock .state_get support to pre-v3.2
clk: scmi: Add support for .is_enabled clk_ops
firmware: arm_scmi: Add Clock OEM config clock operations
drivers/clk/clk-scmi.c | 34 ++++-
drivers/firmware/arm_scmi/clock.c | 220 +++++++++++++++++++++++++++---
include/linux/scmi_protocol.h | 19 ++-
3 files changed, 243 insertions(+), 30 deletions(-)
--
2.42.0
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.
Refactor internal helpers and 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: Cristian Marussi <[email protected]>
---
drivers/firmware/arm_scmi/clock.c | 88 ++++++++++++++++++++++++++++---
1 file changed, 80 insertions(+), 8 deletions(-)
diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 1e8fae4b6570..4f636c1332f2 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -23,6 +23,13 @@ enum scmi_clock_protocol_cmd {
CLOCK_RATE_CHANGE_REQUESTED_NOTIFY = 0xA,
};
+enum clk_state {
+ CLK_STATE_DISABLE,
+ CLK_STATE_ENABLE,
+ CLK_STATE_RESERVED,
+ CLK_STATE_UNCHANGED,
+};
+
struct scmi_msg_resp_clock_protocol_attributes {
__le16 num_clocks;
u8 max_async_req;
@@ -31,7 +38,6 @@ struct scmi_msg_resp_clock_protocol_attributes {
struct scmi_msg_resp_clock_attributes {
__le32 attributes;
-#define CLOCK_ENABLE BIT(0)
#define SUPPORTS_RATE_CHANGED_NOTIF(x) ((x) & BIT(31))
#define SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(x) ((x) & BIT(30))
#define SUPPORTS_EXTENDED_NAMES(x) ((x) & BIT(29))
@@ -39,9 +45,18 @@ struct scmi_msg_resp_clock_attributes {
__le32 clock_enable_latency;
};
-struct scmi_clock_set_config {
+struct scmi_msg_clock_config_set_v2 {
+ __le32 id;
+ __le32 attributes;
+};
+
+struct scmi_msg_clock_config_set_v21 {
__le32 id;
__le32 attributes;
+#define NULL_OEM_TYPE 0
+#define REGMASK_OEM_TYPE_SET GENMASK(23, 16)
+#define REGMASK_CLK_STATE GENMASK(1, 0)
+ __le32 oem_config_val;
};
struct scmi_msg_clock_describe_rates {
@@ -100,6 +115,9 @@ struct clock_info {
int max_async_req;
atomic_t cur_async_req;
struct scmi_clock_info *clk;
+ int (*clock_config_set)(const struct scmi_protocol_handle *ph,
+ u32 clk_id, enum clk_state state,
+ u8 oem_type, u32 oem_val, bool atomic);
};
static enum scmi_clock_protocol_cmd evt_2_cmd[] = {
@@ -394,12 +412,47 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
}
static int
-scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
- u32 config, bool atomic)
+scmi_clock_config_set_v2(const struct scmi_protocol_handle *ph, u32 clk_id,
+ enum clk_state state, u8 __unused0, u32 __unused1,
+ bool atomic)
+{
+ int ret;
+ struct scmi_xfer *t;
+ struct scmi_msg_clock_config_set_v2 *cfg;
+
+ if (state >= CLK_STATE_RESERVED)
+ return -EINVAL;
+
+ ret = ph->xops->xfer_get_init(ph, CLOCK_CONFIG_SET,
+ sizeof(*cfg), 0, &t);
+ if (ret)
+ return ret;
+
+ t->hdr.poll_completion = atomic;
+
+ cfg = t->tx.buf;
+ cfg->id = cpu_to_le32(clk_id);
+ cfg->attributes = cpu_to_le32(state);
+
+ ret = ph->xops->do_xfer(ph, t);
+
+ ph->xops->xfer_put(ph, t);
+ return ret;
+}
+
+static int
+scmi_clock_config_set_v21(const struct scmi_protocol_handle *ph, u32 clk_id,
+ enum clk_state state, u8 oem_type, u32 oem_val,
+ bool atomic)
{
int ret;
+ u32 attrs;
struct scmi_xfer *t;
- struct scmi_clock_set_config *cfg;
+ struct scmi_msg_clock_config_set_v21 *cfg;
+
+ if (state == CLK_STATE_RESERVED ||
+ (!oem_type && state == CLK_STATE_UNCHANGED))
+ return -EINVAL;
ret = ph->xops->xfer_get_init(ph, CLOCK_CONFIG_SET,
sizeof(*cfg), 0, &t);
@@ -408,9 +461,16 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
t->hdr.poll_completion = atomic;
+ attrs = FIELD_PREP(REGMASK_OEM_TYPE_SET, oem_type) |
+ FIELD_PREP(REGMASK_CLK_STATE, state);
+
cfg = t->tx.buf;
cfg->id = cpu_to_le32(clk_id);
- cfg->attributes = cpu_to_le32(config);
+ cfg->attributes = cpu_to_le32(attrs);
+ /* Clear in any case */
+ cfg->oem_config_val = cpu_to_le32(0);
+ if (oem_type)
+ cfg->oem_config_val = cpu_to_le32(oem_val);
ret = ph->xops->do_xfer(ph, t);
@@ -421,13 +481,19 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id,
bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, atomic);
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_set(ph, clk_id, CLK_STATE_ENABLE,
+ NULL_OEM_TYPE, 0, atomic);
}
static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id,
bool atomic)
{
- return scmi_clock_config_set(ph, clk_id, 0, atomic);
+ struct clock_info *ci = ph->get_priv(ph);
+
+ return ci->clock_config_set(ph, clk_id, CLK_STATE_DISABLE,
+ NULL_OEM_TYPE, 0, atomic);
}
static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -592,6 +658,12 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
scmi_clock_describe_rates_get(ph, clkid, clk);
}
+ if (PROTOCOL_REV_MAJOR(version) >= 0x2 &&
+ PROTOCOL_REV_MINOR(version) >= 0x1)
+ cinfo->clock_config_set = scmi_clock_config_set_v21;
+ else
+ cinfo->clock_config_set = scmi_clock_config_set_v2;
+
cinfo->version = version;
return ph->set_priv(ph, cinfo);
}
--
2.42.0
On Sat, 26 Aug 2023 13:53:02 +0100, Cristian Marussi wrote:
> this small series introduces support for the new Clock CONFIG features
> added by SCMI v3.2 specification [1].
>
> It does NOT add support, still, for the SCMI v3.2 Clock reparenting
> features added in v3.2 too.
>
> After a small refactoring in [1/6], support for the new CONFIG_SET message
> format is added in [2/6]: this is just internal rework to support new and
> legacy (pre-v3.2) message formats.
>
> [...]
Applied to sudeep.holla/linux (for-next/scmi/updates), thanks!
[1/6] firmware: arm_scmi: Simplify enable/disable Clock operations
https://git.kernel.org/sudeep.holla/c/03a95cf233b5
[2/6] firmware: arm_scmi: Add Clock v3.2 CONFIG_SET support
https://git.kernel.org/sudeep.holla/c/e49e314a2cf7
[3/6] firmware: arm_scmi: Add v3.2 Clock CONFIG_GET support
https://git.kernel.org/sudeep.holla/c/34592bf0a5cb
[4/6] firmware: arm_scmi: Add Clock .state_get support to pre-v3.2
https://git.kernel.org/sudeep.holla/c/5b8a8ca37e49
[5/6] clk: scmi: Add support for .is_enabled clk_ops
https://git.kernel.org/sudeep.holla/c/1b39ff5140c9
[6/6] firmware: arm_scmi: Add Clock OEM config clock operations
https://git.kernel.org/sudeep.holla/c/141b4fa03625
--
Regards,
Sudeep