Skip to content

Commit e0a94c6

Browse files
shubhraamdbebarino
authored andcommitted
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>
1 parent 8f5ae30 commit e0a94c6

1 file changed

Lines changed: 18 additions & 14 deletions

File tree

drivers/clk/xilinx/clk-xlnx-clock-wizard.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
340340
unsigned long parent_rate)
341341
{
342342
struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
343-
u64 vco_freq, freq, diff, vcomin, vcomax;
343+
u64 vco_freq, freq, diff, vcomin, vcomax, best_diff = -1ULL;
344344
u32 m, d, o;
345345
u32 mmin, mmax, dmin, dmax, omin, omax;
346346

@@ -356,22 +356,26 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
356356
for (m = mmin; m <= mmax; m++) {
357357
for (d = dmin; d <= dmax; d++) {
358358
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
359-
if (vco_freq >= vcomin && vco_freq <= vcomax) {
360-
for (o = omin; o <= omax; o++) {
361-
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
362-
diff = abs(freq - rate);
363-
364-
if (diff < WZRD_MIN_ERR) {
365-
divider->m = m;
366-
divider->d = d;
367-
divider->o = o;
368-
return 0;
369-
}
370-
}
359+
if (vco_freq < vcomin || vco_freq > vcomax)
360+
continue;
361+
362+
o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate);
363+
if (o < omin || o > omax)
364+
continue;
365+
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
366+
diff = abs(freq - rate);
367+
368+
if (diff < best_diff) {
369+
best_diff = diff;
370+
divider->m = m;
371+
divider->d = d;
372+
divider->o = o;
373+
if (!diff)
374+
return 0;
371375
}
372376
}
373377
}
374-
return -EBUSY;
378+
return 0;
375379
}
376380

377381
static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,

0 commit comments

Comments
 (0)