mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 22:14:03 +02:00
clk: xilinx: Optimize divisor search in clk_wzrd_get_divisors_ver()
Optimise the clock wizard divisor calculation by eliminating the innermost loop over output divider o. Earlier there was an error that is returned if the WZRD_MIN_ERR is not achieved error is returned now it computes the best possible frequency. Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
8f5ae30d69
commit
e0a94c6bb5
|
|
@ -340,7 +340,7 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
|
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
|
||||||
u64 vco_freq, freq, diff, vcomin, vcomax;
|
u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL;
|
||||||
u32 m, d, o;
|
u32 m, d, o;
|
||||||
u32 mmin, mmax, dmin, dmax, omin, omax;
|
u32 mmin, mmax, dmin, dmax, omin, omax;
|
||||||
|
|
||||||
|
|
@ -356,22 +356,26 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
|
||||||
for (m = mmin; m <= mmax; m++) {
|
for (m = mmin; m <= mmax; m++) {
|
||||||
for (d = dmin; d <= dmax; d++) {
|
for (d = dmin; d <= dmax; d++) {
|
||||||
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
|
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
|
||||||
if (vco_freq >= vcomin && vco_freq <= vcomax) {
|
if (vco_freq < vcomin || vco_freq > vcomax)
|
||||||
for (o = omin; o <= omax; o++) {
|
continue;
|
||||||
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
|
|
||||||
diff = abs(freq - rate);
|
|
||||||
|
|
||||||
if (diff < WZRD_MIN_ERR) {
|
o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate);
|
||||||
divider->m = m;
|
if (o < omin || o > omax)
|
||||||
divider->d = d;
|
continue;
|
||||||
divider->o = o;
|
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
|
||||||
return 0;
|
diff = abs(freq - rate);
|
||||||
}
|
|
||||||
}
|
if (diff < best_diff) {
|
||||||
|
best_diff = diff;
|
||||||
|
divider->m = m;
|
||||||
|
divider->d = d;
|
||||||
|
divider->o = o;
|
||||||
|
if (!diff)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -EBUSY;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
|
static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user