Low Power Modes

Our phyCORE-AM62x supports two different Low Power Modes (Deep Sleep aka Suspend-2-RAM and MCU only), from which the AM625 SOC can be awakened by various sources such as GP Timers, RTC Timer, UART, I2C, GPIO, and I/O Daisy Chain. In this chapter, we will provide a high-level overview of the low power modes, covering how to enter these modes from Linux to put the device to sleep and how to wake it up using one of the described wakeup sources.

Enable Low Power Modes Overlay

To support entry into and wake-up from low power modes, we have provided a sample device tree overlay. To apply this configuration, load the overlay with the following commands:

Loading Low Power Mode device tree overlays
uboot:~# setenv overlays k3-am62-phyboard-lyra-lpm.dtbo
uboot:~# boot

To make sure the overlay was properly loaded check the output of

phyboard-lyra-am62xx-3:~# cat /proc/interrupts  | grep WAKEUPGPIO
455:          0          0          0          0      GPIO  23 Edge    -davinci_gpio  WAKEUPGPIO
484:          0          0          0          0      pinctrl 468 Edge      WAKEUPGPIO:wakeup

Deep Sleep (Suspend-2-RAM)

Deep Sleep, also known as Suspend-2-RAM, is a low-power state that significantly reduces power consumption in embedded systems. In this mode, the system’s RAM is powered to retain the current state while the processor is turned off. This functionality is particularly advantageous for battery-powered devices, as it extends operational life by minimizing energy usage during periods of inactivity.

Entering Suspend-2-RAM
phyboard-lyra-am62xx-3:~# echo mem > /sys/power/state
[ 1213.003948] PM: suspend entry (deep)
[ 1213.008271] Filesystems sync: 0.000 seconds
[ 1213.042330] remoteproc remoteproc0: stopped remote processor 5000000.m4fss
[ 1213.049785] Freezing user space processes
[ 1213.055479] Freezing user space processes completed (elapsed 0.001 seconds)
[ 1213.062495] OOM killer disabled.
[ 1213.065713] Freezing remaining freezable tasks
[ 1213.071522] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[ 1213.078999] printk: Suspending console(s) (use no_console_suspend to debug)

Waking up using AM62x’s internal RTC

You can use the wakealarm feature of the RTC (Real-Time Clock) to set a specific time for generating a system wakeup event. The internal RTC is known as rtc1. In this example, we will configure the rtc1 device to generate a wake alarm event 15 seconds in the future.

Configuring a wake alarm event
phyboard-lyra-am62xx-3:~# echo +15 > /sys/class/rtc/rtc1/wakealarm && echo mem > /sys/power/state
[   31.863503] PM: suspend entry (deep)
[   31.897359] Filesystems sync: 0.030 seconds
[   31.903427] Freezing user space processes
[   31.909135] Freezing user space processes completed (elapsed 0.001 seconds)
[   31.916128] OOM killer disabled.
[   31.919359] Freezing remaining freezable tasks
[   31.924694] Freezing remaining freezable tasks completed (elapsed 0.000 seconds)
[   31.932090] printk: Suspending console(s) (use no_console_suspend to debug)
[   31.958252] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 178: state: 1: ret 0
[   31.966109] omap8250 2800000.serial: PM domain pd:146 will not be powered off
[   31.966688] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 117: state: 1: ret 0
[   37.146620] k3-m4-rproc 5000000.m4fss: k3_m4_suspend: timedout waiting for rproc completion event
[   37.150129] Disabling non-boot CPUs ...
[   37.151605] psci: CPU1 killed (polled 1 ms)
[   37.154605] psci: CPU2 killed (polled 1 ms)
[   37.158039] psci: CPU3 killed (polled 1 ms)
[   37.159280] Enabling non-boot CPUs ...
[   37.159682] Detected VIPT I-cache on CPU1
[   37.159739] GICv3: CPU1: found redistributor 1 region 0:0x00000000018a0000
[   37.159801] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[   37.160968] CPU1 is up
[   37.161228] Detected VIPT I-cache on CPU2
[   37.161256] GICv3: CPU2: found redistributor 2 region 0:0x00000000018c0000
[   37.161293] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[   37.162137] CPU2 is up
[   37.162405] Detected VIPT I-cache on CPU3
[   37.162437] GICv3: CPU3: found redistributor 3 region 0:0x00000000018e0000
[   37.162476] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[   37.163407] CPU3 is up
[   37.163907] ti-sci 44043000.system-controller: ti_sci_resume: wakeup source: 0x50
[   37.179185] am65-cpsw-nuss 8000000.ethernet: set new flow-id-base 19
[   37.187760] am65-cpsw-nuss 8000000.ethernet eth0: PHY [8000f00.mdio:01] driver [TI DP83867] (irq=POLL)
[   37.187783] am65-cpsw-nuss 8000000.ethernet eth0: configuring for phy/rgmii-rxid link mode
[   37.194565] am65-cpsw-nuss 8000000.ethernet eth1: PHY [8000f00.mdio:03] driver [TI DP83867] (irq=POLL)
[   37.194576] am65-cpsw-nuss 8000000.ethernet eth1: configuring for phy/rgmii-rxid link mode
[   37.369890] OOM killer enabled.
[   37.373033] Restarting tasks ... done.
[   37.378553] random: crng reseeded on system resumption
[   37.383769] PM: suspend exit

You can see that the TISCI firmware reported 0x50 as the wakeup source which is WKUP_RTC0. This mapping is defined by TISCI, see the following table for the complete mapping of the wakeup sources.

Wake Up Sources

Wake Up Source

Source ID

WKUP_I2C0

0x00

WKUP_UART0

0x10

MCU_GPIO0

0x20

WKUP_ICEMELTER0

0x30

WKUP_TIMER0

0x40

WKUP_TIMER1

0x41

WKUP_RTC0

0x50

RESET

0x60

USB0

0x70

USB1

0x71

MAIN_IO

0x80

MCU_IO

0x81

CAN_IO

0x82

MCU_IPC

0x90

INVALID

0xFF

Source: https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/pm/lpm.html

Inspecting interrupt counts
phyboard-lyra-am62xx-3:~# cat /proc/interrupts | grep rtc
495:          1          0          0          0     GICv3 132 Level     2b1f0000.rtc

The above example shows you that an interrupt was generated.

Note

The rtc0 device is an external I2C RTC device that does not have interrupt pins connected. Therefore, it cannot be used as a wakeup source.

Waking up using GPIO (I/O daisy chain)

When the AM62x enters low power mode, the main domain is effectively shut down. This includes controllers such as the UART, GPIO, and I2C. The question then arises: How can the AM62x be awakened by peripherals connected to GPIO, UART or I2C.

This is where I/O daisy chaining plays a crucial role. At the hardware level, all pads in an SoC must be pinmuxed to dedicated controllers like UART or GPIO.

Consider a scenario where a signal on the main GPIO is intended to wake the system from deep sleep. Simply configuring the main GPIO controller as a wakeup source is inadequate. The reason is that the GPIO controller is powered off during deep sleep and thus cannot register any signal events. However, at the pad level, connectivity is maintained, and these pads can be specifically configured to serve as wakeup sources. For detailed information and sequence please refer to I/O Power Management and Daisy Chaining section in the TRM.

We provide an example to utilize a GPIO on MAIN_GPIO1 as a wakeup source in form of an device tree overlay called k3-am62-phyboard-lyra-lpm.dtso. See the usage of interrupts-extended and interrupt-names properties below.

k3-am62-phyboard-lyra-lpm.dtso
&main_pmx0 {
        gpio_keys_pins_default: gpio-keys-default-pins {
                pinctrl-single,pins = <
                        AM62X_IOPAD(0x1d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
                >;
        };
};

&{/} {
        keys {
                compatible = "gpio-keys";
                autorepeat;
                pinctrl-names = "default";
                pinctrl-0 = <&gpio_keys_pins_default>;

                key-home {
                        label = "WAKEUPGPIO";
                        linux,code = <KEY_WAKEUP>;
                        interrupts-extended = <&main_gpio1 23 IRQ_TYPE_EDGE_RISING>, <&main_pmx0 0x1d4>;
                        interrupt-names = "irq", "wakeup";
                };
        };
};

Using this device tree overlay allows us to wakeup from a suspend state using the Button label as BTN1 on the phyBOARD-Lyra carrier board.

Entering Suspend-2-RAM
phyboard-lyra-am62xx-3:~# echo mem > /sys/power/state
[   31.929955] PM: suspend entry (deep)
[   31.949177] Filesystems sync: 0.015 seconds
[   31.955419] Freezing user space processes
[   31.961056] Freezing user space processes completed (elapsed 0.001 seconds)
[   31.968050] OOM killer disabled.
[   31.971279] Freezing remaining freezable tasks
[   31.977099] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[   31.984512] printk: Suspending console(s) (use no_console_suspend to debug)
[   32.014569] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 178: state: 1: ret 0
[   32.022495] omap8250 2800000.serial: PM domain pd:146 will not be powered off
[   32.023045] ti-sci 44043000.system-controller: ti_sci_cmd_set_device_constraint: device: 117: state: 1: ret 0

#
# After press on BTN1
#

[   37.206335] k3-m4-rproc 5000000.m4fss: k3_m4_suspend: timedout waiting for rproc completion event
[   37.209826] Disabling non-boot CPUs ...
[   37.212160] psci: CPU1 killed (polled 1 ms)
[   37.215321] psci: CPU2 killed (polled 1 ms)
[   37.218354] psci: CPU3 killed (polled 1 ms)
[   37.219445] Enabling non-boot CPUs ...
[   37.219847] Detected VIPT I-cache on CPU1
[   37.219903] GICv3: CPU1: found redistributor 1 region 0:0x00000000018a0000
[   37.219965] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[   37.221143] CPU1 is up
[   37.221408] Detected VIPT I-cache on CPU2
[   37.221435] GICv3: CPU2: found redistributor 2 region 0:0x00000000018c0000
[   37.221472] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[   37.222313] CPU2 is up
[   37.222581] Detected VIPT I-cache on CPU3
[   37.222614] GICv3: CPU3: found redistributor 3 region 0:0x00000000018e0000
[   37.222653] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[   37.223559] CPU3 is up
[   37.224044] ti-sci 44043000.system-controller: ti_sci_resume: wakeup source: 0x80
[   37.239158] am65-cpsw-nuss 8000000.ethernet: set new flow-id-base 19
[   37.247745] am65-cpsw-nuss 8000000.ethernet eth0: PHY [8000f00.mdio:01] driver [TI DP83867] (irq=POLL)
[   37.247768] am65-cpsw-nuss 8000000.ethernet eth0: configuring for phy/rgmii-rxid link mode
[   37.254545] am65-cpsw-nuss 8000000.ethernet eth1: PHY [8000f00.mdio:03] driver [TI DP83867] (irq=POLL)
[   37.254554] am65-cpsw-nuss 8000000.ethernet eth1: configuring for phy/rgmii-rxid link mode
[   37.429012] OOM killer enabled.
[   37.432163] Restarting tasks ... done.
[   37.437363] random: crng reseeded on system resumption
[   37.442611] PM: suspend exit

See that TISCI firmware reported 0x80 as the wakeup source which is MAIN_IO.

MCU only

Similar to Deep Sleep, but with the significant difference that the MCU core remains active, allowing it to continue running applications. To enter MCU Only mode, set 100 usec resume latency for CPU0:

Entering MCU only
phyboard-lyra-am62xx-3:~# echo 100 > /sys/devices/system/cpu/cpu0/power/pm_qos_resume_latency_us
phyboard-lyra-am62xx-3:~# echo mem > /sys/power/state

Note

The MCU/M4 demo firmware deployed to our current BSP releas does not work in combination with the MCU only mode. It will be available in future versions.