diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/clkt_dpll.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 13 |
2 files changed, 32 insertions, 9 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 | ||
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index cd5f3a0b97bd..ac3d789ac3cd 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -475,6 +475,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
475 | { | 475 | { |
476 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); | 476 | struct clk_hw_omap *clk = to_clk_hw_omap(hw); |
477 | struct clk *new_parent = NULL; | 477 | struct clk *new_parent = NULL; |
478 | unsigned long rrate; | ||
478 | u16 freqsel = 0; | 479 | u16 freqsel = 0; |
479 | struct dpll_data *dd; | 480 | struct dpll_data *dd; |
480 | int ret; | 481 | int ret; |
@@ -502,8 +503,16 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
502 | __clk_prepare(dd->clk_ref); | 503 | __clk_prepare(dd->clk_ref); |
503 | clk_enable(dd->clk_ref); | 504 | clk_enable(dd->clk_ref); |
504 | 505 | ||
505 | if (dd->last_rounded_rate != rate) | 506 | /* XXX this check is probably pointless in the CCF context */ |
506 | rate = __clk_round_rate(hw->clk, rate); | 507 | if (dd->last_rounded_rate != rate) { |
508 | rrate = __clk_round_rate(hw->clk, rate); | ||
509 | if (rrate != rate) { | ||
510 | pr_warn("%s: %s: final rate %lu does not match desired rate %lu\n", | ||
511 | __func__, __clk_get_name(hw->clk), | ||
512 | rrate, rate); | ||
513 | rate = rrate; | ||
514 | } | ||
515 | } | ||
507 | 516 | ||
508 | if (dd->last_rounded_rate == 0) | 517 | if (dd->last_rounded_rate == 0) |
509 | return -EINVAL; | 518 | return -EINVAL; |