diff options
-rw-r--r-- | drivers/clk/microchip/clk-mpfs.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index acf598a32ce0..911905d0433d 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -15,7 +15,8 @@ /* address offset of control registers */ #define REG_MSSPLL_REF_CR 0x08u -#define REG_MSSPLL_POSTDIV_CR 0x10u +#define REG_MSSPLL_POSTDIV01_CR 0x10u +#define REG_MSSPLL_POSTDIV23_CR 0x14u #define REG_MSSPLL_SSCG_2_CR 0x2Cu #define REG_CLOCK_CONFIG_CR 0x08u #define REG_RTC_CLOCK_CR 0x0Cu @@ -26,7 +27,7 @@ #define MSSPLL_FBDIV_WIDTH 0x0Cu #define MSSPLL_REFDIV_SHIFT 0x08u #define MSSPLL_REFDIV_WIDTH 0x06u -#define MSSPLL_POSTDIV_SHIFT 0x08u +#define MSSPLL_POSTDIV02_SHIFT 0x08u #define MSSPLL_POSTDIV_WIDTH 0x07u #define MSSPLL_FIXED_DIV 4u @@ -62,6 +63,9 @@ struct mpfs_msspll_out_hw_clock { struct clk_hw hw; struct clk_init_data init; unsigned int id; + u32 reg_offset; + u32 shift; + u32 width; u32 flags; }; @@ -175,11 +179,11 @@ static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_c static unsigned long mpfs_clk_msspll_out_recalc_rate(struct clk_hw *hw, unsigned long prate) { struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw); - void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR; + void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset; u32 postdiv; - postdiv = readl_relaxed(postdiv_addr) >> MSSPLL_POSTDIV_SHIFT; - postdiv &= clk_div_mask(MSSPLL_POSTDIV_WIDTH); + postdiv = readl_relaxed(postdiv_addr) >> msspll_out_hw->shift; + postdiv &= clk_div_mask(msspll_out_hw->width); return prate / postdiv; } @@ -189,19 +193,19 @@ static long mpfs_clk_msspll_out_round_rate(struct clk_hw *hw, unsigned long rate { struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw); - return divider_round_rate(hw, rate, prate, NULL, MSSPLL_POSTDIV_WIDTH, + return divider_round_rate(hw, rate, prate, NULL, msspll_out_hw->width, msspll_out_hw->flags); } static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) { struct mpfs_msspll_out_hw_clock *msspll_out_hw = to_mpfs_msspll_out_clk(hw); - void __iomem *postdiv_addr = msspll_out_hw->base + REG_MSSPLL_POSTDIV_CR; + void __iomem *postdiv_addr = msspll_out_hw->base + msspll_out_hw->reg_offset; u32 postdiv; int divider_setting; unsigned long flags; - divider_setting = divider_get_val(rate, prate, NULL, MSSPLL_POSTDIV_WIDTH, + divider_setting = divider_get_val(rate, prate, NULL, msspll_out_hw->width, msspll_out_hw->flags); if (divider_setting < 0) @@ -210,7 +214,7 @@ static int mpfs_clk_msspll_out_set_rate(struct clk_hw *hw, unsigned long rate, u spin_lock_irqsave(&mpfs_clk_lock, flags); postdiv = readl_relaxed(postdiv_addr); - postdiv &= ~(clk_div_mask(MSSPLL_POSTDIV_WIDTH) << MSSPLL_POSTDIV_SHIFT); + postdiv &= ~(clk_div_mask(msspll_out_hw->width) << msspll_out_hw->shift); writel_relaxed(postdiv, postdiv_addr); spin_unlock_irqrestore(&mpfs_clk_lock, flags); @@ -224,14 +228,18 @@ static const struct clk_ops mpfs_clk_msspll_out_ops = { .set_rate = mpfs_clk_msspll_out_set_rate, }; -#define CLK_PLL_OUT(_id, _name, _parent, _flags) { \ +#define CLK_PLL_OUT(_id, _name, _parent, _flags, _shift, _width, _offset) { \ .id = _id, \ + .shift = _shift, \ + .width = _width, \ + .reg_offset = _offset, \ .flags = _flags, \ .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_msspll_out_ops, 0), \ } static struct mpfs_msspll_out_hw_clock mpfs_msspll_out_clks[] = { - CLK_PLL_OUT(CLK_MSSPLL0, "clk_msspll", "clk_msspll_internal", 0), + CLK_PLL_OUT(CLK_MSSPLL0, "clk_msspll", "clk_msspll_internal", 0, + MSSPLL_POSTDIV02_SHIFT, MSSPLL_POSTDIV_WIDTH, REG_MSSPLL_POSTDIV01_CR), }; static int mpfs_clk_register_msspll_outs(struct device *dev, |