aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-vt8500.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk-vt8500.c')
-rw-r--r--drivers/clk/clk-vt8500.c99
1 files changed, 44 insertions, 55 deletions
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index b0f76a84f1e9..37368a399ff9 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -383,51 +383,49 @@ static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
383 return 0; 383 return 0;
384} 384}
385 385
386static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, 386/*
387 u32 *multiplier, u32 *divisor1, u32 *divisor2) 387 * M * parent [O1] => / P [O2] => / D [O3]
388 * Where O1 is 900MHz...3GHz;
389 * O2 is 600MHz >= (M * parent) / P >= 300MHz;
390 * M is 36...120 [25MHz parent]; D is 1 or 2 or 4 or 8.
391 * Possible ranges (O3):
392 * D = 8: 37,5MHz...75MHz
393 * D = 4: 75MHz...150MHz
394 * D = 2: 150MHz...300MHz
395 * D = 1: 300MHz...600MHz
396 */
397static int wm8650_find_pll_bits(unsigned long rate,
398 unsigned long parent_rate, u32 *multiplier, u32 *divisor1,
399 u32 *divisor2)
388{ 400{
389 u32 mul, div1; 401 unsigned long O1, min_err, rate_err;
390 int div2;
391 u32 best_mul, best_div1, best_div2;
392 unsigned long tclk, rate_err, best_err;
393
394 best_err = (unsigned long)-1;
395 402
396 /* Find the closest match (lower or equal to requested) */ 403 if (!parent_rate || (rate < 37500000) || (rate > 600000000))
397 for (div1 = 5; div1 >= 3; div1--) 404 return -EINVAL;
398 for (div2 = 3; div2 >= 0; div2--)
399 for (mul = 3; mul <= 1023; mul++) {
400 tclk = parent_rate * mul / (div1 * (1 << div2));
401 if (tclk > rate)
402 continue;
403 /* error will always be +ve */
404 rate_err = rate - tclk;
405 if (rate_err == 0) {
406 *multiplier = mul;
407 *divisor1 = div1;
408 *divisor2 = div2;
409 return 0;
410 }
411 405
412 if (rate_err < best_err) { 406 *divisor2 = rate <= 75000000 ? 3 : rate <= 150000000 ? 2 :
413 best_err = rate_err; 407 rate <= 300000000 ? 1 : 0;
414 best_mul = mul; 408 /*
415 best_div1 = div1; 409 * Divisor P cannot be calculated. Test all divisors and find where M
416 best_div2 = div2; 410 * will be as close as possible to the requested rate.
417 } 411 */
418 } 412 min_err = ULONG_MAX;
413 for (*divisor1 = 5; *divisor1 >= 3; (*divisor1)--) {
414 O1 = rate * *divisor1 * (1 << (*divisor2));
415 rate_err = O1 % parent_rate;
416 if (rate_err < min_err) {
417 *multiplier = O1 / parent_rate;
418 if (rate_err == 0)
419 return 0;
420
421 min_err = rate_err;
422 }
423 }
419 424
420 if (best_err == (unsigned long)-1) { 425 if ((*multiplier < 3) || (*multiplier > 1023))
421 pr_warn("%s: impossible rate %lu\n", __func__, rate);
422 return -EINVAL; 426 return -EINVAL;
423 }
424 427
425 /* if we got here, it wasn't an exact match */ 428 pr_warn("%s: rate error is %lu\n", __func__, min_err);
426 pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
427 rate - best_err);
428 *multiplier = best_mul;
429 *divisor1 = best_div1;
430 *divisor2 = best_div2;
431 429
432 return 0; 430 return 0;
433} 431}
@@ -464,7 +462,6 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
464{ 462{
465 u32 mul; 463 u32 mul;
466 int div1, div2; 464 int div1, div2;
467 u32 best_mul, best_div1, best_div2;
468 unsigned long tclk, rate_err, best_err; 465 unsigned long tclk, rate_err, best_err;
469 466
470 best_err = (unsigned long)-1; 467 best_err = (unsigned long)-1;
@@ -488,9 +485,9 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
488 485
489 if (rate_err < best_err) { 486 if (rate_err < best_err) {
490 best_err = rate_err; 487 best_err = rate_err;
491 best_mul = mul; 488 *multiplier = mul;
492 best_div1 = div1; 489 *divisor1 = div1;
493 best_div2 = div2; 490 *divisor2 = div2;
494 } 491 }
495 } 492 }
496 493
@@ -503,10 +500,7 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
503 pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, 500 pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
504 rate - best_err); 501 rate - best_err);
505 502
506 *filter = wm8750_get_filter(parent_rate, best_div1); 503 *filter = wm8750_get_filter(parent_rate, *divisor1);
507 *multiplier = best_mul;
508 *divisor1 = best_div1;
509 *divisor2 = best_div2;
510 504
511 return 0; 505 return 0;
512} 506}
@@ -516,7 +510,6 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
516{ 510{
517 u32 mul; 511 u32 mul;
518 int div1, div2; 512 int div1, div2;
519 u32 best_mul, best_div1, best_div2;
520 unsigned long tclk, rate_err, best_err; 513 unsigned long tclk, rate_err, best_err;
521 514
522 best_err = (unsigned long)-1; 515 best_err = (unsigned long)-1;
@@ -540,9 +533,9 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
540 533
541 if (rate_err < best_err) { 534 if (rate_err < best_err) {
542 best_err = rate_err; 535 best_err = rate_err;
543 best_mul = mul; 536 *multiplier = mul;
544 best_div1 = div1; 537 *divisor1 = div1;
545 best_div2 = div2; 538 *divisor2 = div2;
546 } 539 }
547 } 540 }
548 541
@@ -555,10 +548,6 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
555 pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, 548 pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
556 rate - best_err); 549 rate - best_err);
557 550
558 *multiplier = best_mul;
559 *divisor1 = best_div1;
560 *divisor2 = best_div2;
561
562 return 0; 551 return 0;
563} 552}
564 553