|
|
@@ -207,3 +207,44 @@ out:
|
|
|
|
|
|
return dd->last_rounded_rate;
|
|
|
}
|
|
|
+
|
|
|
+/**
|
|
|
+ * omap4_dpll_regm4xen_determine_rate - determine rate for a DPLL
|
|
|
+ * @hw: pointer to the clock to determine rate for
|
|
|
+ * @rate: target rate for the DPLL
|
|
|
+ * @best_parent_rate: pointer for returning best parent rate
|
|
|
+ * @best_parent_clk: pointer for returning best parent clock
|
|
|
+ *
|
|
|
+ * Determines which DPLL mode to use for reaching a desired rate.
|
|
|
+ * Checks whether the DPLL shall be in bypass or locked mode, and if
|
|
|
+ * locked, calculates the M,N values for the DPLL via round-rate.
|
|
|
+ * Returns a positive clock rate with success, negative error value
|
|
|
+ * in failure.
|
|
|
+ */
|
|
|
+long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|
|
+ unsigned long *best_parent_rate,
|
|
|
+ struct clk **best_parent_clk)
|
|
|
+{
|
|
|
+ struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
|
|
+ struct dpll_data *dd;
|
|
|
+
|
|
|
+ if (!hw || !rate)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ dd = clk->dpll_data;
|
|
|
+ if (!dd)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (__clk_get_rate(dd->clk_bypass) == rate &&
|
|
|
+ (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
|
|
+ *best_parent_clk = dd->clk_bypass;
|
|
|
+ } else {
|
|
|
+ rate = omap4_dpll_regm4xen_round_rate(hw, rate,
|
|
|
+ best_parent_rate);
|
|
|
+ *best_parent_clk = dd->clk_ref;
|
|
|
+ }
|
|
|
+
|
|
|
+ *best_parent_rate = rate;
|
|
|
+
|
|
|
+ return rate;
|
|
|
+}
|