[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250729050842.1522-1-shubhrajyoti.datta@amd.com>
Date: Tue, 29 Jul 2025 10:38:42 +0530
From: Shubhrajyoti Datta <shubhrajyoti.datta@....com>
To: <linux-clk@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC: <git@....com>, Michael Turquette <mturquette@...libre.com>, Stephen Boyd
<sboyd@...nel.org>, Michal Simek <michal.simek@....com>, Shubhrajyoti Datta
<shubhrajyoti.datta@....com>
Subject: [PATCH] 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@....com>
---
For someof the input frequency choices
setting 233250000 -> 233331003 diff is 81003
if minerr is 20000 it was returning error now it will
compute the nearest frequency.
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 32 ++++++++++++----------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 3efce7b88906..4775cde45e21 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -344,7 +344,7 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
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 mmin, mmax, dmin, dmax, omin, omax;
@@ -360,22 +360,26 @@ static int clk_wzrd_get_divisors_ver(struct clk_hw *hw, unsigned long rate,
for (m = mmin; m <= mmax; m++) {
for (d = dmin; d <= dmax; d++) {
vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
- if (vco_freq >= vcomin && vco_freq <= vcomax) {
- for (o = omin; o <= omax; o++) {
- freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
- diff = abs(freq - rate);
-
- if (diff < WZRD_MIN_ERR) {
- divider->m = m;
- divider->d = d;
- divider->o = o;
- return 0;
- }
- }
+ if (vco_freq < vcomin || vco_freq > vcomax)
+ continue;
+
+ o = DIV_ROUND_CLOSEST_ULL(vco_freq, rate);
+ if (o < omin || o > omax)
+ continue;
+ freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
+ 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,
--
2.34.1
Powered by blists - more mailing lists