summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Hesling <hesling@chromium.org>2019-10-31 16:56:07 -0700
committerCommit Bot <commit-bot@chromium.org>2019-11-08 22:58:57 +0000
commitecde5dcec0745c56b90d27f307e3504fff20c6ef (patch)
treea23db65ffae4aa0586956f123aa8047cc8b6b172
parent69bbeb8af0a300aef51e70e31f1c2c102bc501f6 (diff)
downloadchrome-ec-ecde5dcec0745c56b90d27f307e3504fff20c6ef.tar.gz
stm32f4: Enable gpio port clocks that are used
We can reduce the power draw of the MCU by limiting which GPIO port clocks are enabled. This CL uses the gpio.inc to determine the minimal set of GPIO ports that need to be enabled/clocked. Only these ports have their clocks enabled at boot. Other stm32 chip variants in EC simply enabled all GPIO port clocks at boot init. Thank you to Ravi Chandra Sadineni for identifying this optimization and validating. For more context, see crrev.com/c/1888116, which this CL replaces. BRANCH=nocturne,hatch BUG=b:130561737 TEST=make buildall -j TEST=make BOARD=bloonchipper # Connect dragonclaw dev board over servo micro sudo servod --board=bloonchipper --config bloonchipper_rev0.1.xml & ./util/flash_ec --board=bloonchipper minicom -D $(dut-control raw_fpmcu_uart_pty | cut -d: -f2) > sysinfo # Check that we are in RW Signed-off-by: Craig Hesling <hesling@chromium.org> Change-Id: Iad51b11eb5959b5d502320560b9ebda7e614d97e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1890924 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--chip/stm32/gpio-stm32f4.c27
-rw-r--r--chip/stm32/gpio_chip.h6
-rw-r--r--chip/stm32/registers-stm32f4.h9
-rw-r--r--chip/stm32/system.c14
4 files changed, 49 insertions, 7 deletions
diff --git a/chip/stm32/gpio-stm32f4.c b/chip/stm32/gpio-stm32f4.c
index 3d4e5ddde1..4a4e095a71 100644
--- a/chip/stm32/gpio-stm32f4.c
+++ b/chip/stm32/gpio-stm32f4.c
@@ -13,15 +13,30 @@
#include "task.h"
#include "util.h"
-void gpio_enable_clocks(void)
+int gpio_required_clocks(void)
{
+ const int gpio_ports_used = (0
+# define GPIO(name, pin, flags) pin
+# define GPIO_INT(name, pin, flags, signal) pin
+# define ALTERNATE(pinmask, function, module, flagz) pinmask
+# define PIN(port, index) | STM32_RCC_AHB1ENR_GPIO_PORT ## port
+# define PIN_MASK(port, mask) PIN(port, 0)
+# include "gpio.wrap"
+ );
+
/*
- * Enable all GPIOs clocks
- *
- * TODO(crosbug.com/p/23770): only enable the banks we need to,
- * and support disabling some of them in low-power idle.
+ * If no ports are in use, then system_is_reboot_warm
+ * may not be valid.
*/
- STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_GPIOMASK;
+ ASSERT(gpio_ports_used);
+
+ return gpio_ports_used;
+}
+
+void gpio_enable_clocks(void)
+{
+ /* Enable only ports that are referenced in the gpio.inc */
+ STM32_RCC_AHB1ENR |= gpio_required_clocks();
/* Delay 1 AHB clock cycle after the clock is enabled */
clock_wait_bus_cycles(BUS_AHB, 1);
diff --git a/chip/stm32/gpio_chip.h b/chip/stm32/gpio_chip.h
index ec9da96e14..a5b642fb05 100644
--- a/chip/stm32/gpio_chip.h
+++ b/chip/stm32/gpio_chip.h
@@ -13,4 +13,10 @@
*/
void gpio_enable_clocks(void);
+/**
+ * Return gpio port clocks that are necessary to support
+ * the pins in gpio.inc.
+ */
+int gpio_required_clocks(void);
+
#endif /* __CROS_EC_CHIP_STM32_GPIO_CHIP_H */
diff --git a/chip/stm32/registers-stm32f4.h b/chip/stm32/registers-stm32f4.h
index aef2f87f6f..452737254a 100644
--- a/chip/stm32/registers-stm32f4.h
+++ b/chip/stm32/registers-stm32f4.h
@@ -521,10 +521,19 @@
#define STM32_RCC_APB2RSTR REG32(STM32_RCC_BASE + 0x24)
#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x30)
+#define STM32_RCC_AHB1ENR_GPIO_PORTA BIT(0)
+#define STM32_RCC_AHB1ENR_GPIO_PORTB BIT(1)
+#define STM32_RCC_AHB1ENR_GPIO_PORTC BIT(2)
+#define STM32_RCC_AHB1ENR_GPIO_PORTD BIT(3)
+#define STM32_RCC_AHB1ENR_GPIO_PORTE BIT(4)
+#define STM32_RCC_AHB1ENR_GPIO_PORTF BIT(5)
+#define STM32_RCC_AHB1ENR_GPIO_PORTG BIT(6)
+#define STM32_RCC_AHB1ENR_GPIO_PORTH BIT(7)
#define STM32_RCC_AHB1ENR_GPIOMASK (0xff << 0)
#define STM32_RCC_AHB1ENR_BKPSRAMEN BIT(18)
#define STM32_RCC_AHB1ENR_DMA1EN BIT(21)
#define STM32_RCC_AHB1ENR_DMA2EN BIT(22)
+
/* TODO(nsanders): normalize naming.*/
#define STM32_RCC_HB1_DMA1 BIT(21)
#define STM32_RCC_HB1_DMA2 BIT(22)
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index ddba03958a..58b77fba92 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -9,6 +9,7 @@
#include "console.h"
#include "cpu.h"
#include "flash.h"
+#include "gpio_chip.h"
#include "host_command.h"
#include "registers.h"
#include "panic.h"
@@ -567,6 +568,17 @@ int system_set_bbram(enum system_bbram_idx idx, uint8_t value)
int system_is_reboot_warm(void)
{
+ /*
+ * Detecting if the system is warm is relevant for a
+ * few reasons.
+ * One such reason is that some firmwares transition from
+ * RO to RW images. When this happens, we may not need to
+ * restart certain clocks. On the flip side, we may need
+ * to restart the clocks if the RW requires a different
+ * set of clocks. Thus, the clock configurations need to
+ * be checked for a perfect match.
+ */
+
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
return ((STM32_RCC_AHBENR & 0x7e0000) == 0x7e0000);
#elif defined(CHIP_FAMILY_STM32L)
@@ -576,7 +588,7 @@ int system_is_reboot_warm(void)
== STM32_RCC_AHB2ENR_GPIOMASK);
#elif defined(CHIP_FAMILY_STM32F4)
return ((STM32_RCC_AHB1ENR & STM32_RCC_AHB1ENR_GPIOMASK)
- == STM32_RCC_AHB1ENR_GPIOMASK);
+ == gpio_required_clocks());
#elif defined(CHIP_FAMILY_STM32H7)
return ((STM32_RCC_AHB4ENR & STM32_RCC_AHB4ENR_GPIOMASK)
== STM32_RCC_AHB4ENR_GPIOMASK);