diff options
Diffstat (limited to 'arch/arm/mach-omap2/clock34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 52385b1506e0..1ad0a1359cb8 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -634,6 +634,71 @@ static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate) | |||
634 | return omap3_noncore_dpll_set_rate(clk, rate); | 634 | return omap3_noncore_dpll_set_rate(clk, rate); |
635 | } | 635 | } |
636 | 636 | ||
637 | |||
638 | /* | ||
639 | * CORE DPLL (DPLL3) rate programming functions | ||
640 | * | ||
641 | * These call into SRAM code to do the actual CM writes, since the SDRAM | ||
642 | * is clocked from DPLL3. | ||
643 | */ | ||
644 | |||
645 | /** | ||
646 | * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider | ||
647 | * @clk: struct clk * of DPLL to set | ||
648 | * @rate: rounded target rate | ||
649 | * | ||
650 | * Program the DPLL M2 divider with the rounded target rate. Returns | ||
651 | * -EINVAL upon error, or 0 upon success. | ||
652 | */ | ||
653 | static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | ||
654 | { | ||
655 | u32 new_div = 0; | ||
656 | unsigned long validrate, sdrcrate; | ||
657 | struct omap_sdrc_params *sp; | ||
658 | |||
659 | if (!clk || !rate) | ||
660 | return -EINVAL; | ||
661 | |||
662 | if (clk != &dpll3_m2_ck) | ||
663 | return -EINVAL; | ||
664 | |||
665 | if (rate == clk->rate) | ||
666 | return 0; | ||
667 | |||
668 | validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); | ||
669 | if (validrate != rate) | ||
670 | return -EINVAL; | ||
671 | |||
672 | sdrcrate = sdrc_ick.rate; | ||
673 | if (rate > clk->rate) | ||
674 | sdrcrate <<= ((rate / clk->rate) - 1); | ||
675 | else | ||
676 | sdrcrate >>= ((clk->rate / rate) - 1); | ||
677 | |||
678 | sp = omap2_sdrc_get_params(sdrcrate); | ||
679 | if (!sp) | ||
680 | return -EINVAL; | ||
681 | |||
682 | pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, | ||
683 | validrate); | ||
684 | pr_info("clock: SDRC timing params used: %08x %08x %08x\n", | ||
685 | sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb); | ||
686 | |||
687 | /* REVISIT: SRAM code doesn't support other M2 divisors yet */ | ||
688 | WARN_ON(new_div != 1 && new_div != 2); | ||
689 | |||
690 | /* REVISIT: Add SDRC_MR changing to this code also */ | ||
691 | local_irq_disable(); | ||
692 | omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla, | ||
693 | sp->actim_ctrlb, new_div); | ||
694 | local_irq_enable(); | ||
695 | |||
696 | omap2_clksel_recalc(clk); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | |||
637 | static const struct clkops clkops_noncore_dpll_ops = { | 702 | static const struct clkops clkops_noncore_dpll_ops = { |
638 | .enable = &omap3_noncore_dpll_enable, | 703 | .enable = &omap3_noncore_dpll_enable, |
639 | .disable = &omap3_noncore_dpll_disable, | 704 | .disable = &omap3_noncore_dpll_disable, |