Last edited 3 weeks ago

STM32MP2 power overview

Applicable for STM32MP21x lines, STM32MP23x lines, 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, based on OP-TEE and TF-A device tree.

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 {
	domain-stop1 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x00000011>;
	};
	domain-lp-stop1 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x00000021>;
	};
	domain-lplv-stop1 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x00000211>;
	};
	domain-stop2 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x40001333>;
	};
	domain-lp-stop2 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x40002333>;
	};
	domain-lplv-stop2 {
		compatible = "domain-idle-state";
		arm,psci-suspend-param = <0x40023333>;
	};
	domain-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/ domain-lp-stop1;
			/delete-node/ domain-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 STM32 MPU 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)[OSTL 1] 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
  1. VDDCPU is not reduced for LPLV-Stop1 in OpenSTLinux on STMicroelectronics boards with STPMIC25 (not implemented)

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 named Functionalities depending on system operating mode of the STM32 MPU 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 PSCI specification define the concept of the power domain topology tree, which plays a crucial role in TF-A BL31 (porting-guide.html) and its PSCI stack (see design/psci-pd-tree.html).

For PSCI suspend requests, STM32MP2 series supports 5 power levels in the PSCI topology to handle the regulators configuration done in OP-TEE, in particular to differentiate the voltages for LP and the LPLV modes with PMIC.

In OpenSTLinux, each STM32MP2 series low power mode is associated to a PSCI State-id, which uses the ARM Recommended StateID Encoding with OS initiated support and the PSCI topology is:

/* State-id - 0x00000001 */
#define PWRSTATE_RUN \
        stm32_make_pwrstate(RUN, RUN, RUN, RUN, RET, PSTATE_TYPE_STANDBY)

/* State-id - 0x00000011 Stop1 */
#define PWRSTATE_STOP1 \
        stm32_make_pwrstate(RUN, RUN, RUN, RET, RET, PSTATE_TYPE_STANDBY)

/* State-id - 0x00000021 LP-Stop1*/
#define PWRSTATE_LP_STOP1 \
        stm32_make_pwrstate(RUN, RUN, RUN, LP, RET, PSTATE_TYPE_STANDBY)

/* State-id - 0x00000211 LPLV-Stop1*/
#define PWRSTATE_LPLV_STOP1 \
        stm32_make_pwrstate(RUN, RUN, LP, RET, RET, PSTATE_TYPE_STANDBY)

/* State-id - 0x40001333 Stop2 */
#define PWRSTATE_STOP2 \
        stm32_make_pwrstate(RUN, RET, OFF, OFF, OFF, PSTATE_TYPE_POWERDOWN)

/* State-id - 0x40002333 LP-Stop2*/
#define PWRSTATE_LP_STOP2 \
        stm32_make_pwrstate(RUN, LP, OFF, OFF, OFF, PSTATE_TYPE_POWERDOWN)

/* State-id - 0x40023333 LPLV-Stop2*/
#define PWRSTATE_LPLV_STOP2 \
        stm32_make_pwrstate(LP, OFF, OFF, OFF, OFF, PSTATE_TYPE_POWERDOWN)

/* State-id - 0x40033333 Standby */
#define PWRSTATE_STANDBY \
        stm32_make_pwrstate(OFF, OFF, OFF, OFF, OFF, PSTATE_TYPE_POWERDOWN)

These value are 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(4)
  • 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)

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 PowerLevel
D2_LPLV(4) D2(3) D1_LPLV(2) D1(1) Core(0)
PSCI_CPU_SUSPEND Sleep (WFI) 0x00000001 PSTATE_TYPE_STANDBY RUN RUN RUN RUN RET
Stop1 0x00000011 PSTATE_TYPE_STANDBY RUN RUN RUN RET RET
LP-Stop1 0x00000021 PSTATE_TYPE_STANDBY RUN RUN RUN LP RET
LPLV-Stop1 0x00000211 PSTATE_TYPE_STANDBY RUN RUN LP RET RET
PSCI_SYSTEM_SUSPEND Stop2 0x40001333 PSTATE_TYPE_POWERDOWN RUN RET OFF OFF OFF
LP-Stop2 0x40002333 PSTATE_TYPE_POWERDOWN RUN LP OFF OFF OFF
LPLV-Stop2 0x40023333 PSTATE_TYPE_POWERDOWN LP OFF OFF OFF OFF
Standby 0x40002333 PSTATE_TYPE_POWERDOWN OFF OFF OFF OFF OFF
Warning white.png Warning
This PSCI topology is a part of OpenSTLinux distribution, used in embedded software compoments, of STM32MP2 series. It must be kept as is, without being modified by the end-user.

4.3. PSCI_CPU_SUSPEND support[edit | edit source]

Linux kernel sent the PSCI_CPU_SUSPEND to TF-A BL31 after a S2IDLE/FREEZE system request and for PSCI CPUIdle OS initiated mode (PSCI OSI). they are described in SoC device tree using the hierarchical model with nodes idle-states and domain-idle-states as described in Documentation/devicetree/bindings/arm/psci.yaml (see Power overview for detail).

See SoC device tree example in arch/arm64/boot/dts/st/stm32mp251.dtsi and in arch/arm64/boot/dts/st/stm32mp253.dtsi .

The targeted arm,psci-suspend-param, based on this topology, is provided to PCSI stack in TF-A BL31 in PSCI_CPU_SUSPEND requested (see Power overview or design_documents/psci_osi_mode.html for detail).

4.4. PSCI_SYSTEM_SUSPEND support[edit | edit source]

Linux kernel sent the PSCI_SYSTEM_SUSPEND to TF-A BL31 after "DEEP"/"S2RAM" request (see Power overview for details). The CPU must reset at wake-up. 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).

4.5. PSCI stack in TF-A[edit | edit source]

In TF-A BL31, we have 3 elements imply in low power managemet

In the PSCI stack call sequence (in lib/psci/psci_suspend.c ) is

  • for PSCI_SYSTEM_SUSPEND {managed by psci_cpu_suspend()}
    1. get_sys_suspend_power_state()
    2. SPD OP-TEE: svc_suspend()
    3. pwr_domain_suspend()
    4. pwr_domain_pwr_down_wfi()
    5. Low power mode (CPU powered down)
    6. pwr_domain_suspend_finish() {called by psci_warmboot_entrypoint()}
    7. SPD OP-TEE: svc_suspend_finish()
  • for PSCI_CPU_SUSPEND {managed by psci_cpu_suspend()}
    1. validate_power_state()
    2. pwr_domain_validate_suspend()
    3. pwr_domain_suspend()
    4. Low power mode (the 2 CPU core are stalled, context is preserved)
    5. pwr_domain_suspend_finish()

For PSCI_CPU_SUSPEND case, the SPD OP-TEE is not managed by PSCI stack as the context is preserved. For OpenSTLinux, th call of OP-TEE hook is required to manage PMIC configuration in OP-TEE, it is done in STM32 functions (stm32_pwr_domain_suspend() / stm32_pwr_domain_suspend_finish())/code>.)

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.

See Power_overview#How_to_trace_and_debug

With the next command:

echo N > /sys/module/printk/parameters/console_suspend 

On PSCI_SYSTEM_SUSPEND TF-A BL31 displays the low power mode selected in stm32_get_sys_suspend_power_state() and, if it is not Standby1, dumps the registers (EXTI1_C1IMR and PWR_CPU2D2SR) used to choose this mode, for example:

echo N > /sys/module/printk/parameters/console_suspend
echo enabled > /sys/class/tty/ttySTM0/power/wakeup
rtcwake --date +5sec -m mem
rtcwake: assuming RTC uses UTC ...
rtcwake: wakeup from "mem" using /dev/rtc0 at Mon Jan  3 03:03:24 2000
[174821.520715] PM: suspend entry (deep)
[174821.520901] Filesystems sync: 0.000 seconds
[174821.524033] Freezing user space processes
[174821.528937] Freezing user space processes completed (elapsed 0.001 seconds)
[174821.534228] OOM killer disabled.
[174821.537468] Freezing remaining freezable tasks
[174821.543294] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[174821.553226] stm32-dwmac 482d0000.eth2 end0: FPE workqueue stop
[174821.555855] stm32-dwmac 482c0000.eth1 end1: FPE workqueue stop
[174821.646337] Disabling non-boot CPUs ...
[174821.648058] psci: CPU1 killed (polled 0 ms)
INFO:    max_pwr_state=40002333 C1IMR1=8000000 C1IMR2=100000 C1IMR3=0 CPU2D2SR=1
INFO:    Entering LP_Stop2 low power mode

See stm32_get_sys_suspend_power_state() and reference Manuel to identified the reason of the low power mode selection.

6.1. How to force low power mode[edit | edit source]

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