Messages in this thread Patch in this message | | | From | "Peng Fan (OSS)" <> | Subject | [RFC] firmware: arm_scmi: support clock denied attributes | Date | Thu, 26 Oct 2023 11:41:25 +0800 |
| |
From: Peng Fan <peng.fan@nxp.com>
This is not in SPEC and is just defined by NXP. This patch is to start the discussion to start include them in SPEC.
Signed-off-by: Peng Fan <peng.fan@nxp.com> --- drivers/clk/clk-scmi.c | 39 +++++++++++++++++++++++++------ drivers/firmware/arm_scmi/clock.c | 9 +++++++ include/linux/scmi_protocol.h | 4 ++++ 3 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index 8cbe24789c24..303f8a8ec8e0 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -75,15 +75,13 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + u64 rate1 = 0; - return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate); -} - -static int scmi_clk_set_parent(struct clk_hw *hw, u8 parent_index) -{ - struct scmi_clk *clk = to_scmi_clk(hw); + if (info->flags & SCMI_CLOCK_SET_RATE_DENIED) + return -EACCES; - return scmi_proto_clk_ops->parent_set(clk->ph, clk->id, parent_index); + return scmi_proto_clk_ops->rate_set(clk->ph, clk->id, rate); } static u8 scmi_clk_get_parent(struct clk_hw *hw) @@ -107,6 +105,17 @@ static u8 scmi_clk_get_parent(struct clk_hw *hw) return p_idx; } +static int scmi_clk_set_parent(struct clk_hw *hw, u8 parent_index) +{ + struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + + if (info->flags & SCMI_CLOCK_SET_ENABLE_DENIED) + return -EACCES; + + return scmi_proto_clk_ops->parent_set(clk->ph, clk->id, parent_index); +} + static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { /* @@ -119,6 +128,10 @@ static int scmi_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *r static int scmi_clk_enable(struct clk_hw *hw) { struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + + if (info->flags & SCMI_CLOCK_SET_ENABLE_DENIED) + return 0; return scmi_proto_clk_ops->enable(clk->ph, clk->id, NOT_ATOMIC); } @@ -126,6 +139,10 @@ static int scmi_clk_enable(struct clk_hw *hw) static void scmi_clk_disable(struct clk_hw *hw) { struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + + if (info->flags & SCMI_CLOCK_SET_ENABLE_DENIED) + return; scmi_proto_clk_ops->disable(clk->ph, clk->id, NOT_ATOMIC); } @@ -133,6 +150,10 @@ static void scmi_clk_disable(struct clk_hw *hw) static int scmi_clk_atomic_enable(struct clk_hw *hw) { struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + + if (info->flags & SCMI_CLOCK_SET_ENABLE_DENIED) + return 0; return scmi_proto_clk_ops->enable(clk->ph, clk->id, ATOMIC); } @@ -140,6 +161,10 @@ static int scmi_clk_atomic_enable(struct clk_hw *hw) static void scmi_clk_atomic_disable(struct clk_hw *hw) { struct scmi_clk *clk = to_scmi_clk(hw); + const struct scmi_clock_info *info = clk->info; + + if (info->flags & SCMI_CLOCK_SET_ENABLE_DENIED) + return; scmi_proto_clk_ops->disable(clk->ph, clk->id, ATOMIC); } diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c index 42b81c181d68..1a62e3b82d34 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -46,6 +46,9 @@ struct scmi_msg_resp_clock_attributes { #define SUPPORTS_RATE_CHANGE_REQUESTED_NOTIF(x) ((x) & BIT(30)) #define SUPPORTS_EXTENDED_NAMES(x) ((x) & BIT(29)) #define SUPPORTS_PARENT_CLOCK(x) ((x) & BIT(28)) +#define SETS_ENABLE_DENIED(x) ((x) & BIT(15)) +#define SETS_RATE_DENIED(x) ((x) & BIT(14)) +#define SETS_PARENT_DENIED(x) ((x) & BIT(13)) u8 name[SCMI_SHORT_NAME_MAX_SIZE]; __le32 clock_enable_latency; }; @@ -327,6 +330,12 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph, clk->rate_change_requested_notifications = true; if (SUPPORTS_PARENT_CLOCK(attributes)) scmi_clock_possible_parents(ph, clk_id, clk); + if (SETS_PARENT_DENIED(attributes)) + clk->flags |= SCMI_CLOCK_SET_PARENT_DENIED; + if (SETS_RATE_DENIED(attributes)) + clk->flags |= SCMI_CLOCK_SET_RATE_DENIED; + if (SETS_ENABLE_DENIED(attributes)) + clk->flags |= SCMI_CLOCK_SET_ENABLE_DENIED; } return ret; diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index f2f05fb42d28..71911dcd8117 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -41,12 +41,16 @@ struct scmi_revision_info { char sub_vendor_id[SCMI_SHORT_NAME_MAX_SIZE]; }; +#define SCMI_CLOCK_SET_PARENT_DENIED BIT(13) +#define SCMI_CLOCK_SET_RATE_DENIED BIT(14) +#define SCMI_CLOCK_SET_ENABLE_DENIED BIT(15) struct scmi_clock_info { char name[SCMI_MAX_STR_SIZE]; unsigned int enable_latency; bool rate_discrete; bool rate_changed_notifications; bool rate_change_requested_notifications; + unsigned int flags; union { struct { int num_rates; -- 2.37.1
| |