We are trying to put our system to sleep in linux by using:
echo mem > /sys/power/state
Sometimes this puts both the A7s and the M4 to sleep, but there are a few times where the M4 remains awake. We saw this comment in the Linux reference manual
If ARM Cortex®-M4 processor is alive together with ARM Cortex-A processor
before the kernel enters standby/mem mode, and if ARM Cortex-M4 processor is not in its low power idle mode, ARM Cortex-A processor triggers the SOC to enter WAIT mode instead of STOP mode to make sure that ARM Cortex-M4 processor can continue running.
We are using a watchdog on our system, so when we get into the case where the M4 does not sleep, it appears that the A7 is in WAIT our watchdog does not get fed and eventually our board reboots.
In Linux, how do we ensure the M4 goes to sleep so that the A7 will enter STOP mode and not WAIT mode?
After further testing we found that Resetting the UART just before echoing "mem" to the power state allows both cores to get into SLEEP mode consistently:
UART5_UCR2=0x30a70084
UART5_UTS=0x30a700b4
UART5_UTS_SOFTRST_MASK=0x01
UART5_UBIR=0x30a700a4
UART5_UBMR=0x30a700a8
reset_uart5()
{
devmem2 ${UART5_UCR2} w 0x00004026 # RST Low (Engage Reset)
while [ $(( $(devmem2 ${UART5_UTS} b | tail -n 1 | cut -d ":" -f 2 | tr -d [:space:]) & ${UART5_UTS_SOFTRST_MASK} )) -ne 0 ]; do
usleep 1000; # wait for reset UART5 to finish
done
devmem2 ${UART5_UCR2} w 0x00004027 # RST High (Release)
devmem2 ${UART5_UBIR} w 0x14f # set baud
devmem2 ${UART5_UBMR} w 0x270 # set baud
}
Whoever, we would prefer not reseting the UART to ensure more uptime on that interface since we have critical comms coming over it.
Originally we thought the M4 was keeping the A7 from going into SLEEP. Now we hypothesis that the UART SDMA is the cause. When we remove DMA (dma-names = "","" vs "rs","tx") from our device tree we do not see the issue.
Is there a way to reset, flush, clear, etc. the SDMA for just the UART5 and would this cause us to lose data?
Hi Victor,
We do have a HW timer enabled and firing when the system tries to enter sleep mode. Is there a hook to disable on sleep and another hook to enable on wake-up?
Does the m4 code need to do anything to explicitly handle sleeping or idling? All the Tasks have code paths to idle waiting on a timer, semaphore, or rpmsg (MU).
Thanks,
Erik Cokeley
Possibly M4 core goes to sleep mode but then wakes up with some event.
Have a great day,
Victor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------