aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock24xx.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-02-19 08:29:22 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-19 12:28:30 -0500
commitc0bf31320dea2cbcbab1f53ee15a8520f762409b (patch)
tree1b4fbb4396da448eb116f2bee8b58030b63cfe3b /arch/arm/mach-omap2/clock24xx.c
parent8b9dbc16d4f5786c6c930ab028722e3ed7e4285b (diff)
[ARM] omap: add support for bypassing DPLLs
This roughly corresponds with OMAP commits: 7d06c48, 3241b19, 88b5d9b, 18a5500, 9c909ac, 5c6497b, 8b1f0bd, 2ac1da8. For both OMAP2 and OMAP3, we note the reference and bypass clocks in the DPLL data structure. Whenever we modify the DPLL rate, we first ensure that both the reference and bypass clocks are enabled. Then, we decide whether to use the reference and DPLL, or the bypass clock if the desired rate is identical to the bypass rate, and program the DPLL appropriately. Finally, we update the clock's parent, and then disable the unused clocks. This keeps the parents correctly balanced, and more importantly ensures that the bypass clock is running whenever we reprogram the DPLL. This is especially important because the procedure for reprogramming the DPLL involves switching to the bypass clock. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-omap2/clock24xx.c')
-rw-r--r--arch/arm/mach-omap2/clock24xx.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index f2b74e9b7d8d..1e839c5a28c5 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -236,19 +236,32 @@ static struct clk *sclk;
236 * Omap24xx specific clock functions 236 * Omap24xx specific clock functions
237 *-------------------------------------------------------------------------*/ 237 *-------------------------------------------------------------------------*/
238 238
239/* This actually returns the rate of core_ck, not dpll_ck. */ 239/**
240static u32 omap2_get_dpll_rate_24xx(struct clk *tclk) 240 * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
241 * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
242 *
243 * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
244 * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
245 * (the latter is unusual). This currently should be called with
246 * struct clk *dpll_ck, which is a composite clock of dpll_ck and
247 * core_ck.
248 */
249static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
241{ 250{
242 long long dpll_clk; 251 long long core_clk;
243 u8 amult; 252 u32 v;
244 253
245 dpll_clk = omap2_get_dpll_rate(tclk); 254 core_clk = omap2_get_dpll_rate(clk);
246 255
247 amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 256 v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
248 amult &= OMAP24XX_CORE_CLK_SRC_MASK; 257 v &= OMAP24XX_CORE_CLK_SRC_MASK;
249 dpll_clk *= amult; 258
259 if (v == CORE_CLK_SRC_32K)
260 core_clk = 32768;
261 else
262 core_clk *= v;
250 263
251 return dpll_clk; 264 return core_clk;
252} 265}
253 266
254static int omap2_enable_osc_ck(struct clk *clk) 267static int omap2_enable_osc_ck(struct clk *clk)
@@ -371,7 +384,7 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
371 384
372static unsigned long omap2_dpllcore_recalc(struct clk *clk) 385static unsigned long omap2_dpllcore_recalc(struct clk *clk)
373{ 386{
374 return omap2_get_dpll_rate_24xx(clk); 387 return omap2xxx_clk_get_core_rate(clk);
375} 388}
376 389
377static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) 390static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
@@ -381,7 +394,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
381 struct prcm_config tmpset; 394 struct prcm_config tmpset;
382 const struct dpll_data *dd; 395 const struct dpll_data *dd;
383 396
384 cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); 397 cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
385 mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); 398 mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
386 mult &= OMAP24XX_CORE_CLK_SRC_MASK; 399 mult &= OMAP24XX_CORE_CLK_SRC_MASK;
387 400
@@ -516,7 +529,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
516 } 529 }
517 530
518 curr_prcm_set = prcm; 531 curr_prcm_set = prcm;
519 cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); 532 cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
520 533
521 if (prcm->dpll_speed == cur_rate / 2) { 534 if (prcm->dpll_speed == cur_rate / 2) {
522 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); 535 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
@@ -728,7 +741,7 @@ int __init omap2_clk_init(void)
728 } 741 }
729 742
730 /* Check the MPU rate set by bootloader */ 743 /* Check the MPU rate set by bootloader */
731 clkrate = omap2_get_dpll_rate_24xx(&dpll_ck); 744 clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
732 for (prcm = rate_table; prcm->mpu_speed; prcm++) { 745 for (prcm = rate_table; prcm->mpu_speed; prcm++) {
733 if (!(prcm->flags & cpu_mask)) 746 if (!(prcm->flags & cpu_mask))
734 continue; 747 continue;