summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2020-11-23 18:32:55 +0100
committerCommit Bot <commit-bot@chromium.org>2020-12-02 09:39:18 +0000
commitd29bdc99139095127efa9a45c12164bb8e0e07e5 (patch)
tree42cf75ca12fa7fc90a8d534cac1023beaf1a99c9 /chip
parent8d98b0e5dc06cd285ea4a65f8a93a76514d9dc59 (diff)
downloadchrome-ec-d29bdc99139095127efa9a45c12164bb8e0e07e5.tar.gz
stm32: low power configuration for STM32F4
As most of the peripherals were not implemented to support switching to 16-MHz HSI (e.g. high speed serial port requires a clock input > 24 Mhz), implement a simpler clock scheme than the dynamic between HSI and PLL used other platforms: - the PLL is disabled only when entering the low-power idle and the PLL locking time is added to wake-up time. - when the host is running (not suspended) we stay in a high power mode (~20mW). Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BUG=b:130561737 TEST=manual, on bloonchipper, check we can still capture fingerprint. read the MCU power consumption: pp3300_dx_mcu_mw is 2.367 mW. BRANCH=fpmcu-bloonchipper Change-Id: Ic1fe015b2501bdea9779a2f63fab296f8812c315 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2555162 Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/stm32/clock-stm32f4.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/chip/stm32/clock-stm32f4.c b/chip/stm32/clock-stm32f4.c
index 87e4fe061b..a50f5f51dd 100644
--- a/chip/stm32/clock-stm32f4.c
+++ b/chip/stm32/clock-stm32f4.c
@@ -435,6 +435,8 @@ static int dsleep_recovery_margin_us = 1000000;
/* STOP_MODE_LATENCY: delay to wake up from STOP mode with main regulator off */
#define STOP_MODE_LATENCY 50 /* us */
+/* PLL_LOCK_LATENCY: delay to switch from HSI to PLL */
+#define PLL_LOCK_LATENCY 150 /* us */
/*
* SET_RTC_MATCH_DELAY: max time to set RTC match alarm. If we set the alarm
* in the past, it will never wake up and cause a watchdog.
@@ -466,7 +468,8 @@ void __idle(void)
next_delay = __hw_clock_event_get() - t0.le.lo;
if (DEEP_SLEEP_ALLOWED &&
- (next_delay > (STOP_MODE_LATENCY + SET_RTC_MATCH_DELAY))) {
+ (next_delay > (STOP_MODE_LATENCY + PLL_LOCK_LATENCY +
+ SET_RTC_MATCH_DELAY))) {
/* Deep-sleep in STOP mode */
idle_dsleep_cnt++;
@@ -478,8 +481,15 @@ void __idle(void)
/* Set deep sleep bit */
CPU_SCB_SYSCTRL |= 0x4;
- set_rtc_alarm(0, next_delay - STOP_MODE_LATENCY,
+ set_rtc_alarm(0, next_delay - STOP_MODE_LATENCY
+ - PLL_LOCK_LATENCY,
&rtc0, 0);
+
+ /* Switch to HSI */
+ clock_switch_osc(OSC_HSI);
+ /* Turn off the PLL1 to save power */
+ clock_enable_osc(OSC_PLL, false);
+
/* ensure outstanding memory transactions complete */
asm volatile("dsb");
@@ -487,6 +497,11 @@ void __idle(void)
CPU_SCB_SYSCTRL &= ~0x4;
+ /* turn on PLL and wait until it's ready */
+ clock_enable_osc(OSC_PLL, true);
+ /* Switch to PLL */
+ clock_switch_osc(OSC_PLL);
+
/*uart_enable_wakeup(0);*/
/* Fast forward timer according to RTC counter */