Commit 3241b19e authored by Paul Walmsley's avatar Paul Walmsley Committed by Tony Lindgren

OMAP3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate()

Removes the clksel-based DPLL rate handling from the OMAP3 clock tree.
In its place, omap2_get_dpll_rate() now has code to determine whether the DPLL
is bypassed.  This obsoletes several clocks, which are removed by this patch.
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 7d06c48d
......@@ -60,6 +60,10 @@
#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
(DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
/* Some OMAP2xxx CM_CLKSEL_PLL.ST_CORE_CLK bits - for omap2_get_dpll_rate() */
#define ST_CORE_CLK_REF 0x1
#define ST_CORE_CLK_32K 0x3
u8 cpu_mask;
/*-------------------------------------------------------------------------
......@@ -137,22 +141,51 @@ void omap2_init_clksel_parent(struct clk *clk)
return;
}
/* Returns the DPLL rate */
/**
* omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
* @clk: struct clk * of a DPLL
*
* DPLLs can be locked or bypassed - basically, enabled or disabled.
* When locked, the DPLL output depends on the M and N values. When
* bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
* or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
* 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
* (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
* Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
* if the clock @clk is not a DPLL.
*/
u32 omap2_get_dpll_rate(struct clk *clk)
{
long long dpll_clk;
u32 dpll_mult, dpll_div, dpll;
u32 dpll_mult, dpll_div, v;
struct dpll_data *dd;
dd = clk->dpll_data;
/* REVISIT: What do we return on error? */
if (!dd)
return 0;
dpll = __raw_readl(dd->mult_div1_reg);
dpll_mult = dpll & dd->mult_mask;
/* Return bypass rate if DPLL is bypassed */
v = __raw_readl(dd->idlest_reg) & dd->idlest_mask;
v >>= __ffs(dd->idlest_mask);
if (cpu_is_omap24xx()) {
if (v == ST_CORE_CLK_REF)
return clk->parent->rate; /* sys_clk */
else if (v == ST_CORE_CLK_32K)
return 32768;
} else if (cpu_is_omap34xx()) {
if (!v)
return dd->bypass_clk->rate;
}
v = __raw_readl(dd->mult_div1_reg);
dpll_mult = v & dd->mult_mask;
dpll_mult >>= __ffs(dd->mult_mask);
dpll_div = dpll & dd->div1_mask;
dpll_div = v & dd->div1_mask;
dpll_div >>= __ffs(dd->div1_mask);
dpll_clk = (long long)clk->parent->rate * dpll_mult;
......
......@@ -535,8 +535,10 @@ static void __init omap2_clk_rewrite_base(struct clk *clk)
{
omap2_clk_check_reg(clk->flags, &clk->clksel_reg);
omap2_clk_check_reg(clk->flags, &clk->enable_reg);
if (clk->dpll_data)
if (clk->dpll_data) {
omap2_clk_check_reg(0, &clk->dpll_data->mult_div1_reg);
omap2_clk_check_reg(0, &clk->dpll_data->idlest_reg);
}
}
int __init omap2_clk_init(void)
......
......@@ -682,6 +682,8 @@ static struct dpll_data dpll_dd = {
.mult_div1_reg = _CM_REG_OFFSET(PLL_MOD, CM_CLKSEL1),
.mult_mask = OMAP24XX_DPLL_MULT_MASK,
.div1_mask = OMAP24XX_DPLL_DIV_MASK,
.idlest_reg = _CM_REG_OFFSET(PLL_MOD, CM_IDLEST),
.idlest_mask = OMAP24XX_ST_CORE_CLK_MASK,
.max_multiplier = 1024,
.max_divider = 16,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment