How to set power modes in Debian

Is there any documentation/libraries that have been written for controlling the Snapdragon 410E’s power states? Like if I wanted to set the processor into suspend mode from a C++ program, and configure wake-up GPIOs to get the processor back to a running state?

I’m not aware of public documentation.

AFAIK there is no way to force a particular CPU to idle, the Kernel scheduler is responsible for this. You can potentially isolate a particular CPU to prevent unwanted scheduling [1], which should let the CPU idle as long as no process explicitly asks for the CPU (set_affinity).

However, from user-space, it’s possible to move offline a CPU via sysfs interface:

echo 0 > /sys/bus/cpu/devices/cpu1/online

I assume this is what you’re looking for when asking for suspend mode.

[1] realtime:documentation:howto🛠cpu-partitioning:isolcpus [Wiki]

What I’m looking to replicate is the Android, or smartphone, style suspend mode, when the CPU goes into a low power state and waits for an interrupt of the power button to wake up. I am wondering how to do something like this in Debian.

So I did a little more testing and I think I found something close to what I wanted to do. My power consumption test resulted in a idle state of around 0.629W and I found a systemctl command:

sudo systemctl suspend

This resulted in a power consumption of 0.459W, an improvement, but I would like to get this down substantially more. I also found that the power button on the DragonBoard (signal PHONE_ON_N in the schematic) wakes up the processor from suspend, and active programs before the suspend still run afterwards. I ran into a problem though. It seems that the GPU crashes after the suspend wake-up. The HDMI display loses signal. Here is a kernel message from dmesg (the program I was running through the suspend was a Qt app called “glasses”):

[269010.568013] qcom-iommu-ctx 1f09000.iommu-ctx: Unhandled context fault: fsr=0x202, iova=0x0000000000000000, fsynr=0x2, cb=1
[269012.802996] msm 1a00000.mdss: A306: hangcheck detected gpu lockup rb 0!
[269012.810620] msm 1a00000.mdss: A306:     completed fence: 1239
[269012.814167] msm 1a00000.mdss: A306:     submitted fence: 1246
[269012.818881] msm 1a00000.mdss: A306: hangcheck recover!
[269012.823477] msm 1a00000.mdss: A306: offending task: flush_queue:0 (./glasses)

So what you want is system-suspend, which is not really optimized on such dev board, and there is no official support.

You can try suspend to mem (this is what android usually do):

echo mem > /sys/power/state

Does the Snapdragon or PM8916 IC have a signal to synchronize the suspend across multiple IC’s? Like a signal that goes low when suspend is enabled?

If you are interesting in more detailed info for DB410c power management, you could refer the doc [1], it has some general introduction for power management for APQ8016E.

Actually I don’t know about DB410c related power features, but for general speaking, in the system the normal devices (or IC’s, like wifi/bluetooth, usb chips, etc) can be powered off by using software method to control PMIC to turn off them. The most tricky thing is after the system run into deepest low power mode, usually the SoC needs to use specific signal to notify external PMIC, so PMIC can decrease the voltage for SoC and PMIC also can set itself for more power saving mode.

You could see in the doc [1] section “XO Shutdown mode”, it mentions “No clock is fed to APQ except the 32 kHz sleep clock, which is required for the always-on processor”. So please note, SoC usually has one Always on (AON) power domain with specific logic, the logic will be used to handshake with external PMIC to accomplish the SoC deepest idle state. Usually this part is transparent for software developers and the hardware logic automatically handshakes between SoC AON and external PMIC.

[1] https://developer.qualcomm.com/qfile/35136/lm80-p0436-73_a_qualcomm_snapdragon_410e_processor_apq8016e_system_power_overview.pdf