Skip to content

Commit 2e9abc6

Browse files
Frank Oltmannsbebarino
authored andcommitted
clk: fractional-divider: Improve approximation when zero based and export
Consider the CLK_FRAC_DIVIDER_ZERO_BASED flag when finding the best approximation for m and n. By doing so, increase the range of valid values for the numerator and denominator by 1. Furthermore, export the approximation function so that users of this function can be compiled as modules. Cc: A.s. Dong <aisheng.dong@nxp.com> Signed-off-by: Frank Oltmanns <frank@oltmanns.dev> Link: https://lore.kernel.org/r/20230617131041.18313-2-frank@oltmanns.dev Signed-off-by: Stephen Boyd <sboyd@kernel.org>
1 parent 0bb80ec commit 2e9abc6

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

drivers/clk/clk-fractional-divider.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
123123
unsigned long *m, unsigned long *n)
124124
{
125125
struct clk_fractional_divider *fd = to_clk_fd(hw);
126+
unsigned long max_m, max_n;
126127

127128
/*
128129
* Get rate closer to *parent_rate to guarantee there is no overflow
@@ -138,10 +139,17 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
138139
rate <<= scale - fd->nwidth;
139140
}
140141

141-
rational_best_approximation(rate, *parent_rate,
142-
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
143-
m, n);
142+
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
143+
max_m = 1 << fd->mwidth;
144+
max_n = 1 << fd->nwidth;
145+
} else {
146+
max_m = GENMASK(fd->mwidth - 1, 0);
147+
max_n = GENMASK(fd->nwidth - 1, 0);
148+
}
149+
150+
rational_best_approximation(rate, *parent_rate, max_m, max_n, m, n);
144151
}
152+
EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation);
145153

146154
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
147155
unsigned long *parent_rate)
@@ -169,13 +177,18 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
169177
{
170178
struct clk_fractional_divider *fd = to_clk_fd(hw);
171179
unsigned long flags = 0;
172-
unsigned long m, n;
180+
unsigned long m, n, max_m, max_n;
173181
u32 mmask, nmask;
174182
u32 val;
175183

176-
rational_best_approximation(rate, parent_rate,
177-
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
178-
&m, &n);
184+
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
185+
max_m = 1 << fd->mwidth;
186+
max_n = 1 << fd->nwidth;
187+
} else {
188+
max_m = GENMASK(fd->mwidth - 1, 0);
189+
max_n = GENMASK(fd->nwidth - 1, 0);
190+
}
191+
rational_best_approximation(rate, parent_rate, max_m, max_n, &m, &n);
179192

180193
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
181194
m--;

0 commit comments

Comments
 (0)