diff options
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.c | 65 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.h | 9 |
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 | */ | ||
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, |
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); | |||
34 | static u32 omap3_dpll_autoidle_read(struct clk *clk); | 34 | static u32 omap3_dpll_autoidle_read(struct clk *clk); |
35 | static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate); | 35 | static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate); |
36 | static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate); | 36 | static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate); |
37 | static 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 | */ | ||
479 | static struct clk dpll3_m2_ck = { | 476 | static 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 | ||