From patchwork Thu May 26 01:56:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nishanth Menon X-Patchwork-Id: 819192 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4Q1va1u023610 for ; Thu, 26 May 2011 01:57:39 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932071Ab1EZB5i (ORCPT ); Wed, 25 May 2011 21:57:38 -0400 Received: from na3sys009aog102.obsmtp.com ([74.125.149.69]:59950 "EHLO na3sys009aog102.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757036Ab1EZB5i (ORCPT ); Wed, 25 May 2011 21:57:38 -0400 Received: from mail-yw0-f50.google.com ([209.85.213.50]) (using TLSv1) by na3sys009aob102.postini.com ([74.125.148.12]) with SMTP ID DSNKTd2zkW36EwPAy0gEe6MzyQFCbsZr47SF@postini.com; Wed, 25 May 2011 18:57:37 PDT Received: by ywa8 with SMTP id 8so202330ywa.23 for ; Wed, 25 May 2011 18:57:37 -0700 (PDT) Received: by 10.150.69.9 with SMTP id r9mr379860yba.261.1306375056955; Wed, 25 May 2011 18:57:36 -0700 (PDT) Received: from localhost (dragon.ti.com [192.94.94.33]) by mx.google.com with ESMTPS id q24sm269234yba.13.2011.05.25.18.57.35 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 May 2011 18:57:36 -0700 (PDT) From: Nishanth Menon To: linux-omap Cc: Rajendra Nayak , Vishwanath BS Subject: [RFC][PATCH 9/9] OMAP4460: dpll: Support MPU frequencies > 1 Ghz Date: Wed, 25 May 2011 18:56:56 -0700 Message-Id: <1306375016-707-10-git-send-email-nm@ti.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1306375016-707-1-git-send-email-nm@ti.com> References: <1306375016-707-1-git-send-email-nm@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 26 May 2011 01:57:39 +0000 (UTC) From: Rajendra Nayak The OMAP4460 platform needs DCC (Duty cycle correction) enabled for frequencies above 1GHz from the MPU DPLL. Further, on OMAP4460 when the MPU Frequency is above 748Mhz, the programmable divider for the Async bridge to ABE must be set to MPU-Freq/8. For lower frequency, it should be MPU-Freq/4. Similarly for MPU Frequency above 920Mhz, the programmable divider for the async bridge to L3 and Memory Adapter interfaces of EMIF must be MPU-Freq/4. For lower frequency, they should be MPU-Freq/2. Also on 4460, the MPU clk for frequencies higher than 1Ghz is sourced from CLKOUTX2_M3, instead of CLKOUT_M2, while value of M3 is fixed to 1. Hence for frequencies higher than 1 Ghz, lock the DPLL at half the rate so the CLKOUTX2_M3 then matches the requested rate. Do all this as part of the DPLL control api. Signed-off-by: Rajendra Nayak Signed-off-by: Vishwanath BS --- arch/arm/mach-omap2/dpll3xxx.c | 58 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index f77022b..81d2f9f 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -34,6 +34,8 @@ #include "clock.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-34xx.h" +#include "cm-regbits-44xx.h" +#include "cm1_44xx.h" /* CM_AUTOIDLE_PLL*.AUTO_* bit values */ #define DPLL_AUTOIDLE_DISABLE 0x0 @@ -311,6 +313,42 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) __raw_writel(v, dd->control_reg); } + /* + * On OMAP4460, to obtain MPU DPLL frequency higher + * than 1GHz, DCC (Duty Cycle Correction) needs to + * be enabled. + * Also the interconnect frequency to EMIF should + * be switched between MPU clk divide by 4 (for + * frequencies higher than 920Mhz) and MPU clk divide + * by 2 (for frequencies lower than or equal to 920Mhz) + * Lastly the async bridge to ABE must be MPU clk divide + * by 8 for MPU clk > 748Mhz and MPU clk divide by 4 + * for lower frequencies. + * TODO: For now use a strcmp, but need to find a + * better way to identify the MPU dpll. + */ + if (cpu_is_omap446x() && !strcmp(clk->name, "dpll_mpu_ck")) { + /* DCC control */ + v = __raw_readl(dd->mult_div1_reg); + if (dd->last_rounded_rate > 1000000000) + v |= OMAP4460_DCC_EN_MASK; /* Enable DCC */ + else + v &= ~OMAP4460_DCC_EN_MASK; /* Disable DCC */ + __raw_writel(v, dd->mult_div1_reg); + + /* EMIF/ABE clock rate control */ + v = __raw_readl(OMAP4430_CM_MPU_MPU_CLKCTRL); + if (dd->last_rounded_rate > 920000000) + v |= OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK; + else + v &= ~OMAP4460_CLKSEL_EMIF_DIV_MODE_MASK; + if (dd->last_rounded_rate > 748000000) + v |= OMAP4460_CLKSEL_ABE_DIV_MODE_MASK; + else + v &= ~OMAP4460_CLKSEL_ABE_DIV_MODE_MASK; + __raw_writel(v, OMAP4430_CM_MPU_MPU_CLKCTRL); + } + /* Set DPLL multiplier, divider */ v = __raw_readl(dd->mult_div1_reg); v &= ~(dd->mult_mask | dd->div1_mask); @@ -427,6 +465,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) u16 freqsel = 0; struct dpll_data *dd; int ret; + unsigned long orig_rate = 0; if (!clk || !rate) return -EINVAL; @@ -454,6 +493,19 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) if (!ret) new_parent = dd->clk_bypass; } else { + /* + * On 4460, the MPU clk for frequencies higher than 1Ghz + * is sourced from CLKOUTX2_M3, instead of CLKOUT_M2, while + * value of M3 is fixed to 1. Hence for frequencies higher + * than 1 Ghz, lock the DPLL at half the rate so the + * CLKOUTX2_M3 then matches the requested rate. + */ + if (cpu_is_omap446x() && !strcmp(clk->name, "dpll_mpu_ck") + && (rate > 1000000000)) { + orig_rate = rate; + rate = rate/2; + } + if (dd->last_rounded_rate != rate) omap2_dpll_round_rate(clk, rate); @@ -468,6 +520,12 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) WARN_ON(1); } + /* Set the rate back to original for book keeping*/ + if (orig_rate) { + rate = orig_rate; + dd->last_rounded_rate = dd->last_rounded_rate * 2; + } + pr_debug("clock: %s: set rate: locking rate to %lu.\n", clk->name, rate);