OMAP3 clock: move DPLL bypass rate calculation into omap2_get_dpll_rate()
authorPaul Walmsley <paul@pwsan.com>
Thu, 18 Sep 2008 16:30:24 +0000 (10:30 -0600)
committerTony Lindgren <tony@atomide.com>
Mon, 22 Sep 2008 14:44:57 +0000 (17:44 +0300)
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: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock24xx.c
arch/arm/mach-omap2/clock24xx.h
arch/arm/mach-omap2/clock34xx.h

index 5f48e14..16cedb2 100644 (file)
 #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;
index c26d9d8..ddb6429 100644 (file)
@@ -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)
index 63349fa..775d08b 100644 (file)
@@ -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
index cc4960d..92d6903 100644 (file)
@@ -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,