From patchwork Tue Aug 1 16:22:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiko Stuebner X-Patchwork-Id: 9874975 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 9B07B603F4 for ; Tue, 1 Aug 2017 16:23:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E4CB28709 for ; Tue, 1 Aug 2017 16:23:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83158286C0; Tue, 1 Aug 2017 16:23:40 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EEDDC286C0 for ; Tue, 1 Aug 2017 16:23:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3yDfpVD+dB5fHLbFnb+WFIeyRPeazzgY0AZAa+Ynm2k=; b=Q5PUEtjUaTkGIU yhglAT5mpVfBmsToR3RKPjH/R7U6BrjzBN9f0B0oV1evNxXx8KEb1eJVat53/SwaHbnDxFKZqnYAK fy8uLiYHcszrjWhC2D/CA8F+xwNx+8sB+otxUCPnF9n7QnU8L1PuLwlUXodg9K4CrqIlxqMtfUmYQ 8P6ZWUypEfSCuXatSphuGAHOlQQ/9DBkYiivRBa1WIQqpWV2RbsKi/WA9iDwalM1c+c5gRbyObN6T cMX5yTAyKNa9AJZxhph4hbk1ZCwN0GSkNtrf7g2zyfGjUC/xvptcLsYYKi2SaSR9IlpkgZbZNLOjp /NNKsh9GuDtJwpxj4weQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dcZwZ-0000v4-Vn; Tue, 01 Aug 2017 16:22:52 +0000 Received: from gloria.sntech.de ([95.129.55.99]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dcZwW-0000tX-T0; Tue, 01 Aug 2017 16:22:50 +0000 Received: from [217.243.129.235] (helo=phil.localnet) by gloria.sntech.de with esmtpsa (TLS1.1:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1dcZw8-0005yu-UK; Tue, 01 Aug 2017 18:22:25 +0200 From: Heiko Stuebner To: Elaine Zhang Subject: [PATCH 2/2] clk: rockchip: add special approximation to fix up fractional clk's jitter Date: Tue, 01 Aug 2017 18:22:24 +0200 Message-ID: <3942563.TMEkxTS0ar@phil> User-Agent: KMail/5.2.3 (Linux/4.9.0-2-amd64; KDE/5.28.0; x86_64; ; ) In-Reply-To: <5990882.df1suBpf8V@phil> References: <1500624187-12165-1-git-send-email-zhangqing@rock-chips.com> <5990882.df1suBpf8V@phil> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170801_092249_097996_F18002E8 X-CRM114-Status: GOOD ( 10.87 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: huangtao@rock-chips.com, xxx@rock-chips.com, xf@rock-chips.com, mturquette@baylibre.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, cl@rock-chips.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Elaine Zhang From Rockchips fractional divider description: 3.1.9 Fractional divider usage To get specific frequency, clocks of I2S, SPDIF, UARTcan be generated by fractional divider. Generally you must set that denominator is 20 times larger than numerator to generate precise clock frequency. So the fractional divider applies only to generate low frequency clock like I2S, UART. Therefore add a special approximation function that handles this special requirement. Signed-off-by: Elaine Zhang Tested-by: Elaine Zhang --- drivers/clk/rockchip/clk.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index fe1d393cf678..b6db79a00602 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "clk.h" /** @@ -164,6 +165,40 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb, return notifier_from_errno(ret); } +/** + * fractional divider must set that denominator is 20 times larger than + * numerator to generate precise clock frequency. + */ +void rockchip_fractional_approximation(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate, + unsigned long *m, unsigned long *n) +{ + struct clk_fractional_divider *fd = to_clk_fd(hw); + unsigned long p_rate, p_parent_rate; + struct clk_hw *p_parent; + unsigned long scale; + + p_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); + if ((rate * 20 > p_rate) && (p_rate % rate != 0)) { + p_parent = clk_hw_get_parent(clk_hw_get_parent(hw)); + p_parent_rate = clk_hw_get_rate(p_parent); + *parent_rate = p_parent_rate; + } + + /* + * Get rate closer to *parent_rate to guarantee there is no overflow + * for m and n. In the result it will be the nearest rate left shifted + * by (scale - fd->nwidth) bits. + */ + scale = fls_long(*parent_rate / rate - 1); + if (scale > fd->nwidth) + rate <<= scale - fd->nwidth; + + rational_best_approximation(rate, *parent_rate, + GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), + m, n); +} + static struct clk *rockchip_clk_register_frac_branch( struct rockchip_clk_provider *ctx, const char *name, const char *const *parent_names, u8 num_parents, @@ -210,6 +245,7 @@ static struct clk *rockchip_clk_register_frac_branch( div->nwidth = 16; div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; div->lock = lock; + div->approximation = rockchip_fractional_approximation; div_ops = &clk_fractional_divider_ops; clk = clk_register_composite(NULL, name, parent_names, num_parents,