Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45682922 authored by Stefan Agner's avatar Stefan Agner Committed by Shawn Guo
Browse files

clk: imx: clk-gate2: allow custom gate configuration



The 2-bit gates found i.MX and Vybrid SoC support different clock
configuration:

0b00: clk disabled
0b01: clk enabled in RUN mode but disabled in WAIT and STOP mode
0b10: clk enabled in RUN, WAIT and STOP mode (only Vybrid)
0b11: clk enabled in RUN and WAIT mode

For some clocks, we might want to configure different behaviour,
e.g. a memory clock should be on even in STOP mode. Add a new
function imx_clk_gate2_cgr which allow to configure specific
gate values through the cgr_val parameter.

Signed-off-by: default avatarStefan Agner <stefan@agner.ch>
Signed-off-by: default avatarShawn Guo <shawnguo@kernel.org>
parent 0b55257e
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ struct clk_gate2 {
	struct clk_hw hw;
	struct clk_hw hw;
	void __iomem	*reg;
	void __iomem	*reg;
	u8		bit_idx;
	u8		bit_idx;
	u8		cgr_val;
	u8		flags;
	u8		flags;
	spinlock_t	*lock;
	spinlock_t	*lock;
	unsigned int	*share_count;
	unsigned int	*share_count;
@@ -50,7 +51,8 @@ static int clk_gate2_enable(struct clk_hw *hw)
		goto out;
		goto out;


	reg = readl(gate->reg);
	reg = readl(gate->reg);
	reg |= 3 << gate->bit_idx;
	reg &= ~(3 << gate->bit_idx);
	reg |= gate->cgr_val << gate->bit_idx;
	writel(reg, gate->reg);
	writel(reg, gate->reg);


out:
out:
@@ -125,7 +127,7 @@ static struct clk_ops clk_gate2_ops = {


struct clk *clk_register_gate2(struct device *dev, const char *name,
struct clk *clk_register_gate2(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx,
		void __iomem *reg, u8 bit_idx, u8 cgr_val,
		u8 clk_gate2_flags, spinlock_t *lock,
		u8 clk_gate2_flags, spinlock_t *lock,
		unsigned int *share_count)
		unsigned int *share_count)
{
{
@@ -140,6 +142,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
	/* struct clk_gate2 assignments */
	/* struct clk_gate2 assignments */
	gate->reg = reg;
	gate->reg = reg;
	gate->bit_idx = bit_idx;
	gate->bit_idx = bit_idx;
	gate->cgr_val = cgr_val;
	gate->flags = clk_gate2_flags;
	gate->flags = clk_gate2_flags;
	gate->lock = lock;
	gate->lock = lock;
	gate->share_count = share_count;
	gate->share_count = share_count;
+10 −3
Original line number Original line Diff line number Diff line
@@ -41,7 +41,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,


struct clk *clk_register_gate2(struct device *dev, const char *name,
struct clk *clk_register_gate2(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx,
		void __iomem *reg, u8 bit_idx, u8 cgr_val,
		u8 clk_gate_flags, spinlock_t *lock,
		u8 clk_gate_flags, spinlock_t *lock,
		unsigned int *share_count);
		unsigned int *share_count);


@@ -55,7 +55,7 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
		void __iomem *reg, u8 shift)
		void __iomem *reg, u8 shift)
{
{
	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
			shift, 0, &imx_ccm_lock, NULL);
			shift, 0x3, 0, &imx_ccm_lock, NULL);
}
}


static inline struct clk *imx_clk_gate2_shared(const char *name,
static inline struct clk *imx_clk_gate2_shared(const char *name,
@@ -63,7 +63,14 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
		unsigned int *share_count)
		unsigned int *share_count)
{
{
	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
			shift, 0, &imx_ccm_lock, share_count);
			shift, 0x3, 0, &imx_ccm_lock, share_count);
}

static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
		void __iomem *reg, u8 shift, u8 cgr_val)
{
	return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
			shift, cgr_val, 0, &imx_ccm_lock, NULL);
}
}


struct clk *imx_clk_pfd(const char *name, const char *parent_name,
struct clk *imx_clk_pfd(const char *name, const char *parent_name,