Last edited 2 weeks ago

STM32MP2 power overview

Applicable for STM32MP25x lines

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]

STM32MP2 Power.png

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:

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>;
	};
};
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;
		};
	};
};
/ {
	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.

Warning white.png Warning
freeze (s2idle) is not fully functional in OpenSTLinux v5.1 see next chapter for details)
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
  1. 1.0 1.1 1.2 1.3 1.4 The wake-up associated to autonomous mode is not managed in OpenSTLinux.

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 for PSCI_CPU_SUSPEND support
  • PLAT_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).

STM32MP2 power domain.png

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.

Warning white.png Warning
freeze, S2Idle and OS initiated mode is not fully functional in OpenSTLinux v5.1; it should be used only for power measurements with the known restrictions:

- the check of activated wake-up sources in EXTI1 is not functional
- Linux console doesn't support pm runtime so CLUSTER_PD is never stopped when console is used
- the GPU power domain is not included in CLUSTER_PD, so GPU is stopped in Idle without protection
- the Cortex-M33 firmware state is not checked (when it is running in DDR)

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.

  • 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:

8. References[edit | edit source]

  1. Arm Power State Coordination Interface (PSCI):
    https://developer.arm.com/documentation/den0022
  2. Arm System Control and Management Interface Platform Design Document (SCMI) specification:
    https://developer.arm.com/documentation/den0056