|
@@ -243,3 +243,45 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
|
|
|
return 0;
|
|
|
|
|
|
/* Return bypass rate if DPLL is bypassed */
|
|
|
+ v = __raw_readl(dd->control_reg);
|
|
|
+ v &= dd->enable_mask;
|
|
|
+ v >>= __ffs(dd->enable_mask);
|
|
|
+
|
|
|
+ if (cpu_is_omap24xx()) {
|
|
|
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
|
|
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
|
|
+ return __clk_get_rate(dd->clk_bypass);
|
|
|
+ } else if (cpu_is_omap34xx()) {
|
|
|
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
|
|
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
|
|
+ return __clk_get_rate(dd->clk_bypass);
|
|
|
+ } else if (soc_is_am33xx() || cpu_is_omap44xx()) {
|
|
|
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
|
|
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
|
|
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
|
|
+ return __clk_get_rate(dd->clk_bypass);
|
|
|
+ }
|
|
|
+
|
|
|
+ v = __raw_readl(dd->mult_div1_reg);
|
|
|
+ dpll_mult = v & dd->mult_mask;
|
|
|
+ dpll_mult >>= __ffs(dd->mult_mask);
|
|
|
+ dpll_div = v & dd->div1_mask;
|
|
|
+ dpll_div >>= __ffs(dd->div1_mask);
|
|
|
+
|
|
|
+ dpll_clk = (long long) __clk_get_rate(dd->clk_ref) * dpll_mult;
|
|
|
+ do_div(dpll_clk, dpll_div + 1);
|
|
|
+
|
|
|
+ return dpll_clk;
|
|
|
+}
|
|
|
+
|
|
|
+/* DPLL rate rounding code */
|
|
|
+
|
|
|
+/**
|
|
|
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
|
|
|
+ * @clk: struct clk * for a DPLL
|
|
|
+ * @target_rate: desired DPLL clock rate
|
|
|
+ *
|
|
|
+ * Given a DPLL and a desired target rate, round the target rate to a
|
|
|
+ * possible, programmable rate for this DPLL. Attempts to select the
|
|
|
+ * minimum possible n. Stores the computed (m, n) in the DPLL's
|
|
|
+ * dpll_data structure so set_rate() will not need to call this
|