/**
* 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;
- propagate_rate(clk);
+ 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 */
ai = omap3_dpll_autoidle_read(clk);
+ omap3_dpll_deny_idle(clk);
+
_omap3_dpll_write_clken(clk, DPLL_LOCKED);
- if (ai) {
- /*
- * If no downstream clocks are enabled, CM_IDLEST bit
- * may never become active, so don't wait for DPLL to lock.
- */
- r = 0;
+ r = _omap3_wait_dpll_status(clk, 1);
+
+ if (ai)
omap3_dpll_allow_idle(clk);
- } else {
- r = _omap3_wait_dpll_status(clk, 1);
- omap3_dpll_deny_idle(clk);
- };
return r;
}
else
r = _omap3_noncore_dpll_lock(clk);
- if (!r)
- clk->rate = omap2_get_dpll_rate(clk);
-
return r;
}
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 &&
}
- omap3_dpll_recalc(clk);
-
return 0;
}
sp->actim_ctrlb, new_div);
local_irq_enable();
- omap2_clksel_recalc(clk);
-
return 0;
}
/**
* 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 */
dd = pclk->dpll_data;
- WARN_ON(!dd->idlest_reg || !dd->idlest_mask);
+ WARN_ON(!dd->enable_mask);
- v = cm_read_mod_reg(pclk->prcm_mod, dd->idlest_reg) & dd->idlest_mask;
- if (!v)
- clk->rate = clk->parent->rate;
- else
- clk->rate = clk->parent->rate * 2;
+ 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)
+ rate *= 2;
- if (clk->flags & RATE_PROPAGATES)
- propagate_rate(clk);
+ if (rate_storage == CURRENT_RATE)
+ clk->rate = rate;
+ else if (rate_storage == TEMP_RATE)
+ clk->temp_rate = rate;
}
/* Common clock code */
.clk_round_rate = omap2_clk_round_rate,
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
+ .clk_get_parent = omap2_clk_get_parent,
.clk_disable_unused = omap2_clk_disable_unused,
};
/* REVISIT: not yet ready for 343x */
#if 0
- if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+ if (clk_set_rate(&virt_prcm_set, mpurate))
printk(KERN_ERR "Could not find matching MPU rate\n");
#endif