diff options
Diffstat (limited to 'arch/arm/mach-omap2/clkt_dpll.c')
-rw-r--r-- | arch/arm/mach-omap2/clkt_dpll.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index 3c34df0f1531..950308fa30d3 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c | |||
@@ -285,10 +285,13 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, | |||
285 | { | 285 | { |
286 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | 286 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); |
287 | int m, n, r, scaled_max_m; | 287 | int m, n, r, scaled_max_m; |
288 | int min_delta_m = INT_MAX, min_delta_n = INT_MAX; | ||
288 | unsigned long scaled_rt_rp; | 289 | unsigned long scaled_rt_rp; |
289 | unsigned long new_rate = 0; | 290 | unsigned long new_rate = 0; |
290 | struct dpll_data *dd; | 291 | struct dpll_data *dd; |
291 | unsigned long ref_rate; | 292 | unsigned long ref_rate; |
293 | long delta; | ||
294 | long prev_min_delta = LONG_MAX; | ||
292 | const char *clk_name; | 295 | const char *clk_name; |
293 | 296 | ||
294 | if (!clk || !clk->dpll_data) | 297 | if (!clk || !clk->dpll_data) |
@@ -334,23 +337,34 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, | |||
334 | if (r == DPLL_MULT_UNDERFLOW) | 337 | if (r == DPLL_MULT_UNDERFLOW) |
335 | continue; | 338 | continue; |
336 | 339 | ||
340 | /* skip rates above our target rate */ | ||
341 | delta = target_rate - new_rate; | ||
342 | if (delta < 0) | ||
343 | continue; | ||
344 | |||
345 | if (delta < prev_min_delta) { | ||
346 | prev_min_delta = delta; | ||
347 | min_delta_m = m; | ||
348 | min_delta_n = n; | ||
349 | } | ||
350 | |||
337 | pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n", | 351 | pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n", |
338 | clk_name, m, n, new_rate); | 352 | clk_name, m, n, new_rate); |
339 | 353 | ||
340 | if (target_rate == new_rate) { | 354 | if (delta == 0) |
341 | dd->last_rounded_m = m; | ||
342 | dd->last_rounded_n = n; | ||
343 | dd->last_rounded_rate = target_rate; | ||
344 | break; | 355 | break; |
345 | } | ||
346 | } | 356 | } |
347 | 357 | ||
348 | if (target_rate != new_rate) { | 358 | if (prev_min_delta == LONG_MAX) { |
349 | pr_debug("clock: %s: cannot round to rate %lu\n", | 359 | pr_debug("clock: %s: cannot round to rate %lu\n", |
350 | clk_name, target_rate); | 360 | clk_name, target_rate); |
351 | return ~0; | 361 | return ~0; |
352 | } | 362 | } |
353 | 363 | ||
354 | return target_rate; | 364 | dd->last_rounded_m = min_delta_m; |
365 | dd->last_rounded_n = min_delta_n; | ||
366 | dd->last_rounded_rate = target_rate - prev_min_delta; | ||
367 | |||
368 | return dd->last_rounded_rate; | ||
355 | } | 369 | } |
356 | 370 | ||