diff options
Diffstat (limited to 'arch/arm/mach-omap2/dpll3xxx.c')
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index fafb28c0dcbc..2bb18838cba9 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -291,16 +291,13 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) | |||
291 | 291 | ||
292 | /* | 292 | /* |
293 | * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly | 293 | * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly |
294 | * @clk: struct clk * of DPLL to set | 294 | * @clk: struct clk * of DPLL to set |
295 | * @m: DPLL multiplier to set | 295 | * @freqsel: FREQSEL value to set |
296 | * @n: DPLL divider to set | ||
297 | * @freqsel: FREQSEL value to set | ||
298 | * | 296 | * |
299 | * Program the DPLL with the supplied M, N values, and wait for the DPLL to | 297 | * Program the DPLL with the last M, N values calculated, and wait for |
300 | * lock.. Returns -EINVAL upon error, or 0 upon success. | 298 | * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success. |
301 | */ | 299 | */ |
302 | static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n, | 300 | static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) |
303 | u16 freqsel) | ||
304 | { | 301 | { |
305 | struct dpll_data *dd = clk->dpll_data; | 302 | struct dpll_data *dd = clk->dpll_data; |
306 | u8 dco, sd_div; | 303 | u8 dco, sd_div; |
@@ -323,23 +320,45 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n, | |||
323 | /* Set DPLL multiplier, divider */ | 320 | /* Set DPLL multiplier, divider */ |
324 | v = __raw_readl(dd->mult_div1_reg); | 321 | v = __raw_readl(dd->mult_div1_reg); |
325 | v &= ~(dd->mult_mask | dd->div1_mask); | 322 | v &= ~(dd->mult_mask | dd->div1_mask); |
326 | v |= m << __ffs(dd->mult_mask); | 323 | v |= dd->last_rounded_m << __ffs(dd->mult_mask); |
327 | v |= (n - 1) << __ffs(dd->div1_mask); | 324 | v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); |
328 | 325 | ||
329 | /* Configure dco and sd_div for dplls that have these fields */ | 326 | /* Configure dco and sd_div for dplls that have these fields */ |
330 | if (dd->dco_mask) { | 327 | if (dd->dco_mask) { |
331 | _lookup_dco(clk, &dco, m, n); | 328 | _lookup_dco(clk, &dco, dd->last_rounded_m, dd->last_rounded_n); |
332 | v &= ~(dd->dco_mask); | 329 | v &= ~(dd->dco_mask); |
333 | v |= dco << __ffs(dd->dco_mask); | 330 | v |= dco << __ffs(dd->dco_mask); |
334 | } | 331 | } |
335 | if (dd->sddiv_mask) { | 332 | if (dd->sddiv_mask) { |
336 | _lookup_sddiv(clk, &sd_div, m, n); | 333 | _lookup_sddiv(clk, &sd_div, dd->last_rounded_m, |
334 | dd->last_rounded_n); | ||
337 | v &= ~(dd->sddiv_mask); | 335 | v &= ~(dd->sddiv_mask); |
338 | v |= sd_div << __ffs(dd->sddiv_mask); | 336 | v |= sd_div << __ffs(dd->sddiv_mask); |
339 | } | 337 | } |
340 | 338 | ||
341 | __raw_writel(v, dd->mult_div1_reg); | 339 | __raw_writel(v, dd->mult_div1_reg); |
342 | 340 | ||
341 | /* Set 4X multiplier and low-power mode */ | ||
342 | if (dd->m4xen_mask || dd->lpmode_mask) { | ||
343 | v = __raw_readl(dd->control_reg); | ||
344 | |||
345 | if (dd->m4xen_mask) { | ||
346 | if (dd->last_rounded_m4xen) | ||
347 | v |= dd->m4xen_mask; | ||
348 | else | ||
349 | v &= ~dd->m4xen_mask; | ||
350 | } | ||
351 | |||
352 | if (dd->lpmode_mask) { | ||
353 | if (dd->last_rounded_lpmode) | ||
354 | v |= dd->lpmode_mask; | ||
355 | else | ||
356 | v &= ~dd->lpmode_mask; | ||
357 | } | ||
358 | |||
359 | __raw_writel(v, dd->control_reg); | ||
360 | } | ||
361 | |||
343 | /* We let the clock framework set the other output dividers later */ | 362 | /* We let the clock framework set the other output dividers later */ |
344 | 363 | ||
345 | /* REVISIT: Set ramp-up delay? */ | 364 | /* REVISIT: Set ramp-up delay? */ |
@@ -492,8 +511,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
492 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", | 511 | pr_debug("%s: %s: set rate: locking rate to %lu.\n", |
493 | __func__, __clk_get_name(hw->clk), rate); | 512 | __func__, __clk_get_name(hw->clk), rate); |
494 | 513 | ||
495 | ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m, | 514 | ret = omap3_noncore_dpll_program(clk, freqsel); |
496 | dd->last_rounded_n, freqsel); | ||
497 | if (!ret) | 515 | if (!ret) |
498 | new_parent = dd->clk_ref; | 516 | new_parent = dd->clk_ref; |
499 | } | 517 | } |