This article gives information about the support power management in OpenSTlinux for STM32MP2 series.
1. Framework purpose[edit | edit source]
The purpose of this article is to explain how OpenSTlinux components handle the STM32MP2 series power management:
- Software overview
- Peripheral power support
- Low-power modes available on the device
See also the page How to define your low-power strategy.
2. Software overview[edit | edit source]
The system power request is treated with the PSCI support with TF-A.
The power requests associated to each device (clock, regulator, operation point) are consolidated by the Linux frameworks and can be treated by Linux driver or by OP-TEE through SCMI requests.
2.1. Component description[edit | edit source]
The OpenSTLinux components for low power are:
Non secure world (Linux):
- Power management frameworks: See Power overview for details
- PSCI library: this is a set of standardized functions to request a low-power service to the secure monitor
- SCMI drivers: driver for system resources (clock, regulators, power domain,...), exposed by OP-TEE with SCMI protocol
- Device driver: any peripheral driver which needs to control power
- RCC driver for clock and reset managed by non secure world
Secure world components (OP-TEE):
- SCMI protocol: see SCMI overview for details
- PM framework: call the low-power callback of each device on the call of TF-A BL31 PM hooks.
- OP-TEE drivers: driver of device for system resources
- RCC driver for clock and reset managed by secure world
- PWR driver for SoC regulators managed by secure world
- PMIC driver for external regulators
Secure monitor components (TF-A BL31):
- PSCI libray: generic PSCI stack
- PM manage PSCI topology and modes with RCC and PWR registers and DDR self refresh
- DDR driver: DDR driver
STM32 peripherals (Hardware):
2.2. API description[edit | edit source]
The OpenSTLinux power management support is based on Arm® interface specifications:
- Power state coordination interface (PSCI) [1] defines many messages (see identifiers in TF-A include/lib/psci/psci.h or in Linux include/kvm/arm_psci.h ), for examples:
- CPU_SUSPEND : used to CPU suspend (freeze/s2idle), including OS initiated state support for CpuIdle
- CPU_ON/CPU_OFF : used for hotplug feature
- SYSTEM_OFF : used for power off
- SYSTEM_RESET : used for system reset
- SYSTEM_SUSPEND : used to system suspend (deep)
- PSCI_VERSION : return the supported version of the PSCI specication, v1.1 is supported by TF-A
- System Control and Management Interface (SCMI)[2], see SCMI overview for details
3. Configuration[edit | edit source]
The objective of this chapter is to explain how to configure OpenSTLinux for low power modes.
See the page power overview for kernel configuration details.
3.1. Supported power modes[edit | edit source]
The SoC device tree describes the PSCI topology in sub-nodes of cpus/domain-idle-states
:
- for Linux in arch/arm64/boot/dts/st/stm32mp251.dtsi , one node for each PSCI_CPU_SUSPEND supported parameter (only the Stop1 modes):
domain-idle-states {
STOP1: domain-stop1 {
compatible = "domain-idle-state";
arm,psci-suspend-param = <0x00000011>;
};
LP_STOP1: domain-lp-stop1 {
compatible = "domain-idle-state";
arm,psci-suspend-param = <0x0000021>;
};
LPLV_STOP1: domain-lplv-stop1 {
compatible = "domain-idle-state";
arm,psci-suspend-param = <0x00000211>;
};
};
- for TF-A BL31 secure monitor, in fdts/stm32mp251.dtsi , one node by state supported in PSCI topology:
domain-idle-states { stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x00000011>; }; lp-stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x00000021>; }; lplv-stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x00000211>; }; stop2 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x40001333>; }; lp-stop2 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x40002333>; }; lplv-stop2 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x40023333>; }; standby { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x40033333>; }; };
The unsupported low power modes and associated references in domain-idle-states power domain nodes must be deleted from TF-A BL31 and Linux board device-tree files.
For example on board without STPMIC25, if the PWR_LP pins control the reduced voltage mode of the VDDCORE and VDDCPU regulators, then only LPLV-StopX modes can be reached. LP-StopX modes must be deleted.
- in TF-A BL31 device tree
/ { cpus { domain-idle-states { /delete-node/ lp-stop1; /delete-node/ lp-stop2; }; }; };
- in Linux device tree (CLUSTER_PD
domain-idle-states = <&STOP1>, <&LP_STOP1>;
for CLUSTER_PD in arch/arm64/boot/dts/st/stm32mp251.dts ):
/ { cpus { domain-idle-states { /delete-node/ domain-lp-stop1; }; }; }; &CLUSTER_PD { domain-idle-states = <&STOP1>; };
3.2. STPMIC configuration for low power mode[edit | edit source]
Please refer to PMIC OP-TEE page for details of PMIC configuration in OP-TEE for each power mode and to application note AN5727 for configurations.
In OpenSTLinux, the selected PSCI power level is indicated to OP-TEE with Secure-EL1 Payload Dispatcher (SPD) PSCI hooks. And this power level is indicated with pm_hint to each OP-TEE drivers to save/restore the device configuration (see core/include/kernel/pm.h and core/arch/arm/plat-stm32mp2/stm32mp_pm.h for details).
This hook is used by the STPMIC25 driver in OP-TEE to configure each regulators according to the selected low power mode as described in device tree by subnodes.
See OP-TEE device tree in core/arch/arm/dts/stm32mp257f-ev1.dts for configuration example:
vddcore: buck2 { regulator-name = "vddcore"; regulator-min-microvolt = <820000>; regulator-max-microvolt = <820000>; regulator-always-on; st,pwrctrl-sel = <1>; st,pwrctrl-enable; default { regulator-on-in-suspend; regulator-suspend-microvolt = <820000>; }; lplv { regulator-on-in-suspend; regulator-suspend-microvolt = <670000>; }; standby { regulator-off-in-suspend; }; off { regulator-off-in-suspend; }; };
4. How to use the framework[edit | edit source]
4.1. Low-power modes[edit | edit source]
Refer to STM32MP25 reference manuals for the full description of low-power modes.
The AN5726 Guidelines for using low-power modes on STM32MP2 MPU also gives much more information on these modes and on associated the wake-up sources.
System mode | Linux Command | PSCI request | Power consumption | Wake-up time | VDDCPU | VDDCORE | DDR state |
---|---|---|---|---|---|---|---|
Stop1 | freeze (s2idle) |
PSCI_CPU_SUSPEND | Medium | Low | ON | ON | SR, VTT on |
LP-Stop1 | Medium | Low | SR, VTT off | ||||
LPLV-Stop1 | Medium | Medium | ON (reduced) | ON (reduced) | |||
Stop2 | mem (deep) |
PSCI_SYSTEM_SUSPEND | Low | Low | OFF | ON | SR, VTT off |
LP-Stop2 | Low | Medium | |||||
LPLV-Stop2 | Low | Medium | ON (reduced) | ||||
Standby1 | Low | High | OFF | ||||
Standby2 | shutdown | PSCI_SYSTEM_OFF | Very-Low | High | Off | ||
VBAT | Very-Low | Very-High |
OpenSTLinux sets the DDR in Self Refresh mode (SR) in all the low-power modes except power off (Standby2 and VBAT). For LP-Stop1 and LP-Stop2 modes, the DDR VTT supply is also switched off on STMicroelectronics reference design thought the PWR_LP signal connected to PWRCTRL1 pin of STPMIC25.
This list of Wake-up capability peripheral for each mode is defined in the Table 94. Functionalities depending on system operating mode of the STM32MP25 reference manuals.
The following tables give the list of wake-up sources available in each mode.
Plaform mode | Available wake-up sources |
---|---|
Stop1/2 and LP-Stop1/2 |
Group1 : Group2 + HPDMAx (x = 1, 2, 3), HSI frequency monitoring, USB, UCPD1, ETHx (x = 1,2), USARTx (x = 1 to 9), I2Cx (x = 1 to 7), I3Cx (x = 1 to 3), SPIx (x = 1 to 7), DTS, LPTIMx (x = 1, 2) |
LPLV-Stop1/2 | Group2 : Group3 + PVD, PVM, GPIOs |
Standby1 | Group3 : Group4 + CPU3, DBG, LPDMA, LPUART1[note 1], I2C8[note 1], I3C4[note 1], SPI8[note 1], ADF1[note 1], LPTIMy (y = 3, 4, 5), WWDG2, MBOX2, HSEM, GPIOZ |
Standby2 | Group4 : Group5 + 6 x WKUP pins |
VBAT | Group5 : BOR, VBATH/VBATL, TEMPH/TEMPL, LSE CSS, RTC/auto wake-up, tamper pins, IWDGx |
4.2. PSCI topology[edit | edit source]
The low power modes for STM32MP2 use the PSCI stack in TF-A BL31, including the PSCI OSI mode (v2.9).
The PSCI topology is defined in TF-A PM driver: plat/st/stm32mp2/stm32mp2_pm.c .
Each low power more is associated to a PSCI State-id, which uses the ARM Recommended StateID Encoding with OS initiated support, based on the PSCI state system topology defined in plat/st/stm32mp2/include/platform_def.h with:
PLAT_MAX_PWR_LVL
= 4, for Core(0), D1(1), D1LPLV(2), D2(3), D2_LPLV(3)PLAT_MIN_SUSPEND_PWR_LVL
=2, limit level forPSCI_CPU_SUSPEND
supportPLAT_NUM_PWR_DOMAINS
= 6 (2 cores and 4 power level)
and with the power domain states:
STM32MP_LOCAL_STATE_RUN
(0)STM32MP_LOCAL_STATE_RET
(1)STM32MP_LOCAL_STATE_LP
(2)STM32MP_LOCAL_STATE_OFF
(3)
For PSCI suspend requests, STM32MP25 supports 5 power levels in the PSCI topology to handle the regulators configuration done in OP-TEE for STPMIC25, in particular to differentiate the voltages for LP and the LPLV modes.
The composite PSCI State-id are used in PSCI_CPU_SUSPEND
requests and in device tree (for S2Idle and for OS initiated support) and for used internal in TF-A BL31 for PSCI_CPU_SUSPEND
request (Deep).
This State-id encoding use the extended format and a simple additive composition method, with one nibble as a local state index for each power level (bits 27:0) and StateType(bit 30):
PSCI request | Name | State-id | StateType | D2_LPLV | D2 | D1_LPLV | D1 | Core |
---|---|---|---|---|---|---|---|---|
PSCI_CPU_SUSPEND | Sleep (WFI) | 0x00000001 | STANDBY | RUN | RUN | RUN | RUN | RET |
Stop1 | 0x00000011 | STANDBY | RUN | RUN | RUN | RET | RET | |
LP-Stop1 | 0x00000021 | STANDBY | RUN | RUN | RUN | LP | RET | |
LPLV-Stop1 | 0x00000211 | STANDBY | RUN | RUN | LP | RET | RET | |
PSCI_SYSTEM_SUSPEND | Stop2 | 0x40001333 | POWERDOWN | RUN | RET | OFF | OFF | OFF |
LP-Stop2 | 0x40002333 | POWERDOWN | RUN | LP | OFF | OFF | OFF | |
LPLV-Stop2 | 0x40023333 | POWERDOWN | LP | OFF | OFF | OFF | OFF | |
Standby | 0x40002333 | POWERDOWN | OFF | OFF | OFF | OFF | OFF |
4.3. PSCI in Linux (PSCI_CPU_SUSPEND)[edit | edit source]
In Linux the power domain and associated low power modes for OS initiated mode are described in SoC device tree (in arch/arm64/boot/dts/st/stm32mp251.dtsi and in arch/arm64/boot/dts/st/stm32mp253.dtsi ) using the hierarchical model as described in Documentation/devicetree/bindings/arm/psci.yaml .
/ { cpus { idle-states { entry-method = "psci"; CPU_PWRDN: cpu-power-down { compatible = "arm,idle-state"; arm,psci-suspend-param = <0x00000001>; }; }; domain-idle-states { STOP1: domain-stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x00000011>; }; LP_STOP1: domain-lp-stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x0000021>; }; LPLV_STOP1: domain-lplv-stop1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x00000211>; }; }; }; psci { compatible = "arm,psci-1.0"; method = "smc"; CPU_PD0: power-domain-cpu0 { #power-domain-cells = <0>; domain-idle-states = <&CPU_PWRDN>; power-domains = <&CLUSTER_PD>; }; CPU_PD1: power-domain-cpu1 { #power-domain-cells = <0>; domain-idle-states = <&CPU_PWRDN>; power-domains = <&CLUSTER_PD>; }; CLUSTER_PD: power-domain-cluster { #power-domain-cells = <0>; domain-idle-states = <&STOP1>, <&LP_STOP1>; power-domains = <&RET_PD>; }; RET_PD: power-domain-retention { #power-domain-cells = <0>; domain-idle-states = <&LPLV_STOP1>; }; };
This power domain hierarchy is used in generic power domain (GenPD) for S2IDLE request and for dynamic power management, based on PSCI OS initiated mode and on PM runtime: Linux kernel selects the lowest possible low power mode with the associated PSCI State Id, according the state of each power domain (device in the power domain is running, wake-up source is activated) and which respects the OS constraint (wake-up latency in OS initiated mode for example).
The devices are assigned to a domain in Soc device tree according the Table 94. Functionalities depending on system operating mode of the reference manuals (autonomous mode is not managed in OpenSTLinux).
- CLUSTER_PD for peripherals not functional in "Stop1/2 and LP-Stop1/2"
- RET_PD for peripherals not functional in "LPLV-Stop1/2"
The EXTI1 driver manages also the activated wake up source: LPLV-Stop1 mode is not not allowed for Group2 wake up source.
The dynamic power management is based on driver activity, with device PM runtime and GenPD, so you need to stop ALL the STM32MP25 peripherals activity, including console to allow low power modes.
4.3.1. PSCI in TF-A (PSCI_SYSTEM_SUSPEND)[edit | edit source]
For deep
request the PSCI_SYSTEM_SUSPEND is sent to T-FA when the secondary core is stopped and all the process are frozen. The activated wake-up are consolidated in TF-A BL31 to select the lowest POWERDOWN supported mode in stm32_get_sys_suspend_power_state() .
If a low power mode is not supported by a board design, it must be removed in TF-A BL31 device tree.
You can limit the maximum supported mode with wake-up sources, but you can't force Stop2 mode by Linux command if LP-Stop2 is supported (same functionalities, same supported wake-up sources).
5. Source code location[edit | edit source]
Below are listed the software frameworks and drivers managing the OpenSTLinux power management.
- Linux®: Linux power management
- TF-A:
- the STM32MP2 PSCI support: plat/st/stm32mp2/stm32mp2_pm.c
- the low power context: plat/st/stm32mp2/stm32mp2_context.c
- the PSCI stack: lib/psci/ and include/lib/psci/psci.h
- OP-TEE:
- TF-A hook for STM32MP2 platform: core/arch/arm/plat-stm32mp2/pm/pm_stm32mp25.c and core/arch/arm/plat-stm32mp2/stm32mp_pm.h
- PM framework: core/kernel/pm.c and core/include/kernel/pm.h
- For each device driver, the PM function registered by register_pm_core_service_cb()
- And drivers for each internal peripheral or external component are described in the associated pages:
6. How to trace and debug[edit | edit source]
See How to debug TF-A BL2 and How_to_debug_OP-TEE to activate the traces.
In TF-A, you can force the selected mode PSCI_SYSTEM_SUSPEND for your board in stm32_get_sys_suspend_power_state()
, for example:
/* Search the max supported POWERDOWN modes <= max_pwr_state */
for (i = ARRAY_SIZE(stm32mp_supported_pwr_states) - 1U; i > 0U; i--) {
pwr_state = stm32mp_supported_pwr_states[i];
if ((pwr_state != 0U) && (pwr_state <= max_pwr_state) &&
(psci_get_pstate_type(pwr_state) == PSTATE_TYPE_POWERDOWN)) {
break;
}
}
pwr_state = PWRSTATE_STOP2;
state_id = psci_get_pstate_id(pwr_state);
or remove some states in TF-A device tree , for example remove LP-Stop2 mode to allow Stop2 selection:
/ { cpus { domain-idle-states { /delete-node/ lp-stop2; }; }; };
7. To go further[edit | edit source]
Refer to reference manual for a detailed description of low-power modes and peripheral wakeup sources:
The next application notes gives additional information on the hardware settings used for low-power management:
- AN5726 - Guidelines for using low-power modes on STM32MP2 MPU
- AN5727 - How to use STPMIC25 for a wall adapter powered application on STM32MP25x lines MPUs
8. References[edit | edit source]
- ↑ Arm Power State Coordination Interface (PSCI):
https://developer.arm.com/documentation/den0022 - ↑ Arm System Control and Management Interface Platform Design Document (SCMI) specification:
https://developer.arm.com/documentation/den0056