diff options
author | Prashant Gaikwad <pgaikwad@nvidia.com> | 2012-08-06 02:27:43 -0400 |
---|---|---|
committer | Stephen Warren <swarren@nvidia.com> | 2012-09-06 13:47:20 -0400 |
commit | 92fe58f07f6e51185497785aed632d0e676afe6e (patch) | |
tree | 3791468579de25fa4ada69abacdaf9666a8b7657 /arch/arm/mach-tegra/tegra30_clocks.c | |
parent | 96a1bd1e11ade7be969d275edd4c06749684cdba (diff) |
ARM: tegra: Port tegra to generic clock framework
This patch converts tegra clock code to generic clock framework in following way:
- Implement clk_ops as required by generic clk framework. (tegraXX_clocks.c)
- Use platform specific struct clk_tegra in clk_ops implementation instead of struct clk.
- Initialize all clock data statically. (tegraXX_clocks_data.c)
Legacy framework did not have recalc_rate and is_enabled functions. Implemented these functions.
Removed init function. It's functionality is splitted into recalc_rate and is_enabled.
Static initialization is used since slab is not up in .init_early and clock
is needed to be initialized before clockevent/clocksource initialization.
Macros redefined for clk_tegra.
Also, single struct clk_tegra is used for all type of clocks (PLL, peripheral etc.). This
is to move quickly to generic common clock framework so that other dependent features will
not be blocked (such as DT binding).
Enabling COMMON_CLOCK config moved to ARCH_TEGRA since it is enabled for both Tegra20
and Tegra30.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra30_clocks.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra30_clocks.c | 1332 |
1 files changed, 781 insertions, 551 deletions
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c index 645ef6900a0e..a9fa8ea0b6e0 100644 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ b/arch/arm/mach-tegra/tegra30_clocks.c | |||
@@ -381,14 +381,16 @@ static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32]; | |||
381 | udelay(2); \ | 381 | udelay(2); \ |
382 | } while (0) | 382 | } while (0) |
383 | 383 | ||
384 | 384 | static inline int clk_set_div(struct clk_tegra *c, u32 n) | |
385 | static inline int clk_set_div(struct clk *c, u32 n) | ||
386 | { | 385 | { |
387 | return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n); | 386 | struct clk *clk = c->hw.clk; |
387 | |||
388 | return clk_set_rate(clk, | ||
389 | (__clk_get_rate(__clk_get_parent(clk)) + n - 1) / n); | ||
388 | } | 390 | } |
389 | 391 | ||
390 | static inline u32 periph_clk_to_reg( | 392 | static inline u32 periph_clk_to_reg( |
391 | struct clk *c, u32 reg_L, u32 reg_V, int offs) | 393 | struct clk_tegra *c, u32 reg_L, u32 reg_V, int offs) |
392 | { | 394 | { |
393 | u32 reg = c->u.periph.clk_num / 32; | 395 | u32 reg = c->u.periph.clk_num / 32; |
394 | BUG_ON(reg >= RST_DEVICES_NUM); | 396 | BUG_ON(reg >= RST_DEVICES_NUM); |
@@ -470,15 +472,32 @@ static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate) | |||
470 | return divider_u16 - 1; | 472 | return divider_u16 - 1; |
471 | } | 473 | } |
472 | 474 | ||
475 | static unsigned long tegra30_clk_fixed_recalc_rate(struct clk_hw *hw, | ||
476 | unsigned long parent_rate) | ||
477 | { | ||
478 | return to_clk_tegra(hw)->fixed_rate; | ||
479 | } | ||
480 | |||
481 | struct clk_ops tegra_clk_32k_ops = { | ||
482 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
483 | }; | ||
484 | |||
473 | /* clk_m functions */ | 485 | /* clk_m functions */ |
474 | static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c) | 486 | static unsigned long tegra30_clk_m_recalc_rate(struct clk_hw *hw, |
487 | unsigned long parent_rate) | ||
488 | { | ||
489 | if (!to_clk_tegra(hw)->fixed_rate) | ||
490 | to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq(); | ||
491 | return to_clk_tegra(hw)->fixed_rate; | ||
492 | } | ||
493 | |||
494 | static void tegra30_clk_m_init(struct clk_hw *hw) | ||
475 | { | 495 | { |
476 | u32 osc_ctrl = clk_readl(OSC_CTRL); | 496 | u32 osc_ctrl = clk_readl(OSC_CTRL); |
477 | u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK; | 497 | u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK; |
478 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; | 498 | u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK; |
479 | 499 | ||
480 | c->rate = clk_measure_input_freq(); | 500 | switch (to_clk_tegra(hw)->fixed_rate) { |
481 | switch (c->rate) { | ||
482 | case 12000000: | 501 | case 12000000: |
483 | auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; | 502 | auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; |
484 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); | 503 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1); |
@@ -508,46 +527,44 @@ static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c) | |||
508 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); | 527 | BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4); |
509 | break; | 528 | break; |
510 | default: | 529 | default: |
511 | pr_err("%s: Unexpected clock rate %ld", __func__, c->rate); | 530 | pr_err("%s: Unexpected clock rate %ld", __func__, |
531 | to_clk_tegra(hw)->fixed_rate); | ||
512 | BUG(); | 532 | BUG(); |
513 | } | 533 | } |
514 | clk_writel(auto_clock_control, OSC_CTRL); | 534 | clk_writel(auto_clock_control, OSC_CTRL); |
515 | return c->rate; | ||
516 | } | 535 | } |
517 | 536 | ||
518 | static void tegra30_clk_m_init(struct clk *c) | 537 | struct clk_ops tegra30_clk_m_ops = { |
519 | { | 538 | .init = tegra30_clk_m_init, |
520 | pr_debug("%s on clock %s\n", __func__, c->name); | 539 | .recalc_rate = tegra30_clk_m_recalc_rate, |
521 | tegra30_clk_m_autodetect_rate(c); | 540 | }; |
522 | } | ||
523 | 541 | ||
524 | static int tegra30_clk_m_enable(struct clk *c) | 542 | static unsigned long tegra30_clk_m_div_recalc_rate(struct clk_hw *hw, |
543 | unsigned long parent_rate) | ||
525 | { | 544 | { |
526 | pr_debug("%s on clock %s\n", __func__, c->name); | 545 | struct clk_tegra *c = to_clk_tegra(hw); |
527 | return 0; | 546 | u64 rate = parent_rate; |
528 | } | ||
529 | 547 | ||
530 | static void tegra30_clk_m_disable(struct clk *c) | 548 | if (c->mul != 0 && c->div != 0) { |
531 | { | 549 | rate *= c->mul; |
532 | pr_debug("%s on clock %s\n", __func__, c->name); | 550 | rate += c->div - 1; /* round up */ |
533 | WARN(1, "Attempting to disable main SoC clock\n"); | 551 | do_div(rate, c->div); |
534 | } | 552 | } |
535 | 553 | ||
536 | struct clk_ops tegra30_clk_m_ops = { | 554 | return rate; |
537 | .init = tegra30_clk_m_init, | 555 | } |
538 | .enable = tegra30_clk_m_enable, | ||
539 | .disable = tegra30_clk_m_disable, | ||
540 | }; | ||
541 | 556 | ||
542 | struct clk_ops tegra_clk_m_div_ops = { | 557 | struct clk_ops tegra_clk_m_div_ops = { |
543 | .enable = tegra30_clk_m_enable, | 558 | .recalc_rate = tegra30_clk_m_div_recalc_rate, |
544 | }; | 559 | }; |
545 | 560 | ||
546 | /* PLL reference divider functions */ | 561 | /* PLL reference divider functions */ |
547 | static void tegra30_pll_ref_init(struct clk *c) | 562 | static unsigned long tegra30_pll_ref_recalc_rate(struct clk_hw *hw, |
563 | unsigned long parent_rate) | ||
548 | { | 564 | { |
565 | struct clk_tegra *c = to_clk_tegra(hw); | ||
566 | unsigned long rate = parent_rate; | ||
549 | u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK; | 567 | u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK; |
550 | pr_debug("%s on clock %s\n", __func__, c->name); | ||
551 | 568 | ||
552 | switch (pll_ref_div) { | 569 | switch (pll_ref_div) { |
553 | case OSC_CTRL_PLL_REF_DIV_1: | 570 | case OSC_CTRL_PLL_REF_DIV_1: |
@@ -564,13 +581,18 @@ static void tegra30_pll_ref_init(struct clk *c) | |||
564 | BUG(); | 581 | BUG(); |
565 | } | 582 | } |
566 | c->mul = 1; | 583 | c->mul = 1; |
567 | c->state = ON; | 584 | |
585 | if (c->mul != 0 && c->div != 0) { | ||
586 | rate *= c->mul; | ||
587 | rate += c->div - 1; /* round up */ | ||
588 | do_div(rate, c->div); | ||
589 | } | ||
590 | |||
591 | return rate; | ||
568 | } | 592 | } |
569 | 593 | ||
570 | struct clk_ops tegra_pll_ref_ops = { | 594 | struct clk_ops tegra_pll_ref_ops = { |
571 | .init = tegra30_pll_ref_init, | 595 | .recalc_rate = tegra30_pll_ref_recalc_rate, |
572 | .enable = tegra30_clk_m_enable, | ||
573 | .disable = tegra30_clk_m_disable, | ||
574 | }; | 596 | }; |
575 | 597 | ||
576 | /* super clock functions */ | 598 | /* super clock functions */ |
@@ -581,56 +603,50 @@ struct clk_ops tegra_pll_ref_ops = { | |||
581 | * only when its parent is a fixed rate PLL, since we can't change PLL rate | 603 | * only when its parent is a fixed rate PLL, since we can't change PLL rate |
582 | * in this case. | 604 | * in this case. |
583 | */ | 605 | */ |
584 | static void tegra30_super_clk_init(struct clk *c) | 606 | static void tegra30_super_clk_init(struct clk_hw *hw) |
585 | { | 607 | { |
586 | u32 val; | 608 | struct clk_tegra *c = to_clk_tegra(hw); |
587 | int source; | 609 | struct clk_tegra *p = |
588 | int shift; | 610 | to_clk_tegra(__clk_get_hw(__clk_get_parent(hw->clk))); |
589 | const struct clk_mux_sel *sel; | ||
590 | val = clk_readl(c->reg + SUPER_CLK_MUX); | ||
591 | c->state = ON; | ||
592 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && | ||
593 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | ||
594 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | ||
595 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | ||
596 | source = (val >> shift) & SUPER_SOURCE_MASK; | ||
597 | if (c->flags & DIV_2) | ||
598 | source |= val & SUPER_LP_DIV2_BYPASS; | ||
599 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
600 | if (sel->value == source) | ||
601 | break; | ||
602 | } | ||
603 | BUG_ON(sel->input == NULL); | ||
604 | c->parent = sel->input; | ||
605 | 611 | ||
612 | c->state = ON; | ||
606 | if (c->flags & DIV_U71) { | 613 | if (c->flags & DIV_U71) { |
607 | /* Init safe 7.1 divider value (does not affect PLLX path) */ | 614 | /* Init safe 7.1 divider value (does not affect PLLX path) */ |
608 | clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT, | 615 | clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT, |
609 | c->reg + SUPER_CLK_DIVIDER); | 616 | c->reg + SUPER_CLK_DIVIDER); |
610 | c->mul = 2; | 617 | c->mul = 2; |
611 | c->div = 2; | 618 | c->div = 2; |
612 | if (!(c->parent->flags & PLLX)) | 619 | if (!(p->flags & PLLX)) |
613 | c->div += SUPER_CLOCK_DIV_U71_MIN; | 620 | c->div += SUPER_CLOCK_DIV_U71_MIN; |
614 | } else | 621 | } else |
615 | clk_writel(0, c->reg + SUPER_CLK_DIVIDER); | 622 | clk_writel(0, c->reg + SUPER_CLK_DIVIDER); |
616 | } | 623 | } |
617 | 624 | ||
618 | static int tegra30_super_clk_enable(struct clk *c) | 625 | static u8 tegra30_super_clk_get_parent(struct clk_hw *hw) |
619 | { | 626 | { |
620 | return 0; | 627 | struct clk_tegra *c = to_clk_tegra(hw); |
621 | } | 628 | u32 val; |
629 | int source; | ||
630 | int shift; | ||
622 | 631 | ||
623 | static void tegra30_super_clk_disable(struct clk *c) | 632 | val = clk_readl(c->reg + SUPER_CLK_MUX); |
624 | { | 633 | BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && |
625 | /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and | 634 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); |
626 | geared up g-mode super clock - mode switch may request to disable | 635 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? |
627 | either of them; accept request with no affect on h/w */ | 636 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; |
637 | source = (val >> shift) & SUPER_SOURCE_MASK; | ||
638 | if (c->flags & DIV_2) | ||
639 | source |= val & SUPER_LP_DIV2_BYPASS; | ||
640 | |||
641 | return source; | ||
628 | } | 642 | } |
629 | 643 | ||
630 | static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p) | 644 | static int tegra30_super_clk_set_parent(struct clk_hw *hw, u8 index) |
631 | { | 645 | { |
646 | struct clk_tegra *c = to_clk_tegra(hw); | ||
647 | struct clk_tegra *p = | ||
648 | to_clk_tegra(__clk_get_hw(clk_get_parent(hw->clk))); | ||
632 | u32 val; | 649 | u32 val; |
633 | const struct clk_mux_sel *sel; | ||
634 | int shift; | 650 | int shift; |
635 | 651 | ||
636 | val = clk_readl(c->reg + SUPER_CLK_MUX); | 652 | val = clk_readl(c->reg + SUPER_CLK_MUX); |
@@ -638,48 +654,36 @@ static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p) | |||
638 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); | 654 | ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); |
639 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? | 655 | shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? |
640 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; | 656 | SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; |
641 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
642 | if (sel->input == p) { | ||
643 | /* For LP mode super-clock switch between PLLX direct | ||
644 | and divided-by-2 outputs is allowed only when other | ||
645 | than PLLX clock source is current parent */ | ||
646 | if ((c->flags & DIV_2) && (p->flags & PLLX) && | ||
647 | ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) { | ||
648 | if (c->parent->flags & PLLX) | ||
649 | return -EINVAL; | ||
650 | val ^= SUPER_LP_DIV2_BYPASS; | ||
651 | clk_writel_delay(val, c->reg); | ||
652 | } | ||
653 | val &= ~(SUPER_SOURCE_MASK << shift); | ||
654 | val |= (sel->value & SUPER_SOURCE_MASK) << shift; | ||
655 | |||
656 | /* 7.1 divider for CPU super-clock does not affect | ||
657 | PLLX path */ | ||
658 | if (c->flags & DIV_U71) { | ||
659 | u32 div = 0; | ||
660 | if (!(p->flags & PLLX)) { | ||
661 | div = clk_readl(c->reg + | ||
662 | SUPER_CLK_DIVIDER); | ||
663 | div &= SUPER_CLOCK_DIV_U71_MASK; | ||
664 | div >>= SUPER_CLOCK_DIV_U71_SHIFT; | ||
665 | } | ||
666 | c->div = div + 2; | ||
667 | c->mul = 2; | ||
668 | } | ||
669 | 657 | ||
670 | if (c->refcnt) | 658 | /* For LP mode super-clock switch between PLLX direct |
671 | clk_enable(p); | 659 | and divided-by-2 outputs is allowed only when other |
672 | 660 | than PLLX clock source is current parent */ | |
673 | clk_writel_delay(val, c->reg); | 661 | if ((c->flags & DIV_2) && (p->flags & PLLX) && |
674 | 662 | ((index ^ val) & SUPER_LP_DIV2_BYPASS)) { | |
675 | if (c->refcnt && c->parent) | 663 | if (p->flags & PLLX) |
676 | clk_disable(c->parent); | 664 | return -EINVAL; |
665 | val ^= SUPER_LP_DIV2_BYPASS; | ||
666 | clk_writel_delay(val, c->reg); | ||
667 | } | ||
668 | val &= ~(SUPER_SOURCE_MASK << shift); | ||
669 | val |= (index & SUPER_SOURCE_MASK) << shift; | ||
677 | 670 | ||
678 | clk_reparent(c, p); | 671 | /* 7.1 divider for CPU super-clock does not affect |
679 | return 0; | 672 | PLLX path */ |
673 | if (c->flags & DIV_U71) { | ||
674 | u32 div = 0; | ||
675 | if (!(p->flags & PLLX)) { | ||
676 | div = clk_readl(c->reg + | ||
677 | SUPER_CLK_DIVIDER); | ||
678 | div &= SUPER_CLOCK_DIV_U71_MASK; | ||
679 | div >>= SUPER_CLOCK_DIV_U71_SHIFT; | ||
680 | } | 680 | } |
681 | c->div = div + 2; | ||
682 | c->mul = 2; | ||
681 | } | 683 | } |
682 | return -EINVAL; | 684 | clk_writel_delay(val, c->reg); |
685 | |||
686 | return 0; | ||
683 | } | 687 | } |
684 | 688 | ||
685 | /* | 689 | /* |
@@ -691,10 +695,15 @@ static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p) | |||
691 | * rate of this PLL can't be changed, and it has many other children. In | 695 | * rate of this PLL can't be changed, and it has many other children. In |
692 | * this case use 7.1 fractional divider to adjust the super clock rate. | 696 | * this case use 7.1 fractional divider to adjust the super clock rate. |
693 | */ | 697 | */ |
694 | static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate) | 698 | static int tegra30_super_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
699 | unsigned long parent_rate) | ||
695 | { | 700 | { |
696 | if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) { | 701 | struct clk_tegra *c = to_clk_tegra(hw); |
697 | int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate, | 702 | struct clk *parent = __clk_get_parent(hw->clk); |
703 | struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent)); | ||
704 | |||
705 | if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) { | ||
706 | int div = clk_div71_get_divider(parent_rate, | ||
698 | rate, c->flags, ROUND_DIVIDER_DOWN); | 707 | rate, c->flags, ROUND_DIVIDER_DOWN); |
699 | div = max(div, SUPER_CLOCK_DIV_U71_MIN); | 708 | div = max(div, SUPER_CLOCK_DIV_U71_MIN); |
700 | 709 | ||
@@ -704,55 +713,86 @@ static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate) | |||
704 | c->mul = 2; | 713 | c->mul = 2; |
705 | return 0; | 714 | return 0; |
706 | } | 715 | } |
707 | return clk_set_rate(c->parent, rate); | 716 | return 0; |
717 | } | ||
718 | |||
719 | static unsigned long tegra30_super_clk_recalc_rate(struct clk_hw *hw, | ||
720 | unsigned long parent_rate) | ||
721 | { | ||
722 | struct clk_tegra *c = to_clk_tegra(hw); | ||
723 | u64 rate = parent_rate; | ||
724 | |||
725 | if (c->mul != 0 && c->div != 0) { | ||
726 | rate *= c->mul; | ||
727 | rate += c->div - 1; /* round up */ | ||
728 | do_div(rate, c->div); | ||
729 | } | ||
730 | |||
731 | return rate; | ||
732 | } | ||
733 | |||
734 | static long tegra30_super_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
735 | unsigned long *prate) | ||
736 | { | ||
737 | struct clk_tegra *c = to_clk_tegra(hw); | ||
738 | struct clk *parent = __clk_get_parent(hw->clk); | ||
739 | struct clk_tegra *cparent = to_clk_tegra(__clk_get_hw(parent)); | ||
740 | int mul = 2; | ||
741 | int div; | ||
742 | |||
743 | if ((c->flags & DIV_U71) && (cparent->flags & PLL_FIXED)) { | ||
744 | div = clk_div71_get_divider(*prate, | ||
745 | rate, c->flags, ROUND_DIVIDER_DOWN); | ||
746 | div = max(div, SUPER_CLOCK_DIV_U71_MIN) + 2; | ||
747 | rate = *prate * mul; | ||
748 | rate += div - 1; /* round up */ | ||
749 | do_div(rate, c->div); | ||
750 | |||
751 | return rate; | ||
752 | } | ||
753 | return *prate; | ||
708 | } | 754 | } |
709 | 755 | ||
710 | struct clk_ops tegra30_super_ops = { | 756 | struct clk_ops tegra30_super_ops = { |
711 | .init = tegra30_super_clk_init, | 757 | .init = tegra30_super_clk_init, |
712 | .enable = tegra30_super_clk_enable, | 758 | .set_parent = tegra30_super_clk_set_parent, |
713 | .disable = tegra30_super_clk_disable, | 759 | .get_parent = tegra30_super_clk_get_parent, |
714 | .set_parent = tegra30_super_clk_set_parent, | 760 | .recalc_rate = tegra30_super_clk_recalc_rate, |
715 | .set_rate = tegra30_super_clk_set_rate, | 761 | .round_rate = tegra30_super_clk_round_rate, |
762 | .set_rate = tegra30_super_clk_set_rate, | ||
716 | }; | 763 | }; |
717 | 764 | ||
718 | static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate) | 765 | static unsigned long tegra30_twd_clk_recalc_rate(struct clk_hw *hw, |
766 | unsigned long parent_rate) | ||
719 | { | 767 | { |
720 | /* The input value 'rate' is the clock rate of the CPU complex. */ | 768 | struct clk_tegra *c = to_clk_tegra(hw); |
721 | c->rate = (rate * c->mul) / c->div; | 769 | u64 rate = parent_rate; |
722 | return 0; | 770 | |
771 | if (c->mul != 0 && c->div != 0) { | ||
772 | rate *= c->mul; | ||
773 | rate += c->div - 1; /* round up */ | ||
774 | do_div(rate, c->div); | ||
775 | } | ||
776 | |||
777 | return rate; | ||
723 | } | 778 | } |
724 | 779 | ||
725 | struct clk_ops tegra30_twd_ops = { | 780 | struct clk_ops tegra30_twd_ops = { |
726 | .set_rate = tegra30_twd_clk_set_rate, | 781 | .recalc_rate = tegra30_twd_clk_recalc_rate, |
727 | }; | 782 | }; |
728 | 783 | ||
729 | /* Blink output functions */ | 784 | /* Blink output functions */ |
730 | 785 | static int tegra30_blink_clk_is_enabled(struct clk_hw *hw) | |
731 | static void tegra30_blink_clk_init(struct clk *c) | ||
732 | { | 786 | { |
787 | struct clk_tegra *c = to_clk_tegra(hw); | ||
733 | u32 val; | 788 | u32 val; |
734 | 789 | ||
735 | val = pmc_readl(PMC_CTRL); | 790 | val = pmc_readl(PMC_CTRL); |
736 | c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; | 791 | c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; |
737 | c->mul = 1; | 792 | return c->state; |
738 | val = pmc_readl(c->reg); | ||
739 | |||
740 | if (val & PMC_BLINK_TIMER_ENB) { | ||
741 | unsigned int on_off; | ||
742 | |||
743 | on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & | ||
744 | PMC_BLINK_TIMER_DATA_ON_MASK; | ||
745 | val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
746 | val &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
747 | on_off += val; | ||
748 | /* each tick in the blink timer is 4 32KHz clocks */ | ||
749 | c->div = on_off * 4; | ||
750 | } else { | ||
751 | c->div = 1; | ||
752 | } | ||
753 | } | 793 | } |
754 | 794 | ||
755 | static int tegra30_blink_clk_enable(struct clk *c) | 795 | static int tegra30_blink_clk_enable(struct clk_hw *hw) |
756 | { | 796 | { |
757 | u32 val; | 797 | u32 val; |
758 | 798 | ||
@@ -765,7 +805,7 @@ static int tegra30_blink_clk_enable(struct clk *c) | |||
765 | return 0; | 805 | return 0; |
766 | } | 806 | } |
767 | 807 | ||
768 | static void tegra30_blink_clk_disable(struct clk *c) | 808 | static void tegra30_blink_clk_disable(struct clk_hw *hw) |
769 | { | 809 | { |
770 | u32 val; | 810 | u32 val; |
771 | 811 | ||
@@ -776,9 +816,11 @@ static void tegra30_blink_clk_disable(struct clk *c) | |||
776 | pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); | 816 | pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); |
777 | } | 817 | } |
778 | 818 | ||
779 | static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate) | 819 | static int tegra30_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
820 | unsigned long parent_rate) | ||
780 | { | 821 | { |
781 | unsigned long parent_rate = clk_get_rate(c->parent); | 822 | struct clk_tegra *c = to_clk_tegra(hw); |
823 | |||
782 | if (rate >= parent_rate) { | 824 | if (rate >= parent_rate) { |
783 | c->div = 1; | 825 | c->div = 1; |
784 | pmc_writel(0, c->reg); | 826 | pmc_writel(0, c->reg); |
@@ -801,40 +843,77 @@ static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate) | |||
801 | return 0; | 843 | return 0; |
802 | } | 844 | } |
803 | 845 | ||
804 | struct clk_ops tegra30_blink_clk_ops = { | 846 | static unsigned long tegra30_blink_clk_recalc_rate(struct clk_hw *hw, |
805 | .init = &tegra30_blink_clk_init, | 847 | unsigned long parent_rate) |
806 | .enable = &tegra30_blink_clk_enable, | 848 | { |
807 | .disable = &tegra30_blink_clk_disable, | 849 | struct clk_tegra *c = to_clk_tegra(hw); |
808 | .set_rate = &tegra30_blink_clk_set_rate, | 850 | u64 rate = parent_rate; |
809 | }; | 851 | u32 val; |
852 | u32 mul; | ||
853 | u32 div; | ||
854 | u32 on_off; | ||
810 | 855 | ||
811 | /* PLL Functions */ | 856 | mul = 1; |
812 | static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg, | 857 | val = pmc_readl(c->reg); |
813 | u32 lock_bit) | 858 | |
859 | if (val & PMC_BLINK_TIMER_ENB) { | ||
860 | on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) & | ||
861 | PMC_BLINK_TIMER_DATA_ON_MASK; | ||
862 | val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT; | ||
863 | val &= PMC_BLINK_TIMER_DATA_OFF_MASK; | ||
864 | on_off += val; | ||
865 | /* each tick in the blink timer is 4 32KHz clocks */ | ||
866 | div = on_off * 4; | ||
867 | } else { | ||
868 | div = 1; | ||
869 | } | ||
870 | |||
871 | if (mul != 0 && div != 0) { | ||
872 | rate *= mul; | ||
873 | rate += div - 1; /* round up */ | ||
874 | do_div(rate, div); | ||
875 | } | ||
876 | return rate; | ||
877 | } | ||
878 | |||
879 | static long tegra30_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
880 | unsigned long *prate) | ||
814 | { | 881 | { |
815 | #if USE_PLL_LOCK_BITS | 882 | int div; |
816 | int i; | 883 | int mul; |
817 | for (i = 0; i < c->u.pll.lock_delay; i++) { | 884 | long round_rate = *prate; |
818 | if (clk_readl(lock_reg) & lock_bit) { | 885 | |
819 | udelay(PLL_POST_LOCK_DELAY); | 886 | mul = 1; |
820 | return 0; | 887 | |
821 | } | 888 | if (rate >= *prate) { |
822 | udelay(2); /* timeout = 2 * lock time */ | 889 | div = 1; |
890 | } else { | ||
891 | div = DIV_ROUND_UP(*prate / 8, rate); | ||
892 | div *= 8; | ||
823 | } | 893 | } |
824 | pr_err("Timed out waiting for lock bit on pll %s", c->name); | ||
825 | return -1; | ||
826 | #endif | ||
827 | udelay(c->u.pll.lock_delay); | ||
828 | 894 | ||
829 | return 0; | 895 | round_rate *= mul; |
896 | round_rate += div - 1; | ||
897 | do_div(round_rate, div); | ||
898 | |||
899 | return round_rate; | ||
830 | } | 900 | } |
831 | 901 | ||
832 | static void tegra30_utmi_param_configure(struct clk *c) | 902 | struct clk_ops tegra30_blink_clk_ops = { |
903 | .is_enabled = tegra30_blink_clk_is_enabled, | ||
904 | .enable = tegra30_blink_clk_enable, | ||
905 | .disable = tegra30_blink_clk_disable, | ||
906 | .recalc_rate = tegra30_blink_clk_recalc_rate, | ||
907 | .round_rate = tegra30_blink_clk_round_rate, | ||
908 | .set_rate = tegra30_blink_clk_set_rate, | ||
909 | }; | ||
910 | |||
911 | static void tegra30_utmi_param_configure(struct clk_hw *hw) | ||
833 | { | 912 | { |
913 | unsigned long main_rate = | ||
914 | __clk_get_rate(__clk_get_parent(__clk_get_parent(hw->clk))); | ||
834 | u32 reg; | 915 | u32 reg; |
835 | int i; | 916 | int i; |
836 | unsigned long main_rate = | ||
837 | clk_get_rate(c->parent->parent); | ||
838 | 917 | ||
839 | for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { | 918 | for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) { |
840 | if (main_rate == utmi_parameters[i].osc_frequency) | 919 | if (main_rate == utmi_parameters[i].osc_frequency) |
@@ -885,50 +964,52 @@ static void tegra30_utmi_param_configure(struct clk *c) | |||
885 | clk_writel(reg, UTMIP_PLL_CFG1); | 964 | clk_writel(reg, UTMIP_PLL_CFG1); |
886 | } | 965 | } |
887 | 966 | ||
888 | static void tegra30_pll_clk_init(struct clk *c) | 967 | /* PLL Functions */ |
968 | static int tegra30_pll_clk_wait_for_lock(struct clk_tegra *c, u32 lock_reg, | ||
969 | u32 lock_bit) | ||
970 | { | ||
971 | int ret = 0; | ||
972 | |||
973 | #if USE_PLL_LOCK_BITS | ||
974 | int i; | ||
975 | for (i = 0; i < c->u.pll.lock_delay; i++) { | ||
976 | if (clk_readl(lock_reg) & lock_bit) { | ||
977 | udelay(PLL_POST_LOCK_DELAY); | ||
978 | return 0; | ||
979 | } | ||
980 | udelay(2); /* timeout = 2 * lock time */ | ||
981 | } | ||
982 | pr_err("Timed out waiting for lock bit on pll %s", | ||
983 | __clk_get_name(hw->clk)); | ||
984 | ret = -1; | ||
985 | #else | ||
986 | udelay(c->u.pll.lock_delay); | ||
987 | #endif | ||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | static int tegra30_pll_clk_is_enabled(struct clk_hw *hw) | ||
889 | { | 992 | { |
993 | struct clk_tegra *c = to_clk_tegra(hw); | ||
890 | u32 val = clk_readl(c->reg + PLL_BASE); | 994 | u32 val = clk_readl(c->reg + PLL_BASE); |
891 | 995 | ||
892 | c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; | 996 | c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; |
997 | return c->state; | ||
998 | } | ||
893 | 999 | ||
894 | if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { | 1000 | static void tegra30_pll_clk_init(struct clk_hw *hw) |
895 | const struct clk_pll_freq_table *sel; | 1001 | { |
896 | unsigned long input_rate = clk_get_rate(c->parent); | 1002 | struct clk_tegra *c = to_clk_tegra(hw); |
897 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
898 | if (sel->input_rate == input_rate && | ||
899 | sel->output_rate == c->u.pll.fixed_rate) { | ||
900 | c->mul = sel->n; | ||
901 | c->div = sel->m * sel->p; | ||
902 | return; | ||
903 | } | ||
904 | } | ||
905 | pr_err("Clock %s has unknown fixed frequency\n", c->name); | ||
906 | BUG(); | ||
907 | } else if (val & PLL_BASE_BYPASS) { | ||
908 | c->mul = 1; | ||
909 | c->div = 1; | ||
910 | } else { | ||
911 | c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; | ||
912 | c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; | ||
913 | if (c->flags & PLLU) | ||
914 | c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; | ||
915 | else | ||
916 | c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >> | ||
917 | PLL_BASE_DIVP_SHIFT)); | ||
918 | if (c->flags & PLL_FIXED) { | ||
919 | unsigned long rate = clk_get_rate_locked(c); | ||
920 | BUG_ON(rate != c->u.pll.fixed_rate); | ||
921 | } | ||
922 | } | ||
923 | 1003 | ||
924 | if (c->flags & PLLU) | 1004 | if (c->flags & PLLU) |
925 | tegra30_utmi_param_configure(c); | 1005 | tegra30_utmi_param_configure(hw); |
926 | } | 1006 | } |
927 | 1007 | ||
928 | static int tegra30_pll_clk_enable(struct clk *c) | 1008 | static int tegra30_pll_clk_enable(struct clk_hw *hw) |
929 | { | 1009 | { |
1010 | struct clk_tegra *c = to_clk_tegra(hw); | ||
930 | u32 val; | 1011 | u32 val; |
931 | pr_debug("%s on clock %s\n", __func__, c->name); | 1012 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); |
932 | 1013 | ||
933 | #if USE_PLL_LOCK_BITS | 1014 | #if USE_PLL_LOCK_BITS |
934 | val = clk_readl(c->reg + PLL_MISC(c)); | 1015 | val = clk_readl(c->reg + PLL_MISC(c)); |
@@ -951,10 +1032,11 @@ static int tegra30_pll_clk_enable(struct clk *c) | |||
951 | return 0; | 1032 | return 0; |
952 | } | 1033 | } |
953 | 1034 | ||
954 | static void tegra30_pll_clk_disable(struct clk *c) | 1035 | static void tegra30_pll_clk_disable(struct clk_hw *hw) |
955 | { | 1036 | { |
1037 | struct clk_tegra *c = to_clk_tegra(hw); | ||
956 | u32 val; | 1038 | u32 val; |
957 | pr_debug("%s on clock %s\n", __func__, c->name); | 1039 | pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk)); |
958 | 1040 | ||
959 | val = clk_readl(c->reg); | 1041 | val = clk_readl(c->reg); |
960 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | 1042 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); |
@@ -967,36 +1049,36 @@ static void tegra30_pll_clk_disable(struct clk *c) | |||
967 | } | 1049 | } |
968 | } | 1050 | } |
969 | 1051 | ||
970 | static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate) | 1052 | static int tegra30_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
1053 | unsigned long parent_rate) | ||
971 | { | 1054 | { |
1055 | struct clk_tegra *c = to_clk_tegra(hw); | ||
972 | u32 val, p_div, old_base; | 1056 | u32 val, p_div, old_base; |
973 | unsigned long input_rate; | 1057 | unsigned long input_rate; |
974 | const struct clk_pll_freq_table *sel; | 1058 | const struct clk_pll_freq_table *sel; |
975 | struct clk_pll_freq_table cfg; | 1059 | struct clk_pll_freq_table cfg; |
976 | 1060 | ||
977 | pr_debug("%s: %s %lu\n", __func__, c->name, rate); | ||
978 | |||
979 | if (c->flags & PLL_FIXED) { | 1061 | if (c->flags & PLL_FIXED) { |
980 | int ret = 0; | 1062 | int ret = 0; |
981 | if (rate != c->u.pll.fixed_rate) { | 1063 | if (rate != c->u.pll.fixed_rate) { |
982 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", | 1064 | pr_err("%s: Can not change %s fixed rate %lu to %lu\n", |
983 | __func__, c->name, c->u.pll.fixed_rate, rate); | 1065 | __func__, __clk_get_name(hw->clk), |
1066 | c->u.pll.fixed_rate, rate); | ||
984 | ret = -EINVAL; | 1067 | ret = -EINVAL; |
985 | } | 1068 | } |
986 | return ret; | 1069 | return ret; |
987 | } | 1070 | } |
988 | 1071 | ||
989 | if (c->flags & PLLM) { | 1072 | if (c->flags & PLLM) { |
990 | if (rate != clk_get_rate_locked(c)) { | 1073 | if (rate != __clk_get_rate(hw->clk)) { |
991 | pr_err("%s: Can not change memory %s rate in flight\n", | 1074 | pr_err("%s: Can not change memory %s rate in flight\n", |
992 | __func__, c->name); | 1075 | __func__, __clk_get_name(hw->clk)); |
993 | return -EINVAL; | 1076 | return -EINVAL; |
994 | } | 1077 | } |
995 | return 0; | ||
996 | } | 1078 | } |
997 | 1079 | ||
998 | p_div = 0; | 1080 | p_div = 0; |
999 | input_rate = clk_get_rate(c->parent); | 1081 | input_rate = parent_rate; |
1000 | 1082 | ||
1001 | /* Check if the target rate is tabulated */ | 1083 | /* Check if the target rate is tabulated */ |
1002 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | 1084 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { |
@@ -1054,7 +1136,7 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate) | |||
1054 | (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) || | 1136 | (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) || |
1055 | (cfg.output_rate > c->u.pll.vco_max)) { | 1137 | (cfg.output_rate > c->u.pll.vco_max)) { |
1056 | pr_err("%s: Failed to set %s out-of-table rate %lu\n", | 1138 | pr_err("%s: Failed to set %s out-of-table rate %lu\n", |
1057 | __func__, c->name, rate); | 1139 | __func__, __clk_get_name(hw->clk), rate); |
1058 | return -EINVAL; | 1140 | return -EINVAL; |
1059 | } | 1141 | } |
1060 | p_div <<= PLL_BASE_DIVP_SHIFT; | 1142 | p_div <<= PLL_BASE_DIVP_SHIFT; |
@@ -1072,7 +1154,7 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate) | |||
1072 | return 0; | 1154 | return 0; |
1073 | 1155 | ||
1074 | if (c->state == ON) { | 1156 | if (c->state == ON) { |
1075 | tegra30_pll_clk_disable(c); | 1157 | tegra30_pll_clk_disable(hw); |
1076 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); | 1158 | val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); |
1077 | } | 1159 | } |
1078 | clk_writel(val, c->reg + PLL_BASE); | 1160 | clk_writel(val, c->reg + PLL_BASE); |
@@ -1094,21 +1176,149 @@ static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate) | |||
1094 | } | 1176 | } |
1095 | 1177 | ||
1096 | if (c->state == ON) | 1178 | if (c->state == ON) |
1097 | tegra30_pll_clk_enable(c); | 1179 | tegra30_pll_clk_enable(hw); |
1180 | |||
1181 | c->u.pll.fixed_rate = rate; | ||
1098 | 1182 | ||
1099 | return 0; | 1183 | return 0; |
1100 | } | 1184 | } |
1101 | 1185 | ||
1186 | static long tegra30_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1187 | unsigned long *prate) | ||
1188 | { | ||
1189 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1190 | unsigned long input_rate = *prate; | ||
1191 | unsigned long output_rate = *prate; | ||
1192 | const struct clk_pll_freq_table *sel; | ||
1193 | struct clk_pll_freq_table cfg; | ||
1194 | int mul; | ||
1195 | int div; | ||
1196 | u32 p_div; | ||
1197 | u32 val; | ||
1198 | |||
1199 | if (c->flags & PLL_FIXED) | ||
1200 | return c->u.pll.fixed_rate; | ||
1201 | |||
1202 | if (c->flags & PLLM) | ||
1203 | return __clk_get_rate(hw->clk); | ||
1204 | |||
1205 | p_div = 0; | ||
1206 | /* Check if the target rate is tabulated */ | ||
1207 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1208 | if (sel->input_rate == input_rate && sel->output_rate == rate) { | ||
1209 | if (c->flags & PLLU) { | ||
1210 | BUG_ON(sel->p < 1 || sel->p > 2); | ||
1211 | if (sel->p == 1) | ||
1212 | p_div = PLLU_BASE_POST_DIV; | ||
1213 | } else { | ||
1214 | BUG_ON(sel->p < 1); | ||
1215 | for (val = sel->p; val > 1; val >>= 1) | ||
1216 | p_div++; | ||
1217 | p_div <<= PLL_BASE_DIVP_SHIFT; | ||
1218 | } | ||
1219 | break; | ||
1220 | } | ||
1221 | } | ||
1222 | |||
1223 | if (sel->input_rate == 0) { | ||
1224 | unsigned long cfreq; | ||
1225 | BUG_ON(c->flags & PLLU); | ||
1226 | sel = &cfg; | ||
1227 | |||
1228 | switch (input_rate) { | ||
1229 | case 12000000: | ||
1230 | case 26000000: | ||
1231 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000; | ||
1232 | break; | ||
1233 | case 13000000: | ||
1234 | cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000; | ||
1235 | break; | ||
1236 | case 16800000: | ||
1237 | case 19200000: | ||
1238 | cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000; | ||
1239 | break; | ||
1240 | default: | ||
1241 | pr_err("%s: Unexpected reference rate %lu\n", | ||
1242 | __func__, input_rate); | ||
1243 | BUG(); | ||
1244 | } | ||
1245 | |||
1246 | /* Raise VCO to guarantee 0.5% accuracy */ | ||
1247 | for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq; | ||
1248 | cfg.output_rate <<= 1) | ||
1249 | p_div++; | ||
1250 | |||
1251 | cfg.p = 0x1 << p_div; | ||
1252 | cfg.m = input_rate / cfreq; | ||
1253 | cfg.n = cfg.output_rate / cfreq; | ||
1254 | } | ||
1255 | |||
1256 | mul = sel->n; | ||
1257 | div = sel->m * sel->p; | ||
1258 | |||
1259 | output_rate *= mul; | ||
1260 | output_rate += div - 1; /* round up */ | ||
1261 | do_div(output_rate, div); | ||
1262 | |||
1263 | return output_rate; | ||
1264 | } | ||
1265 | |||
1266 | static unsigned long tegra30_pll_recalc_rate(struct clk_hw *hw, | ||
1267 | unsigned long parent_rate) | ||
1268 | { | ||
1269 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1270 | u64 rate = parent_rate; | ||
1271 | u32 val = clk_readl(c->reg + PLL_BASE); | ||
1272 | |||
1273 | if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { | ||
1274 | const struct clk_pll_freq_table *sel; | ||
1275 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | ||
1276 | if (sel->input_rate == parent_rate && | ||
1277 | sel->output_rate == c->u.pll.fixed_rate) { | ||
1278 | c->mul = sel->n; | ||
1279 | c->div = sel->m * sel->p; | ||
1280 | break; | ||
1281 | } | ||
1282 | } | ||
1283 | pr_err("Clock %s has unknown fixed frequency\n", | ||
1284 | __clk_get_name(hw->clk)); | ||
1285 | BUG(); | ||
1286 | } else if (val & PLL_BASE_BYPASS) { | ||
1287 | c->mul = 1; | ||
1288 | c->div = 1; | ||
1289 | } else { | ||
1290 | c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT; | ||
1291 | c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT; | ||
1292 | if (c->flags & PLLU) | ||
1293 | c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2; | ||
1294 | else | ||
1295 | c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >> | ||
1296 | PLL_BASE_DIVP_SHIFT)); | ||
1297 | } | ||
1298 | |||
1299 | if (c->mul != 0 && c->div != 0) { | ||
1300 | rate *= c->mul; | ||
1301 | rate += c->div - 1; /* round up */ | ||
1302 | do_div(rate, c->div); | ||
1303 | } | ||
1304 | |||
1305 | return rate; | ||
1306 | } | ||
1307 | |||
1102 | struct clk_ops tegra30_pll_ops = { | 1308 | struct clk_ops tegra30_pll_ops = { |
1103 | .init = tegra30_pll_clk_init, | 1309 | .is_enabled = tegra30_pll_clk_is_enabled, |
1104 | .enable = tegra30_pll_clk_enable, | 1310 | .init = tegra30_pll_clk_init, |
1105 | .disable = tegra30_pll_clk_disable, | 1311 | .enable = tegra30_pll_clk_enable, |
1106 | .set_rate = tegra30_pll_clk_set_rate, | 1312 | .disable = tegra30_pll_clk_disable, |
1313 | .recalc_rate = tegra30_pll_recalc_rate, | ||
1314 | .round_rate = tegra30_pll_round_rate, | ||
1315 | .set_rate = tegra30_pll_clk_set_rate, | ||
1107 | }; | 1316 | }; |
1108 | 1317 | ||
1109 | static int | 1318 | int tegra30_plld_clk_cfg_ex(struct clk_hw *hw, |
1110 | tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | 1319 | enum tegra_clk_ex_param p, u32 setting) |
1111 | { | 1320 | { |
1321 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1112 | u32 val, mask, reg; | 1322 | u32 val, mask, reg; |
1113 | 1323 | ||
1114 | switch (p) { | 1324 | switch (p) { |
@@ -1140,41 +1350,27 @@ tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | |||
1140 | return 0; | 1350 | return 0; |
1141 | } | 1351 | } |
1142 | 1352 | ||
1143 | struct clk_ops tegra_plld_ops = { | 1353 | static int tegra30_plle_clk_is_enabled(struct clk_hw *hw) |
1144 | .init = tegra30_pll_clk_init, | ||
1145 | .enable = tegra30_pll_clk_enable, | ||
1146 | .disable = tegra30_pll_clk_disable, | ||
1147 | .set_rate = tegra30_pll_clk_set_rate, | ||
1148 | .clk_cfg_ex = tegra30_plld_clk_cfg_ex, | ||
1149 | }; | ||
1150 | |||
1151 | static void tegra30_plle_clk_init(struct clk *c) | ||
1152 | { | 1354 | { |
1355 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1153 | u32 val; | 1356 | u32 val; |
1154 | 1357 | ||
1155 | val = clk_readl(PLLE_AUX); | ||
1156 | c->parent = (val & PLLE_AUX_PLLP_SEL) ? | ||
1157 | tegra_get_clock_by_name("pll_p") : | ||
1158 | tegra_get_clock_by_name("pll_ref"); | ||
1159 | |||
1160 | val = clk_readl(c->reg + PLL_BASE); | 1358 | val = clk_readl(c->reg + PLL_BASE); |
1161 | c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF; | 1359 | c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF; |
1162 | c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT; | 1360 | return c->state; |
1163 | c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT; | ||
1164 | c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT; | ||
1165 | } | 1361 | } |
1166 | 1362 | ||
1167 | static void tegra30_plle_clk_disable(struct clk *c) | 1363 | static void tegra30_plle_clk_disable(struct clk_hw *hw) |
1168 | { | 1364 | { |
1365 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1169 | u32 val; | 1366 | u32 val; |
1170 | pr_debug("%s on clock %s\n", __func__, c->name); | ||
1171 | 1367 | ||
1172 | val = clk_readl(c->reg + PLL_BASE); | 1368 | val = clk_readl(c->reg + PLL_BASE); |
1173 | val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); | 1369 | val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE); |
1174 | clk_writel(val, c->reg + PLL_BASE); | 1370 | clk_writel(val, c->reg + PLL_BASE); |
1175 | } | 1371 | } |
1176 | 1372 | ||
1177 | static void tegra30_plle_training(struct clk *c) | 1373 | static void tegra30_plle_training(struct clk_tegra *c) |
1178 | { | 1374 | { |
1179 | u32 val; | 1375 | u32 val; |
1180 | 1376 | ||
@@ -1197,12 +1393,15 @@ static void tegra30_plle_training(struct clk *c) | |||
1197 | } while (!(val & PLLE_MISC_READY)); | 1393 | } while (!(val & PLLE_MISC_READY)); |
1198 | } | 1394 | } |
1199 | 1395 | ||
1200 | static int tegra30_plle_configure(struct clk *c, bool force_training) | 1396 | static int tegra30_plle_configure(struct clk_hw *hw, bool force_training) |
1201 | { | 1397 | { |
1202 | u32 val; | 1398 | struct clk_tegra *c = to_clk_tegra(hw); |
1399 | struct clk *parent = __clk_get_parent(hw->clk); | ||
1203 | const struct clk_pll_freq_table *sel; | 1400 | const struct clk_pll_freq_table *sel; |
1401 | u32 val; | ||
1402 | |||
1204 | unsigned long rate = c->u.pll.fixed_rate; | 1403 | unsigned long rate = c->u.pll.fixed_rate; |
1205 | unsigned long input_rate = clk_get_rate(c->parent); | 1404 | unsigned long input_rate = __clk_get_rate(parent); |
1206 | 1405 | ||
1207 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { | 1406 | for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { |
1208 | if (sel->input_rate == input_rate && sel->output_rate == rate) | 1407 | if (sel->input_rate == input_rate && sel->output_rate == rate) |
@@ -1213,7 +1412,7 @@ static int tegra30_plle_configure(struct clk *c, bool force_training) | |||
1213 | return -ENOSYS; | 1412 | return -ENOSYS; |
1214 | 1413 | ||
1215 | /* disable PLLE, clear setup fiels */ | 1414 | /* disable PLLE, clear setup fiels */ |
1216 | tegra30_plle_clk_disable(c); | 1415 | tegra30_plle_clk_disable(hw); |
1217 | 1416 | ||
1218 | val = clk_readl(c->reg + PLL_MISC(c)); | 1417 | val = clk_readl(c->reg + PLL_MISC(c)); |
1219 | val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); | 1418 | val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK); |
@@ -1251,52 +1450,64 @@ static int tegra30_plle_configure(struct clk *c, bool force_training) | |||
1251 | return 0; | 1450 | return 0; |
1252 | } | 1451 | } |
1253 | 1452 | ||
1254 | static int tegra30_plle_clk_enable(struct clk *c) | 1453 | static int tegra30_plle_clk_enable(struct clk_hw *hw) |
1255 | { | 1454 | { |
1256 | pr_debug("%s on clock %s\n", __func__, c->name); | 1455 | struct clk_tegra *c = to_clk_tegra(hw); |
1257 | return tegra30_plle_configure(c, !c->set); | 1456 | |
1457 | return tegra30_plle_configure(hw, !c->set); | ||
1458 | } | ||
1459 | |||
1460 | static unsigned long tegra30_plle_clk_recalc_rate(struct clk_hw *hw, | ||
1461 | unsigned long parent_rate) | ||
1462 | { | ||
1463 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1464 | unsigned long rate = parent_rate; | ||
1465 | u32 val; | ||
1466 | |||
1467 | val = clk_readl(c->reg + PLL_BASE); | ||
1468 | c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT; | ||
1469 | c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT; | ||
1470 | c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT; | ||
1471 | |||
1472 | if (c->mul != 0 && c->div != 0) { | ||
1473 | rate *= c->mul; | ||
1474 | rate += c->div - 1; /* round up */ | ||
1475 | do_div(rate, c->div); | ||
1476 | } | ||
1477 | return rate; | ||
1258 | } | 1478 | } |
1259 | 1479 | ||
1260 | struct clk_ops tegra30_plle_ops = { | 1480 | struct clk_ops tegra30_plle_ops = { |
1261 | .init = tegra30_plle_clk_init, | 1481 | .is_enabled = tegra30_plle_clk_is_enabled, |
1262 | .enable = tegra30_plle_clk_enable, | 1482 | .enable = tegra30_plle_clk_enable, |
1263 | .disable = tegra30_plle_clk_disable, | 1483 | .disable = tegra30_plle_clk_disable, |
1484 | .recalc_rate = tegra30_plle_clk_recalc_rate, | ||
1264 | }; | 1485 | }; |
1265 | 1486 | ||
1266 | /* Clock divider ops */ | 1487 | /* Clock divider ops */ |
1267 | static void tegra30_pll_div_clk_init(struct clk *c) | 1488 | static int tegra30_pll_div_clk_is_enabled(struct clk_hw *hw) |
1268 | { | 1489 | { |
1490 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1491 | |||
1269 | if (c->flags & DIV_U71) { | 1492 | if (c->flags & DIV_U71) { |
1270 | u32 divu71; | ||
1271 | u32 val = clk_readl(c->reg); | 1493 | u32 val = clk_readl(c->reg); |
1272 | val >>= c->reg_shift; | 1494 | val >>= c->reg_shift; |
1273 | c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; | 1495 | c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; |
1274 | if (!(val & PLL_OUT_RESET_DISABLE)) | 1496 | if (!(val & PLL_OUT_RESET_DISABLE)) |
1275 | c->state = OFF; | 1497 | c->state = OFF; |
1276 | |||
1277 | divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; | ||
1278 | c->div = (divu71 + 2); | ||
1279 | c->mul = 2; | ||
1280 | } else if (c->flags & DIV_2) { | ||
1281 | c->state = ON; | ||
1282 | if (c->flags & (PLLD | PLLX)) { | ||
1283 | c->div = 2; | ||
1284 | c->mul = 1; | ||
1285 | } else | ||
1286 | BUG(); | ||
1287 | } else { | 1498 | } else { |
1288 | c->state = ON; | 1499 | c->state = ON; |
1289 | c->div = 1; | ||
1290 | c->mul = 1; | ||
1291 | } | 1500 | } |
1501 | return c->state; | ||
1292 | } | 1502 | } |
1293 | 1503 | ||
1294 | static int tegra30_pll_div_clk_enable(struct clk *c) | 1504 | static int tegra30_pll_div_clk_enable(struct clk_hw *hw) |
1295 | { | 1505 | { |
1506 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1296 | u32 val; | 1507 | u32 val; |
1297 | u32 new_val; | 1508 | u32 new_val; |
1298 | 1509 | ||
1299 | pr_debug("%s: %s\n", __func__, c->name); | 1510 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); |
1300 | if (c->flags & DIV_U71) { | 1511 | if (c->flags & DIV_U71) { |
1301 | val = clk_readl(c->reg); | 1512 | val = clk_readl(c->reg); |
1302 | new_val = val >> c->reg_shift; | 1513 | new_val = val >> c->reg_shift; |
@@ -1314,12 +1525,13 @@ static int tegra30_pll_div_clk_enable(struct clk *c) | |||
1314 | return -EINVAL; | 1525 | return -EINVAL; |
1315 | } | 1526 | } |
1316 | 1527 | ||
1317 | static void tegra30_pll_div_clk_disable(struct clk *c) | 1528 | static void tegra30_pll_div_clk_disable(struct clk_hw *hw) |
1318 | { | 1529 | { |
1530 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1319 | u32 val; | 1531 | u32 val; |
1320 | u32 new_val; | 1532 | u32 new_val; |
1321 | 1533 | ||
1322 | pr_debug("%s: %s\n", __func__, c->name); | 1534 | pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk)); |
1323 | if (c->flags & DIV_U71) { | 1535 | if (c->flags & DIV_U71) { |
1324 | val = clk_readl(c->reg); | 1536 | val = clk_readl(c->reg); |
1325 | new_val = val >> c->reg_shift; | 1537 | new_val = val >> c->reg_shift; |
@@ -1333,14 +1545,14 @@ static void tegra30_pll_div_clk_disable(struct clk *c) | |||
1333 | } | 1545 | } |
1334 | } | 1546 | } |
1335 | 1547 | ||
1336 | static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate) | 1548 | static int tegra30_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
1549 | unsigned long parent_rate) | ||
1337 | { | 1550 | { |
1551 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1338 | u32 val; | 1552 | u32 val; |
1339 | u32 new_val; | 1553 | u32 new_val; |
1340 | int divider_u71; | 1554 | int divider_u71; |
1341 | unsigned long parent_rate = clk_get_rate(c->parent); | ||
1342 | 1555 | ||
1343 | pr_debug("%s: %s %lu\n", __func__, c->name, rate); | ||
1344 | if (c->flags & DIV_U71) { | 1556 | if (c->flags & DIV_U71) { |
1345 | divider_u71 = clk_div71_get_divider( | 1557 | divider_u71 = clk_div71_get_divider( |
1346 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); | 1558 | parent_rate, rate, c->flags, ROUND_DIVIDER_UP); |
@@ -1358,19 +1570,59 @@ static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate) | |||
1358 | clk_writel_delay(val, c->reg); | 1570 | clk_writel_delay(val, c->reg); |
1359 | c->div = divider_u71 + 2; | 1571 | c->div = divider_u71 + 2; |
1360 | c->mul = 2; | 1572 | c->mul = 2; |
1573 | c->fixed_rate = rate; | ||
1361 | return 0; | 1574 | return 0; |
1362 | } | 1575 | } |
1363 | } else if (c->flags & DIV_2) | 1576 | } else if (c->flags & DIV_2) { |
1364 | return clk_set_rate(c->parent, rate * 2); | 1577 | c->fixed_rate = rate; |
1578 | return 0; | ||
1579 | } | ||
1365 | 1580 | ||
1366 | return -EINVAL; | 1581 | return -EINVAL; |
1367 | } | 1582 | } |
1368 | 1583 | ||
1369 | static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate) | 1584 | static unsigned long tegra30_pll_div_clk_recalc_rate(struct clk_hw *hw, |
1585 | unsigned long parent_rate) | ||
1586 | { | ||
1587 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1588 | u64 rate = parent_rate; | ||
1589 | |||
1590 | if (c->flags & DIV_U71) { | ||
1591 | u32 divu71; | ||
1592 | u32 val = clk_readl(c->reg); | ||
1593 | val >>= c->reg_shift; | ||
1594 | |||
1595 | divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; | ||
1596 | c->div = (divu71 + 2); | ||
1597 | c->mul = 2; | ||
1598 | } else if (c->flags & DIV_2) { | ||
1599 | if (c->flags & (PLLD | PLLX)) { | ||
1600 | c->div = 2; | ||
1601 | c->mul = 1; | ||
1602 | } else | ||
1603 | BUG(); | ||
1604 | } else { | ||
1605 | c->div = 1; | ||
1606 | c->mul = 1; | ||
1607 | } | ||
1608 | if (c->mul != 0 && c->div != 0) { | ||
1609 | rate *= c->mul; | ||
1610 | rate += c->div - 1; /* round up */ | ||
1611 | do_div(rate, c->div); | ||
1612 | } | ||
1613 | |||
1614 | return rate; | ||
1615 | } | ||
1616 | |||
1617 | static long tegra30_pll_div_clk_round_rate(struct clk_hw *hw, | ||
1618 | unsigned long rate, unsigned long *prate) | ||
1370 | { | 1619 | { |
1620 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1621 | unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); | ||
1371 | int divider; | 1622 | int divider; |
1372 | unsigned long parent_rate = clk_get_rate(c->parent); | 1623 | |
1373 | pr_debug("%s: %s %lu\n", __func__, c->name, rate); | 1624 | if (prate) |
1625 | parent_rate = *prate; | ||
1374 | 1626 | ||
1375 | if (c->flags & DIV_U71) { | 1627 | if (c->flags & DIV_U71) { |
1376 | divider = clk_div71_get_divider( | 1628 | divider = clk_div71_get_divider( |
@@ -1378,23 +1630,25 @@ static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate) | |||
1378 | if (divider < 0) | 1630 | if (divider < 0) |
1379 | return divider; | 1631 | return divider; |
1380 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); | 1632 | return DIV_ROUND_UP(parent_rate * 2, divider + 2); |
1381 | } else if (c->flags & DIV_2) | 1633 | } else if (c->flags & DIV_2) { |
1382 | /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */ | 1634 | *prate = rate * 2; |
1383 | return rate; | 1635 | return rate; |
1636 | } | ||
1384 | 1637 | ||
1385 | return -EINVAL; | 1638 | return -EINVAL; |
1386 | } | 1639 | } |
1387 | 1640 | ||
1388 | struct clk_ops tegra30_pll_div_ops = { | 1641 | struct clk_ops tegra30_pll_div_ops = { |
1389 | .init = tegra30_pll_div_clk_init, | 1642 | .is_enabled = tegra30_pll_div_clk_is_enabled, |
1390 | .enable = tegra30_pll_div_clk_enable, | 1643 | .enable = tegra30_pll_div_clk_enable, |
1391 | .disable = tegra30_pll_div_clk_disable, | 1644 | .disable = tegra30_pll_div_clk_disable, |
1392 | .set_rate = tegra30_pll_div_clk_set_rate, | 1645 | .set_rate = tegra30_pll_div_clk_set_rate, |
1393 | .round_rate = tegra30_pll_div_clk_round_rate, | 1646 | .recalc_rate = tegra30_pll_div_clk_recalc_rate, |
1647 | .round_rate = tegra30_pll_div_clk_round_rate, | ||
1394 | }; | 1648 | }; |
1395 | 1649 | ||
1396 | /* Periph clk ops */ | 1650 | /* Periph clk ops */ |
1397 | static inline u32 periph_clk_source_mask(struct clk *c) | 1651 | static inline u32 periph_clk_source_mask(struct clk_tegra *c) |
1398 | { | 1652 | { |
1399 | if (c->flags & MUX8) | 1653 | if (c->flags & MUX8) |
1400 | return 7 << 29; | 1654 | return 7 << 29; |
@@ -1408,7 +1662,7 @@ static inline u32 periph_clk_source_mask(struct clk *c) | |||
1408 | return 3 << 30; | 1662 | return 3 << 30; |
1409 | } | 1663 | } |
1410 | 1664 | ||
1411 | static inline u32 periph_clk_source_shift(struct clk *c) | 1665 | static inline u32 periph_clk_source_shift(struct clk_tegra *c) |
1412 | { | 1666 | { |
1413 | if (c->flags & MUX8) | 1667 | if (c->flags & MUX8) |
1414 | return 29; | 1668 | return 29; |
@@ -1422,47 +1676,9 @@ static inline u32 periph_clk_source_shift(struct clk *c) | |||
1422 | return 30; | 1676 | return 30; |
1423 | } | 1677 | } |
1424 | 1678 | ||
1425 | static void tegra30_periph_clk_init(struct clk *c) | 1679 | static int tegra30_periph_clk_is_enabled(struct clk_hw *hw) |
1426 | { | 1680 | { |
1427 | u32 val = clk_readl(c->reg); | 1681 | struct clk_tegra *c = to_clk_tegra(hw); |
1428 | const struct clk_mux_sel *mux = 0; | ||
1429 | const struct clk_mux_sel *sel; | ||
1430 | if (c->flags & MUX) { | ||
1431 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
1432 | if (((val & periph_clk_source_mask(c)) >> | ||
1433 | periph_clk_source_shift(c)) == sel->value) | ||
1434 | mux = sel; | ||
1435 | } | ||
1436 | BUG_ON(!mux); | ||
1437 | |||
1438 | c->parent = mux->input; | ||
1439 | } else { | ||
1440 | c->parent = c->inputs[0].input; | ||
1441 | } | ||
1442 | |||
1443 | if (c->flags & DIV_U71) { | ||
1444 | u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
1445 | if ((c->flags & DIV_U71_UART) && | ||
1446 | (!(val & PERIPH_CLK_UART_DIV_ENB))) { | ||
1447 | divu71 = 0; | ||
1448 | } | ||
1449 | if (c->flags & DIV_U71_IDLE) { | ||
1450 | val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK << | ||
1451 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
1452 | val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL << | ||
1453 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
1454 | clk_writel(val, c->reg); | ||
1455 | } | ||
1456 | c->div = divu71 + 2; | ||
1457 | c->mul = 2; | ||
1458 | } else if (c->flags & DIV_U16) { | ||
1459 | u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
1460 | c->div = divu16 + 1; | ||
1461 | c->mul = 1; | ||
1462 | } else { | ||
1463 | c->div = 1; | ||
1464 | c->mul = 1; | ||
1465 | } | ||
1466 | 1682 | ||
1467 | c->state = ON; | 1683 | c->state = ON; |
1468 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) | 1684 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) |
@@ -1470,11 +1686,12 @@ static void tegra30_periph_clk_init(struct clk *c) | |||
1470 | if (!(c->flags & PERIPH_NO_RESET)) | 1686 | if (!(c->flags & PERIPH_NO_RESET)) |
1471 | if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) | 1687 | if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) |
1472 | c->state = OFF; | 1688 | c->state = OFF; |
1689 | return c->state; | ||
1473 | } | 1690 | } |
1474 | 1691 | ||
1475 | static int tegra30_periph_clk_enable(struct clk *c) | 1692 | static int tegra30_periph_clk_enable(struct clk_hw *hw) |
1476 | { | 1693 | { |
1477 | pr_debug("%s on clock %s\n", __func__, c->name); | 1694 | struct clk_tegra *c = to_clk_tegra(hw); |
1478 | 1695 | ||
1479 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; | 1696 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; |
1480 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) | 1697 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) |
@@ -1493,31 +1710,29 @@ static int tegra30_periph_clk_enable(struct clk *c) | |||
1493 | return 0; | 1710 | return 0; |
1494 | } | 1711 | } |
1495 | 1712 | ||
1496 | static void tegra30_periph_clk_disable(struct clk *c) | 1713 | static void tegra30_periph_clk_disable(struct clk_hw *hw) |
1497 | { | 1714 | { |
1715 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1498 | unsigned long val; | 1716 | unsigned long val; |
1499 | pr_debug("%s on clock %s\n", __func__, c->name); | ||
1500 | 1717 | ||
1501 | if (c->refcnt) | 1718 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; |
1502 | tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; | ||
1503 | 1719 | ||
1504 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) { | 1720 | if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0) |
1505 | /* If peripheral is in the APB bus then read the APB bus to | 1721 | return; |
1506 | * flush the write operation in apb bus. This will avoid the | ||
1507 | * peripheral access after disabling clock*/ | ||
1508 | if (c->flags & PERIPH_ON_APB) | ||
1509 | val = chipid_readl(); | ||
1510 | 1722 | ||
1511 | clk_writel_delay( | 1723 | /* If peripheral is in the APB bus then read the APB bus to |
1512 | PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c)); | 1724 | * flush the write operation in apb bus. This will avoid the |
1513 | } | 1725 | * peripheral access after disabling clock*/ |
1726 | if (c->flags & PERIPH_ON_APB) | ||
1727 | val = chipid_readl(); | ||
1728 | |||
1729 | clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c)); | ||
1514 | } | 1730 | } |
1515 | 1731 | ||
1516 | static void tegra30_periph_clk_reset(struct clk *c, bool assert) | 1732 | void tegra30_periph_clk_reset(struct clk_hw *hw, bool assert) |
1517 | { | 1733 | { |
1734 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1518 | unsigned long val; | 1735 | unsigned long val; |
1519 | pr_debug("%s %s on clock %s\n", __func__, | ||
1520 | assert ? "assert" : "deassert", c->name); | ||
1521 | 1736 | ||
1522 | if (!(c->flags & PERIPH_NO_RESET)) { | 1737 | if (!(c->flags & PERIPH_NO_RESET)) { |
1523 | if (assert) { | 1738 | if (assert) { |
@@ -1536,42 +1751,40 @@ static void tegra30_periph_clk_reset(struct clk *c, bool assert) | |||
1536 | } | 1751 | } |
1537 | } | 1752 | } |
1538 | 1753 | ||
1539 | static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p) | 1754 | static int tegra30_periph_clk_set_parent(struct clk_hw *hw, u8 index) |
1540 | { | 1755 | { |
1756 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1541 | u32 val; | 1757 | u32 val; |
1542 | const struct clk_mux_sel *sel; | ||
1543 | pr_debug("%s: %s %s\n", __func__, c->name, p->name); | ||
1544 | 1758 | ||
1545 | if (!(c->flags & MUX)) | 1759 | if (!(c->flags & MUX)) |
1546 | return (p == c->parent) ? 0 : (-EINVAL); | 1760 | return (index == 0) ? 0 : (-EINVAL); |
1547 | 1761 | ||
1548 | for (sel = c->inputs; sel->input != NULL; sel++) { | 1762 | val = clk_readl(c->reg); |
1549 | if (sel->input == p) { | 1763 | val &= ~periph_clk_source_mask(c); |
1550 | val = clk_readl(c->reg); | 1764 | val |= (index << periph_clk_source_shift(c)); |
1551 | val &= ~periph_clk_source_mask(c); | 1765 | clk_writel_delay(val, c->reg); |
1552 | val |= (sel->value << periph_clk_source_shift(c)); | 1766 | return 0; |
1553 | 1767 | } | |
1554 | if (c->refcnt) | ||
1555 | clk_enable(p); | ||
1556 | |||
1557 | clk_writel_delay(val, c->reg); | ||
1558 | 1768 | ||
1559 | if (c->refcnt && c->parent) | 1769 | static u8 tegra30_periph_clk_get_parent(struct clk_hw *hw) |
1560 | clk_disable(c->parent); | 1770 | { |
1771 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1772 | u32 val = clk_readl(c->reg); | ||
1773 | int source = (val & periph_clk_source_mask(c)) >> | ||
1774 | periph_clk_source_shift(c); | ||
1561 | 1775 | ||
1562 | clk_reparent(c, p); | 1776 | if (!(c->flags & MUX)) |
1563 | return 0; | 1777 | return 0; |
1564 | } | ||
1565 | } | ||
1566 | 1778 | ||
1567 | return -EINVAL; | 1779 | return source; |
1568 | } | 1780 | } |
1569 | 1781 | ||
1570 | static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate) | 1782 | static int tegra30_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
1783 | unsigned long parent_rate) | ||
1571 | { | 1784 | { |
1785 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1572 | u32 val; | 1786 | u32 val; |
1573 | int divider; | 1787 | int divider; |
1574 | unsigned long parent_rate = clk_get_rate(c->parent); | ||
1575 | 1788 | ||
1576 | if (c->flags & DIV_U71) { | 1789 | if (c->flags & DIV_U71) { |
1577 | divider = clk_div71_get_divider( | 1790 | divider = clk_div71_get_divider( |
@@ -1610,12 +1823,15 @@ static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate) | |||
1610 | return -EINVAL; | 1823 | return -EINVAL; |
1611 | } | 1824 | } |
1612 | 1825 | ||
1613 | static long tegra30_periph_clk_round_rate(struct clk *c, | 1826 | static long tegra30_periph_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
1614 | unsigned long rate) | 1827 | unsigned long *prate) |
1615 | { | 1828 | { |
1829 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1830 | unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk)); | ||
1616 | int divider; | 1831 | int divider; |
1617 | unsigned long parent_rate = clk_get_rate(c->parent); | 1832 | |
1618 | pr_debug("%s: %s %lu\n", __func__, c->name, rate); | 1833 | if (prate) |
1834 | parent_rate = *prate; | ||
1619 | 1835 | ||
1620 | if (c->flags & DIV_U71) { | 1836 | if (c->flags & DIV_U71) { |
1621 | divider = clk_div71_get_divider( | 1837 | divider = clk_div71_get_divider( |
@@ -1633,20 +1849,85 @@ static long tegra30_periph_clk_round_rate(struct clk *c, | |||
1633 | return -EINVAL; | 1849 | return -EINVAL; |
1634 | } | 1850 | } |
1635 | 1851 | ||
1852 | static unsigned long tegra30_periph_clk_recalc_rate(struct clk_hw *hw, | ||
1853 | unsigned long parent_rate) | ||
1854 | { | ||
1855 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1856 | u64 rate = parent_rate; | ||
1857 | u32 val = clk_readl(c->reg); | ||
1858 | |||
1859 | if (c->flags & DIV_U71) { | ||
1860 | u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK; | ||
1861 | if ((c->flags & DIV_U71_UART) && | ||
1862 | (!(val & PERIPH_CLK_UART_DIV_ENB))) { | ||
1863 | divu71 = 0; | ||
1864 | } | ||
1865 | if (c->flags & DIV_U71_IDLE) { | ||
1866 | val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK << | ||
1867 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
1868 | val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL << | ||
1869 | PERIPH_CLK_SOURCE_DIVIDLE_SHIFT); | ||
1870 | clk_writel(val, c->reg); | ||
1871 | } | ||
1872 | c->div = divu71 + 2; | ||
1873 | c->mul = 2; | ||
1874 | } else if (c->flags & DIV_U16) { | ||
1875 | u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK; | ||
1876 | c->div = divu16 + 1; | ||
1877 | c->mul = 1; | ||
1878 | } else { | ||
1879 | c->div = 1; | ||
1880 | c->mul = 1; | ||
1881 | } | ||
1882 | |||
1883 | if (c->mul != 0 && c->div != 0) { | ||
1884 | rate *= c->mul; | ||
1885 | rate += c->div - 1; /* round up */ | ||
1886 | do_div(rate, c->div); | ||
1887 | } | ||
1888 | return rate; | ||
1889 | } | ||
1890 | |||
1636 | struct clk_ops tegra30_periph_clk_ops = { | 1891 | struct clk_ops tegra30_periph_clk_ops = { |
1637 | .init = &tegra30_periph_clk_init, | 1892 | .is_enabled = tegra30_periph_clk_is_enabled, |
1893 | .enable = tegra30_periph_clk_enable, | ||
1894 | .disable = tegra30_periph_clk_disable, | ||
1895 | .set_parent = tegra30_periph_clk_set_parent, | ||
1896 | .get_parent = tegra30_periph_clk_get_parent, | ||
1897 | .set_rate = tegra30_periph_clk_set_rate, | ||
1898 | .round_rate = tegra30_periph_clk_round_rate, | ||
1899 | .recalc_rate = tegra30_periph_clk_recalc_rate, | ||
1900 | }; | ||
1901 | |||
1902 | static int tegra30_dsib_clk_set_parent(struct clk_hw *hw, u8 index) | ||
1903 | { | ||
1904 | struct clk *d = clk_get_sys(NULL, "pll_d"); | ||
1905 | /* The DSIB parent selection bit is in PLLD base | ||
1906 | register - can not do direct r-m-w, must be | ||
1907 | protected by PLLD lock */ | ||
1908 | tegra_clk_cfg_ex( | ||
1909 | d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, index); | ||
1910 | |||
1911 | return 0; | ||
1912 | } | ||
1913 | |||
1914 | struct clk_ops tegra30_dsib_clk_ops = { | ||
1915 | .is_enabled = tegra30_periph_clk_is_enabled, | ||
1638 | .enable = &tegra30_periph_clk_enable, | 1916 | .enable = &tegra30_periph_clk_enable, |
1639 | .disable = &tegra30_periph_clk_disable, | 1917 | .disable = &tegra30_periph_clk_disable, |
1640 | .set_parent = &tegra30_periph_clk_set_parent, | 1918 | .set_parent = &tegra30_dsib_clk_set_parent, |
1919 | .get_parent = &tegra30_periph_clk_get_parent, | ||
1641 | .set_rate = &tegra30_periph_clk_set_rate, | 1920 | .set_rate = &tegra30_periph_clk_set_rate, |
1642 | .round_rate = &tegra30_periph_clk_round_rate, | 1921 | .round_rate = &tegra30_periph_clk_round_rate, |
1643 | .reset = &tegra30_periph_clk_reset, | 1922 | .recalc_rate = &tegra30_periph_clk_recalc_rate, |
1644 | }; | 1923 | }; |
1645 | 1924 | ||
1646 | /* Periph extended clock configuration ops */ | 1925 | /* Periph extended clock configuration ops */ |
1647 | static int | 1926 | int tegra30_vi_clk_cfg_ex(struct clk_hw *hw, |
1648 | tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | 1927 | enum tegra_clk_ex_param p, u32 setting) |
1649 | { | 1928 | { |
1929 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1930 | |||
1650 | if (p == TEGRA_CLK_VI_INP_SEL) { | 1931 | if (p == TEGRA_CLK_VI_INP_SEL) { |
1651 | u32 val = clk_readl(c->reg); | 1932 | u32 val = clk_readl(c->reg); |
1652 | val &= ~PERIPH_CLK_VI_SEL_EX_MASK; | 1933 | val &= ~PERIPH_CLK_VI_SEL_EX_MASK; |
@@ -1658,20 +1939,11 @@ tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | |||
1658 | return -EINVAL; | 1939 | return -EINVAL; |
1659 | } | 1940 | } |
1660 | 1941 | ||
1661 | struct clk_ops tegra_vi_clk_ops = { | 1942 | int tegra30_nand_clk_cfg_ex(struct clk_hw *hw, |
1662 | .init = &tegra30_periph_clk_init, | 1943 | enum tegra_clk_ex_param p, u32 setting) |
1663 | .enable = &tegra30_periph_clk_enable, | ||
1664 | .disable = &tegra30_periph_clk_disable, | ||
1665 | .set_parent = &tegra30_periph_clk_set_parent, | ||
1666 | .set_rate = &tegra30_periph_clk_set_rate, | ||
1667 | .round_rate = &tegra30_periph_clk_round_rate, | ||
1668 | .clk_cfg_ex = &tegra30_vi_clk_cfg_ex, | ||
1669 | .reset = &tegra30_periph_clk_reset, | ||
1670 | }; | ||
1671 | |||
1672 | static int | ||
1673 | tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | ||
1674 | { | 1944 | { |
1945 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1946 | |||
1675 | if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) { | 1947 | if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) { |
1676 | u32 val = clk_readl(c->reg); | 1948 | u32 val = clk_readl(c->reg); |
1677 | if (setting) | 1949 | if (setting) |
@@ -1684,20 +1956,11 @@ tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | |||
1684 | return -EINVAL; | 1956 | return -EINVAL; |
1685 | } | 1957 | } |
1686 | 1958 | ||
1687 | struct clk_ops tegra_nand_clk_ops = { | 1959 | int tegra30_dtv_clk_cfg_ex(struct clk_hw *hw, |
1688 | .init = &tegra30_periph_clk_init, | 1960 | enum tegra_clk_ex_param p, u32 setting) |
1689 | .enable = &tegra30_periph_clk_enable, | ||
1690 | .disable = &tegra30_periph_clk_disable, | ||
1691 | .set_parent = &tegra30_periph_clk_set_parent, | ||
1692 | .set_rate = &tegra30_periph_clk_set_rate, | ||
1693 | .round_rate = &tegra30_periph_clk_round_rate, | ||
1694 | .clk_cfg_ex = &tegra30_nand_clk_cfg_ex, | ||
1695 | .reset = &tegra30_periph_clk_reset, | ||
1696 | }; | ||
1697 | |||
1698 | static int | ||
1699 | tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | ||
1700 | { | 1961 | { |
1962 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1963 | |||
1701 | if (p == TEGRA_CLK_DTV_INVERT) { | 1964 | if (p == TEGRA_CLK_DTV_INVERT) { |
1702 | u32 val = clk_readl(c->reg); | 1965 | u32 val = clk_readl(c->reg); |
1703 | if (setting) | 1966 | if (setting) |
@@ -1710,91 +1973,27 @@ tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting) | |||
1710 | return -EINVAL; | 1973 | return -EINVAL; |
1711 | } | 1974 | } |
1712 | 1975 | ||
1713 | struct clk_ops tegra_dtv_clk_ops = { | ||
1714 | .init = &tegra30_periph_clk_init, | ||
1715 | .enable = &tegra30_periph_clk_enable, | ||
1716 | .disable = &tegra30_periph_clk_disable, | ||
1717 | .set_parent = &tegra30_periph_clk_set_parent, | ||
1718 | .set_rate = &tegra30_periph_clk_set_rate, | ||
1719 | .round_rate = &tegra30_periph_clk_round_rate, | ||
1720 | .clk_cfg_ex = &tegra30_dtv_clk_cfg_ex, | ||
1721 | .reset = &tegra30_periph_clk_reset, | ||
1722 | }; | ||
1723 | |||
1724 | static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p) | ||
1725 | { | ||
1726 | const struct clk_mux_sel *sel; | ||
1727 | struct clk *d = tegra_get_clock_by_name("pll_d"); | ||
1728 | |||
1729 | pr_debug("%s: %s %s\n", __func__, c->name, p->name); | ||
1730 | |||
1731 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
1732 | if (sel->input == p) { | ||
1733 | if (c->refcnt) | ||
1734 | clk_enable(p); | ||
1735 | |||
1736 | /* The DSIB parent selection bit is in PLLD base | ||
1737 | register - can not do direct r-m-w, must be | ||
1738 | protected by PLLD lock */ | ||
1739 | tegra_clk_cfg_ex( | ||
1740 | d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value); | ||
1741 | |||
1742 | if (c->refcnt && c->parent) | ||
1743 | clk_disable(c->parent); | ||
1744 | |||
1745 | clk_reparent(c, p); | ||
1746 | return 0; | ||
1747 | } | ||
1748 | } | ||
1749 | |||
1750 | return -EINVAL; | ||
1751 | } | ||
1752 | |||
1753 | struct clk_ops tegra_dsib_clk_ops = { | ||
1754 | .init = &tegra30_periph_clk_init, | ||
1755 | .enable = &tegra30_periph_clk_enable, | ||
1756 | .disable = &tegra30_periph_clk_disable, | ||
1757 | .set_parent = &tegra30_dsib_clk_set_parent, | ||
1758 | .set_rate = &tegra30_periph_clk_set_rate, | ||
1759 | .round_rate = &tegra30_periph_clk_round_rate, | ||
1760 | .reset = &tegra30_periph_clk_reset, | ||
1761 | }; | ||
1762 | |||
1763 | /* pciex clock support only reset function */ | ||
1764 | struct clk_ops tegra_pciex_clk_ops = { | ||
1765 | .reset = tegra30_periph_clk_reset, | ||
1766 | }; | ||
1767 | |||
1768 | /* Output clock ops */ | 1976 | /* Output clock ops */ |
1769 | 1977 | ||
1770 | static DEFINE_SPINLOCK(clk_out_lock); | 1978 | static DEFINE_SPINLOCK(clk_out_lock); |
1771 | 1979 | ||
1772 | static void tegra30_clk_out_init(struct clk *c) | 1980 | static int tegra30_clk_out_is_enabled(struct clk_hw *hw) |
1773 | { | 1981 | { |
1774 | const struct clk_mux_sel *mux = 0; | 1982 | struct clk_tegra *c = to_clk_tegra(hw); |
1775 | const struct clk_mux_sel *sel; | ||
1776 | u32 val = pmc_readl(c->reg); | 1983 | u32 val = pmc_readl(c->reg); |
1777 | 1984 | ||
1778 | c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF; | 1985 | c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF; |
1779 | c->mul = 1; | 1986 | c->mul = 1; |
1780 | c->div = 1; | 1987 | c->div = 1; |
1781 | 1988 | return c->state; | |
1782 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
1783 | if (((val & periph_clk_source_mask(c)) >> | ||
1784 | periph_clk_source_shift(c)) == sel->value) | ||
1785 | mux = sel; | ||
1786 | } | ||
1787 | BUG_ON(!mux); | ||
1788 | c->parent = mux->input; | ||
1789 | } | 1989 | } |
1790 | 1990 | ||
1791 | static int tegra30_clk_out_enable(struct clk *c) | 1991 | static int tegra30_clk_out_enable(struct clk_hw *hw) |
1792 | { | 1992 | { |
1993 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1793 | u32 val; | 1994 | u32 val; |
1794 | unsigned long flags; | 1995 | unsigned long flags; |
1795 | 1996 | ||
1796 | pr_debug("%s on clock %s\n", __func__, c->name); | ||
1797 | |||
1798 | spin_lock_irqsave(&clk_out_lock, flags); | 1997 | spin_lock_irqsave(&clk_out_lock, flags); |
1799 | val = pmc_readl(c->reg); | 1998 | val = pmc_readl(c->reg); |
1800 | val |= (0x1 << c->u.periph.clk_num); | 1999 | val |= (0x1 << c->u.periph.clk_num); |
@@ -1804,13 +2003,12 @@ static int tegra30_clk_out_enable(struct clk *c) | |||
1804 | return 0; | 2003 | return 0; |
1805 | } | 2004 | } |
1806 | 2005 | ||
1807 | static void tegra30_clk_out_disable(struct clk *c) | 2006 | static void tegra30_clk_out_disable(struct clk_hw *hw) |
1808 | { | 2007 | { |
2008 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1809 | u32 val; | 2009 | u32 val; |
1810 | unsigned long flags; | 2010 | unsigned long flags; |
1811 | 2011 | ||
1812 | pr_debug("%s on clock %s\n", __func__, c->name); | ||
1813 | |||
1814 | spin_lock_irqsave(&clk_out_lock, flags); | 2012 | spin_lock_irqsave(&clk_out_lock, flags); |
1815 | val = pmc_readl(c->reg); | 2013 | val = pmc_readl(c->reg); |
1816 | val &= ~(0x1 << c->u.periph.clk_num); | 2014 | val &= ~(0x1 << c->u.periph.clk_num); |
@@ -1818,58 +2016,59 @@ static void tegra30_clk_out_disable(struct clk *c) | |||
1818 | spin_unlock_irqrestore(&clk_out_lock, flags); | 2016 | spin_unlock_irqrestore(&clk_out_lock, flags); |
1819 | } | 2017 | } |
1820 | 2018 | ||
1821 | static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p) | 2019 | static int tegra30_clk_out_set_parent(struct clk_hw *hw, u8 index) |
1822 | { | 2020 | { |
2021 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1823 | u32 val; | 2022 | u32 val; |
1824 | unsigned long flags; | 2023 | unsigned long flags; |
1825 | const struct clk_mux_sel *sel; | ||
1826 | 2024 | ||
1827 | pr_debug("%s: %s %s\n", __func__, c->name, p->name); | 2025 | spin_lock_irqsave(&clk_out_lock, flags); |
1828 | 2026 | val = pmc_readl(c->reg); | |
1829 | for (sel = c->inputs; sel->input != NULL; sel++) { | 2027 | val &= ~periph_clk_source_mask(c); |
1830 | if (sel->input == p) { | 2028 | val |= (index << periph_clk_source_shift(c)); |
1831 | if (c->refcnt) | 2029 | pmc_writel(val, c->reg); |
1832 | clk_enable(p); | 2030 | spin_unlock_irqrestore(&clk_out_lock, flags); |
1833 | 2031 | ||
1834 | spin_lock_irqsave(&clk_out_lock, flags); | 2032 | return 0; |
1835 | val = pmc_readl(c->reg); | 2033 | } |
1836 | val &= ~periph_clk_source_mask(c); | ||
1837 | val |= (sel->value << periph_clk_source_shift(c)); | ||
1838 | pmc_writel(val, c->reg); | ||
1839 | spin_unlock_irqrestore(&clk_out_lock, flags); | ||
1840 | 2034 | ||
1841 | if (c->refcnt && c->parent) | 2035 | static u8 tegra30_clk_out_get_parent(struct clk_hw *hw) |
1842 | clk_disable(c->parent); | 2036 | { |
2037 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2038 | u32 val = pmc_readl(c->reg); | ||
2039 | int source; | ||
1843 | 2040 | ||
1844 | clk_reparent(c, p); | 2041 | source = (val & periph_clk_source_mask(c)) >> |
1845 | return 0; | 2042 | periph_clk_source_shift(c); |
1846 | } | 2043 | return source; |
1847 | } | ||
1848 | return -EINVAL; | ||
1849 | } | 2044 | } |
1850 | 2045 | ||
1851 | struct clk_ops tegra_clk_out_ops = { | 2046 | struct clk_ops tegra_clk_out_ops = { |
1852 | .init = &tegra30_clk_out_init, | 2047 | .is_enabled = tegra30_clk_out_is_enabled, |
1853 | .enable = &tegra30_clk_out_enable, | 2048 | .enable = tegra30_clk_out_enable, |
1854 | .disable = &tegra30_clk_out_disable, | 2049 | .disable = tegra30_clk_out_disable, |
1855 | .set_parent = &tegra30_clk_out_set_parent, | 2050 | .set_parent = tegra30_clk_out_set_parent, |
2051 | .get_parent = tegra30_clk_out_get_parent, | ||
2052 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
1856 | }; | 2053 | }; |
1857 | 2054 | ||
1858 | /* Clock doubler ops */ | 2055 | /* Clock doubler ops */ |
1859 | static void tegra30_clk_double_init(struct clk *c) | 2056 | static int tegra30_clk_double_is_enabled(struct clk_hw *hw) |
1860 | { | 2057 | { |
1861 | u32 val = clk_readl(c->reg); | 2058 | struct clk_tegra *c = to_clk_tegra(hw); |
1862 | c->mul = val & (0x1 << c->reg_shift) ? 1 : 2; | 2059 | |
1863 | c->div = 1; | ||
1864 | c->state = ON; | 2060 | c->state = ON; |
1865 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) | 2061 | if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c))) |
1866 | c->state = OFF; | 2062 | c->state = OFF; |
2063 | return c->state; | ||
1867 | }; | 2064 | }; |
1868 | 2065 | ||
1869 | static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate) | 2066 | static int tegra30_clk_double_set_rate(struct clk_hw *hw, unsigned long rate, |
2067 | unsigned long parent_rate) | ||
1870 | { | 2068 | { |
2069 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1871 | u32 val; | 2070 | u32 val; |
1872 | unsigned long parent_rate = clk_get_rate(c->parent); | 2071 | |
1873 | if (rate == parent_rate) { | 2072 | if (rate == parent_rate) { |
1874 | val = clk_readl(c->reg) | (0x1 << c->reg_shift); | 2073 | val = clk_readl(c->reg) | (0x1 << c->reg_shift); |
1875 | clk_writel(val, c->reg); | 2074 | clk_writel(val, c->reg); |
@@ -1886,108 +2085,139 @@ static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate) | |||
1886 | return -EINVAL; | 2085 | return -EINVAL; |
1887 | } | 2086 | } |
1888 | 2087 | ||
1889 | struct clk_ops tegra30_clk_double_ops = { | 2088 | static unsigned long tegra30_clk_double_recalc_rate(struct clk_hw *hw, |
1890 | .init = &tegra30_clk_double_init, | 2089 | unsigned long parent_rate) |
1891 | .enable = &tegra30_periph_clk_enable, | 2090 | { |
1892 | .disable = &tegra30_periph_clk_disable, | 2091 | struct clk_tegra *c = to_clk_tegra(hw); |
1893 | .set_rate = &tegra30_clk_double_set_rate, | 2092 | u64 rate = parent_rate; |
1894 | }; | ||
1895 | 2093 | ||
1896 | /* Audio sync clock ops */ | 2094 | u32 val = clk_readl(c->reg); |
1897 | static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate) | 2095 | c->mul = val & (0x1 << c->reg_shift) ? 1 : 2; |
2096 | c->div = 1; | ||
2097 | |||
2098 | if (c->mul != 0 && c->div != 0) { | ||
2099 | rate *= c->mul; | ||
2100 | rate += c->div - 1; /* round up */ | ||
2101 | do_div(rate, c->div); | ||
2102 | } | ||
2103 | |||
2104 | return rate; | ||
2105 | } | ||
2106 | |||
2107 | static long tegra30_clk_double_round_rate(struct clk_hw *hw, unsigned long rate, | ||
2108 | unsigned long *prate) | ||
1898 | { | 2109 | { |
1899 | c->rate = rate; | 2110 | unsigned long output_rate = *prate; |
1900 | return 0; | 2111 | |
2112 | do_div(output_rate, 2); | ||
2113 | return output_rate; | ||
1901 | } | 2114 | } |
1902 | 2115 | ||
2116 | struct clk_ops tegra30_clk_double_ops = { | ||
2117 | .is_enabled = tegra30_clk_double_is_enabled, | ||
2118 | .enable = tegra30_periph_clk_enable, | ||
2119 | .disable = tegra30_periph_clk_disable, | ||
2120 | .recalc_rate = tegra30_clk_double_recalc_rate, | ||
2121 | .round_rate = tegra30_clk_double_round_rate, | ||
2122 | .set_rate = tegra30_clk_double_set_rate, | ||
2123 | }; | ||
2124 | |||
2125 | /* Audio sync clock ops */ | ||
1903 | struct clk_ops tegra_sync_source_ops = { | 2126 | struct clk_ops tegra_sync_source_ops = { |
1904 | .set_rate = &tegra30_sync_source_set_rate, | 2127 | .recalc_rate = tegra30_clk_fixed_recalc_rate, |
1905 | }; | 2128 | }; |
1906 | 2129 | ||
1907 | static void tegra30_audio_sync_clk_init(struct clk *c) | 2130 | static int tegra30_audio_sync_clk_is_enabled(struct clk_hw *hw) |
1908 | { | 2131 | { |
1909 | int source; | 2132 | struct clk_tegra *c = to_clk_tegra(hw); |
1910 | const struct clk_mux_sel *sel; | ||
1911 | u32 val = clk_readl(c->reg); | 2133 | u32 val = clk_readl(c->reg); |
1912 | c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON; | 2134 | c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON; |
1913 | source = val & AUDIO_SYNC_SOURCE_MASK; | 2135 | return c->state; |
1914 | for (sel = c->inputs; sel->input != NULL; sel++) | ||
1915 | if (sel->value == source) | ||
1916 | break; | ||
1917 | BUG_ON(sel->input == NULL); | ||
1918 | c->parent = sel->input; | ||
1919 | } | 2136 | } |
1920 | 2137 | ||
1921 | static int tegra30_audio_sync_clk_enable(struct clk *c) | 2138 | static int tegra30_audio_sync_clk_enable(struct clk_hw *hw) |
1922 | { | 2139 | { |
2140 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1923 | u32 val = clk_readl(c->reg); | 2141 | u32 val = clk_readl(c->reg); |
1924 | clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg); | 2142 | clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg); |
1925 | return 0; | 2143 | return 0; |
1926 | } | 2144 | } |
1927 | 2145 | ||
1928 | static void tegra30_audio_sync_clk_disable(struct clk *c) | 2146 | static void tegra30_audio_sync_clk_disable(struct clk_hw *hw) |
1929 | { | 2147 | { |
2148 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1930 | u32 val = clk_readl(c->reg); | 2149 | u32 val = clk_readl(c->reg); |
1931 | clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg); | 2150 | clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg); |
1932 | } | 2151 | } |
1933 | 2152 | ||
1934 | static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p) | 2153 | static int tegra30_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index) |
1935 | { | 2154 | { |
2155 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1936 | u32 val; | 2156 | u32 val; |
1937 | const struct clk_mux_sel *sel; | ||
1938 | for (sel = c->inputs; sel->input != NULL; sel++) { | ||
1939 | if (sel->input == p) { | ||
1940 | val = clk_readl(c->reg); | ||
1941 | val &= ~AUDIO_SYNC_SOURCE_MASK; | ||
1942 | val |= sel->value; | ||
1943 | |||
1944 | if (c->refcnt) | ||
1945 | clk_enable(p); | ||
1946 | 2157 | ||
1947 | clk_writel(val, c->reg); | 2158 | val = clk_readl(c->reg); |
2159 | val &= ~AUDIO_SYNC_SOURCE_MASK; | ||
2160 | val |= index; | ||
1948 | 2161 | ||
1949 | if (c->refcnt && c->parent) | 2162 | clk_writel(val, c->reg); |
1950 | clk_disable(c->parent); | 2163 | return 0; |
2164 | } | ||
1951 | 2165 | ||
1952 | clk_reparent(c, p); | 2166 | static u8 tegra30_audio_sync_clk_get_parent(struct clk_hw *hw) |
1953 | return 0; | 2167 | { |
1954 | } | 2168 | struct clk_tegra *c = to_clk_tegra(hw); |
1955 | } | 2169 | u32 val = clk_readl(c->reg); |
2170 | int source; | ||
1956 | 2171 | ||
1957 | return -EINVAL; | 2172 | source = val & AUDIO_SYNC_SOURCE_MASK; |
2173 | return source; | ||
1958 | } | 2174 | } |
1959 | 2175 | ||
1960 | struct clk_ops tegra30_audio_sync_clk_ops = { | 2176 | struct clk_ops tegra30_audio_sync_clk_ops = { |
1961 | .init = tegra30_audio_sync_clk_init, | 2177 | .is_enabled = tegra30_audio_sync_clk_is_enabled, |
1962 | .enable = tegra30_audio_sync_clk_enable, | 2178 | .enable = tegra30_audio_sync_clk_enable, |
1963 | .disable = tegra30_audio_sync_clk_disable, | 2179 | .disable = tegra30_audio_sync_clk_disable, |
1964 | .set_parent = tegra30_audio_sync_clk_set_parent, | 2180 | .set_parent = tegra30_audio_sync_clk_set_parent, |
2181 | .get_parent = tegra30_audio_sync_clk_get_parent, | ||
2182 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
1965 | }; | 2183 | }; |
1966 | 2184 | ||
1967 | /* cml0 (pcie), and cml1 (sata) clock ops */ | 2185 | /* cml0 (pcie), and cml1 (sata) clock ops */ |
1968 | static void tegra30_cml_clk_init(struct clk *c) | 2186 | static int tegra30_cml_clk_is_enabled(struct clk_hw *hw) |
1969 | { | 2187 | { |
2188 | struct clk_tegra *c = to_clk_tegra(hw); | ||
1970 | u32 val = clk_readl(c->reg); | 2189 | u32 val = clk_readl(c->reg); |
1971 | c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF; | 2190 | c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF; |
2191 | return c->state; | ||
1972 | } | 2192 | } |
1973 | 2193 | ||
1974 | static int tegra30_cml_clk_enable(struct clk *c) | 2194 | static int tegra30_cml_clk_enable(struct clk_hw *hw) |
1975 | { | 2195 | { |
2196 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2197 | |||
1976 | u32 val = clk_readl(c->reg); | 2198 | u32 val = clk_readl(c->reg); |
1977 | val |= (0x1 << c->u.periph.clk_num); | 2199 | val |= (0x1 << c->u.periph.clk_num); |
1978 | clk_writel(val, c->reg); | 2200 | clk_writel(val, c->reg); |
2201 | |||
1979 | return 0; | 2202 | return 0; |
1980 | } | 2203 | } |
1981 | 2204 | ||
1982 | static void tegra30_cml_clk_disable(struct clk *c) | 2205 | static void tegra30_cml_clk_disable(struct clk_hw *hw) |
1983 | { | 2206 | { |
2207 | struct clk_tegra *c = to_clk_tegra(hw); | ||
2208 | |||
1984 | u32 val = clk_readl(c->reg); | 2209 | u32 val = clk_readl(c->reg); |
1985 | val &= ~(0x1 << c->u.periph.clk_num); | 2210 | val &= ~(0x1 << c->u.periph.clk_num); |
1986 | clk_writel(val, c->reg); | 2211 | clk_writel(val, c->reg); |
1987 | } | 2212 | } |
1988 | 2213 | ||
1989 | struct clk_ops tegra_cml_clk_ops = { | 2214 | struct clk_ops tegra_cml_clk_ops = { |
1990 | .init = &tegra30_cml_clk_init, | 2215 | .is_enabled = tegra30_cml_clk_is_enabled, |
1991 | .enable = &tegra30_cml_clk_enable, | 2216 | .enable = tegra30_cml_clk_enable, |
1992 | .disable = &tegra30_cml_clk_disable, | 2217 | .disable = tegra30_cml_clk_disable, |
2218 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
2219 | }; | ||
2220 | |||
2221 | struct clk_ops tegra_pciex_clk_ops = { | ||
2222 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | ||
1993 | }; | 2223 | }; |