aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/dpll3xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/dpll3xxx.c')
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c46
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 */
302static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n, 300static 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 }