aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/clock34xx.c65
-rw-r--r--arch/arm/mach-omap2/clock34xx.h9
2 files changed, 69 insertions, 5 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,
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index aadd296c05a2..681acf0427c1 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -34,6 +34,7 @@ static void omap3_dpll_deny_idle(struct clk *clk);
34static u32 omap3_dpll_autoidle_read(struct clk *clk); 34static u32 omap3_dpll_autoidle_read(struct clk *clk);
35static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate); 35static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
36static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate); 36static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
37static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
37 38
38/* Maximum DPLL multiplier, divider values for OMAP3 */ 39/* Maximum DPLL multiplier, divider values for OMAP3 */
39#define OMAP3_MAX_DPLL_MULT 2048 40#define OMAP3_MAX_DPLL_MULT 2048
@@ -471,11 +472,7 @@ static const struct clksel div31_dpll3m2_clksel[] = {
471 { .parent = NULL } 472 { .parent = NULL }
472}; 473};
473 474
474/* 475/* DPLL3 output M2 - primary control point for CORE speed */
475 * DPLL3 output M2
476 * REVISIT: This DPLL output divider must be changed in SRAM, so until
477 * that code is ready, this should remain a 'read-only' clksel clock.
478 */
479static struct clk dpll3_m2_ck = { 476static struct clk dpll3_m2_ck = {
480 .name = "dpll3_m2_ck", 477 .name = "dpll3_m2_ck",
481 .ops = &clkops_null, 478 .ops = &clkops_null,
@@ -486,6 +483,8 @@ static struct clk dpll3_m2_ck = {
486 .clksel = div31_dpll3m2_clksel, 483 .clksel = div31_dpll3m2_clksel,
487 .flags = RATE_PROPAGATES, 484 .flags = RATE_PROPAGATES,
488 .clkdm_name = "dpll3_clkdm", 485 .clkdm_name = "dpll3_clkdm",
486 .round_rate = &omap2_clksel_round_rate,
487 .set_rate = &omap3_core_dpll_m2_set_rate,
489 .recalc = &omap2_clksel_recalc, 488 .recalc = &omap2_clksel_recalc,
490}; 489};
491 490