* [PATCH] clk: ti: Use CPU ticks to count timeout
@ 2026-07-08 8:38 Bastien Curutchet
2026-07-10 21:25 ` Tom Rini
0 siblings, 1 reply; 2+ messages in thread
From: Bastien Curutchet @ 2026-07-08 8:38 UTC (permalink / raw)
To: u-boot; +Cc: Thomas Petazzoni, Lukasz Majewski, Tom Rini, Bastien Curutchet
readl_relaxed_poll_timeout() relies on timers. On the beaglebone black,
the timer used by readl_relaxed_poll_timeout() depends on this clock
driver. So we have a sort of circular dependency [enable_clock ->
timer_init -> enable_clock -> timer_init]. It leads to a
division-per-zero during the second timer_init() and the beaglebone
fails to boot with following message:
| CPU : AM335X-GP rev 2.1
| Model: TI AM335x BeagleBone Black
| DRAM: 512 MiB
| ### ERROR ### Please RESET the board ###
Replace readl_relaxed_poll_timeout() with a simple loop that uses CPU
ticks to countdown the timeout. This loop and the value of LDELAY are
inspired from what's done in arch/arm/mach-omap2/am33xx/clock.c
Also, arch/arm/mach-omap2/am33xx/clock.c doesn't return an error on
timeout, it only logs it, so let's stick with it.
Fixes: de2e3f00f2fa ("clk: ti: Remove AM33xx dependency")
Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
---
drivers/clk/ti/clk-ctrl.c | 53 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/ti/clk-ctrl.c b/drivers/clk/ti/clk-ctrl.c
index 08f7410edce..e3564277982 100644
--- a/drivers/clk/ti/clk-ctrl.c
+++ b/drivers/clk/ti/clk-ctrl.c
@@ -12,7 +12,7 @@
#include <asm/io.h>
#include <linux/iopoll.h>
-#define TRANSITION_TIMEOUT_US 10000
+#define LDELAY 1000000
struct clk_ti_ctrl_offs {
fdt_addr_t start;
@@ -39,30 +39,59 @@ static int clk_ti_ctrl_check_offs(struct clk *clk, fdt_addr_t offs)
#define IDLEST_DISABLED (MODULE_CLKCTRL_IDLEST_DISABLED << MODULE_CLKCTRL_IDLEST_SHIFT)
#define IDLEST_TRANSITION (MODULE_CLKCTRL_IDLEST_TRANSITIONING << MODULE_CLKCTRL_IDLEST_SHIFT)
-static int clk_ti_ctrl_disable_clock_module(u32 addr)
+static inline void wait_for_clk_disable(u32 addr)
{
- int val;
+ u32 bound = LDELAY;
+ int val = 0;
+
+ while ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_DISABLED) {
+ val = readl(addr);
+
+ if (--bound == 0) {
+ printf("Clock disable failed for 0x%x idlest 0x%x\n",
+ addr, val);
+ return;
+ }
+ }
+}
+static int clk_ti_ctrl_disable_clock_module(u32 addr)
+{
clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
MODULE_CLKCTRL_MODULEMODE_SHIFT);
- return readl_relaxed_poll_timeout(addr, val,
- (val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_DISABLED,
- TRANSITION_TIMEOUT_US);
+ wait_for_clk_disable(addr);
+
+ return 0;
}
-static int clk_ti_ctrl_enable_clock_module(u32 addr)
+static inline void wait_for_clk_enable(u32 addr)
{
- int val;
+ int val = IDLEST_DISABLED;
+ u32 bound = LDELAY;
+ while (((val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_DISABLED) ||
+ ((val & MODULE_CLKCTRL_IDLEST_MASK) == IDLEST_TRANSITION)) {
+ val = readl(addr);
+
+ if (--bound == 0) {
+ printf("Clock enable failed for 0x%x idlest 0x%x\n",
+ addr, val);
+ return;
+ }
+ }
+}
+
+static int clk_ti_ctrl_enable_clock_module(u32 addr)
+{
clrsetbits_le32(addr, MODULE_CLKCTRL_MODULEMODE_MASK,
MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
MODULE_CLKCTRL_MODULEMODE_SHIFT);
- return readl_relaxed_poll_timeout(addr, val,
- ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_DISABLED) &&
- ((val & MODULE_CLKCTRL_IDLEST_MASK) != IDLEST_TRANSITION),
- TRANSITION_TIMEOUT_US);
+
+ wait_for_clk_enable(addr);
+
+ return 0;
}
static int clk_ti_ctrl_disable(struct clk *clk)
---
base-commit: ee5d46b45ec0c63f8f9dd1e816e0dac3452ccc3d
change-id: 20260708-fix-beagle-66a3c8bac755
Best regards,
--
Bastien Curutchet <bastien.curutchet@bootlin.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] clk: ti: Use CPU ticks to count timeout
2026-07-08 8:38 [PATCH] clk: ti: Use CPU ticks to count timeout Bastien Curutchet
@ 2026-07-10 21:25 ` Tom Rini
0 siblings, 0 replies; 2+ messages in thread
From: Tom Rini @ 2026-07-10 21:25 UTC (permalink / raw)
To: Bastien Curutchet; +Cc: u-boot, Thomas Petazzoni, Lukasz Majewski
[-- Attachment #1: Type: text/plain, Size: 1178 bytes --]
On Wed, Jul 08, 2026 at 10:38:10AM +0200, Bastien Curutchet wrote:
> readl_relaxed_poll_timeout() relies on timers. On the beaglebone black,
> the timer used by readl_relaxed_poll_timeout() depends on this clock
> driver. So we have a sort of circular dependency [enable_clock ->
> timer_init -> enable_clock -> timer_init]. It leads to a
> division-per-zero during the second timer_init() and the beaglebone
> fails to boot with following message:
> | CPU : AM335X-GP rev 2.1
> | Model: TI AM335x BeagleBone Black
> | DRAM: 512 MiB
> | ### ERROR ### Please RESET the board ###
>
> Replace readl_relaxed_poll_timeout() with a simple loop that uses CPU
> ticks to countdown the timeout. This loop and the value of LDELAY are
> inspired from what's done in arch/arm/mach-omap2/am33xx/clock.c
> Also, arch/arm/mach-omap2/am33xx/clock.c doesn't return an error on
> timeout, it only logs it, so let's stick with it.
>
> Fixes: de2e3f00f2fa ("clk: ti: Remove AM33xx dependency")
> Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Reported-by: Tom Rini <trini@konsulko.com>
Tested-by: Tom Rini <trini@konsulko.com>
Thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-10 21:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08 8:38 [PATCH] clk: ti: Use CPU ticks to count timeout Bastien Curutchet
2026-07-10 21:25 ` Tom Rini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.