mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
clk: imx: scu: add set parent support
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> [sboyd@kernel.org: Remove le32_to_cpu() on get_parent op] Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
cd67d32727
commit
666aed2d13
2 changed files with 100 additions and 3 deletions
|
@ -65,6 +65,41 @@ struct imx_sc_msg_get_clock_rate {
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* struct imx_sc_msg_req_clock_enable - clock gate protocol
|
||||||
* @hdr: SCU protocol header
|
* @hdr: SCU protocol header
|
||||||
|
@ -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);
|
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 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,
|
static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource,
|
||||||
u8 clk, bool enable, bool autog)
|
u8 clk, bool enable, bool autog)
|
||||||
{
|
{
|
||||||
|
@ -228,11 +306,14 @@ static const struct clk_ops clk_scu_ops = {
|
||||||
.recalc_rate = clk_scu_recalc_rate,
|
.recalc_rate = clk_scu_recalc_rate,
|
||||||
.round_rate = clk_scu_round_rate,
|
.round_rate = clk_scu_round_rate,
|
||||||
.set_rate = clk_scu_set_rate,
|
.set_rate = clk_scu_set_rate,
|
||||||
|
.get_parent = clk_scu_get_parent,
|
||||||
|
.set_parent = clk_scu_set_parent,
|
||||||
.prepare = clk_scu_prepare,
|
.prepare = clk_scu_prepare,
|
||||||
.unprepare = clk_scu_unprepare,
|
.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_init_data init;
|
||||||
struct clk_scu *clk;
|
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.name = name;
|
||||||
init.ops = &clk_scu_ops;
|
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
|
* Note on MX8, the clocks are tightly coupled with power domain
|
||||||
* that once the power domain is off, the clock status may be
|
* that once the power domain is off, the clock status may be
|
||||||
|
|
|
@ -10,7 +10,21 @@
|
||||||
#include <linux/firmware/imx/sci.h>
|
#include <linux/firmware/imx/sci.h>
|
||||||
|
|
||||||
int imx_clk_scu_init(void);
|
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,
|
struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name,
|
||||||
unsigned long flags, void __iomem *reg,
|
unsigned long flags, void __iomem *reg,
|
||||||
|
|
Loading…
Reference in a new issue