I have an issue where I can only suspend the iMX8MP up to 128 seconds before it reboots due to the watchdog timer.
Using the mem sleep state.
I see in the watchdog control register, bit 0 is for suspending dog on STOP/DOZE and bit 8 is for suspending on WAIT.
Looking at the NXP iMX Linux Reference manual, it seems that the IMX8M family doesn’t support STOP or WAIT, only a software based power domain suspend.
The imx2_wdt.c driver when suspending attempts to turn the clock off, but this doesn’t seem to have any effect - WDT still resets the device after 128 seconds.
We are using upstream NXP Linux 6.6 + Toradex patches and mainline u-boot + Toradex patches.
Is this supposed to work, or is it not possible to use suspend and wdt at the same time?
I’m wondering if it is a result of using mainline u-boot an nxp linux together, is that a stupid thing to do?
I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.
Did you like my answer?
Hello! Thank you for your detailed description of the issue.
You are correct that on the i.MX 8M Plus, the Linux kernel uses the WDOG1 watchdog by default, and the watchdog timer continues running during suspend-to-RAM (deep sleep) unless special handling is implemented. This behavior can indeed result in the system being reset by the watchdog if the device remains in suspend for longer than the watchdog timeout (which is often 128 seconds, as you observed)(1).
Suspend and Watchdog Behavior
The i.MX 8M Plus does not support traditional STOP or WAIT CPU power states. Instead, suspend-to-RAM is handled via a software-managed power domain(3).
The imx2_wdt driver attempts to disable the watchdog during suspend by gating its clock, but the actual hardware does not always support this as intended—meaning the watchdog can continue counting down during suspend and will eventually reset the board.
Thus, unless the watchdog is explicitly managed in a board- or driver-specific way, you will encounter resets after the timeout during suspend-to-RAM.
Using Mainline U-Boot with NXP Linux
Using mainline U-Boot with an NXP-provided (or Toradex-patched) Linux kernel is possible and often works, but it is generally recommended to use the combinations validated by Toradex BSP releases for best stability and compatibility(4).
In this case, though, the suspend/watchdog interaction is not likely a direct result of using mainline U-Boot, but rather is due to the way the SoC handles suspend and the watchdog in hardware. The reset you are seeing is expected with the standard upstream software stack.
Possible Solutions
Increase Watchdog Timeout: If you control your own system, you can increase the watchdog timeout before suspend so that typical suspend durations do not trigger a reset.
Disable Watchdog Prior to Suspend: Some implementations explicitly stop the watchdog prior to entering suspend (for example, via a systemd or custom suspend script) and re-enable it on resume, but this introduces a short window where no watchdog protection is present.
Custom Kernel Patches: In theory, the imx2_wdt driver could be modified to better support suspend on this hardware, but support is limited by hardware capabilities. As such, there is usually not a way to have the watchdog safely stopped during suspend-to-RAM on this SoC.
Use Suspend-to-Idle (s2idle): If deep power savings are less critical, you can use the lighter s2idle suspend mode, where the watchdog should continue to be properly serviced.
Summary
To directly answer your question: This behavior is expected on the i.MX 8M Plus with standard Linux implementations, and it is not the result of mixing mainline U-Boot and NXP Linux per se. The hardware design does not stop the watchdog during suspend-to-RAM, and it is not currently possible to keep the watchdog running without risking resets after the timeout. Most systems either increase the watchdog timeout or disable the watchdog during suspend.
Hi @phil , the suspend feature of Verdin iMX8MP is not fully supported on mainline kernel yet. If this is essential to your application, we suggest downstream image. And it is never a stupid thing to choose mainline release. Our R&D team at Toradex is working actively on mainline, and it is also important to our products.
Sorry, there was a typo. It is downstream Linux reference multimedia image v7.3.0 where suspend and wake-up works.
This image includes upstream U-Boot v2024.07 and the NXP downstream kernel v6.6. The system wakes up from suspend-to-RAM state after 150 seconds via the RTC.
I also grabbed your kernel config from the BSP 7.1.0 release shown in the release matrix. I think (hope) our kernel versions are similar enough both being based off the NXP 6.6 release.
Still not working.
I don’t have rtcwake available so I can’t do the exact same test, however I just checked the source for it and it is very simply, sets an alarm then writes to the same file I am.
One key difference between your example images and the one I have, is I am putting my image together with buildroot.
Right now the u-boots match. The kernel is very similar.
I’m running out of ideas of what to try. Have you got any suggestions?
I don’t have rtcwake available so I can’t do the exact same test, however I just checked the source for it and it is very simply, sets an alarm then writes to the same file I am.
Yes, they are basically the same.
Our latest downstream kernel for Verdin iMX8MP is based on lf-6.6.52-2.2.0 and R&D team customs the kernel to make it work on the module. There could be lots of changes against NXP Linux lf-6.6.y. But we don’t have patch set for NXP Linux lf-6.6.y that works with buildroot. It may be the reason suspend doesn’t work.
I’ve just based our linux off toradex_6.6-2.2.x-imx branch.
So now linux and uboot are the same version. The uboot config and dts is identical. Linux config/dts is very similar (we have additional drivers for peripherals enabled).
Still no luck. I might need to dig out the Toradex dev kit and test it myself and see if i notice anything different.
I’m pretty much out of ideas now so I think I will have to disable the WDT entirely.
Hey @phil , any luck with this?
I am facing exactly the same issue while using upstream U-Boot v2024.07 and toradex_6.6-2.2.x-imx kernel. @benjamin.tx can you please explain how exactly this issued got solved in downstream Linux reference multimedia image v7.3.0?
Like Phil, I am also using Buildroot to build an image for my Toradex imx8mp SOM + Dahlia carrier board.
As you can see, in our reference images, it’s set as deep by default. With this, the timer is properly stopped when the system is suspended. However, when I set the mode to s2idle, by doing the following:
The watchdog keeps running after suspend, and the system gets reset. There’s a flag on the device tree (fsl,suspend-in-wait) that should set the bit WDW of the WCR register. This bit controls whether the timer is suspended during low power WAIT mode, and should prevent the system from rebooting even in the s2idle.
This flag will only have an effect if the watchdog timer is not running when the Linux kernel watchdog driver is started. Our default U-Boot already starts the watchdog timer, preventing this flag from enabling the bit.
As I see it, you have two options to make this work:
Set the default suspend method of the mem type to deep
Disable the automatic starting of the watchdog timer in U-Boot, then set the fsl,suspend-in-wait flag in your device tree.
Hi @rafael.tx , thank you very much for your prompt response.
So, in my system the memory suspend mode is also set to sleep*,* but however, as stated before, the system is still rebooting after sleeping for more than ~2minutes.
The other alternative you propose seems a bit risky because that would imply no watchdog monitoring during the bootloader stage.
I’ve been doing some research and it seems that the suspend driver in the kernel allows registering some hooks to be run before the system is suspended and right after it resumes, so eventually the watchdog timeout could be set to a very high value just before the suspension and then get reset to its initial value when the system resumes.
I don’t know if the above is really possible yet. Do you reckon that might be something you guys are doing for instance?