From patchwork Thu Sep 28 17:50:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 9976571 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 98DE360365 for ; Thu, 28 Sep 2017 17:54:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89CA528A10 for ; Thu, 28 Sep 2017 17:54:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7E964296D9; Thu, 28 Sep 2017 17:54:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA8B628A10 for ; Thu, 28 Sep 2017 17:54:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752338AbdI1RyQ (ORCPT ); Thu, 28 Sep 2017 13:54:16 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:50456 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752344AbdI1RvP (ORCPT ); Thu, 28 Sep 2017 13:51:15 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id A2A0460C07; Thu, 28 Sep 2017 17:51:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1506621074; bh=JhV5hWc1qThD1t0g4JN2/W2NKlG7IowcL9nO4k0tm08=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ghPgTRnNdIufioqLPZMA7y7SnLYqxrdHkH6FwYb6j6Fjo0BGi0PfCHwpqShyWBsE7 N8XcW5uolcVHRGTlbVKNUNYZetipsHgfR+SjAdIhrh8yooq+tWIHHHO6oJoX/myMKw 3FXjhh6azPVm2VCP4F/cgcSHKQaaByViYDwL+rhE= Received: from absahu-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: absahu@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id C48F26071D; Thu, 28 Sep 2017 17:51:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1506621073; bh=JhV5hWc1qThD1t0g4JN2/W2NKlG7IowcL9nO4k0tm08=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kc0cfNh2/EtoM+tW6nU2kgfSrd0zEk8xxy3K3vHB2Xr/p195i+qCP1AyTGF2qiCvc mTMnkzELtTPYDymM/+FpYnmvROGr4DEgkVWuk6XVEI3xZKrkDXTd2As+hWKnInos2s Y0bwcv7K2RCueXfpG1WEeoE5LpGC9gi4gWeCOL40= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org C48F26071D Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=absahu@codeaurora.org From: Abhishek Sahu To: Stephen Boyd , Michael Turquette Cc: Andy Gross , David Brown , Rajendra Nayak , linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Abhishek Sahu Subject: [PATCH 04/13] clk: qcom: fix 16 bit alpha support calculation Date: Thu, 28 Sep 2017 23:20:41 +0530 Message-Id: <1506621050-10129-5-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1506621050-10129-1-git-send-email-absahu@codeaurora.org> References: <1506621050-10129-1-git-send-email-absahu@codeaurora.org> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The alpha value calculation function has been written for 40 bit alpha which is not coming properly for 16 bit 1. Alpha value is being calculated on the basis of ALPHA_BITWIDTH to make the computation easy for 40 bit alpha. After calculating the 32 bit alpha, It is being converted to 40 bit alpha by making making lower bits zero. But if actual alpha register width is less than ALPHA_BITWIDTH, then the actual width can be used for calculation 2. During 40 bit alpha pll set rate, the lower alpha register is not being configured Now the changes have been made to calculate the rate and register values from alpha_width instead hardcoding it so that it can work for all the cases. Signed-off-by: Abhishek Sahu --- drivers/clk/qcom/clk-alpha-pll.c | 55 ++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index d5bfc52..a12f7b4 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -45,8 +45,12 @@ * Even though 40 bits are present, use only 32 for ease of calculation. */ #define ALPHA_REG_BITWIDTH 40 +#define ALPHA_REG_16BIT_WIDTH 16 #define ALPHA_BITWIDTH 32 -#define ALPHA_16BIT_MASK 0xffff + +/* Returns the Alpha register width for pll */ +#define pll_alpha_width(pll) (pll->flags & SUPPORTS_16BIT_ALPHA ? \ + ALPHA_REG_16BIT_WIDTH : ALPHA_REG_BITWIDTH) /* Returns the alpha_pll_clk_ops for pll type */ #define pll_clk_ops(hw) (alpha_pll_props[to_clk_alpha_pll(hw)-> \ @@ -364,13 +368,16 @@ static void alpha_pll_default_disable(struct clk_hw *hw) regmap_update_bits(pll->clkr.regmap, off, mask, 0); } -static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) +static unsigned long +alpha_pll_calc_rate(u64 prate, u32 l, u32 a, u32 alpha_width) { - return (prate * l) + ((prate * a) >> ALPHA_BITWIDTH); + return (prate * l) + ((prate * a) >> + (alpha_width < ALPHA_BITWIDTH ? alpha_width : ALPHA_BITWIDTH)); } static unsigned long -alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a) +alpha_pll_round_rate(unsigned long rate, unsigned long prate, u32 *l, u64 *a, + u32 alpha_width) { u64 remainder; u64 quotient; @@ -385,14 +392,16 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) } /* Upper ALPHA_BITWIDTH bits of Alpha */ - quotient = remainder << ALPHA_BITWIDTH; + quotient = remainder << (alpha_width < ALPHA_BITWIDTH ? + alpha_width : ALPHA_BITWIDTH); + remainder = do_div(quotient, prate); if (remainder) quotient++; *a = quotient; - return alpha_pll_calc_rate(prate, *l, *a); + return alpha_pll_calc_rate(prate, *l, *a, alpha_width); } static const struct pll_vco * @@ -414,7 +423,7 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) u32 l, low, high, ctl; u64 a = 0, prate = parent_rate; struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - u32 off = pll->offset; + u32 off = pll->offset, alpha_width = pll_alpha_width(pll); u8 type = pll->pll_type; regmap_read(pll->clkr.regmap, off + pll_l(type), &l); @@ -422,17 +431,19 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) regmap_read(pll->clkr.regmap, off + pll_user_ctl(type), &ctl); if (ctl & PLL_ALPHA_EN) { regmap_read(pll->clkr.regmap, off + pll_alpha(type), &low); - if (pll->flags & SUPPORTS_16BIT_ALPHA) { - a = low & ALPHA_16BIT_MASK; - } else { + if (alpha_width > 32) { regmap_read(pll->clkr.regmap, off + pll_alpha_u(type), &high); a = (u64)high << 32 | low; - a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; + } else { + a = low & GENMASK(alpha_width - 1, 0); } + + if (alpha_width > ALPHA_BITWIDTH) + a >>= alpha_width - ALPHA_BITWIDTH; } - return alpha_pll_calc_rate(prate, l, a); + return alpha_pll_calc_rate(prate, l, a, alpha_width); } static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate, @@ -440,11 +451,11 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); const struct pll_vco *vco; - u32 l, off = pll->offset; + u32 l, off = pll->offset, alpha_width = pll_alpha_width(pll); u8 type = pll->pll_type; u64 a; - rate = alpha_pll_round_rate(rate, prate, &l, &a); + rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); vco = alpha_pll_find_vco(pll, rate); if (!vco) { pr_err("alpha pll not in a valid vco range\n"); @@ -453,14 +464,14 @@ static int alpha_pll_default_set_rate(struct clk_hw *hw, unsigned long rate, regmap_write(pll->clkr.regmap, off + pll_l(type), l); - if (pll->flags & SUPPORTS_16BIT_ALPHA) { - regmap_write(pll->clkr.regmap, off + pll_alpha(type), - a & ALPHA_16BIT_MASK); - } else { - a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); + if (alpha_width > ALPHA_BITWIDTH) + a <<= alpha_width - ALPHA_BITWIDTH; + + if (alpha_width > 32) regmap_write(pll->clkr.regmap, off + pll_alpha_u(type), a >> 32); - } + + regmap_write(pll->clkr.regmap, off + pll_alpha(type), a); regmap_update_bits(pll->clkr.regmap, off + pll_user_ctl(type), PLL_VCO_MASK << PLL_VCO_SHIFT, @@ -476,11 +487,11 @@ static long alpha_pll_default_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); - u32 l; + u32 l, alpha_width = pll_alpha_width(pll); u64 a; unsigned long min_freq, max_freq; - rate = alpha_pll_round_rate(rate, *prate, &l, &a); + rate = alpha_pll_round_rate(rate, *prate, &l, &a, alpha_width); if (alpha_pll_find_vco(pll, rate)) return rate;