Power management: low-power sleep (s2idle) investigation #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal: usable battery life via suspend. Constraints discovered so far:
psci: failed to set PC mode: -3every boot), so deep PSCI suspend states may be off-limits; s2idle (suspend-to-idle) with cpuidle + RPMh sleep/wake state voting is the realistic first target./sys/devices/system/cpu/cpu*/cpuidle/state*/usage).sync_statesituation resolved (chronicsync_state() pendingfor gcc/rpmhpd/gpucc due to gmu/dispcc consumers) — related to theregulator_ignore_unusedcrutch still in the cmdline; proper rail ownership is a prerequisite.Correction: the
sync_stateprerequisite in the description is mostly a non-issueThe description lists "RPMh sleep votes need the
sync_statesituation resolved (chronicsync_state() pendingfor gcc/rpmhpd/gpucc due to gmu/dispcc consumers)" as a prerequisite. Investigated 2026-08-25 — it is much smaller than it looks, and two of the three parts are not real.gcc and gpucc have no
sync_statecallback at all.gcc-sm8150.candgpucc-sm8150.cdefine plainplatform_drivers with only.probe; nothing indrivers/clk/qcom/sets.sync_stateexcept the ipq parts. So there is nothing being skipped for those two — the warning is noise.Unused clocks and power domains are already being cleaned up, just by a different mechanism than sync_state. Both run normally at 0.65 s:
That is
clk_disable_unused/genpd_power_off_unused, which are global late_initcalls and unrelated tosync_state. (Note the current debug image passesclk_ignore_unused pd_ignore_unused, which suppresses them — but that is a deliberate bring-up flag, not a defect.)Only
rpmhpdgenuinely has async_state, and we deliberately stubbed it out — commit11c730d573b7, with the reason recorded in the code:So RPMh power-domain corners staying at XBL's boot values is our own choice, made to avoid a specific crash — not an accident of fw_devlink.
Why it never fires anyway: the pending consumers are
2c6a000.gmuandad00000.clock-controller. Both are permanently unbound —0xad00000is camcc, which we have no driver for, and the a6xx GPU driver uses the GMU node directly without binding a driver to it. Neither will ever probe, sosync_statecan never run regardless of the stub.What this means for this issue
The real prerequisite is narrower than written: rpmhpd needs to be able to apply real corners, which means un-stubbing
rpmhpd_sync_state()and having enough real consumers in the DT that releasing XBL's votes does not collapse the SoC.fw_devlink.sync_state=timeoutwould force it to fire, and is a cheap way to find out what breaks — worth trying once the display situation (#17) is settled, since the stub's comment blames the display scanout specifically.regulator_ignore_unusedin the cmdline is a separate crutch and still stands as written.Also relevant to the baseline-power measurement in the description: the fuel gauge (#9) is a pure SM5705 I2C port — pm8150b is not fitted on this board, so there is no PMIC ADC route to battery current either.