Skip to content

Commit 19b3940

Browse files
ABESTMnashif
authored andcommitted
soc: st: Add support for STOP3 on STM32U5
LPTIM is not available in STOP3 mode, so RTC needs to be used instead. This code usese similar approach as STM32WBAx for suspend to ram. The STOP3 is disabled by default in device tree. Signed-off-by: Adam Berlinger <[email protected]>
1 parent 2c88cc0 commit 19b3940

File tree

7 files changed

+129
-6
lines changed

7 files changed

+129
-6
lines changed

drivers/counter/counter_ll_stm32_rtc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ static void rtc_stm32_irq_config(const struct device *dev);
185185

186186
static int rtc_stm32_start(const struct device *dev)
187187
{
188-
#if defined(CONFIG_SOC_SERIES_STM32WBAX)
188+
#if defined(CONFIG_SOC_SERIES_STM32WBAX) || defined(CONFIG_SOC_SERIES_STM32U5X)
189189
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
190190
const struct rtc_stm32_config *cfg = dev->config;
191191

@@ -208,7 +208,7 @@ static int rtc_stm32_start(const struct device *dev)
208208

209209
static int rtc_stm32_stop(const struct device *dev)
210210
{
211-
#if defined(CONFIG_SOC_SERIES_STM32WBAX)
211+
#if defined(CONFIG_SOC_SERIES_STM32WBAX) || defined(CONFIG_SOC_SERIES_STM32U5X)
212212
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
213213
const struct rtc_stm32_config *cfg = dev->config;
214214

drivers/timer/Kconfig.stm32_lptim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,18 @@ config STM32_LPTIM_TICK_FREQ_RATIO_OVERRIDE
5959
This options allows to override this check
6060

6161
config STM32_LPTIM_STDBY_TIMER
62-
bool "Use an additional timer while entering Standby mode"
62+
bool
6363
default $(dt_chosen_enabled,$(DT_CHOSEN_STDBY_TIMER))
6464
depends on COUNTER
6565
depends on TICKLESS_KERNEL
6666
select EXPERIMENTAL
6767
help
68+
Use an additional timer while entering Standby mode.
6869
There are chips e.g. STM32WBAX family that use LPTIM as a system timer,
6970
but LPTIM is not clocked in standby mode. These chips usually have
7071
another timer that is not stopped, but it has lower frequency e.g.
7172
RTC, thus it can't be used as a main system timer.
73+
Same approach is used on STM32U5 and STOP3 mode.
7274

7375
Use the Standby timer for timeout (wakeup) when the system is entering
7476
Standby state.

drivers/timer/stm32_lptim_timer.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,22 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
204204

205205
next = pm_policy_next_state(CURRENT_CPU, ticks);
206206

207-
if ((next != NULL) && idle && (next->state == PM_STATE_SUSPEND_TO_RAM)) {
207+
/* Check if STANBY or STOP3 is requested */
208+
timeout_stdby = false;
209+
if ((next != NULL) && idle) {
210+
#ifdef CONFIG_PM_S2RAM
211+
if (next->state == PM_STATE_SUSPEND_TO_RAM) {
212+
timeout_stdby = true;
213+
}
214+
#endif
215+
#ifdef CONFIG_STM32_STOP3_LP_MODE
216+
if ((next->state == PM_STATE_SUSPEND_TO_IDLE) && (next->substate_id == 4)) {
217+
timeout_stdby = true;
218+
}
219+
#endif
220+
}
221+
222+
if (timeout_stdby) {
208223
uint64_t timeout_us =
209224
((uint64_t)ticks * USEC_PER_SEC) / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
210225

@@ -215,8 +230,6 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
215230
.flags = 0,
216231
};
217232

218-
timeout_stdby = true;
219-
220233
/* Set the alarm using timer that runs the standby.
221234
* Needed rump-up/setting time, lower accurency etc. should be
222235
* included in the exit-latency in the power state definition.

dts/arm/st/u5/stm32u5.dtsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@
6565
substate-id = <3>;
6666
min-residency-us = <900>;
6767
};
68+
/omit-if-no-ref/ stop3: state3 {
69+
compatible = "zephyr,power-state";
70+
power-state-name = "suspend-to-idle";
71+
substate-id = <4>;
72+
min-residency-us = <200000>;
73+
exit-latency-us = <130>;
74+
};
6875
};
6976
};
7077

soc/st/stm32/stm32u5x/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# Copyright (c) 2021 Linaro Limited
44
# SPDX-License-Identifier: Apache-2.0
55

6+
DT_CHOSEN_STDBY_TIMER := st,lptim-stdby-timer
7+
68
config SOC_SERIES_STM32U5X
79
select ARM
810
select CPU_CORTEX_M33
@@ -15,3 +17,16 @@ config SOC_SERIES_STM32U5X
1517
select HAS_STM32CUBE
1618
select HAS_PM
1719
select HAS_POWEROFF
20+
21+
config STM32_STOP3_LP_MODE
22+
bool
23+
default $(dt_path_enabled,/cpus/power-states/state3) && $(dt_chosen_enabled,$(DT_CHOSEN_STDBY_TIMER))
24+
help
25+
Enable support for STM32 STOP3 low-power mode.
26+
Based on the Cortex-M33 Deepsleep mode combined with peripheral clock gating.
27+
All clocks in the core domain are stopped.
28+
The PLL, MSIS, MSIK, HSI16, and HSE oscillators are disabled.
29+
All SRAMs and register contents are preserved.
30+
SRAMs can be totally or partially switched off to further reduce consumption.
31+
GPIOs are left floating and additional pull-up or pull-down can be applied
32+
via PWR registers.

soc/st/stm32/stm32u5x/Kconfig.defconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,26 @@ rsource "Kconfig.defconfig.stm32u5*"
1010
config ROM_START_OFFSET
1111
default 0x400 if BOOTLOADER_MCUBOOT
1212

13+
if STM32_STOP3_LP_MODE
14+
15+
config COUNTER
16+
default y
17+
18+
config COUNTER_RTC_STM32_SUBSECONDS
19+
default y
20+
21+
config STM32_LPTIM_STDBY_TIMER
22+
default y
23+
24+
config TICKLESS_KERNEL
25+
default y
26+
27+
config COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS
28+
default y
29+
30+
config IDLE_STACK_SIZE
31+
default 512
32+
33+
endif #STM32_USE_STOP3
34+
1335
endif # SOC_SERIES_STM32U5X

soc/st/stm32/stm32u5x/power.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <stm32u5xx_ll_bus.h>
1313
#include <stm32u5xx_ll_cortex.h>
1414
#include <stm32u5xx_ll_pwr.h>
15+
#include <stm32u5xx_ll_icache.h>
1516
#include <stm32u5xx_ll_rcc.h>
1617
#include <stm32u5xx_ll_system.h>
1718
#include <clock_control/clock_stm32_ll_common.h>
@@ -26,6 +27,32 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
2627
#define RCC_STOP_WAKEUPCLOCK_SELECTED LL_RCC_STOP_WAKEUPCLOCK_HSI
2728
#endif
2829

30+
#ifdef CONFIG_STM32_STOP3_LP_MODE
31+
static void pwr_stop3_isr(const struct device *dev)
32+
{
33+
ARG_UNUSED(dev);
34+
35+
/* Clear all wake-up flags */
36+
LL_PWR_ClearFlag_WU();
37+
}
38+
39+
static void disable_cache(void)
40+
{
41+
/* Disabling ICACHE */
42+
LL_ICACHE_Disable();
43+
while (LL_ICACHE_IsEnabled() == 1U) {
44+
}
45+
46+
/* Wait until ICACHE_SR.BUSYF is cleared */
47+
while (LL_ICACHE_IsActiveFlag_BUSY() == 1U) {
48+
}
49+
50+
/* Wait until ICACHE_SR.BSYENDF is set */
51+
while (LL_ICACHE_IsActiveFlag_BSYEND() == 0U) {
52+
}
53+
}
54+
#endif
55+
2956
void set_mode_stop(uint8_t substate_id)
3057
{
3158
/* ensure the proper wake-up system clock */
@@ -41,6 +68,25 @@ void set_mode_stop(uint8_t substate_id)
4168
case 3: /* enter STOP2 mode */
4269
LL_PWR_SetPowerMode(LL_PWR_STOP2_MODE);
4370
break;
71+
#ifdef CONFIG_STM32_STOP3_LP_MODE
72+
case 4: /* enter STOP3 mode */
73+
74+
LL_PWR_SetSRAM2SBRetention(LL_PWR_SRAM2_SB_FULL_RETENTION);
75+
/* Enable RTC wakeup
76+
* This configures an internal pin that generates an event to wakeup the system
77+
*/
78+
LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN7);
79+
LL_PWR_SetWakeUpPinSignal3Selection(LL_PWR_WAKEUP_PIN7);
80+
81+
/* Clear flags */
82+
LL_PWR_ClearFlag_SB();
83+
LL_PWR_ClearFlag_WU();
84+
85+
disable_cache();
86+
87+
LL_PWR_SetPowerMode(LL_PWR_STOP3_MODE);
88+
break;
89+
#endif
4490
default:
4591
LOG_DBG("Unsupported power state substate-id %u", substate_id);
4692
break;
@@ -85,6 +131,18 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
85131
if (substate_id <= 3) {
86132
LL_LPM_DisableSleepOnExit();
87133
LL_LPM_EnableSleep();
134+
#ifdef CONFIG_STM32_STOP3_LP_MODE
135+
} else if (substate_id == 4) {
136+
stm32_clock_control_standby_exit();
137+
138+
LL_ICACHE_SetMode(LL_ICACHE_1WAY);
139+
LL_ICACHE_Enable();
140+
while (LL_ICACHE_IsEnabled() == 0U) {
141+
}
142+
143+
LL_LPM_DisableSleepOnExit();
144+
LL_LPM_EnableSleep();
145+
#endif
88146
} else {
89147
LOG_DBG("Unsupported power substate-id %u",
90148
substate_id);
@@ -118,6 +176,12 @@ static int stm32_power_init(void)
118176
/* enable Power clock */
119177
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PWR);
120178

179+
#ifdef CONFIG_STM32_STOP3_LP_MODE
180+
IRQ_CONNECT(PWR_S3WU_IRQn, 0,
181+
pwr_stop3_isr, 0, 0);
182+
irq_enable(PWR_S3WU_IRQn);
183+
#endif
184+
121185
return 0;
122186
}
123187

0 commit comments

Comments
 (0)