فهرست منبع

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 <maxime.ripard@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
Maxime Ripard 8 سال پیش
والد
کامیت
ee28648cb2
4فایلهای تغییر یافته به همراه74 افزوده شده و 51 حذف شده
  1. 0 3
      drivers/clk/sunxi-ng/Kconfig
  2. 15 16
      drivers/clk/sunxi-ng/ccu_nkm.c
  3. 18 19
      drivers/clk/sunxi-ng/ccu_nkmp.c
  4. 41 13
      drivers/clk/sunxi-ng/ccu_nm.c

+ 0 - 3
drivers/clk/sunxi-ng/Kconfig

@@ -35,17 +35,14 @@ config SUNXI_CCU_NK
 
 
 config SUNXI_CCU_NKM
 config SUNXI_CCU_NKM
 	bool
 	bool
-	select RATIONAL
 	select SUNXI_CCU_GATE
 	select SUNXI_CCU_GATE
 
 
 config SUNXI_CCU_NKMP
 config SUNXI_CCU_NKMP
 	bool
 	bool
-	select RATIONAL
 	select SUNXI_CCU_GATE
 	select SUNXI_CCU_GATE
 
 
 config SUNXI_CCU_NM
 config SUNXI_CCU_NM
 	bool
 	bool
-	select RATIONAL
 	select SUNXI_CCU_FRAC
 	select SUNXI_CCU_FRAC
 	select SUNXI_CCU_GATE
 	select SUNXI_CCU_GATE
 
 

+ 15 - 16
drivers/clk/sunxi-ng/ccu_nkm.c

@@ -9,7 +9,6 @@
  */
  */
 
 
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
-#include <linux/rational.h>
 
 
 #include "ccu_gate.h"
 #include "ccu_gate.h"
 #include "ccu_nkm.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;
 	unsigned long _n, _k, _m;
 
 
 	for (_k = 1; _k <= nkm->max_k; _k++) {
 	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;
+				}
+			}
 		}
 		}
 	}
 	}
 
 

+ 18 - 19
drivers/clk/sunxi-ng/ccu_nkmp.c

@@ -9,7 +9,6 @@
  */
  */
 
 
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
-#include <linux/rational.h>
 
 
 #include "ccu_gate.h"
 #include "ccu_gate.h"
 #include "ccu_nkmp.h"
 #include "ccu_nkmp.h"
@@ -29,24 +28,24 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
 	unsigned long _n, _k, _m, _p;
 	unsigned long _n, _k, _m, _p;
 
 
 	for (_k = 1; _k <= nkmp->max_k; _k++) {
 	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;
+					}
+				}
 			}
 			}
 		}
 		}
 	}
 	}

+ 41 - 13
drivers/clk/sunxi-ng/ccu_nm.c

@@ -9,12 +9,42 @@
  */
  */
 
 
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
-#include <linux/rational.h>
 
 
 #include "ccu_frac.h"
 #include "ccu_frac.h"
 #include "ccu_gate.h"
 #include "ccu_gate.h"
 #include "ccu_nm.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)
 static void ccu_nm_disable(struct clk_hw *hw)
 {
 {
 	struct ccu_nm *nm = hw_to_ccu_nm(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)
 			      unsigned long *parent_rate)
 {
 {
 	struct ccu_nm *nm = hw_to_ccu_nm(hw);
 	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,
 static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
 			   unsigned long parent_rate)
 			   unsigned long parent_rate)
 {
 {
 	struct ccu_nm *nm = hw_to_ccu_nm(hw);
 	struct ccu_nm *nm = hw_to_ccu_nm(hw);
+	struct _ccu_nm _nm;
 	unsigned long flags;
 	unsigned long flags;
-	unsigned long max_n, max_m;
-	unsigned long n, m;
 	u32 reg;
 	u32 reg;
 
 
 	if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
 	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
 	else
 		ccu_frac_helper_disable(&nm->common, &nm->frac);
 		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);
 	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->n.width + nm->n.shift - 1, nm->n.shift);
 	reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.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);
 	       nm->common.base + nm->common.reg);
 
 
 	spin_unlock_irqrestore(nm->common.lock, flags);
 	spin_unlock_irqrestore(nm->common.lock, flags);