4.1.5. How to Suspend to RAM (Deep Sleep) on AM62x

AM62x has limited support for Low Power Mode (LPM) in current SDK release. Since not all peripherals drivers are updated to work across suspend/resume cycle,a cut-down version of DT file is provided with limited peripherals and Cores enabled to demonstrate Suspend to RAM (S2R) capability.

Supported Low power mode:

  1. Suspend to RAM (S2R): All power domains are off except for Wakeup Domain that has Wakeup Co-processor (DM R5) running. DDR is in Self Refresh.

4.1.5.1. Switching to LPM demo dts

LPM demo is only possible with cut-down dtb: k3-am625-sk-lpmdemo.dtb. U-Boot needs to be configured to switch to this dtb during kernel Image load and execute

Steps to switch to LPM DT:

  1. Stop boot at U-Boot prompt

  2. Run following cmd

    => run envboot; setenv name_fdt k3-am625-sk-lpmdemo.dtb; run init_mmc; run get_kern_mmc;run get_fdt_mmc;run get_overlay_mmc; booti ${loadaddr} ${rdaddr}:${filesize} ${fdtaddr}
    
    Alternately, update uEnv.txt to following
    
    #uenvcmd=run check_for_board; run findfdt
    uenvcmd=run check_for_board; setenv name_fdt k3-am625-sk-lpmdemo.dtb
    
  3. At Linux prompt, using RTC as wakeup source, test S2R using following cmd

    root@am62xx-evm:~# rtcwake -s 10 -m mem
    rtcwake: wakeup from "mem" using /dev/rtc0 at Fri May 20 09:41:11 2022
    [   42.148655] PM: suspend entry (deep)
    [   42.152391] Filesystems sync: 0.000 seconds
    [   42.166102] Freezing user space processes ... (elapsed 0.001 seconds)    done.
    [   42.175081] OOM killer disabled.
    [   42.178325] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
    [   42.186951] printk: Suspending console(s) (use no_console_suspend to debug)
    [   42.428329] Disabling non-boot CPUs ...
    [   42.826185] OOM killer enabled.
    [   42.829327] Restarting tasks ... done.
    [   42.855525] PM: suspend exit
    root@am62xx-evm:~#
    

This puts system to sleep for 10s and then wakes it up via RTC interrupt

4.1.5.2. Limitations

  • Only one A53 core is enabled. Multi-core support is not enabled.

  • Following IPs are enabled in k3-am625-sk-lpmdemo.dts and function across system suspend and resume: UART, I2C, RTC, MMC/SD, MMC/eMMC, INTR, GPIO, CPSW, DMA, INTA, OSPI, USB, MCAN, DM Timer, ECAP.

  • There is a known issue of performance drop after resuming from deep sleep. It can be worked around by temporarily disabling DFS and cycling through deep sleep:

    root@am62xx-evm:~# echo 1400000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
    root@am62xx-evm:~# rtcwake -s 1 -m mem
    
  • To reenable DFS during the same session, scaling_min_freq will need to be reset:

    root@am62xx-evm:~# echo 200000 > /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
    

Upcoming releases will add support for additional peripherals and cores.

4.1.5.3. Supported Peripherals

4.1.5.3.1. GPIO

The Deep Sleep support for the AM62x GPIOs is provided by two standalone drivers in Linux.

System suspend and resume of the GPIO IP block is fully supported in the gpio-davinci.c driver. The information about the requested GPIOs and their state is saved on suspend and restored on resume from deep sleep.

The GPIO interrupts require an additional setup of the IRQ routing in the Interrupt Router (INTR) with the help of TISCI_MSG_RM_IRQ_SET message over TISCI. This interrupt configuration is currently not stored by the System Firmware when entering Suspend-to-RAM. The irq-ti-sci-intr.c (INTR) driver provides support for restoring the IRQ routing setup after resuming from Deep Sleep from internally cached state.

Validating the system suspend and resume support for GPIO on AM62x requires verifying the above two components. Any requested GPIO must preserve state after resuming from Deep Sleep and the requested GPIO interrupt handlers must trigger on the specified GPIO state change. The current version of the LPM demo for AM625-SK has a couple of GPIO consumers we can use for validation and testing.

GPIO state preservation

GPIO1_49 is used by the leds-gpio driver as heartbeat indicator. When the system is suspended to RAM the LD1 LED on the board will be off. After resuming LD1 must continue to indicate the system heartbeat. We can also switch the trigger to default-on and verify if the brightness sysfs attribute of the LED device is set to max. value (255).

root@am62xx-evm:~# echo default-on > /sys/class/leds/am62-sk\:green\:heartbeat/trigger
root@am62xx-evm:~# rtcwake -s 1 -m mem
rtcwake: assuming RTC uses UTC ...
...
root@am62xx-evm:~# cat /sys/class/leds/am62-sk\:green\:heartbeat/brightness
255

Interrupt routing state preservation

On AM625-SK, GPIO1_23 is configured as interrupt for a GPIO IO expander which it’s also wired to the SW4 button. We can use the button to generate an interrupt as if it originates from the IO expander. All we need to know is the kernel registering the interrupt.

root@am62xx-evm:~# grep davinci_gpio /proc/interrupts
278:          0      GPIO  23 Edge    -davinci_gpio  0-0022
root@am62xx-evm:~# rtcwake -s 1 -m mem
rtcwake: assuming RTC uses UTC ...
...
root@am62xx-evm:~# grep davinci_gpio /proc/interrupts
278:          0      GPIO  23 Edge    -davinci_gpio  0-0022
# Press the SW4 button
root@am62xx-evm:~# grep davinci_gpio /proc/interrupts
278:          1      GPIO  23 Edge    -davinci_gpio  0-0022