]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-omap2/clock34xx.c
OMAP clock: support "dry run" rate and parent changes
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / clock34xx.c
index 22cbccedad8657cc099d4a31913d7cc1222c7bbc..917664df1ac5f586b5b6e0fa76b51a4176991399 100644 (file)
 /**
  * omap3_dpll_recalc - recalculate DPLL rate
  * @clk: DPLL struct clk
+ * @parent_rate: rate of the DPLL's parent clock
+ * @rate_storage: flag indicating whether current or temporary rate is changing
  *
  * Recalculate and propagate the DPLL rate.
  */
-static void omap3_dpll_recalc(struct clk *clk)
+static void omap3_dpll_recalc(struct clk *clk, unsigned long parent_rate,
+                             u8 rate_storage)
 {
-       clk->rate = omap2_get_dpll_rate(clk);
+       unsigned long rate;
+
+       rate = omap2_get_dpll_rate(clk, parent_rate);
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = rate;
 }
 
 /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
@@ -278,9 +288,6 @@ static int omap3_noncore_dpll_enable(struct clk *clk)
        else
                r = _omap3_noncore_dpll_lock(clk);
 
-       if (!r)
-               clk->rate = omap2_get_dpll_rate(clk);
-
        return r;
 }
 
@@ -392,7 +399,7 @@ static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
        if (!dd)
                return -EINVAL;
 
-       if (rate == omap2_get_dpll_rate(clk))
+       if (rate == omap2_get_dpll_rate(clk, clk->parent->rate))
                return 0;
 
        if (dd->bypass_clk->rate == rate &&
@@ -578,14 +585,18 @@ static void omap3_dpll_deny_idle(struct clk *clk)
 /**
  * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
  * @clk: DPLL output struct clk
+ * @parent_rate: rate of the parent clock of @clk
+ * @rate_storage: flag indicating whether current or temporary rate is changing
  *
  * Using parent clock DPLL data, look up DPLL state.  If locked, set our
  * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
  */
-static void omap3_clkoutx2_recalc(struct clk *clk)
+static void omap3_clkoutx2_recalc(struct clk *clk, unsigned long parent_rate,
+                                 u8 rate_storage)
 {
        const struct dpll_data *dd;
        u32 v;
+       unsigned long rate;
        struct clk *pclk;
 
        /* Walk up the parents of clk, looking for a DPLL */
@@ -600,12 +611,17 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
 
        WARN_ON(!dd->enable_mask);
 
+       rate = parent_rate;
+
        v = cm_read_mod_reg(pclk->prcm_mod, dd->control_reg) & dd->enable_mask;
        v >>= __ffs(dd->enable_mask);
-       if (v != OMAP3XXX_EN_DPLL_LOCKED)
-               clk->rate = clk->parent->rate;
-       else
-               clk->rate = clk->parent->rate * 2;
+       if (v == OMAP3XXX_EN_DPLL_LOCKED)
+               rate *= 2;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = rate;
 }
 
 /* Common clock code */