Message ID | 1548855205-12249-1-git-send-email-aisheng.dong@nxp.com (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
Series | [1/1] clk: imx: scu: add set parent support | expand |
Ping > From: Aisheng Dong > Sent: Wednesday, January 30, 2019 9:39 PM > > Add clk scu set parents support. > > Cc: Stephen Boyd <sboyd@kernel.org> > Cc: Shawn Guo <shawnguo@kernel.org> > Cc: Sascha Hauer <kernel@pengutronix.de> > Cc: Fabio Estevam <fabio.estevam@nxp.com> > Cc: Michael Turquette <mturquette@baylibre.com> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> > --- > drivers/clk/imx/clk-scu.c | 87 > +++++++++++++++++++++++++++++++++++++++++++++-- > drivers/clk/imx/clk-scu.h | 16 ++++++++- > 2 files changed, 100 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index > 7ccf7ed..3c13c41 100644 > --- a/drivers/clk/imx/clk-scu.c > +++ b/drivers/clk/imx/clk-scu.c > @@ -66,6 +66,41 @@ struct imx_sc_msg_get_clock_rate { }; > > /* > + * struct imx_sc_msg_get_clock_parent - clock get parent protocol > + * @hdr: SCU protocol header > + * @req: get parent request protocol > + * @resp: get parent response protocol > + * > + * This structure describes the SCU protocol of clock get parent */ > +struct imx_sc_msg_get_clock_parent { > + struct imx_sc_rpc_msg hdr; > + union { > + struct req_get_clock_parent { > + __le16 resource; > + u8 clk; > + } __packed req; > + struct resp_get_clock_parent { > + u8 parent; > + } resp; > + } data; > +}; > + > +/* > + * struct imx_sc_msg_set_clock_parent - clock set parent protocol > + * @hdr: SCU protocol header > + * @req: set parent request protocol > + * > + * This structure describes the SCU protocol of clock set parent */ > +struct imx_sc_msg_set_clock_parent { > + struct imx_sc_rpc_msg hdr; > + __le16 resource; > + u8 clk; > + u8 parent; > +} __packed; > + > +/* > * struct imx_sc_msg_req_clock_enable - clock gate protocol > * @hdr: SCU protocol header > * @resource: clock resource to gate > @@ -173,6 +208,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, > unsigned long rate, > return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); } > > +static u8 clk_scu_get_parent(struct clk_hw *hw) { > + struct clk_scu *clk = to_clk_scu(hw); > + struct imx_sc_msg_get_clock_parent msg; > + struct imx_sc_rpc_msg *hdr = &msg.hdr; > + int ret; > + > + hdr->ver = IMX_SC_RPC_VERSION; > + hdr->svc = IMX_SC_RPC_SVC_PM; > + hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT; > + hdr->size = 2; > + > + msg.data.req.resource = cpu_to_le16(clk->rsrc_id); > + msg.data.req.clk = clk->clk_type; > + > + ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); > + if (ret) { > + pr_err("%s: failed to get clock parent %d\n", > + clk_hw_get_name(hw), ret); > + return 0; > + } > + > + return le32_to_cpu(msg.data.resp.parent); > +} > + > +static int clk_scu_set_parent(struct clk_hw *hw, u8 index) { > + struct clk_scu *clk = to_clk_scu(hw); > + struct imx_sc_msg_set_clock_parent msg; > + struct imx_sc_rpc_msg *hdr = &msg.hdr; > + > + hdr->ver = IMX_SC_RPC_VERSION; > + hdr->svc = IMX_SC_RPC_SVC_PM; > + hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_PARENT; > + hdr->size = 2; > + > + msg.resource = cpu_to_le16(clk->rsrc_id); > + msg.clk = clk->clk_type; > + msg.parent = index; > + > + return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); } > + > static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, > u8 clk, bool enable, bool autog) { @@ -228,11 +306,14 > @@ static const struct clk_ops clk_scu_ops = { > .recalc_rate = clk_scu_recalc_rate, > .round_rate = clk_scu_round_rate, > .set_rate = clk_scu_set_rate, > + .get_parent = clk_scu_get_parent, > + .set_parent = clk_scu_set_parent, > .prepare = clk_scu_prepare, > .unprepare = clk_scu_unprepare, > }; > > -struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) > +struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, > + int num_parents, u32 rsrc_id, u8 clk_type) > { > struct clk_init_data init; > struct clk_scu *clk; > @@ -248,7 +329,9 @@ struct clk_hw *imx_clk_scu(const char *name, u32 > rsrc_id, u8 clk_type) > > init.name = name; > init.ops = &clk_scu_ops; > - init.num_parents = 0; > + init.parent_names = parents; > + init.num_parents = num_parents; > + > /* > * Note on MX8, the clocks are tightly coupled with power domain > * that once the power domain is off, the clock status may be diff --git > a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h index 52c1746..2bcfaf0 > 100644 > --- a/drivers/clk/imx/clk-scu.h > +++ b/drivers/clk/imx/clk-scu.h > @@ -10,7 +10,21 @@ > #include <linux/firmware/imx/sci.h> > > int imx_clk_scu_init(void); > -struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type); > + > +struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, > + int num_parents, u32 rsrc_id, u8 clk_type); > + > +static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, > + u8 clk_type) > +{ > + return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type); } > + > +static inline struct clk_hw *imx_clk_scu2(const char *name, const char * > const *parents, > + int num_parents, u32 rsrc_id, u8 clk_type) { > + return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type); } > > struct clk_hw *imx_clk_lpcg_scu(const char *name, const char > *parent_name, > unsigned long flags, void __iomem *reg, > -- > 2.7.4
Quoting Aisheng Dong (2019-01-30 05:39:15) > Add clk scu set parents support. > > Cc: Stephen Boyd <sboyd@kernel.org> > Cc: Shawn Guo <shawnguo@kernel.org> > Cc: Sascha Hauer <kernel@pengutronix.de> > Cc: Fabio Estevam <fabio.estevam@nxp.com> > Cc: Michael Turquette <mturquette@baylibre.com> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> Applied to clk-next + below > @@ -173,6 +208,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate, > return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); > } > > +static u8 clk_scu_get_parent(struct clk_hw *hw) > +{ > + struct clk_scu *clk = to_clk_scu(hw); > + struct imx_sc_msg_get_clock_parent msg; > + struct imx_sc_rpc_msg *hdr = &msg.hdr; > + int ret; > + > + hdr->ver = IMX_SC_RPC_VERSION; > + hdr->svc = IMX_SC_RPC_SVC_PM; > + hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT; > + hdr->size = 2; > + > + msg.data.req.resource = cpu_to_le16(clk->rsrc_id); > + msg.data.req.clk = clk->clk_type; > + > + ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); > + if (ret) { > + pr_err("%s: failed to get clock parent %d\n", > + clk_hw_get_name(hw), ret); > + return 0; > + } > + > + return le32_to_cpu(msg.data.resp.parent); Sparse complains about this line because it's a u8 not an __le32 that's being converted. I removed the le32_to_cpu() to fix this.
diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 7ccf7ed..3c13c41 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -66,6 +66,41 @@ struct imx_sc_msg_get_clock_rate { }; /* + * struct imx_sc_msg_get_clock_parent - clock get parent protocol + * @hdr: SCU protocol header + * @req: get parent request protocol + * @resp: get parent response protocol + * + * This structure describes the SCU protocol of clock get parent + */ +struct imx_sc_msg_get_clock_parent { + struct imx_sc_rpc_msg hdr; + union { + struct req_get_clock_parent { + __le16 resource; + u8 clk; + } __packed req; + struct resp_get_clock_parent { + u8 parent; + } resp; + } data; +}; + +/* + * struct imx_sc_msg_set_clock_parent - clock set parent protocol + * @hdr: SCU protocol header + * @req: set parent request protocol + * + * This structure describes the SCU protocol of clock set parent + */ +struct imx_sc_msg_set_clock_parent { + struct imx_sc_rpc_msg hdr; + __le16 resource; + u8 clk; + u8 parent; +} __packed; + +/* * struct imx_sc_msg_req_clock_enable - clock gate protocol * @hdr: SCU protocol header * @resource: clock resource to gate @@ -173,6 +208,49 @@ static int clk_scu_set_rate(struct clk_hw *hw, unsigned long rate, return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); } +static u8 clk_scu_get_parent(struct clk_hw *hw) +{ + struct clk_scu *clk = to_clk_scu(hw); + struct imx_sc_msg_get_clock_parent msg; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + int ret; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_PM; + hdr->func = IMX_SC_PM_FUNC_GET_CLOCK_PARENT; + hdr->size = 2; + + msg.data.req.resource = cpu_to_le16(clk->rsrc_id); + msg.data.req.clk = clk->clk_type; + + ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); + if (ret) { + pr_err("%s: failed to get clock parent %d\n", + clk_hw_get_name(hw), ret); + return 0; + } + + return le32_to_cpu(msg.data.resp.parent); +} + +static int clk_scu_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_scu *clk = to_clk_scu(hw); + struct imx_sc_msg_set_clock_parent msg; + struct imx_sc_rpc_msg *hdr = &msg.hdr; + + hdr->ver = IMX_SC_RPC_VERSION; + hdr->svc = IMX_SC_RPC_SVC_PM; + hdr->func = IMX_SC_PM_FUNC_SET_CLOCK_PARENT; + hdr->size = 2; + + msg.resource = cpu_to_le16(clk->rsrc_id); + msg.clk = clk->clk_type; + msg.parent = index; + + return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); +} + static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, u8 clk, bool enable, bool autog) { @@ -228,11 +306,14 @@ static const struct clk_ops clk_scu_ops = { .recalc_rate = clk_scu_recalc_rate, .round_rate = clk_scu_round_rate, .set_rate = clk_scu_set_rate, + .get_parent = clk_scu_get_parent, + .set_parent = clk_scu_set_parent, .prepare = clk_scu_prepare, .unprepare = clk_scu_unprepare, }; -struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) +struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, + int num_parents, u32 rsrc_id, u8 clk_type) { struct clk_init_data init; struct clk_scu *clk; @@ -248,7 +329,9 @@ struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type) init.name = name; init.ops = &clk_scu_ops; - init.num_parents = 0; + init.parent_names = parents; + init.num_parents = num_parents; + /* * Note on MX8, the clocks are tightly coupled with power domain * that once the power domain is off, the clock status may be diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h index 52c1746..2bcfaf0 100644 --- a/drivers/clk/imx/clk-scu.h +++ b/drivers/clk/imx/clk-scu.h @@ -10,7 +10,21 @@ #include <linux/firmware/imx/sci.h> int imx_clk_scu_init(void); -struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, u8 clk_type); + +struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, + int num_parents, u32 rsrc_id, u8 clk_type); + +static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, + u8 clk_type) +{ + return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type); +} + +static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents, + int num_parents, u32 rsrc_id, u8 clk_type) +{ + return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type); +} struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, unsigned long flags, void __iomem *reg,
Add clk scu set parents support. Cc: Stephen Boyd <sboyd@kernel.org> Cc: Shawn Guo <shawnguo@kernel.org> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Fabio Estevam <fabio.estevam@nxp.com> Cc: Michael Turquette <mturquette@baylibre.com> Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com> --- drivers/clk/imx/clk-scu.c | 87 +++++++++++++++++++++++++++++++++++++++++++++-- drivers/clk/imx/clk-scu.h | 16 ++++++++- 2 files changed, 100 insertions(+), 3 deletions(-)