From patchwork Thu Jan 7 07:36:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sripathy, Vishwanath" X-Patchwork-Id: 71557 X-Patchwork-Delegate: paul@pwsan.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o077Xx4m025894 for ; Thu, 7 Jan 2010 07:34:10 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756311Ab0AGHeF (ORCPT ); Thu, 7 Jan 2010 02:34:05 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756308Ab0AGHeF (ORCPT ); Thu, 7 Jan 2010 02:34:05 -0500 Received: from devils.ext.ti.com ([198.47.26.153]:49032 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756273Ab0AGHeB (ORCPT ); Thu, 7 Jan 2010 02:34:01 -0500 Received: from dbdp31.itg.ti.com ([172.24.170.98]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id o077XvCI025827 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 7 Jan 2010 01:33:59 -0600 Received: from localhost.localdomain (localhost [127.0.0.1]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id o077Xq4R022701; Thu, 7 Jan 2010 13:03:53 +0530 (IST) From: Vishwanath BS To: linux-omap@vger.kernel.org Cc: Vishwanath BS , Paul Walmsley , Richard Woodruff , Nishanth Menon , Vishwanath BS Subject: [PATCHV4 1/4] OMAP3: introduce DPLL4 Jtype Date: Thu, 7 Jan 2010 13:06:38 +0530 Message-Id: <1262849801-9955-2-git-send-email-vishwanath.bs@ti.com> X-Mailer: git-send-email 1.5.6.3 In-Reply-To: <1262849801-9955-1-git-send-email-vishwanath.bs@ti.com> References: <1262849801-9955-1-git-send-email-vishwanath.bs@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 93c48df..297ade8 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -47,6 +47,10 @@ #define DPLL_LOW_POWER_BYPASS 0x5 #define DPLL_LOCKED 0x7 +/*DPLL Type and DCO Selection Flags*/ +#define DPLL_J_TYPE 0x1 +#define DPLL_NO_DCO_SEL 0x2 + int omap2_clk_init(void); int omap2_clk_enable(struct clk *clk); void omap2_clk_disable(struct clk *clk); diff --git a/arch/arm/mach-omap2/clock34xx_data.c b/arch/arm/mach-omap2/clock34xx_data.c index 043caed..66a3a96 --- a/arch/arm/mach-omap2/clock34xx_data.c +++ b/arch/arm/mach-omap2/clock34xx_data.c @@ -552,6 +552,30 @@ static struct dpll_data dpll4_dd = { .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE }; +static struct dpll_data dpll4_dd_3630 = { + .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), + .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, + .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, + .clk_bypass = &sys_ck, + .clk_ref = &sys_ck, + .freqsel_mask = OMAP3430_PERIPH_DPLL_FREQSEL_MASK, + .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), + .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, + .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), + .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, + .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, + .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, + .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), + .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, + .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), + .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, + .max_multiplier = OMAP3_MAX_DPLL_MULT, + .min_divider = 1, + .max_divider = OMAP3_MAX_DPLL_DIV, + .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE, + .flags = DPLL_J_TYPE +}; + static struct clk dpll4_ck = { .name = "dpll4_ck", .ops = &clkops_noncore_dpll_ops, @@ -3241,6 +3265,8 @@ int __init omap2_clk_init(void) cpu_clkflg |= CK_3430ES2; } } + if (cpu_is_omap3630()) + dpll4_dd = dpll4_dd_3630; clk_init(&omap2_clk_functions); diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 2210e22..a95930e --- 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 = { .max_multiplier = OMAP4430_MAX_DPLL_MULT, .max_divider = OMAP4430_MAX_DPLL_DIV, .min_divider = 1, + .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL }; diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 6923deb..6f2802b 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -516,9 +516,13 @@ /* CM_CLKSEL2_PLL */ #define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8 -#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8) +#define OMAP3430_PERIPH_DPLL_MULT_MASK (0xfff << 8) #define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0 #define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0) +#define OMAP3630_PERIPH_DPLL_DCO_SEL_SHIFT 21 +#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21) +#define OMAP3630_PERIPH_DPLL_SD_DIV_SHIFT 24 +#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24) /* CM_CLKSEL3_PLL */ #define OMAP3430_DIV_96M_SHIFT 0 diff --git a/arch/arm/mach-omap2/dpll.c b/arch/arm/mach-omap2/dpll.c index f6055b4..4f5570e --- a/arch/arm/mach-omap2/dpll.c +++ b/arch/arm/mach-omap2/dpll.c @@ -238,6 +238,42 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) } /** + * lookup_dco_sddiv - Set j-type DPLL4 compensation variables + * @clk: pointer to a DPLL struct clk + * @dco: digital control oscillator selector + * @sd_div: target sigma-delta divider + * @m: DPLL multiplier to set + * @n: DPLL divider to set + */ +static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 + m, u8 n) + { + unsigned long fint, clkinp, sd; /* watch out for overflow */ + int mod1, mod2; + + clkinp = clk->parent->rate; + fint = (clkinp / n) * m; + + if (fint < 1000000000) + *dco = 2; + else + *dco = 4; + /* + * target sigma-delta to near 250MHz + * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] + */ + clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2*/ + mod1 = (clkinp * m) % (250 * n); + sd = (clkinp * m) / (250 * n); + mod2 = sd % 10; + sd /= 10; + + if (mod1 || mod2) + sd++; + *sd_div = sd; +} + +/** * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode * @clk: pointer to a DPLL struct clk * @@ -323,6 +359,15 @@ int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) v &= ~(dd->mult_mask | dd->div1_mask); v |= m << __ffs(dd->mult_mask); v |= (n - 1) << __ffs(dd->div1_mask); + + if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) { + u8 dco, sd_div; + lookup_dco_sddiv(clk, &dco, &sd_div, m, n); + v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK + | OMAP3630_PERIPH_DPLL_SD_DIV_MASK); + v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK); + v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK); + } __raw_writel(v, dd->mult_div1_reg); /* We let the clock framework set the other output dividers later */ @@ -530,7 +575,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk) v = __raw_readl(dd->control_reg) & dd->enable_mask; v >>= __ffs(dd->enable_mask); - if (v != OMAP3XXX_EN_DPLL_LOCKED) + if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE)) rate = clk->parent->rate; else 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 309b6d1..148d8ae --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -62,6 +62,8 @@ struct dpll_data { void __iomem *idlest_reg; u32 autoidle_mask; u32 freqsel_mask; + u8 flags; /* indiciates what is the type of dpll + (like j_type, no_dco_sel) */ u32 idlest_mask; u8 auto_recal_bit; u8 recal_en_bit;