| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- From ee28648cb2b4d4ab5c2eb8199ea86675fe19016b Mon Sep 17 00:00:00 2001
- From: Maxime Ripard <[email protected]>
- Date: Thu, 29 Sep 2016 22:53:12 +0200
- Subject: clk: sunxi-ng: Remove the use of rational computations
- 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 <[email protected]>
- Acked-by: Chen-Yu Tsai <[email protected]>
- ---
- drivers/clk/sunxi-ng/Kconfig | 3 ---
- drivers/clk/sunxi-ng/ccu_nkm.c | 31 ++++++++++++-----------
- drivers/clk/sunxi-ng/ccu_nkmp.c | 37 ++++++++++++++--------------
- drivers/clk/sunxi-ng/ccu_nm.c | 54 +++++++++++++++++++++++++++++++----------
- 4 files changed, 74 insertions(+), 51 deletions(-)
- --- a/drivers/clk/sunxi-ng/Kconfig
- +++ b/drivers/clk/sunxi-ng/Kconfig
- @@ -36,17 +36,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
-
- --- a/drivers/clk/sunxi-ng/ccu_nkm.c
- +++ b/drivers/clk/sunxi-ng/ccu_nkm.c
- @@ -9,7 +9,6 @@
- */
-
- #include <linux/clk-provider.h>
- -#include <linux/rational.h>
-
- #include "ccu_gate.h"
- #include "ccu_nkm.h"
- @@ -28,21 +27,21 @@ static void ccu_nkm_find_best(unsigned l
- 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;
- + }
- + }
- }
- }
-
- --- a/drivers/clk/sunxi-ng/ccu_nkmp.c
- +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
- @@ -9,7 +9,6 @@
- */
-
- #include <linux/clk-provider.h>
- -#include <linux/rational.h>
-
- #include "ccu_gate.h"
- #include "ccu_nkmp.h"
- @@ -29,24 +28,24 @@ static void ccu_nkmp_find_best(unsigned
- 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 <= nkmp->max_n; _n++) {
- + for (_m = 1; _n <= nkmp->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;
- + }
- + }
- }
- }
- }
- --- a/drivers/clk/sunxi-ng/ccu_nm.c
- +++ b/drivers/clk/sunxi-ng/ccu_nm.c
- @@ -9,12 +9,42 @@
- */
-
- #include <linux/clk-provider.h>
- -#include <linux/rational.h>
-
- #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
- 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
- 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
- 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);
|