The fractional divider approximation does not utilize the full available
range for clocks that are flagged CLK_FRAC_DIVIDER_ZERO_BASED. This
patchset aims to fix that.
It also adds test cases for the edge cases of fractional divider clocks
with and without the CLK_FRAC_DIVIDER_ZERO_BASED flag to highlight the
changes.
Finally, it also exports clk_fractional_divider_general_approximation so
that the test cases (but also other users like rockchip clk driver) can
be compiled as a module.
Unfortunately, I have no boards to test this patch. So all we have are
the unit tests. It seems the only user of this flag in mainline is
drivers/clk/imx/clk-composite-7ulp.c, therefore I'm cc-ing
get_maintainers.pl --git-blame -f drivers/clk/imx/clk-composite-7ulp.c
in the hopes of a wider audience.
Thank you for considering this contribution,
Frank
P.S.: V4 was short-lived, because it triggered a compiler warning on
clang. I'm sorry for the noise. -- Frank
V4: https://lore.kernel.org/all/[email protected]/
V3: https://lore.kernel.org/all/[email protected]/
V2: https://lore.kernel.org/lkml/[email protected]/
V1: https://lore.kernel.org/lkml/[email protected]/
Changes in V5 (since V4):
- Fix compiler warnings on clang by removing superfluous variable max_m
in the test cases for the maximum denominator (n) and max_n in the
test cases for max numerator (m).
Thank you, Intel, for your kernel test robot!
Changes in V4 (since V3):
- Export clk_fractional_divider_general_approximation so that users
(e.g., the testcases) can be compiled as modules.
- Change test cases so that they test
clk_fractional_divider_general_approximation again (like in V2)
instead of clk_fd_round_rate (like in V3), but keeping the structure
of V3 with separate file and individual test cases for each edge
case.
Changes in V3 (since V2):
- Completely reworked the test cases
- Moved tests to separate file as per Stephen's request
- Move each edge case into their individual test case as per
Stephen's request
- Test clk_fd_round_rate instead of
clk_fractional_divider_general_approximation as testing the latter
broke builds
Changes in V2 (since V1):
- Added test case as requested by Stephen Boyd
- Fixed commit message as the Cc: was missing a closing bracket, so that the
original mail unfortunately did not go out to A. s. Dong.
Frank Oltmanns (2):
clk: fractional-divider: Improve approximation when zero based and
export
clk: fractional-divider: tests: Add test suite for edge cases
drivers/clk/.kunitconfig | 1 +
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-fractional-divider.c | 27 +++-
drivers/clk/clk-fractional-divider_test.c | 157 ++++++++++++++++++++++
5 files changed, 186 insertions(+), 7 deletions(-)
create mode 100644 drivers/clk/clk-fractional-divider_test.c
--
2.41.0
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 <[email protected]>
Signed-off-by: Frank Oltmanns <[email protected]>
---
drivers/clk/clk-fractional-divider.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c
index 479297763e70..5067e067e906 100644
--- a/drivers/clk/clk-fractional-divider.c
+++ b/drivers/clk/clk-fractional-divider.c
@@ -123,6 +123,7 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
unsigned long *m, unsigned long *n)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
+ unsigned long max_m, max_n;
/*
* 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,
rate <<= scale - fd->nwidth;
}
- rational_best_approximation(rate, *parent_rate,
- GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
- m, n);
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ max_m = 1 << fd->mwidth;
+ max_n = 1 << fd->nwidth;
+ } else {
+ max_m = GENMASK(fd->mwidth - 1, 0);
+ max_n = GENMASK(fd->nwidth - 1, 0);
+ }
+
+ rational_best_approximation(rate, *parent_rate, max_m, max_n, m, n);
}
+EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation);
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
@@ -169,13 +177,18 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
- unsigned long m, n;
+ unsigned long m, n, max_m, max_n;
u32 mmask, nmask;
u32 val;
- rational_best_approximation(rate, parent_rate,
- GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
- &m, &n);
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
+ max_m = 1 << fd->mwidth;
+ max_n = 1 << fd->nwidth;
+ } else {
+ max_m = GENMASK(fd->mwidth - 1, 0);
+ max_n = GENMASK(fd->nwidth - 1, 0);
+ }
+ rational_best_approximation(rate, parent_rate, max_m, max_n, &m, &n);
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
m--;
--
2.41.0
Hi,
On 2023-06-17 at 15:10:39 +0200, Frank Oltmanns <[email protected]> wrote:
> The fractional divider approximation does not utilize the full available
> range for clocks that are flagged CLK_FRAC_DIVIDER_ZERO_BASED. This
> patchset aims to fix that.
>
> It also adds test cases for the edge cases of fractional divider clocks
> with and without the CLK_FRAC_DIVIDER_ZERO_BASED flag to highlight the
> changes.
>
> Finally, it also exports clk_fractional_divider_general_approximation so
> that the test cases (but also other users like rockchip clk driver) can
> be compiled as a module.
>
> Unfortunately, I have no boards to test this patch. So all we have are
> the unit tests. It seems the only user of this flag in mainline is
> drivers/clk/imx/clk-composite-7ulp.c, therefore I'm cc-ing
> get_maintainers.pl --git-blame -f drivers/clk/imx/clk-composite-7ulp.c
> in the hopes of a wider audience.
Are there remarks or questions on this patchset? Anything that needs to
be improved?
Thanks,
Frank
>
> Thank you for considering this contribution,
> Frank
>
> P.S.: V4 was short-lived, because it triggered a compiler warning on
> clang. I'm sorry for the noise. -- Frank
>
> V4: https://lore.kernel.org/all/[email protected]/
> V3: https://lore.kernel.org/all/[email protected]/
> V2: https://lore.kernel.org/lkml/[email protected]/
> V1: https://lore.kernel.org/lkml/[email protected]/
>
> Changes in V5 (since V4):
> - Fix compiler warnings on clang by removing superfluous variable max_m
> in the test cases for the maximum denominator (n) and max_n in the
> test cases for max numerator (m).
> Thank you, Intel, for your kernel test robot!
>
> Changes in V4 (since V3):
> - Export clk_fractional_divider_general_approximation so that users
> (e.g., the testcases) can be compiled as modules.
> - Change test cases so that they test
> clk_fractional_divider_general_approximation again (like in V2)
> instead of clk_fd_round_rate (like in V3), but keeping the structure
> of V3 with separate file and individual test cases for each edge
> case.
>
> Changes in V3 (since V2):
> - Completely reworked the test cases
> - Moved tests to separate file as per Stephen's request
> - Move each edge case into their individual test case as per
> Stephen's request
> - Test clk_fd_round_rate instead of
> clk_fractional_divider_general_approximation as testing the latter
> broke builds
>
> Changes in V2 (since V1):
> - Added test case as requested by Stephen Boyd
> - Fixed commit message as the Cc: was missing a closing bracket, so that the
> original mail unfortunately did not go out to A. s. Dong.
>
> Frank Oltmanns (2):
> clk: fractional-divider: Improve approximation when zero based and
> export
> clk: fractional-divider: tests: Add test suite for edge cases
>
> drivers/clk/.kunitconfig | 1 +
> drivers/clk/Kconfig | 7 +
> drivers/clk/Makefile | 1 +
> drivers/clk/clk-fractional-divider.c | 27 +++-
> drivers/clk/clk-fractional-divider_test.c | 157 ++++++++++++++++++++++
> 5 files changed, 186 insertions(+), 7 deletions(-)
> create mode 100644 drivers/clk/clk-fractional-divider_test.c