Hi,
We have a custom board with AM3354 SoC running our Yocto based Linux distro with upstream Linux kernel v5.10.166. We are using the Yocto layer meta-ti tagged: 07.03.00.005
We have run into suspend/resume issue on this SoC.
We are referring to the document "AM335x Low Power Design Guide Rev. A" (SPRAC74A – February 2017 – Revised March 2017) to enable power management on this SoC.
This is the state of kernel configs:
CONFIG_MAILBOX=y CONFIG_OMAP2PLUS_MBOX=m CONFIG_WKUP_M3_RPROC=m CONFIG_SOC_TI=y CONFIG_AMX3_PM=m CONFIG_WKUP_M3_IPC=m CONFIG_TI_EMIF_SRAM=m
This shows that the firmware was loaded into CM3 successfully:
root@lp-am3354:~# dmesg | grep -iE "remote|ipc|wkup|mailbox" [ 12.766082] remoteproc remoteproc0: wkup_m3 is available [ 12.785892] wkup_m3_ipc 44e11324.wkup_m3_ipc: IPC Request for A8->M3 Channel failed! -517 [ 13.105999] wkup_m3_ipc 44e11324.wkup_m3_ipc: IPC Request for A8->M3 Channel failed! -517 [ 13.231233] wkup_m3_ipc 44e11324.wkup_m3_ipc: IPC Request for A8->M3 Channel failed! -517 [ 13.478769] wkup_m3_ipc 44e11324.wkup_m3_ipc: IPC Request for A8->M3 Channel failed! -517 [ 13.522549] omap-mailbox 480c8000.mailbox: omap mailbox rev 0x400 [ 13.661037] remoteproc remoteproc0: powering up wkup_m3 [ 13.920713] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 244024 [ 13.929014] remoteproc remoteproc0: remote processor wkup_m3 is now up [ 13.929036] wkup_m3_ipc 44e11324.wkup_m3_ipc: CM3 Firmware Version = 0x192
We are using v1.9.2 of the CM3 PM firmware built from git.ti.com/processor-firmware/ti-amx3-cm3-pm-firmware.git branch: ti-v4.1.y, commit hash: fb484c5e54f2e31cf0a338d2927a06a2870bcc2c.
We have also tried the CM3 firmware binary downloaded from the above mentioned git repo (git.ti.com/.../ against the release tag: 08.02.00.004. Which essentially points to the same tag as branch: ti-v4.1.y, commit hash: fb484c5e54f2e31cf0a338d2927a06a2870bcc2c.
There is no VTT termination on the DRAM: MT41K256M16, and there is a 10K ohm pull-down resistor on the DDR_CKE. The DDR_CKE pin goes LOW when we put the SoC to suspend mode using either of the following commands:
$ echo mem > /sys/power/state $ echo standby > /sys/power/state
The SoC does not wake up when we type anything on the UART0 console.
root@lp-am3354:~# echo mem > /sys/power/state root@lp-am3354:~# [ 110.842841] PM: suspend entry (deep) [ 110.853425] Filesystems sync: 0.006 seconds [ 110.874009] Freezing user space processes ... (elapsed 0.001 seconds) done. [ 110.882481] OOM killer disabled. [ 110.885838] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [ 110.894957] printk: Suspending console(s) (use no_console_suspend to debug)
However, when we add the "no_console_suspend" in the kernel commandline args, we are able to wake up the SoC using UART0 only from standby mode:
root@lp-am3354:~# echo standby > /sys/power/state root@lp-am3354:~# [ 986.212016] PM: suspend entry (shallow) [ 986.222320] Filesystems sync: 0.006 seconds [ 986.255885] Freezing user space processes ... (elapsed 0.001 seconds) done. [ 986.264063] OOM killer disabled. [ 986.267286] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [ 986.428728] Disabling non-boot CPUs ... [ 986.432517] pm33xx pm33xx: PM: Successfully put all powerdomains to target state [ 986.432517] PM: Wakeup source MPU_WAKE ��[ 986.443311] spi-nor spi0.0: trying to lock already unlocked area [ 986.449524] cpsw 4a100000.ethernet: initializing cpsw version 1.12 (0) [ 986.541566] Micrel KSZ8081 or KSZ8091 4a101000.mdio:05: attached PHY driver [Micrel KSZ8081 or KSZ8091] (mii_bus:phy_addr=4a101000.mdio:05, irq=POLL) [ 986.561872] Micrel KSZ8081 or KSZ8091 4a101000.mdio:05: Micrel KSZ8081 or KSZ8091: resetting PHY on link down [ 986.768201] OOM killer enabled. [ 986.771343] Restarting tasks ... done. [ 986.885854] PM: suspend exit root@lp-am3354:~# [ 989.776988] cpsw 4a100000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off
... but not from mem/deepsleep mode:
root@lp-am3354:~# echo mem > /sys/power/state root@lp-am3354:~# [ 281.843135] PM: suspend entry (deep) [ 281.857175] Filesystems sync: 0.010 seconds [ 281.880809] Freezing user space processes ... (elapsed 0.001 seconds) done. [ 281.889450] OOM killer disabled. [ 281.892697] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [ 281.922471] Disabling non-boot CPUs ...
The "AM335x Low Power Design Guide Rev. A" (SPRAC74A – February 2017 – Revised March 2017) document states at page 23, section 3.3.4.2 "Serial Console Output During Suspend/Resume" that, "Note that if this (i.e. no_console_suspend) is used then the serial port cannot be used as a wakeup source for the processor.". This is totally opposite to our case.
Adding wakeup-source to the uart0 node in the dts also did not help:
&uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins>; status = "okay"; wakeup-source; };
We have also tried plugging in/out a Flash drive into USB1 to wake up the SoC, but it did not work. Is this a correct test?
The internal RTC is not in use and linux is not able to enable/disable its clock probably because of:
root@lp-am3354:~# dmesg | grep -iE "rtc" [ 1.478468] l4-rtc-clkctrl:0000:0: failed to enable [ 2.936790] rtc-ds1307 0-0068: registered as rtc0 [ 2.941742] rtc-ds1307 0-0068: setting system clock to 2000-01-01T01:23:14 UTC (946689794) [ 3.054168] vrtc: supplied by vcc5v [ 6.654989] l4-rtc-clkctrl:0000:0: failed to disable [ 16.656550] PM: no-rtc available, rtc-only mode disabled.
Therefore we have patched the pm33xx.c driver to not go for rtc-only mode suspend:
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c index dc21aa855..16455539b 100644 --- a/drivers/soc/ti/pm33xx.c +++ b/drivers/soc/ti/pm33xx.c @@ -306,12 +306,12 @@ static void am33xx_pm_end(void) u32 val = 0; struct nvmem_device *nvmem; - nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0"); - if (IS_ERR(nvmem)) - return; - m3_ipc->ops->finish_low_power(m3_ipc); if (rtc_only_idle) { + nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0"); + if (IS_ERR(nvmem)) + return; + if (retrigger_irq) { /* * 32 bits of Interrupt Set-Pending correspond to 32 @@ -443,7 +443,7 @@ static int am33xx_pm_rtc_setup(void) np = of_find_node_by_name(NULL, "rtc"); - if (of_device_is_available(np)) { + if (of_device_is_available(np) && 0) { /* RTC interconnect target module clock */ rtc_fck = of_clk_get_by_name(np->parent, "fck"); if (IS_ERR(rtc_fck))
We never got to wake up the SoC from deepsleep mode. However, only once, we saw this when we kept pressing the Enter key on the UART0 console:
root@lp-am3354:~# echo mem > /sys/power/state [ 40.918408] PM: suspend entry (deep) [ 40.935296] Filesystems sync: 0.013 seconds [ 40.954440] Freezing user space processes ... (elapsed 0.003 seconds) done. [ 40.965119] OOM killer disabled. [ 40.968240] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done. [ 41.030803] Disabling non-boot CPUs ... [ 41.034843] pm33xx pm33xx: PM: Kernel suspend failure [ 41.046149] spi-nor spi0.0: trying to lock already unlocked area [ 41.052138] cpsw 4a100000.ethernet: initializing cpsw version 1.12 (0) [ 41.140257] Micrel KSZ8081 or KSZ8091 4a101000.mdio:05: attached PHY driver [Micrel KSZ8081 or KSZ8091] (mii_bus:phy_addr=4a101000.mdio:05, irq=POLL) [ 41.160627] Micrel KSZ8081 or KSZ8091 4a101000.mdio:05: Micrel KSZ8081 or KSZ8091: resetting PHY on link down [ 41.624064] usb 2-1: reset high-speed USB device number 2 using musb-hdrc
We need your help to get the suspend/resume to work on this SoC.
Best regards,
Arsalan H. Awan