aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clkt_dpll.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clkt_dpll.c')
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c28
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