Skip to content

Commit a5ebc33

Browse files
jernejskmripard
authored andcommitted
clk: sunxi-ng: Use u64 for calculation of nkmp rate
When parent rate is 24MHz and multiplier N >= 180, intermediate clock rate doesn't fit in 32 bit variable anymore. Because of that, introduce function for calculating clock rate which uses 64 bit variable for intermediate result. Acked-by: Maxime Ripard <[email protected]> Signed-off-by: Jernej Skrabec <[email protected]> Signed-off-by: Maxime Ripard <[email protected]>
1 parent d897ef5 commit a5ebc33

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

drivers/clk/sunxi-ng/ccu_nkmp.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ struct _ccu_nkmp {
2020
unsigned long p, min_p, max_p;
2121
};
2222

23+
static unsigned long ccu_nkmp_calc_rate(unsigned long parent,
24+
unsigned long n, unsigned long k,
25+
unsigned long m, unsigned long p)
26+
{
27+
u64 rate = parent;
28+
29+
rate *= n * k;
30+
do_div(rate, m * p);
31+
32+
return rate;
33+
}
34+
2335
static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
2436
struct _ccu_nkmp *nkmp)
2537
{
@@ -33,7 +45,9 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
3345
for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) {
3446
unsigned long tmp_rate;
3547

36-
tmp_rate = parent * _n * _k / (_m * _p);
48+
tmp_rate = ccu_nkmp_calc_rate(parent,
49+
_n, _k,
50+
_m, _p);
3751

3852
if (tmp_rate > rate)
3953
continue;
@@ -107,7 +121,7 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
107121
p = reg >> nkmp->p.shift;
108122
p &= (1 << nkmp->p.width) - 1;
109123

110-
return (parent_rate * n * k >> p) / m;
124+
return ccu_nkmp_calc_rate(parent_rate, n, k, m, 1 << p);
111125
}
112126

113127
static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -127,7 +141,8 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
127141

128142
ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
129143

130-
return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p);
144+
return ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
145+
_nkmp.m, _nkmp.p);
131146
}
132147

133148
static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,

0 commit comments

Comments
 (0)