The Common Clock Framework is expected to keep a clockâs rate stable
after setting a new rate with:
clk_set_rate(clk, NEW_RATE);
Clock consumers do not know about the clock hierarchy, sibling clocks,
or the type of clocks involved. However, several longstanding issues
affect how rate changes propagate through the clock tree when
CLK_SET_RATE_PARENT is involved, and the parent's clock rate is changed:
- A clock in some cases can unknowingly change a sibling clock's rate.
- No negotiation is done with the sibling clocks, so an inappropriate
or less than ideal parent rate can be selected.
A selection of some real world examples of where this shows up is at
[1]. DRM needs to run at precise clock rates, and this issue shows up
there, however will also show up in other subsystems that require
precise clock rates, such as sound.
This series introduces kunit tests to illustrate the current behavior in
the clk core. As discussed at Linux Plumbers Conference 2025 in Tokyo
[2], it was suggested to move the negotiation logic into the clk
providers themselves so that only the clks with this issue can have
their rate preserved, and add some common helpers to the clk core.
Changes since v6:
https://lore.kernel.org/r/[email protected]
- Move 24 MHz assertions at the end of
clk_rate_change_sibling_div_div_test_init() into the top of the
various divider tests to make it clear about the initial state of the
clk tree in each of the tests to make it more readable. (Maxime)
- Move divider tests from clk_test.c into new file clk-divider_test.c
(Maxime)
- Dropped clk_v2_rate_negotiation kernel parameter since it's no longer
needed since the new code is very targeted to a specific part of a
clk tree with this new approach. With the kernel parameter, we would
have two code paths to check, and the unlikely path would get very
little or no testing. This keeps it so that we have one path. (Maxime)
- Add Maxime's Reviewed-by on one patch. He added more Reviewed-bys on
v6, however I didn't include them since I refactored some of those
patches due to other changes requested.
- Drop test for clk rate of 0 in clk_hw_get_children_lcm(). Add
clk_hw_is_enabled() check instead.
- Export clk_dummy_rate_ops and clk_dummy_context() from clk_test.c to
avoid code duplication in the clk-divider tests.
- Simplify test names (s/sibling_div_div/divider/)
Changes since v5:
https://lore.kernel.org/r/[email protected]
- Dropped all of the helpers, and complexity to the clk core. To solve
this problem, we don't need to chain rate requests together.
- Add more unit tests
- Convert clk-divider.c so that there's a real user of this new API.
- This series no longer has the problem where large numbers of boards are
moved over at once to the new v2 negotiation logic.
Changes since v4:
https://lore.kernel.org/linux-clk/[email protected]/
- Reworked based on feedback at Linux Plumbers [2] as described in two
paragraphs above.
- Dropped gate and mux tests.
Changes since v3:
https://lore.kernel.org/r/[email protected]
- Update clk_core struct members (Maxime)
- Add v2 rate negotiation logic and additional kunit tests
- Drop clk_dummy_rate_mhz() in kunit tests; use HZ_PER_MHZ
[1]
https://lore.kernel.org/lkml/[email protected]/
https://lore.kernel.org/linux-kernel/[email protected]/
https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/linux-clk/20241121-ge-ian-debug-imx8-clk-tree-v1-0-0f1b72258...@bootlin.com/
[2] Fixing Clock Tree Propagation in the Common Clk Framework
https://www.youtube.com/watch?v=R8TytDzlcFs
https://lpc.events/event/19/contributions/2152/
Link: https://lore.kernel.org/linux-clk/[email protected]/
Link: https://lpc.events/event/19/contributions/2152/
Signed-off-by: Brian Masney <[email protected]>
---
Brian Masney (8):
clk: test: export clk_dummy_rate_ops and clk_dummy_context() for other
tests
clk: divider: introduce divider kunit tests
clk: introduce new helper clk_hw_get_children_lcm() to calculate LCM of
all child rates
clk: divider: test: introduce additional test case for parent rate change
clk: introduce new flag CLK_V2_RATE_NEGOTIATION for sensitive clocks
clk: divider: enable optional support for v2 rate negotiation
clk: divider: test: introduce additional test case showing v2 rate change
+ LCM parent
clk: divider: test: mark some tests as supporting only v1 negotiation
drivers/clk/.kunitconfig | 1 +
drivers/clk/Kconfig | 7 +
drivers/clk/Makefile | 1 +
drivers/clk/clk-divider.c | 28 +++-
drivers/clk/clk-divider_test.c | 364 +++++++++++++++++++++++++++++++++++++++++
drivers/clk/clk.c | 107 ++++++++++--
drivers/clk/clk_test.c | 9 +-
include/kunit/clk.h | 7 +
include/linux/clk-provider.h | 5 +
9 files changed, 508 insertions(+), 21 deletions(-)
---
base-commit: 785f0eb2f85decbe7c1ef9ae922931f0194ffc2e
change-id: 20260305-clk-scaling-b3b63cae7624
Best regards,
--
Brian Masney <[email protected]>