aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock34xx.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-01-28 14:27:42 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-08 12:50:40 -0500
commit0eafd4725cf5d828e76e474b8991a228bbdd3f2b (patch)
tree797186618cb16d1ddb3f42a1ac9c9d4f84bdc7c1 /arch/arm/mach-omap2/clock34xx.c
parent87246b7567f7d1951bfcea29875523ef435c0ebf (diff)
[ARM] OMAP3 clock: add omap3_core_dpll_m2_set_rate()
Add the omap3_core_dpll_m2_set_rate() function to the OMAP3 clock code, which calls into the SRAM function omap3_sram_configure_core_dpll() to change the CORE DPLL M2 divider. (SRAM code is necessary since rate changes on clocks upstream from the SDRC can glitch SDRAM accesses.) Use this function for the set_rate function pointer in the dpll3_m2_ck struct clk. With this function in place, PM/OPP code should be able to alter SDRAM speed via code similar to: clk_set_rate(&dpll3_m2_ck, target_rate). linux-omap source commit is 7f8b2b0f4fe52238c67d79dedcd2794dcef4dddd. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-omap2/clock34xx.c')
-rw-r--r--arch/arm/mach-omap2/clock34xx.c65
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 */
653static 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
637static const struct clkops clkops_noncore_dpll_ops = { 702static 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,