X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap2%2Fclock24xx.c;h=3b7ecc6c43e4b2a7cb8c31a27c66310ae229631f;hb=be99ca4dd45b5ffc3ff30b2c80d7103aa1451afc;hp=1a885976c2579f150438f20410e3fde61110dbdd;hpb=3f0a820c4c0b4670fb5f164baa5582e23c2ef118;p=linux-2.6-omap-h63xx.git diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index 1a885976c25..3b7ecc6c43e 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c @@ -236,19 +236,32 @@ static struct clk *sclk; * Omap24xx specific clock functions *-------------------------------------------------------------------------*/ -/* This actually returns the rate of core_ck, not dpll_ck. */ -static u32 omap2_get_dpll_rate_24xx(struct clk *tclk) +/** + * omap2xxx_clk_get_core_rate - return the CORE_CLK rate + * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck") + * + * Returns the CORE_CLK rate. CORE_CLK can have one of three rate + * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz + * (the latter is unusual). This currently should be called with + * struct clk *dpll_ck, which is a composite clock of dpll_ck and + * core_ck. + */ +static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk) { - long long dpll_clk; - u8 amult; + long long core_clk; + u32 v; - dpll_clk = omap2_get_dpll_rate(tclk); + core_clk = omap2_get_dpll_rate(clk); - amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); - amult &= OMAP24XX_CORE_CLK_SRC_MASK; - dpll_clk *= amult; + v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); + v &= OMAP24XX_CORE_CLK_SRC_MASK; - return dpll_clk; + if (v == CORE_CLK_SRC_32K) + core_clk = 32768; + else + core_clk *= v; + + return core_clk; } static int omap2_enable_osc_ck(struct clk *clk) @@ -369,9 +382,9 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate) } -static void omap2_dpllcore_recalc(struct clk *clk) +static unsigned long omap2_dpllcore_recalc(struct clk *clk) { - clk->rate = omap2_get_dpll_rate_24xx(clk); + return omap2xxx_clk_get_core_rate(clk); } static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) @@ -380,11 +393,8 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) u32 bypass = 0; struct prcm_config tmpset; const struct dpll_data *dd; - unsigned long flags; - int ret = -EINVAL; - local_irq_save(flags); - cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); + cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck); mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); mult &= OMAP24XX_CORE_CLK_SRC_MASK; @@ -395,7 +405,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) } else if (rate != cur_rate) { valid_rate = omap2_dpllcore_round_rate(rate); if (valid_rate != rate) - goto dpll_exit; + return -EINVAL; if (mult == 1) low = curr_prcm_set->dpll_speed; @@ -404,7 +414,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) dd = clk->dpll_data; if (!dd) - goto dpll_exit; + return -EINVAL; tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg); tmpset.cm_clksel1_pll &= ~(dd->mult_mask | @@ -441,11 +451,8 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked()); omap2xxx_sdrc_reprogram(done_rate, 0); } - ret = 0; -dpll_exit: - local_irq_restore(flags); - return(ret); + return 0; } /** @@ -454,9 +461,9 @@ dpll_exit: * * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. */ -static void omap2_table_mpu_recalc(struct clk *clk) +static unsigned long omap2_table_mpu_recalc(struct clk *clk) { - clk->rate = curr_prcm_set->mpu_speed; + return curr_prcm_set->mpu_speed; } /* @@ -522,7 +529,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) } curr_prcm_set = prcm; - cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); + cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck); if (prcm->dpll_speed == cur_rate / 2) { omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); @@ -653,14 +660,14 @@ static u32 omap2_get_sysclkdiv(void) return div; } -static void omap2_osc_clk_recalc(struct clk *clk) +static unsigned long omap2_osc_clk_recalc(struct clk *clk) { - clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv(); + return omap2_get_apll_clkin() * omap2_get_sysclkdiv(); } -static void omap2_sys_clk_recalc(struct clk *clk) +static unsigned long omap2_sys_clk_recalc(struct clk *clk) { - clk->rate = clk->parent->rate / omap2_get_sysclkdiv(); + return clk->parent->rate / omap2_get_sysclkdiv(); } /* @@ -713,9 +720,11 @@ int __init omap2_clk_init(void) clk_init(&omap2_clk_functions); - omap2_osc_clk_recalc(&osc_ck); + clk_init_one(&osc_ck); + clk_init_one(&sys_ck); + osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); propagate_rate(&osc_ck); - omap2_sys_clk_recalc(&sys_ck); + sys_ck.rate = omap2_sys_clk_recalc(&sys_ck); propagate_rate(&sys_ck); for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) @@ -734,7 +743,7 @@ int __init omap2_clk_init(void) } /* Check the MPU rate set by bootloader */ - clkrate = omap2_get_dpll_rate_24xx(&dpll_ck); + clkrate = omap2xxx_clk_get_core_rate(&dpll_ck); for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue;