]> git.karo-electronics.de Git - linux-beck.git/blobdiff - arch/arm/mach-omap2/clock.c
ARM: OMAP4: PM: Add init api for DPLL nodes
[linux-beck.git] / arch / arm / mach-omap2 / clock.c
index 4716206547ac06adfe839d057edf397363f3da88..759c72a48f7f188c5232919df2702edaabf562cd 100644 (file)
 u8 cpu_mask;
 
 /*-------------------------------------------------------------------------
- * OMAP2/3 specific clock functions
+ * OMAP2/3/4 specific clock functions
  *-------------------------------------------------------------------------*/
 
+void omap2_init_dpll_parent(struct clk *clk)
+{
+       u32 v;
+       struct dpll_data *dd;
+
+       dd = clk->dpll_data;
+       if (!dd)
+               return;
+
+       /* Return bypass rate if DPLL is bypassed */
+       v = __raw_readl(dd->control_reg);
+       v &= dd->enable_mask;
+       v >>= __ffs(dd->enable_mask);
+
+       /* Reparent in case the dpll is in bypass */
+       if (cpu_is_omap24xx()) {
+               if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+                   v == OMAP2XXX_EN_DPLL_FRBYPASS)
+                       clk_reparent(clk, dd->clk_bypass);
+       } else if (cpu_is_omap34xx()) {
+               if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+                   v == OMAP3XXX_EN_DPLL_FRBYPASS)
+                       clk_reparent(clk, dd->clk_bypass);
+       } else if (cpu_is_omap44xx()) {
+               if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+                   v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+                   v == OMAP4XXX_EN_DPLL_MNBYPASS)
+                       clk_reparent(clk, dd->clk_bypass);
+       }
+       return;
+}
+
 /**
  * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
  * @clk: struct clk *
@@ -149,6 +181,7 @@ static int _dpll_test_fint(struct clk *clk, u8 n)
  * clockdomain pointer, and save it into the struct clk.  Intended to be
  * called during clk_register().  No return value.
  */
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
 void omap2_init_clk_clkdm(struct clk *clk)
 {
        struct clockdomain *clkdm;
@@ -166,6 +199,7 @@ void omap2_init_clk_clkdm(struct clk *clk)
                         "clkdm %s\n", clk->name, clk->clkdm_name);
        }
 }
+#endif
 
 /**
  * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
@@ -247,6 +281,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
                if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
                    v == OMAP3XXX_EN_DPLL_FRBYPASS)
                        return dd->clk_bypass->rate;
+       } else if (cpu_is_omap44xx()) {
+               if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+                   v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+                   v == OMAP4XXX_EN_DPLL_MNBYPASS)
+                       return dd->clk_bypass->rate;
        }
 
        v = __raw_readl(dd->mult_div1_reg);
@@ -437,8 +476,10 @@ void omap2_clk_disable(struct clk *clk)
                _omap2_clk_disable(clk);
                if (clk->parent)
                        omap2_clk_disable(clk->parent);
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
                if (clk->clkdm)
                        omap2_clkdm_clk_disable(clk->clkdm, clk);
+#endif
 
        }
 }
@@ -448,8 +489,10 @@ int omap2_clk_enable(struct clk *clk)
        int ret = 0;
 
        if (clk->usecount++ == 0) {
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
                if (clk->clkdm)
                        omap2_clkdm_clk_enable(clk->clkdm, clk);
+#endif
 
                if (clk->parent) {
                        ret = omap2_clk_enable(clk->parent);
@@ -468,8 +511,10 @@ int omap2_clk_enable(struct clk *clk)
        return ret;
 
 err:
+#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdm f/w is in place */
        if (clk->clkdm)
                omap2_clkdm_clk_disable(clk->clkdm, clk);
+#endif
        clk->usecount--;
        return ret;
 }