From patchwork Wed Jun 5 13:51:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter De Schrijver X-Patchwork-Id: 2670121 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork2.kernel.org (Postfix) with ESMTP id 66C3ADF264 for ; Wed, 5 Jun 2013 13:52:39 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UkE8j-0000BW-1x; Wed, 05 Jun 2013 13:52:37 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UkE8g-0004U7-HY; Wed, 05 Jun 2013 13:52:34 +0000 Received: from hqemgate03.nvidia.com ([216.228.121.140]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UkE8d-0004Sg-65 for linux-arm-kernel@lists.infradead.org; Wed, 05 Jun 2013 13:52:32 +0000 Received: from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by hqemgate03.nvidia.com id ; Wed, 05 Jun 2013 06:58:59 -0700 Received: from hqemhub02.nvidia.com ([172.20.12.94]) by hqnvupgp08.nvidia.com (PGP Universal service); Wed, 05 Jun 2013 06:52:06 -0700 X-PGP-Universal: processed; by hqnvupgp08.nvidia.com on Wed, 05 Jun 2013 06:52:06 -0700 Received: from hqnvemgw01.nvidia.com (172.20.150.20) by hqemhub02.nvidia.com (172.20.150.31) with Microsoft SMTP Server id 8.3.298.1; Wed, 5 Jun 2013 06:52:06 -0700 Received: from thelma.nvidia.com (Not Verified[172.16.212.77]) by hqnvemgw01.nvidia.com with MailMarshal (v7,1,2,5326) id ; Wed, 05 Jun 2013 06:52:05 -0700 Received: from tbergstrom-lnx.nvidia.com (tbergstrom-lnx.nvidia.com [10.21.24.170]) by thelma.nvidia.com (8.13.8+Sun/8.8.8) with ESMTP id r55Dpjg2011012; Wed, 5 Jun 2013 06:52:03 -0700 (PDT) From: Peter De Schrijver To: Peter De Schrijver Subject: [PATCH 1/2] clk: tegra: allow PLL m,n,p init from SoC files Date: Wed, 5 Jun 2013 16:51:25 +0300 Message-ID: <1370440301-3562-2-git-send-email-pdeschrijver@nvidia.com> X-Mailer: git-send-email 1.7.7.rc0.72.g4b5ea.dirty In-Reply-To: <1370440301-3562-1-git-send-email-pdeschrijver@nvidia.com> References: <1370440301-3562-1-git-send-email-pdeschrijver@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130605_095231_360277_B6742A73 X-CRM114-Status: GOOD ( 14.12 ) X-Spam-Score: -7.4 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [216.228.121.140 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Prashant Gaikwad , mturquette@linaro.org, Stephen Warren , linux-kernel@vger.kernel.org, Thierry Reding , linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The m,n,p fields don't have the same bit offset and width across all PLLs. This patch allows SoC specific files to indicate the offset and width. Signed-off-by: Peter De Schrijver --- drivers/clk/tegra/clk-pll.c | 60 +++++++++++++++++++++++------------------- drivers/clk/tegra/clk.h | 32 ++++++++++++++-------- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 85bec1d..3b778d3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -134,15 +134,24 @@ #define pll_writel_misc(val, p) pll_writel(val, p->params->misc_reg, p) #define mask(w) ((1 << (w)) - 1) -#define divm_mask(p) mask(p->divm_width) -#define divn_mask(p) mask(p->divn_width) +#define divm_mask(p) mask(p->params->div_nmp->divm_width) +#define divn_mask(p) mask(p->params->div_nmp->divn_width) #define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \ - mask(p->divp_width)) + mask(p->params->div_nmp->divp_width)) #define divm_max(p) (divm_mask(p)) #define divn_max(p) (divn_mask(p)) #define divp_max(p) (1 << (divp_mask(p))) +static struct div_nmp default_nmp = { + .divn_shift = PLL_BASE_DIVN_SHIFT, + .divn_width = PLL_BASE_DIVN_WIDTH, + .divm_shift = PLL_BASE_DIVM_SHIFT, + .divm_width = PLL_BASE_DIVM_WIDTH, + .divp_shift = PLL_BASE_DIVP_SHIFT, + .divp_width = PLL_BASE_DIVP_WIDTH, +}; + static void clk_pll_enable_lock(struct tegra_clk_pll *pll) { u32 val; @@ -407,12 +416,12 @@ static void _update_pll_mnp(struct tegra_clk_pll *pll, val = pll_readl_base(pll); - val &= ~((divm_mask(pll) << pll->divm_shift) | - (divn_mask(pll) << pll->divn_shift) | - (divp_mask(pll) << pll->divp_shift)); - val |= ((cfg->m << pll->divm_shift) | - (cfg->n << pll->divn_shift) | - (cfg->p << pll->divp_shift)); + val &= ~((divm_mask(pll) << pll->params->div_nmp->divm_shift) | + (divn_mask(pll) << pll->params->div_nmp->divn_shift) | + (divp_mask(pll) << pll->params->div_nmp->divp_shift)); + val |= ((cfg->m << pll->params->div_nmp->divm_shift) | + (cfg->n << pll->params->div_nmp->divn_shift) | + (cfg->p << pll->params->div_nmp->divp_shift)); pll_writel_base(val, pll); } @@ -424,9 +433,9 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, val = pll_readl_base(pll); - cfg->m = (val >> pll->divm_shift) & (divm_mask(pll)); - cfg->n = (val >> pll->divn_shift) & (divn_mask(pll)); - cfg->p = (val >> pll->divp_shift) & (divp_mask(pll)); + cfg->m = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll)); + cfg->n = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll)); + cfg->p = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll)); } static void _update_pll_cpcon(struct tegra_clk_pll *pll, @@ -646,9 +655,9 @@ static int clk_plle_enable(struct clk_hw *hw) val = pll_readl_base(pll); val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); - val |= sel.m << pll->divm_shift; - val |= sel.n << pll->divn_shift; - val |= sel.p << pll->divp_shift; + val |= sel.m << pll->params->div_nmp->divm_shift; + val |= sel.n << pll->params->div_nmp->divn_shift; + val |= sel.p << pll->params->div_nmp->divp_shift; val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; pll_writel_base(val, pll); } @@ -679,9 +688,9 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw, u32 divn = 0, divm = 0, divp = 0; u64 rate = parent_rate; - divp = (val >> pll->divp_shift) & (divp_mask(pll)); - divn = (val >> pll->divn_shift) & (divn_mask(pll)); - divm = (val >> pll->divm_shift) & (divm_mask(pll)); + divp = (val >> pll->params->div_nmp->divp_shift) & (divp_mask(pll)); + divn = (val >> pll->params->div_nmp->divn_shift) & (divn_mask(pll)); + divm = (val >> pll->params->div_nmp->divm_shift) & (divm_mask(pll)); divm *= divp; rate *= divn; @@ -902,7 +911,8 @@ static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate, val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE); val &= ~(divn_mask(pll) | divm_mask(pll)); - val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift); + val |= (cfg.m << pll->params->div_nmp->divm_shift) | + (cfg.n << pll->params->div_nmp->divn_shift); writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE); } else _update_pll_mnp(pll, &cfg); @@ -1180,8 +1190,8 @@ static int clk_plle_tegra114_enable(struct clk_hw *hw) val = pll_readl_base(pll); val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll)); val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT); - val |= sel.m << pll->divm_shift; - val |= sel.n << pll->divn_shift; + val |= sel.m << pll->params->div_nmp->divm_shift; + val |= sel.n << pll->params->div_nmp->divn_shift; val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT; pll_writel_base(val, pll); udelay(1); @@ -1242,12 +1252,8 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, pll->flags = pll_flags; pll->lock = lock; - pll->divp_shift = PLL_BASE_DIVP_SHIFT; - pll->divp_width = PLL_BASE_DIVP_WIDTH; - pll->divn_shift = PLL_BASE_DIVN_SHIFT; - pll->divn_width = PLL_BASE_DIVN_WIDTH; - pll->divm_shift = PLL_BASE_DIVM_SHIFT; - pll->divm_width = PLL_BASE_DIVM_WIDTH; + if (!pll_params->div_nmp) + pll_params->div_nmp = &default_nmp; return pll; } diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 11278a8..d70eb2d 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -128,6 +128,25 @@ struct pdiv_map { }; /** + * struct div_nmp - offset and width of m,n and p fields + * + * @divn_shift: shift to the feedback divider bit field + * @divn_width: width of the feedback divider bit field + * @divm_shift: shift to the input divider bit field + * @divm_width: width of the input divider bit field + * @divp_shift: shift to the post divider bit field + * @divp_width: width of the post divider bit field + */ +struct div_nmp { + u8 divn_shift; + u8 divn_width; + u8 divm_shift; + u8 divm_width; + u8 divp_shift; + u8 divp_width; +}; + +/** * struct clk_pll_params - PLL parameters * * @input_min: Minimum input frequency @@ -166,6 +185,7 @@ struct tegra_clk_pll_params { int lock_delay; int max_p; struct pdiv_map *pdiv_tohw; + struct div_nmp *div_nmp; }; /** @@ -179,12 +199,6 @@ struct tegra_clk_pll_params { * @flags: PLL flags * @fixed_rate: PLL rate if it is fixed * @lock: register lock - * @divn_shift: shift to the feedback divider bit field - * @divn_width: width of the feedback divider bit field - * @divm_shift: shift to the input divider bit field - * @divm_width: width of the input divider bit field - * @divp_shift: shift to the post divider bit field - * @divp_width: width of the post divider bit field * * Flags: * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for @@ -214,12 +228,6 @@ struct tegra_clk_pll { u32 flags; unsigned long fixed_rate; spinlock_t *lock; - u8 divn_shift; - u8 divn_width; - u8 divm_shift; - u8 divm_width; - u8 divp_shift; - u8 divp_width; struct tegra_clk_pll_freq_table *freq_table; struct tegra_clk_pll_params *params; };