Linux Low Power Mode on i.MX 6ULL Print


This application note explains how to use the Linux low power mode (the so-called "suspend to RAM") on the Emcraft Systems i.MX 6ULL System-On-Module (SOM). When suspended, the SOM consumes approximately 5.4 mA @3.3V, at the same time providing instantaneous wake-up on configured I/O events, such as GPIO triggers.

Support for the low power mode is enabled in the standard rootfs project available from the Emcraft software distribution and installed on each module shipped by Emcraft. With Linux booted up to the shell, and with no commands entered from the interactive shell or a shell script, the system is idling awaiting user input or some other I/O events. The power consumption of the SOM is around 82 mA on the average at such times. If you create some load for the system, the power consumption will go up. For instance, using the following shell commands to create an endless command loop:

~ # while echo hey > /dev/null
> do
> echo Linux is running
> done
Linux is running
Linux is running
<...>
^C
~ #

you should measure the SOM power consumption of around 86 mA.

Now, let's put the system into the low power mode. This is done by running the following command:

~ # echo mem > /sys/power/state
[ 28.549812] PM: Syncing filesystems ... done.
[ 28.554657] PM: Preparing system for sleep (mem)
[ 28.561347] Freezing user space processes ... (elapsed 0.001 seconds) done.
[ 28.569777] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[ 28.578559] PM: Suspending system (mem)
[ 28.582452] Suspending console(s) (use no_console_suspend to debug)

At this time, the power consumption goes down dramatically and should measure at less than 5.4 mA. Press the BTN1 or BTN2 User Button on the IMX6ULL-SOM-BSB board to wake the system up:

[ 28.712557] PM: suspend of devices complete after 123.288 msecs
[ 28.712570] PM: suspend devices took 0.130 seconds
[ 28.713542] PM: late suspend of devices complete after 0.952 msecs
[ 28.714438] PM: noirq suspend of devices complete after 0.872 msecs
[ 28.714445] Turn off M/F mix!
[ 28.715128] PM: noirq resume of devices complete after 0.596 msecs
[ 28.715912] imx-sdma 20ec000.sdma: loaded firmware 3.3
[ 28.716424] PM: early resume of devices complete after 1.074 msecs
[ 28.716903] gpmi-nand 1806000.gpmi-nand: use legacy bch geometry
[ 28.716943] gpmi-nand 1806000.gpmi-nand: mode:4 ,failed in set feature.
[ 28.805826] Suspended for 1.883 seconds
[ 28.805907] PM: resume of devices complete after 89.466 msecs
[ 28.806609] PM: resume devices took 0.090 seconds
[ 28.877751] PM: Finishing wakeup.
[ 28.881099] Restarting tasks ... done.
~ #

Note also that the system automatically restores the TCP/IP stack on wake-up from the suspended state. The following test illustrates this:

~ # ping 192.168.0.3 &
[1] 216 ping 192.168.0.3
~ # PING 192.168.0.3 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: seq=0 ttl=128 time=6.051 ms
64 bytes from 192.168.0.3: seq=1 ttl=128 time=1.639 ms
64 bytes from 192.168.0.3: seq=2 ttl=128 time=1.618 ms
echo mem > /sys/power/state
[ 36.482246] PM: Syncing filesystems ... done.
[ 36.486927] PM: Preparing system for sleep (mem)
[ 36.493737] Freezing user space processes ... (elapsed 0.001 seconds) done.
[ 36.502178] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[ 36.510890] PM: Suspending system (mem)
[ 36.514784] Suspending console(s) (use no_console_suspend to debug)
<Press BTN1 or BTN2>
[ 36.642584] PM: suspend of devices complete after 120.932 msecs
[ 36.642595] PM: suspend devices took 0.130 seconds
[ 36.643571] PM: late suspend of devices complete after 0.956 msecs
[ 36.644504] PM: noirq suspend of devices complete after 0.910 msecs
[ 36.644510] Turn off M/F mix!
[ 36.645379] PM: noirq resume of devices complete after 0.782 msecs
[ 36.646027] imx-sdma 20ec000.sdma: loaded firmware 3.3
[ 36.646529] PM: early resume of devices complete after 0.920 msecs
[ 36.647002] gpmi-nand 1806000.gpmi-nand: use legacy bch geometry
[ 36.647044] gpmi-nand 1806000.gpmi-nand: mode:4 ,failed in set feature.
[ 36.735826] Suspended for 6.954 seconds
[ 36.735907] PM: resume of devices complete after 89.359 msecs
[ 36.736610] PM: resume devices took 0.090 seconds
[ 36.807729] PM: Finishing wakeup.
[ 36.811075] Restarting tasks ... done.
~ # [ 38.722371] fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
64 bytes from 192.168.0.3: seq=5 ttl=128 time=1.661 ms
64 bytes from 192.168.0.3: seq=6 ttl=128 time=1.650 ms
64 bytes from 192.168.0.3: seq=7 ttl=128 time=1.590 ms

Similarly, if you were running any operations with the on-module Flash prior to suspending the system, these operations will automatically resume when the system wakes up. The following test illustrates this:

~ # flash_eraseall -j /dev/mtd1
Erasing 128 Kibyte @ a00000 - 100% complete.Cleanmarker written at 9e0000.
~ # mount -t jffs2 /dev/mtdblock1 /mnt
~ # mkdir /m
~ # mount -o nolock 192.168.0.4:/nfs /m
~ # ls /mnt
~ # ls -l /m/rootfs.uImage
-rw-rw-r-- 1 root root 5936360 Oct 12 2018 /m/rootfs.uImage
~ # time cp /m/rootfs.uImage /mnt &
[1] 225 time cp /m/rootfs.uImage /mnt
~ # echo mem > /sys/power/state
[ 55.609633] PM: Syncing filesystems ... done.
[ 55.633617] PM: Preparing system for sleep (mem)
[ 55.645384] Freezing user space processes ... (elapsed 0.016 seconds) done.
[ 55.669075] Freezing remaining freezable tasks ... (elapsed 0.003 seconds) done.
[ 55.679942] PM: Suspending system (mem)
[ 55.683833] Suspending console(s) (use no_console_suspend to debug)
<Press BTN1 or BTN2>
[ 55.812734] PM: suspend of devices complete after 122.080 msecs
[ 55.812746] PM: suspend devices took 0.130 seconds
[ 55.813720] PM: late suspend of devices complete after 0.956 msecs
[ 55.814662] PM: noirq suspend of devices complete after 0.916 msecs
[ 55.814668] Turn off M/F mix!
[ 55.815335] PM: noirq resume of devices complete after 0.580 msecs
[ 55.816111] imx-sdma 20ec000.sdma: loaded firmware 3.3
[ 55.816620] PM: early resume of devices complete after 1.064 msecs
[ 55.817086] gpmi-nand 1806000.gpmi-nand: use legacy bch geometry
[ 55.817129] gpmi-nand 1806000.gpmi-nand: mode:4 ,failed in set feature.
[ 55.905843] Suspended for 2.751 seconds
[ 55.905925] PM: resume of devices complete after 89.288 msecs
[ 55.906627] PM: resume devices took 0.090 seconds
[ 55.977645] PM: Finishing wakeup.
[ 55.980992] Restarting tasks ... done.
~ # [ 57.922429] fec 2188000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
real 0m 10.60s
user 0m 0.01s
sys 0m 4.82s
ls -l /mnt/rootfs.uImage
[1] Done time cp /m/rootfs.uImage /mnt
-rw-r--r-- 1 root root 5936360 Jan 1 00:33 /mnt/rootfs.uImage
~ #

The default triggers used for system wake-up are the BTN1 and BTN2 User Buttons on the IMX6ULL-SOM-BSB development board. They are connected to GPIO5_IO00 and GPIO5_IO01 on the i.MX 6ULL. The gpio-keys and iomuxc nodes in the rootfs.dts file configure these GPIOs appropriately:

  • The user-btn1 and user-btn2 nodes in gpio-keys specify the wakeup-source property to enable wake-up from this button;
  • The pinctrl_gpio_keys node in iomuxc defines the GPIO pull-up settings.

... gpio-keys { ... user-btn1 { label = "BTN1"; gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; linux,code = ; wakeup-source; }; user-btn2 { label = "BTN2"; gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; linux,code = ; wakeup-source; }; }; ... &iomuxc { ... pinctrl_gpio_keys: gpio_keysgrp { fsl,pins = < MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 MX6UL_GPIO_KEY_PAD_CTRL MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 MX6UL_GPIO_KEY_PAD_CTRL >; }; ... };