aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/imx/clk-pllv3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/imx/clk-pllv3.c')
-rw-r--r--drivers/clk/imx/clk-pllv3.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 4826b3c9e19e..19f9b622981a 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -29,8 +29,8 @@
29 * struct clk_pllv3 - IMX PLL clock version 3 29 * struct clk_pllv3 - IMX PLL clock version 3
30 * @clk_hw: clock source 30 * @clk_hw: clock source
31 * @base: base address of PLL registers 31 * @base: base address of PLL registers
32 * @powerup_set: set POWER bit to power up the PLL 32 * @power_bit: pll power bit mask
33 * @powerdown: pll powerdown offset bit 33 * @powerup_set: set power_bit to power up the PLL
34 * @div_mask: mask of divider bits 34 * @div_mask: mask of divider bits
35 * @div_shift: shift of divider bits 35 * @div_shift: shift of divider bits
36 * 36 *
@@ -40,8 +40,8 @@
40struct clk_pllv3 { 40struct clk_pllv3 {
41 struct clk_hw hw; 41 struct clk_hw hw;
42 void __iomem *base; 42 void __iomem *base;
43 u32 power_bit;
43 bool powerup_set; 44 bool powerup_set;
44 u32 powerdown;
45 u32 div_mask; 45 u32 div_mask;
46 u32 div_shift; 46 u32 div_shift;
47 unsigned long ref_clock; 47 unsigned long ref_clock;
@@ -52,7 +52,7 @@ struct clk_pllv3 {
52static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) 52static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
53{ 53{
54 unsigned long timeout = jiffies + msecs_to_jiffies(10); 54 unsigned long timeout = jiffies + msecs_to_jiffies(10);
55 u32 val = readl_relaxed(pll->base) & pll->powerdown; 55 u32 val = readl_relaxed(pll->base) & pll->power_bit;
56 56
57 /* No need to wait for lock when pll is not powered up */ 57 /* No need to wait for lock when pll is not powered up */
58 if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) 58 if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
@@ -77,9 +77,9 @@ static int clk_pllv3_prepare(struct clk_hw *hw)
77 77
78 val = readl_relaxed(pll->base); 78 val = readl_relaxed(pll->base);
79 if (pll->powerup_set) 79 if (pll->powerup_set)
80 val |= BM_PLL_POWER; 80 val |= pll->power_bit;
81 else 81 else
82 val &= ~BM_PLL_POWER; 82 val &= ~pll->power_bit;
83 writel_relaxed(val, pll->base); 83 writel_relaxed(val, pll->base);
84 84
85 return clk_pllv3_wait_lock(pll); 85 return clk_pllv3_wait_lock(pll);
@@ -92,9 +92,9 @@ static void clk_pllv3_unprepare(struct clk_hw *hw)
92 92
93 val = readl_relaxed(pll->base); 93 val = readl_relaxed(pll->base);
94 if (pll->powerup_set) 94 if (pll->powerup_set)
95 val &= ~BM_PLL_POWER; 95 val &= ~pll->power_bit;
96 else 96 else
97 val |= BM_PLL_POWER; 97 val |= pll->power_bit;
98 writel_relaxed(val, pll->base); 98 writel_relaxed(val, pll->base);
99} 99}
100 100
@@ -218,8 +218,12 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
218 u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); 218 u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
219 u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); 219 u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
220 u32 div = readl_relaxed(pll->base) & pll->div_mask; 220 u32 div = readl_relaxed(pll->base) & pll->div_mask;
221 u64 temp64 = (u64)parent_rate;
221 222
222 return (parent_rate * div) + ((parent_rate / mfd) * mfn); 223 temp64 *= mfn;
224 do_div(temp64, mfd);
225
226 return (parent_rate * div) + (u32)temp64;
223} 227}
224 228
225static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, 229static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -243,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
243 do_div(temp64, parent_rate); 247 do_div(temp64, parent_rate);
244 mfn = temp64; 248 mfn = temp64;
245 249
246 return parent_rate * div + parent_rate / mfd * mfn; 250 return parent_rate * div + parent_rate * mfn / mfd;
247} 251}
248 252
249static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, 253static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -312,7 +316,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
312 if (!pll) 316 if (!pll)
313 return ERR_PTR(-ENOMEM); 317 return ERR_PTR(-ENOMEM);
314 318
315 pll->powerdown = BM_PLL_POWER; 319 pll->power_bit = BM_PLL_POWER;
316 320
317 switch (type) { 321 switch (type) {
318 case IMX_PLLV3_SYS: 322 case IMX_PLLV3_SYS:
@@ -328,7 +332,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
328 ops = &clk_pllv3_av_ops; 332 ops = &clk_pllv3_av_ops;
329 break; 333 break;
330 case IMX_PLLV3_ENET_IMX7: 334 case IMX_PLLV3_ENET_IMX7:
331 pll->powerdown = IMX7_ENET_PLL_POWER; 335 pll->power_bit = IMX7_ENET_PLL_POWER;
332 pll->ref_clock = 1000000000; 336 pll->ref_clock = 1000000000;
333 ops = &clk_pllv3_enet_ops; 337 ops = &clk_pllv3_enet_ops;
334 break; 338 break;