From patchwork Mon Oct 3 08:09:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 9360223 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 86EE1607D8 for ; Mon, 3 Oct 2016 08:13:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6305628795 for ; Mon, 3 Oct 2016 08:13:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 57BA0288CB; Mon, 3 Oct 2016 08:13:04 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D4D1128795 for ; Mon, 3 Oct 2016 08:13:03 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bqyLg-000090-V4; Mon, 03 Oct 2016 08:11:44 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bqyK1-0006EM-8a for linux-arm-kernel@lists.infradead.org; Mon, 03 Oct 2016 08:10:05 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id F1FB1228C; Mon, 3 Oct 2016 10:09:23 +0200 (CEST) Received: from localhost (per18-1-82-246-202-189.fbx.proxad.net [82.246.202.189]) by mail.free-electrons.com (Postfix) with ESMTPSA id 9952CA5E; Mon, 3 Oct 2016 10:09:23 +0200 (CEST) From: Maxime Ripard To: Mike Turquette , Stephen Boyd , Chen-Yu Tsai , Maxime Ripard Subject: [PATCH v3 2/9] clk: sunxi-ng: Remove the use of rational computations Date: Mon, 3 Oct 2016 10:09:06 +0200 Message-Id: <20161003080913.24197-3-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161003080913.24197-1-maxime.ripard@free-electrons.com> References: <20161003080913.24197-1-maxime.ripard@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161003_011001_758981_D9484C95 X-CRM114-Status: GOOD ( 14.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andre Przywara , linux-sunxi@googlegroups.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP While the rational library works great, it doesn't really allow us to add more constraints, like the minimum. Remove that in order to be able to deal with the constraints we'll need. Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/Kconfig | 3 --- drivers/clk/sunxi-ng/ccu_nkm.c | 31 ++++++++++++----------- drivers/clk/sunxi-ng/ccu_nkmp.c | 45 +++++++++++++++++----------------- drivers/clk/sunxi-ng/ccu_nm.c | 54 +++++++++++++++++++++++++++++++---------- 4 files changed, 78 insertions(+), 55 deletions(-) diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 254d9526c018..1b4c55a53d7a 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig @@ -35,17 +35,14 @@ config SUNXI_CCU_NK config SUNXI_CCU_NKM bool - select RATIONAL select SUNXI_CCU_GATE config SUNXI_CCU_NKMP bool - select RATIONAL select SUNXI_CCU_GATE config SUNXI_CCU_NM bool - select RATIONAL select SUNXI_CCU_FRAC select SUNXI_CCU_GATE diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 059fdc3b4f96..0b08d000eb38 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -9,7 +9,6 @@ */ #include -#include #include "ccu_gate.h" #include "ccu_nkm.h" @@ -28,21 +27,21 @@ static void ccu_nkm_find_best(unsigned long parent, unsigned long rate, unsigned long _n, _k, _m; for (_k = 1; _k <= nkm->max_k; _k++) { - unsigned long tmp_rate; - - rational_best_approximation(rate / _k, parent, - nkm->max_n, nkm->max_m, &_n, &_m); - - tmp_rate = parent * _n * _k / _m; - - if (tmp_rate > rate) - continue; - - if ((rate - tmp_rate) < (rate - best_rate)) { - best_rate = tmp_rate; - best_n = _n; - best_k = _k; - best_m = _m; + for (_n = 1; _n <= nkm->max_n; _n++) { + for (_m = 1; _n <= nkm->max_m; _m++) { + unsigned long tmp_rate; + + tmp_rate = parent * _n * _k / _m; + + if (tmp_rate > rate) + continue; + if ((rate - tmp_rate) < (rate - best_rate)) { + best_rate = tmp_rate; + best_n = _n; + best_k = _k; + best_m = _m; + } + } } } diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index 9769dee99511..4b457d8cce11 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -9,16 +9,15 @@ */ #include -#include #include "ccu_gate.h" #include "ccu_nkmp.h" struct _ccu_nkmp { - unsigned long n, max_n; - unsigned long k, max_k; - unsigned long m, max_m; - unsigned long p, max_p; + unsigned long n, min_n, max_n; + unsigned long k, min_k, max_k; + unsigned long m, min_m, max_m; + unsigned long p, min_p, max_p; }; static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, @@ -29,24 +28,24 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, unsigned long _n, _k, _m, _p; for (_k = 1; _k <= nkmp->max_k; _k++) { - for (_p = 1; _p <= nkmp->max_p; _p <<= 1) { - unsigned long tmp_rate; - - rational_best_approximation(rate / _k, parent / _p, - nkmp->max_n, nkmp->max_m, - &_n, &_m); - - tmp_rate = parent * _n * _k / (_m * _p); - - if (tmp_rate > rate) - continue; - - if ((rate - tmp_rate) < (rate - best_rate)) { - best_rate = tmp_rate; - best_n = _n; - best_k = _k; - best_m = _m; - best_p = _p; + for (_n = 1; _n <= nkm->max_n; _n++) { + for (_m = 1; _n <= nkm->max_m; _m++) { + for (_p = 1; _p <= nkmp->max_p; _p <<= 1) { + unsigned long tmp_rate; + + tmp_rate = parent * _n * _k / (_m * _p); + + if (tmp_rate > rate) + continue; + + if ((rate - tmp_rate) < (rate - best_rate)) { + best_rate = tmp_rate; + best_n = _n; + best_k = _k; + best_m = _m; + best_p = _p; + } + } } } } diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index b61bdd8c7a7f..c6d652289320 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -9,12 +9,42 @@ */ #include -#include #include "ccu_frac.h" #include "ccu_gate.h" #include "ccu_nm.h" +struct _ccu_nm { + unsigned long n, max_n; + unsigned long m, max_m; +}; + +static void ccu_nm_find_best(unsigned long parent, unsigned long rate, + struct _ccu_nm *nm) +{ + unsigned long best_rate = 0; + unsigned long best_n = 0, best_m = 0; + unsigned long _n, _m; + + for (_n = 1; _n <= nm->max_n; _n++) { + for (_m = 1; _n <= nm->max_m; _m++) { + unsigned long tmp_rate = parent * _n / _m; + + if (tmp_rate > rate) + continue; + + if ((rate - tmp_rate) < (rate - best_rate)) { + best_rate = tmp_rate; + best_n = _n; + best_m = _m; + } + } + } + + nm->n = best_n; + nm->m = best_m; +} + static void ccu_nm_disable(struct clk_hw *hw) { struct ccu_nm *nm = hw_to_ccu_nm(hw); @@ -61,24 +91,22 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct ccu_nm *nm = hw_to_ccu_nm(hw); - unsigned long max_n, max_m; - unsigned long n, m; + struct _ccu_nm _nm; - max_n = 1 << nm->n.width; - max_m = nm->m.max ?: 1 << nm->m.width; + _nm.max_n = 1 << nm->n.width; + _nm.max_m = nm->m.max ?: 1 << nm->m.width; - rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m); + ccu_nm_find_best(*parent_rate, rate, &_nm); - return *parent_rate * n / m; + return *parent_rate * _nm.n / _nm.m; } static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct ccu_nm *nm = hw_to_ccu_nm(hw); + struct _ccu_nm _nm; unsigned long flags; - unsigned long max_n, max_m; - unsigned long n, m; u32 reg; if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) @@ -86,10 +114,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, else ccu_frac_helper_disable(&nm->common, &nm->frac); - max_n = 1 << nm->n.width; - max_m = nm->m.max ?: 1 << nm->m.width; + _nm.max_n = 1 << nm->n.width; + _nm.max_m = nm->m.max ?: 1 << nm->m.width; - rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m); + ccu_nm_find_best(parent_rate, rate, &_nm); spin_lock_irqsave(nm->common.lock, flags); @@ -97,7 +125,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift); reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift); - writel(reg | ((m - 1) << nm->m.shift) | ((n - 1) << nm->n.shift), + writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift), nm->common.base + nm->common.reg); spin_unlock_irqrestore(nm->common.lock, flags);