aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/clock.h4
-rw-r--r--arch/arm/mach-omap2/clock34xx_data.c32
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c1
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h5
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c67
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h5
6 files changed, 109 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 86e32bf2a693..0b0f52083121 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -47,6 +47,10 @@
47#define DPLL_LOW_POWER_BYPASS 0x5 47#define DPLL_LOW_POWER_BYPASS 0x5
48#define DPLL_LOCKED 0x7 48#define DPLL_LOCKED 0x7
49 49
50/* DPLL Type and DCO Selection Flags */
51#define DPLL_J_TYPE 0x1
52#define DPLL_NO_DCO_SEL 0x2
53
50int omap2_clk_enable(struct clk *clk); 54int omap2_clk_enable(struct clk *clk);
51void omap2_clk_disable(struct clk *clk); 55void omap2_clk_disable(struct clk *clk);
52long omap2_clk_round_rate(struct clk *clk, unsigned long rate); 56long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c
index 8bb8134872ce..60c6140b86af 100644
--- a/arch/arm/mach-omap2/clock34xx_data.c
+++ b/arch/arm/mach-omap2/clock34xx_data.c
@@ -38,6 +38,7 @@
38 38
39/* Maximum DPLL multiplier, divider values for OMAP3 */ 39/* Maximum DPLL multiplier, divider values for OMAP3 */
40#define OMAP3_MAX_DPLL_MULT 2048 40#define OMAP3_MAX_DPLL_MULT 2048
41#define OMAP3630_MAX_JTYPE_DPLL_MULT 4095
41#define OMAP3_MAX_DPLL_DIV 128 42#define OMAP3_MAX_DPLL_DIV 128
42 43
43/* 44/*
@@ -529,7 +530,8 @@ static struct clk emu_core_alwon_ck = {
529/* DPLL4 */ 530/* DPLL4 */
530/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ 531/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
531/* Type: DPLL */ 532/* Type: DPLL */
532static struct dpll_data dpll4_dd = { 533static struct dpll_data dpll4_dd;
534static struct dpll_data dpll4_dd_34xx __initdata = {
533 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), 535 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
534 .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, 536 .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
535 .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, 537 .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
@@ -552,6 +554,29 @@ static struct dpll_data dpll4_dd = {
552 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 554 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
553}; 555};
554 556
557static struct dpll_data dpll4_dd_3630 __initdata = {
558 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
559 .mult_mask = OMAP3630_PERIPH_DPLL_MULT_MASK,
560 .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
561 .clk_bypass = &sys_ck,
562 .clk_ref = &sys_ck,
563 .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
564 .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
565 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
566 .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
567 .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
568 .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT,
569 .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
570 .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
571 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
572 .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
573 .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
574 .min_divider = 1,
575 .max_divider = OMAP3_MAX_DPLL_DIV,
576 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE,
577 .flags = DPLL_J_TYPE
578};
579
555static struct clk dpll4_ck = { 580static struct clk dpll4_ck = {
556 .name = "dpll4_ck", 581 .name = "dpll4_ck",
557 .ops = &omap3_clkops_noncore_dpll_ops, 582 .ops = &omap3_clkops_noncore_dpll_ops,
@@ -3377,6 +3402,11 @@ int __init omap3xxx_clk_init(void)
3377 &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore; 3402 &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
3378 } 3403 }
3379 3404
3405 if (cpu_is_omap3630())
3406 dpll4_dd = dpll4_dd_3630;
3407 else
3408 dpll4_dd = dpll4_dd_34xx;
3409
3380 clk_init(&omap2_clk_functions); 3410 clk_init(&omap2_clk_functions);
3381 3411
3382 for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++) 3412 for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks); c++)
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 86af31d80a34..8d8b57340950 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -980,6 +980,7 @@ static struct dpll_data dpll_usb_dd = {
980 .max_multiplier = OMAP4430_MAX_DPLL_MULT, 980 .max_multiplier = OMAP4430_MAX_DPLL_MULT,
981 .max_divider = OMAP4430_MAX_DPLL_DIV, 981 .max_divider = OMAP4430_MAX_DPLL_DIV,
982 .min_divider = 1, 982 .min_divider = 1,
983 .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL
983}; 984};
984 985
985 986
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index c04c7c68f033..29cd13b838ca 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -531,8 +531,13 @@
531/* CM_CLKSEL2_PLL */ 531/* CM_CLKSEL2_PLL */
532#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8 532#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8
533#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8) 533#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8)
534#define OMAP3630_PERIPH_DPLL_MULT_MASK (0xfff << 8)
534#define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0 535#define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0
535#define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0) 536#define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0)
537#define OMAP3630_PERIPH_DPLL_DCO_SEL_SHIFT 21
538#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21)
539#define OMAP3630_PERIPH_DPLL_SD_DIV_SHIFT 24
540#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24)
536 541
537/* CM_CLKSEL3_PLL */ 542/* CM_CLKSEL3_PLL */
538#define OMAP3430_DIV_96M_SHIFT 0 543#define OMAP3430_DIV_96M_SHIFT 0
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 68268cd89e05..417c3caa05db 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -1,11 +1,14 @@
1/* 1/*
2 * OMAP3/4 - specific DPLL control functions 2 * OMAP3/4 - specific DPLL control functions
3 * 3 *
4 * Copyright (C) 2009 Texas Instruments, Inc. 4 * Copyright (C) 2009-2010 Texas Instruments, Inc.
5 * Copyright (C) 2009 Nokia Corporation 5 * Copyright (C) 2009-2010 Nokia Corporation
6 * 6 *
7 * Written by Paul Walmsley 7 * Written by Paul Walmsley
8 * Testing and integration fixes by Jouni Högander 8 * Testing and integration fixes by Jouni Högander
9 *
10 * 36xx support added by Vishwanath BS, Richard Woodruff, and Nishanth
11 * Menon
9 * 12 *
10 * Parts of this code are based on code written by 13 * Parts of this code are based on code written by
11 * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu 14 * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
@@ -225,6 +228,47 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
225 return 0; 228 return 0;
226} 229}
227 230
231/**
232 * lookup_dco_sddiv - Set j-type DPLL4 compensation variables
233 * @clk: pointer to a DPLL struct clk
234 * @dco: digital control oscillator selector
235 * @sd_div: target sigma-delta divider
236 * @m: DPLL multiplier to set
237 * @n: DPLL divider to set
238 *
239 * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
240 *
241 * XXX This code is not needed for 3430/AM35xx; can it be optimized
242 * out in non-multi-OMAP builds for those chips?
243 */
244static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m,
245 u8 n)
246{
247 unsigned long fint, clkinp, sd; /* watch out for overflow */
248 int mod1, mod2;
249
250 clkinp = clk->parent->rate;
251 fint = (clkinp / n) * m;
252
253 if (fint < 1000000000)
254 *dco = 2;
255 else
256 *dco = 4;
257 /*
258 * target sigma-delta to near 250MHz
259 * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
260 */
261 clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2 */
262 mod1 = (clkinp * m) % (250 * n);
263 sd = (clkinp * m) / (250 * n);
264 mod2 = sd % 10;
265 sd /= 10;
266
267 if (mod1 || mod2)
268 sd++;
269 *sd_div = sd;
270}
271
228/* 272/*
229 * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly 273 * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
230 * @clk: struct clk * of DPLL to set 274 * @clk: struct clk * of DPLL to set
@@ -259,6 +303,21 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
259 v &= ~(dd->mult_mask | dd->div1_mask); 303 v &= ~(dd->mult_mask | dd->div1_mask);
260 v |= m << __ffs(dd->mult_mask); 304 v |= m << __ffs(dd->mult_mask);
261 v |= (n - 1) << __ffs(dd->div1_mask); 305 v |= (n - 1) << __ffs(dd->div1_mask);
306
307 /*
308 * XXX This code is not needed for 3430/AM35XX; can it be optimized
309 * out in non-multi-OMAP builds for those chips?
310 */
311 if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) {
312 u8 dco, sd_div;
313 lookup_dco_sddiv(clk, &dco, &sd_div, m, n);
314 /* XXX This probably will need revision for OMAP4 */
315 v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK
316 | OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
317 v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK);
318 v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK);
319 }
320
262 __raw_writel(v, dd->mult_div1_reg); 321 __raw_writel(v, dd->mult_div1_reg);
263 322
264 /* We let the clock framework set the other output dividers later */ 323 /* We let the clock framework set the other output dividers later */
@@ -536,7 +595,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
536 595
537 v = __raw_readl(dd->control_reg) & dd->enable_mask; 596 v = __raw_readl(dd->control_reg) & dd->enable_mask;
538 v >>= __ffs(dd->enable_mask); 597 v >>= __ffs(dd->enable_mask);
539 if (v != OMAP3XXX_EN_DPLL_LOCKED) 598 if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
540 rate = clk->parent->rate; 599 rate = clk->parent->rate;
541 else 600 else
542 rate = clk->parent->rate * 2; 601 rate = clk->parent->rate * 2;
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index e49162469791..f5f30c73db33 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -41,6 +41,10 @@ struct clksel {
41 const struct clksel_rate *rates; 41 const struct clksel_rate *rates;
42}; 42};
43 43
44/*
45 * A new flag called flag has been added which indicates what is the
46 * type of dpll (like j_type, no_dco_sel)
47 */
44struct dpll_data { 48struct dpll_data {
45 void __iomem *mult_div1_reg; 49 void __iomem *mult_div1_reg;
46 u32 mult_mask; 50 u32 mult_mask;
@@ -67,6 +71,7 @@ struct dpll_data {
67 u8 auto_recal_bit; 71 u8 auto_recal_bit;
68 u8 recal_en_bit; 72 u8 recal_en_bit;
69 u8 recal_st_bit; 73 u8 recal_st_bit;
74 u8 flags;
70# endif 75# endif
71}; 76};
72 77