|
@@ -49,16 +49,12 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
|
- unsigned long *parent_rate)
|
|
|
+static void clk_fd_general_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 scale;
|
|
|
- unsigned long m, n;
|
|
|
- u64 ret;
|
|
|
-
|
|
|
- if (!rate || rate >= *parent_rate)
|
|
|
- return *parent_rate;
|
|
|
|
|
|
/*
|
|
|
* Get rate closer to *parent_rate to guarantee there is no overflow
|
|
@@ -71,7 +67,23 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
|
|
|
|
rational_best_approximation(rate, *parent_rate,
|
|
|
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
|
|
|
- &m, &n);
|
|
|
+ m, n);
|
|
|
+}
|
|
|
+
|
|
|
+static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
|
+ unsigned long *parent_rate)
|
|
|
+{
|
|
|
+ struct clk_fractional_divider *fd = to_clk_fd(hw);
|
|
|
+ unsigned long m, n;
|
|
|
+ u64 ret;
|
|
|
+
|
|
|
+ if (!rate || rate >= *parent_rate)
|
|
|
+ return *parent_rate;
|
|
|
+
|
|
|
+ if (fd->approximation)
|
|
|
+ fd->approximation(hw, rate, parent_rate, &m, &n);
|
|
|
+ else
|
|
|
+ clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
|
|
|
|
|
|
ret = (u64)*parent_rate * m;
|
|
|
do_div(ret, n);
|