Skip to content

Commit

Permalink
clk: imx: gate2: Add cgr_mask for more flexible number of control bits
Browse files Browse the repository at this point in the history
On some i.MX8 platforms, there are HW gates that share the same bit.
So in order to make this clock type more usable, use a mask to specify
how many bits belong to those HW gates.

Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
  • Loading branch information
abelvesa authored and Shawn Guo committed Nov 2, 2020
1 parent 03681d0 commit bcd418a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
16 changes: 10 additions & 6 deletions drivers/clk/imx/clk-gate2.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct clk_gate2 {
void __iomem *reg;
u8 bit_idx;
u8 cgr_val;
u8 cgr_mask;
u8 flags;
spinlock_t *lock;
unsigned int *share_count;
Expand All @@ -43,9 +44,9 @@ static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
u32 reg;

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

Expand Down Expand Up @@ -86,11 +87,12 @@ static void clk_gate2_disable(struct clk_hw *hw)
spin_unlock_irqrestore(gate->lock, flags);
}

static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx, u8 cgr_val)
static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx,
u8 cgr_val, u8 cgr_mask)
{
u32 val = readl(reg);

if (((val >> bit_idx) & 3) == cgr_val)
if (((val >> bit_idx) & cgr_mask) == cgr_val)
return 1;

return 0;
Expand All @@ -100,7 +102,8 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
{
struct clk_gate2 *gate = to_clk_gate2(hw);

return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx, gate->cgr_val);
return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
gate->cgr_val, gate->cgr_mask);
}

static void clk_gate2_disable_unused(struct clk_hw *hw)
Expand All @@ -125,7 +128,7 @@ static const struct clk_ops clk_gate2_ops = {

struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx, u8 cgr_val,
void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
u8 clk_gate2_flags, spinlock_t *lock,
unsigned int *share_count)
{
Expand All @@ -142,6 +145,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
gate->reg = reg;
gate->bit_idx = bit_idx;
gate->cgr_val = cgr_val;
gate->cgr_mask = cgr_mask;
gate->flags = clk_gate2_flags;
gate->lock = lock;
gate->share_count = share_count;
Expand Down
24 changes: 12 additions & 12 deletions drivers/clk/imx/clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll;
to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))

#define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
cgr_val, clk_gate_flags, lock, share_count) \
cgr_val, cgr_mask, clk_gate_flags, lock, share_count) \
to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
cgr_val, clk_gate_flags, lock, share_count))
cgr_val, cgr_mask, clk_gate_flags, lock, share_count))

#define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
Expand Down Expand Up @@ -196,7 +196,7 @@ struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,

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

Expand Down Expand Up @@ -349,30 +349,30 @@ static inline struct clk_hw *imx_clk_hw_gate2(const char *name, const char *pare
void __iomem *reg, u8 shift)
{
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
shift, 0x3, 0, &imx_ccm_lock, NULL);
shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
}

static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent,
void __iomem *reg, u8 shift, unsigned long flags)
{
return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
shift, 0x3, 0, &imx_ccm_lock, NULL);
shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
}

static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name,
const char *parent, void __iomem *reg, u8 shift,
unsigned int *share_count)
{
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
shift, 0x3, 0, &imx_ccm_lock, share_count);
shift, 0x3, 0x3, 0, &imx_ccm_lock, share_count);
}

static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name,
const char *parent, void __iomem *reg, u8 shift,
unsigned int *share_count)
{
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0x3, 0,
&imx_ccm_lock, share_count);
}

Expand All @@ -382,15 +382,15 @@ static inline struct clk_hw *imx_dev_clk_hw_gate_shared(struct device *dev,
unsigned int *share_count)
{
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
CLK_OPS_PARENT_ENABLE, reg, shift, 0x1, 0,
&imx_ccm_lock, share_count);
CLK_OPS_PARENT_ENABLE, reg, shift, 0x1,
0x1, 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);
shift, cgr_val, 0x3, 0, &imx_ccm_lock, NULL);
}

static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent,
Expand Down Expand Up @@ -418,7 +418,7 @@ static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *pare
{
return clk_hw_register_gate2(NULL, name, parent,
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
}

static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name,
Expand All @@ -427,7 +427,7 @@ static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name,
{
return clk_hw_register_gate2(NULL, name, parent,
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL);
}

#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
Expand Down

0 comments on commit bcd418a

Please sign in to comment.