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
......
......@@ -261,16 +261,6 @@ static struct clk sys_clkout1 = {
/* CM CLOCKS */
static const struct clksel_rate dpll_bypass_rates[] = {
{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 0 }
};
static const struct clksel_rate dpll_locked_rates[] = {
{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 0 }
};
static const struct clksel_rate div16_dpll_rates[] = {
{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 2, .val = 2, .flags = RATE_IN_343X },
......@@ -534,40 +524,22 @@ static struct clk dpll3_m2_ck = {
.recalc = &omap2_clksel_recalc,
};
static const struct clksel core_ck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk core_ck = {
.name = "core_ck",
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = core_ck_clksel,
.parent = &dpll3_m2_ck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "cm_clkdm" },
.recalc = &omap2_clksel_recalc,
};
static const struct clksel dpll3_m2x2_ck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
.recalc = &followparent_recalc,
};
static struct clk dpll3_m2x2_ck = {
.name = "dpll3_m2x2_ck",
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = dpll3_m2x2_ck_clksel,
.parent = &dpll3_x2_ck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "dpll3_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
......@@ -601,23 +573,13 @@ static struct clk dpll3_m3x2_ck = {
.recalc = &omap3_clkoutx2_recalc,
};
static const struct clksel emu_core_alwon_ck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk emu_core_alwon_ck = {
.name = "emu_core_alwon_ck",
.parent = &dpll3_m3x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
.clksel = emu_core_alwon_ck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "dpll3_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
/* DPLL4 */
......@@ -701,12 +663,6 @@ static struct clk dpll4_m2x2_ck = {
.recalc = &omap3_clkoutx2_recalc,
};
static const struct clksel omap_96m_alwon_fck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
/*
* DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
* PRM_96M_ALWON_(F)CLK. Two clocks then emerge from the PRM:
......@@ -716,14 +672,10 @@ static const struct clksel omap_96m_alwon_fck_clksel[] = {
static struct clk omap_96m_alwon_fck = {
.name = "omap_96m_alwon_fck",
.parent = &dpll4_m2x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = omap_96m_alwon_fck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "prm_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
static struct clk cm_96m_fck = {
......@@ -790,25 +742,6 @@ static struct clk dpll4_m3x2_ck = {
.recalc = &omap3_clkoutx2_recalc,
};
static const struct clksel virt_omap_54m_fck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk virt_omap_54m_fck = {
.name = "virt_omap_54m_fck",
.parent = &dpll4_m3x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = virt_omap_54m_fck_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "dpll4_clkdm" },
.recalc = &omap2_clksel_recalc,
};
static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 0 }
......@@ -820,7 +753,7 @@ static const struct clksel_rate omap_54m_alt_rates[] = {
};
static const struct clksel omap_54m_clksel[] = {
{ .parent = &virt_omap_54m_fck, .rates = omap_54m_d4m3x2_rates },
{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
{ .parent = &sys_altclk, .rates = omap_54m_alt_rates },
{ .parent = NULL }
};
......@@ -1016,25 +949,6 @@ static struct clk dpll5_m2_ck = {
.recalc = &omap2_clksel_recalc,
};
static const struct clksel omap_120m_fck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk omap_120m_fck = {
.name = "omap_120m_fck",
.parent = &dpll5_m2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST2),
.clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
.clksel = omap_120m_fck_clksel,
.flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "dpll5_clkdm" },
.recalc = &omap2_clksel_recalc,
};
/* CM EXTERNAL CLOCK OUTPUTS */
static const struct clksel_rate clkout2_src_core_rates[] = {
......@@ -1141,29 +1055,13 @@ static struct clk dpll1_fck = {
.recalc = &omap2_clksel_recalc,
};
/*
* MPU clksel:
* If DPLL1 is locked, mpu_ck derives from DPLL1; otherwise, mpu_ck
* derives from the high-frequency bypass clock originating from DPLL3,
* called 'dpll1_fck'
*/
static const struct clksel mpu_clksel[] = {
{ .parent = &dpll1_fck, .rates = dpll_bypass_rates },
{ .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk mpu_ck = {
.name = "mpu_ck",
.parent = &dpll1_x2m2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
.clksel_mask = OMAP3430_ST_MPU_CLK_MASK,
.clksel = mpu_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
.clkdm = { .name = "mpu_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
......@@ -1219,32 +1117,15 @@ static struct clk dpll2_fck = {
.recalc = &omap2_clksel_recalc,
};
/*
* IVA2 clksel:
* If DPLL2 is locked, iva2_ck derives from DPLL2; otherwise, iva2_ck
* derives from the high-frequency bypass clock originating from DPLL3,
* called 'dpll2_fck'
*/
static const struct clksel iva2_clksel[] = {
{ .parent = &dpll2_fck, .rates = dpll_bypass_rates },
{ .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk iva2_ck = {
.name = "iva2_ck",
.parent = &dpll2_m2_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
.clksel_reg = _OMAP34XX_CM_REGADDR(OMAP3430_IVA2_MOD,
OMAP3430_CM_IDLEST_PLL),
.clksel_mask = OMAP3430_ST_IVA2_CLK_MASK,
.clksel = iva2_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
.clkdm = { .name = "iva2_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
/* Common interface clocks */
......@@ -1476,7 +1357,7 @@ static struct clk ts_fck = {
static struct clk usbtll_fck = {
.name = "usbtll_fck",
.parent = &omap_120m_fck,
.parent = &dpll5_m2_ck,
.enable_reg = _OMAP34XX_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
......@@ -2212,24 +2093,14 @@ static struct clk des1_ick = {
};
/* DSS */
static const struct clksel dss1_alwon_fck_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk dss1_alwon_fck = {
.name = "dss1_alwon_fck",
.parent = &dpll4_m4x2_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = _OMAP34XX_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_DSS1_SHIFT,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = dss1_alwon_fck_clksel,
.flags = CLOCK_IN_OMAP343X,
.clkdm = { .name = "dss_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
static struct clk dss_tv_fck = {
......@@ -2275,24 +2146,14 @@ static struct clk dss_ick = {
/* CAM */
static const struct clksel cam_mclk_clksel[] = {
{ .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
static struct clk cam_mclk = {
.name = "cam_mclk",
.parent = &dpll4_m5x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = _OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST),
.clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = cam_mclk_clksel,
.enable_reg = _OMAP34XX_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
.flags = CLOCK_IN_OMAP343X,
.clkdm = { .name = "cam_clkdm" },
.recalc = &omap2_clksel_recalc,
.recalc = &followparent_recalc,
};
static struct clk cam_ick = {
......@@ -2320,7 +2181,7 @@ static struct clk csi2_96m_fck = {
static struct clk usbhost_120m_fck = {
.name = "usbhost_120m_fck",
.parent = &omap_120m_fck,
.parent = &dpll5_m2_ck,
.enable_reg = _OMAP34XX_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
......@@ -2369,7 +2230,7 @@ static const struct clksel_rate usim_120m_rates[] = {
static const struct clksel usim_clksel[] = {
{ .parent = &omap_96m_fck, .rates = usim_96m_rates },
{ .parent = &omap_120m_fck, .rates = usim_120m_rates },
{ .parent = &dpll5_m2_ck, .rates = usim_120m_rates },
{ .parent = &sys_ck, .rates = div2_rates },
{ .parent = NULL },
};
......@@ -3181,7 +3042,6 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&omap_96m_alwon_fck,
&omap_96m_fck,
&cm_96m_fck,
&virt_omap_54m_fck,
&omap_54m_fck,
&omap_48m_fck,
&omap_12m_fck,
......@@ -3198,7 +3058,6 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&emu_per_alwon_ck,
&dpll5_ck,
&dpll5_m2_ck,
&omap_120m_fck,
&clkout2_src_ck,
&sys_clkout2,
&corex2_fck,
......
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