From patchwork Thu Jul 27 11:10:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 9866641 X-Patchwork-Delegate: sboyd@codeaurora.org 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 91FFB6038C for ; Thu, 27 Jul 2017 11:13:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 846CC28758 for ; Thu, 27 Jul 2017 11:13:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 79553287CF; Thu, 27 Jul 2017 11:13:13 +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 09A6F28758 for ; Thu, 27 Jul 2017 11:13:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751621AbdG0LK7 (ORCPT ); Thu, 27 Jul 2017 07:10:59 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:58412 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751530AbdG0LK5 (ORCPT ); Thu, 27 Jul 2017 07:10:57 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 63A83609D1; Thu, 27 Jul 2017 11:10:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1501153857; bh=p6jrP7nKqDKSWeEf76ujUpz8Xo4jEsMCeBl3uzUIta0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NkxMsdV5cCAbph+xWJpH+Fooh8FipMtiyl5LmToXc/zr0Jo7vutE/5SAx3tTQN1zD WVIXYZVCCqglfOSsqHB+eWtn79U27dKFdYz7QmrgtvlrprpkUDIB2AX4hqZYYmu9QK kFOXogVwm7GqgUpW7Bdx6cIUWuPMNWX7Ye9be5tY= 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 04E9460998; Thu, 27 Jul 2017 11:10:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1501153856; bh=p6jrP7nKqDKSWeEf76ujUpz8Xo4jEsMCeBl3uzUIta0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HuJ5YnawYoM01HFc3SqxEdJLw8d0kmQSj/ijJyUlcAdtoCltUvESefZCjD8G8jqE0 J67s/QncWMJLlTRzjE/feW3W28hmyhKuYTFJLeKbWxVzukV/HP76EhsEEXsM+FeN+T Bx0XWAgsOYFi3H2B8yixLE20qmH831UsxiKyYmFc= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 04E9460998 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: sboyd@codeaurora.org, mturquette@baylibre.com Cc: andy.gross@linaro.org, david.brown@linaro.org, rnayak@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, Abhishek Sahu Subject: [RFC 05/12] clk: qcom: fix 16 bit alpha support calculation Date: Thu, 27 Jul 2017 16:40:18 +0530 Message-Id: <1501153825-5181-6-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501153825-5181-1-git-send-email-absahu@codeaurora.org> References: <1501153825-5181-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 alpha. Signed-off-by: Abhishek Sahu --- drivers/clk/qcom/clk-alpha-pll.c | 58 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index ef24c80..3a7ec42 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -45,8 +45,11 @@ * 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 + +#define pll_alpha_width(pll) (pll->flags & SUPPORTS_16BIT_ALPHA ? \ + ALPHA_REG_16BIT_WIDTH : ALPHA_REG_BITWIDTH) #define pll_mode(pll) (pll->base + pll->offsets[ALPHA_PLL_MODE]) #define pll_l(pll) (pll->base + pll->offsets[ALPHA_PLL_L_VAL]) @@ -316,13 +319,16 @@ static void clk_alpha_pll_disable(struct clk_hw *hw) regmap_update_bits(pll->clkr.regmap, pll_mode(pll), 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_BITWIDTH : alpha_width)); } 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; @@ -337,14 +343,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_BITWIDTH : alpha_width); + 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 * @@ -363,26 +371,26 @@ static unsigned long alpha_pll_calc_rate(u64 prate, u32 l, u32 a) static unsigned long clk_alpha_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - u32 l, low, high, ctl; - u64 a = 0, prate = parent_rate; struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + u32 l, low, high, ctl, alpha_width = pll_alpha_width(pll); + u64 a = 0, prate = parent_rate; regmap_read(pll->clkr.regmap, pll_l(pll), &l); regmap_read(pll->clkr.regmap, pll_user_ctl(pll), &ctl); if (ctl & PLL_ALPHA_EN) { regmap_read(pll->clkr.regmap, pll_alpha(pll), &low); - if (pll->flags & SUPPORTS_16BIT_ALPHA) { - a = low & ALPHA_16BIT_MASK; - } else { + if (alpha_width > ALPHA_BITWIDTH) { regmap_read(pll->clkr.regmap, pll_alpha_u(pll), &high); - a = (u64)high << 32 | low; - a >>= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH; + a = (u64)high << ALPHA_BITWIDTH | low; + a >>= alpha_width - ALPHA_BITWIDTH; + } else { + a = low; } } - return alpha_pll_calc_rate(prate, l, a); + return alpha_pll_calc_rate(prate, l, a, alpha_width); } static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -390,10 +398,10 @@ static int clk_alpha_pll_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; + u32 l, alpha_width = pll_alpha_width(pll); 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"); @@ -402,14 +410,16 @@ static int clk_alpha_pll_set_rate(struct clk_hw *hw, unsigned long rate, regmap_write(pll->clkr.regmap, pll_l(pll), l); - if (pll->flags & SUPPORTS_16BIT_ALPHA) { - regmap_write(pll->clkr.regmap, pll_alpha(pll), - a & ALPHA_16BIT_MASK); - } else { - a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH); - regmap_write(pll->clkr.regmap, pll_alpha_u(pll), a >> 32); + if (alpha_width > ALPHA_BITWIDTH) { + a <<= (alpha_width - ALPHA_BITWIDTH); + regmap_update_bits(pll->clkr.regmap, pll_alpha_u(pll), + GENMASK(0, alpha_width - ALPHA_BITWIDTH - 1), + a >> ALPHA_BITWIDTH); } + regmap_update_bits(pll->clkr.regmap, pll_alpha(pll), + GENMASK(0, alpha_width - 1), a); + regmap_update_bits(pll->clkr.regmap, pll_user_ctl(pll), PLL_VCO_MASK << PLL_VCO_SHIFT, vco->val << PLL_VCO_SHIFT); @@ -424,11 +434,11 @@ static long clk_alpha_pll_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;