Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32 Add PM Suspend to Ram support #67534

Merged

Conversation

gautierg-st
Copy link
Contributor

@gautierg-st gautierg-st commented Jan 12, 2024

This PR adds generic support for Suspend to RAM PM mode.

To that end, we use STM32 Standby mode with RAM retention (for SoC that provide it).
In low power applications, the Systick is typically given by a LPTIM. Since LPTIM is not clocked in Standby mode, before switching to this mode, we activate another clock (typically RTC) that works in Standby to play the role of Systick.
This was heavily influenced by the work in #63187 (Many thanks!).

A few peripherals (GPIO, ADC, Serial and entropy) have also been adapted to be compatible with this mode.

This other PR #67536 demonstrates the functionality on the STM32WBA series.

drivers/timer/Kconfig.stm32_lptim Show resolved Hide resolved
drivers/timer/stm32_lptim_timer.c Show resolved Hide resolved
drivers/serial/uart_stm32.c Show resolved Hide resolved
Comment on lines 765 to 769
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE,
PM_ALL_SUBSTATES);
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_RAM,
PM_ALL_SUBSTATES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ceolin Shouldn't preventing to go in one state also preventing to go in a deeper state ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it just excludes the given state / substate. If the next scheduled event is enough for a deeper state be used, this will happen.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ceolin I understand this opens to more cases, but are there possible cases were a subsystem can work in one state but can work in a deeper state ?

Remove initialization of static variable to 0 to prevent resetting the
value when reinitializing the driver after resume from standby.
This has no impact since static variables are initialized to 0 by default.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
Add support for a backup standby timer in STM32 LPTIM driver for cases
when the LPTIM is not available (ie standby low power mode).
A counter (typically RTC) is used for such a case.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
Fix a bug where after a standby, it was impossible to reenable a GPIO
clock.

A counter is incremented each time pm_device_runtime_get is called, and
decremented each time pm_device_runtime_put is called. The
clock is only enabled if this counter equals 1.
When configuring a GPIO (as input or output), the timer is incremented, and
when disconnecting it, it is both incremented and decremented. Thus the
next time we try to configuring it, the clock is not enabled (since the
counter will now be equal to 2).

This causes a problem when using low power standby mode: after wakeup all
clocks are disabled and the GPIO clock can not be reenabled.

This commit fixes this bug by not incrementing the counter when disconnect
is asked (or in other words incrementing it only when configuring either
an input or an output).

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
@erwango erwango self-requested a review January 17, 2024 10:47
@gautierg-st gautierg-st force-pushed the stm32_suspend_to_ram_support branch 2 times, most recently from f7bdfd8 to 8fd57db Compare January 17, 2024 14:08
Copy link
Member

@erwango erwango left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise LGTM

drivers/adc/adc_stm32.c Outdated Show resolved Hide resolved
drivers/gpio/gpio_stm32.c Show resolved Hide resolved
…ress

Prevent the system to enter Suspend to RAM state while UART operation is
in progress.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
When resuming from low power mode, if UART is disabled, this means that
we come from a mode that reset the registers, so we redo a full init of
the driver.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
Prevents the system to go in Suspend to RAM low power mode while ADC
measurement is in progress.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
…gress

Prevent the system to enter Suspend to RAM state while RNG operation is
in progress.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
With PM, when resuming from low power mode, reenable the RNG register
clocks and check the health register. If it is not set to the desired
value, it means we exit Suspend to RAM mode, and that the RNG needs to be
reinitialized.

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
@erwango erwango self-requested a review January 19, 2024 09:50
@carlescufi carlescufi merged commit 5aff88a into zephyrproject-rtos:main Jan 25, 2024
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ADC Analog-to-Digital Converter (ADC) area: Crypto / RNG area: GPIO area: Timer Timer area: UART Universal Asynchronous Receiver-Transmitter platform: STM32 ST Micro STM32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants