summaryrefslogtreecommitdiff
path: root/chip/stm32
diff options
context:
space:
mode:
authorBrian J. Nemec <bnemec@chromium.org>2019-11-11 23:51:35 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-18 01:16:43 +0000
commit771dd33b149fb94725edf0e29670207b9a013cb6 (patch)
tree295d1dbe58d3c280054ee8bf89ae9345f8205c83 /chip/stm32
parentc520344abe270967b1bd96d43559fb00c0d431d4 (diff)
downloadchrome-ec-771dd33b149fb94725edf0e29670207b9a013cb6.tar.gz
ServoMicro: Enable Brownout detection with PVD circuit
Enables the programmable voltage detector (PVD) interrupt in ServoMicro. This interrupt fires when the supply voltage drops from the expected 3.3V to under 2.3V after power on. This gives several hundred microseconds of time for the device to respond to the power reduction. In order to ensure that the ServoMicro does not enter a non-responsive state, it triggers a reboot of the system to restore it to a good configuration. BRANCH=servo BUG=chromium:1023715 TEST=Configured GPIO output to trigger on pvd_interrupt() and verified the interrupt fires during the following situations using Saleae analyzer: * USB Power removed from working device * Ramping supply voltage from 1.5V to 5V with a DC supply * Repoducing failure condition from crbug/1016051 1 Connect ServoMicro to Cyan board 2 dut-control power_state:on 3 dut-control fw_wp_vref:pp3300 4 dut-control power_state:off 5 GPIO toggles and system reset occurs Change-Id: I721f48ab84b01d52a5f98747cc9d879ff2876a07 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1911759 Reviewed-by: Ruben Rodriguez Buchillon <coconutruben@chromium.org> Tested-by: Brian Nemec <bnemec@chromium.org> Commit-Queue: Brian Nemec <bnemec@chromium.org> Auto-Submit: Brian Nemec <bnemec@chromium.org>
Diffstat (limited to 'chip/stm32')
-rw-r--r--chip/stm32/registers-stm32f0.h14
-rw-r--r--chip/stm32/registers.h1
-rw-r--r--chip/stm32/system.c36
3 files changed, 47 insertions, 4 deletions
diff --git a/chip/stm32/registers-stm32f0.h b/chip/stm32/registers-stm32f0.h
index 72d3cdb7a6..442edaed9a 100644
--- a/chip/stm32/registers-stm32f0.h
+++ b/chip/stm32/registers-stm32f0.h
@@ -277,6 +277,11 @@
/* --- Power / Reset / Clocks --- */
+#define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00)
+#define STM32_PWD_PVD_LS_MASK (0x07 << 5)
+#define STM32_PWD_PVD_LS(n) ((n & 0x07) << 5)
+#define STM32_PWR_PVDE BIT(4)
+
#define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04)
#define STM32_PWR_CSR_EWUP1 BIT(8)
@@ -382,8 +387,8 @@
#define RESET_CAUSE_OTHER 0xfe000000
#define RESET_CAUSE_RMVF 0x01000000
/* Power cause in PWR CSR register */
-#define STM32_PWR_RESET_CAUSE STM32_PWR_CSR
-#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CR
+#define STM32_PWR_RESET_CAUSE STM32_PWR_CSR
+#define STM32_PWR_RESET_CAUSE_CLR STM32_PWR_CR
#define RESET_CAUSE_SBF 0x00000002
#define RESET_CAUSE_SBF_CLR 0x00000004
@@ -528,8 +533,9 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_EXTI_SWIER REG32(STM32_EXTI_BASE + 0x10)
#define STM32_EXTI_PR REG32(STM32_EXTI_BASE + 0x14)
-#define EXTI_RTC_ALR_EVENT BIT(17)
-#define EXTI_COMP2_EVENT BIT(22)
+#define EXTI_PVD_EVENT BIT(16)
+#define EXTI_RTC_ALR_EVENT BIT(17)
+#define EXTI_COMP2_EVENT BIT(22)
/* --- ADC --- */
#define STM32_ADC_ISR REG32(STM32_ADC1_BASE + 0x00)
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 08b9d61e20..5926dda278 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -229,6 +229,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_PB1_USART3 BIT(18)
#define STM32_RCC_PB1_USART4 BIT(19)
#define STM32_RCC_PB1_USART5 BIT(20)
+#define STM32_RCC_PB1_PWREN BIT(28)
#define STM32_RCC_PB2_SPI1 BIT(12)
/* Reset causes definitions */
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index 0864b8bc9d..37e5d66b78 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -178,6 +178,38 @@ void chip_pre_init(void)
STM32_DBGMCU_APB2FZ |= apb2fz_reg;
}
+#ifdef CONFIG_PVD
+/* Configures the programmable voltage detector to monitor for brown out conditions. */
+static void configure_pvd(void)
+{
+ /* Clear Interrupt Enable Mask Register. */
+ STM32_EXTI_IMR &= ~EXTI_PVD_EVENT;
+
+ /* Clear Rising and Falling Trigger Selection Registers. */
+ STM32_EXTI_RTSR &= ~EXTI_PVD_EVENT;
+ STM32_EXTI_FTSR &= ~EXTI_PVD_EVENT;
+
+ /* Clear the value of the PVD Level Selection. */
+ STM32_PWR_CR &= ~STM32_PWD_PVD_LS_MASK;
+
+ /* Set the new value of the PVD Level Selection. */
+ STM32_PWR_CR |= STM32_PWD_PVD_LS(PVD_THRESHOLD);
+
+ /* Enable Power Clock. */
+ STM32_RCC_APB1ENR |= STM32_RCC_PB1_PWREN;
+
+ /* Configure the NVIC for PVD. */
+ task_enable_irq(STM32_IRQ_PVD);
+
+ /* Configure interrupt mode. */
+ STM32_EXTI_IMR |= EXTI_PVD_EVENT;
+ STM32_EXTI_RTSR |= EXTI_PVD_EVENT;
+
+ /* Enable the PVD Output. */
+ STM32_PWR_CR |= STM32_PWR_PVDE;
+}
+#endif
+
void system_pre_init(void)
{
#ifdef CONFIG_SOFTWARE_PANIC
@@ -256,6 +288,10 @@ void system_pre_init(void)
bkpdata_write(BKPDATA_INDEX_SAVED_PANIC_EXCEPTION, 0);
}
#endif
+
+#ifdef CONFIG_PVD
+ configure_pvd();
+#endif
}
void system_reset(int flags)