aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/bcm
diff options
context:
space:
mode:
authorSimran Rai <ssimran@broadcom.com>2015-10-19 18:27:19 -0400
committerMichael Turquette <mturquette@baylibre.com>2015-10-21 05:43:57 -0400
commit63243a4da7d0dfa19dcacd0a529782eeb2f86f92 (patch)
tree98b30265294172b55b6f7f195d5d56e5ad9535f6 /drivers/clk/bcm
parent1256f10fb26e5824fde12314b5f4690797478678 (diff)
clk: iproc: Fix PLL output frequency calculation
This patch affects the clocks that use fractional ndivider in their PLL output frequency calculation. Instead of 2^20 divide factor, the clock's ndiv integer shift was used. Fixed the bug by replacing ndiv integer shift with 2^20 factor. Signed-off-by: Simran Rai <ssimran@broadcom.com> Signed-off-by: Ray Jui <rjui@broadcom.com> Reviewed-by: Scott Branden <sbranden@broadcom.com> Fixes: 5fe225c105fd ("clk: iproc: add initial common clock support") Cc: <stable@vger.kernel.org> # v4.1+ Signed-off-by: Michael Turquette <mturquette@baylibre.com>
Diffstat (limited to 'drivers/clk/bcm')
-rw-r--r--drivers/clk/bcm/clk-iproc-pll.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c
index 2dda4e8295a9..d679ab869653 100644
--- a/drivers/clk/bcm/clk-iproc-pll.c
+++ b/drivers/clk/bcm/clk-iproc-pll.c
@@ -345,8 +345,8 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
345 struct iproc_pll *pll = clk->pll; 345 struct iproc_pll *pll = clk->pll;
346 const struct iproc_pll_ctrl *ctrl = pll->ctrl; 346 const struct iproc_pll_ctrl *ctrl = pll->ctrl;
347 u32 val; 347 u32 val;
348 u64 ndiv; 348 u64 ndiv, ndiv_int, ndiv_frac;
349 unsigned int ndiv_int, ndiv_frac, pdiv; 349 unsigned int pdiv;
350 350
351 if (parent_rate == 0) 351 if (parent_rate == 0)
352 return 0; 352 return 0;
@@ -366,22 +366,19 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
366 val = readl(pll->pll_base + ctrl->ndiv_int.offset); 366 val = readl(pll->pll_base + ctrl->ndiv_int.offset);
367 ndiv_int = (val >> ctrl->ndiv_int.shift) & 367 ndiv_int = (val >> ctrl->ndiv_int.shift) &
368 bit_mask(ctrl->ndiv_int.width); 368 bit_mask(ctrl->ndiv_int.width);
369 ndiv = (u64)ndiv_int << ctrl->ndiv_int.shift; 369 ndiv = ndiv_int << 20;
370 370
371 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { 371 if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
372 val = readl(pll->pll_base + ctrl->ndiv_frac.offset); 372 val = readl(pll->pll_base + ctrl->ndiv_frac.offset);
373 ndiv_frac = (val >> ctrl->ndiv_frac.shift) & 373 ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
374 bit_mask(ctrl->ndiv_frac.width); 374 bit_mask(ctrl->ndiv_frac.width);
375 375 ndiv += ndiv_frac;
376 if (ndiv_frac != 0)
377 ndiv = ((u64)ndiv_int << ctrl->ndiv_int.shift) |
378 ndiv_frac;
379 } 376 }
380 377
381 val = readl(pll->pll_base + ctrl->pdiv.offset); 378 val = readl(pll->pll_base + ctrl->pdiv.offset);
382 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); 379 pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
383 380
384 clk->rate = (ndiv * parent_rate) >> ctrl->ndiv_int.shift; 381 clk->rate = (ndiv * parent_rate) >> 20;
385 382
386 if (pdiv == 0) 383 if (pdiv == 0)
387 clk->rate *= 2; 384 clk->rate *= 2;