summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-05-14 14:16:44 -0700
committerKatie Roberts-Hoffman <katierh@chromium.org>2013-05-22 16:21:40 -0700
commit1a6a26811c7de5e70c53f5d4fe9bcf610594fc90 (patch)
tree3893caa64a849c5a7569ca0042ddb36bc4c233c7
parent5428f32cf975b71e400c629ef3f1867051bb5f88 (diff)
downloadchrome-ec-1a6a26811c7de5e70c53f5d4fe9bcf610594fc90.tar.gz
Set SPI lines to inputs when AP is off
When AP is off, turn off pullup on NSS, and set MISO to an input so the SPI module won't drive it high if the last sent bit was a 1. This reduces leakage when the AP is off. This patch also fixes a bug where gpio_set_alternate_function() set the wrong pins to normal-mode when func=-1; that didn't hit anything else because that functionality wasn't used on STM32 until now. BUG=chrome-os-partner:19304 BRANCH=none TEST=boot pit On EC console, with AP on, 'rw 0x40020000' returns read 0x40020000 = 0x6569aa20 <- must have 0x____aa__ Then 'apshutdown' and 'rw 0x40020000' returns read 0x40020000 = 0x65690020 <- must have 0x____00__ The 'power on' and AP turns back on. At u-boot prompt, 'sspi 2:0 256 9f00000000' returns FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEEC010001 (some number of 0xFD's followed by FEEC...) This shows SPI functionality is restored when AP is powered back on, and not just at init time. Change-Id: Ia3cd3e0bc222dc663d635509918fa3d383fd7971 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/51182 Reviewed-by: Simon Glass <sjg@chromium.org> (cherry picked from commit 3c2c1398ec993cc597903a4d4ba38546182b7053) Reviewed-on: https://gerrit.chromium.org/gerrit/56319 Commit-Queue: Katie Roberts-Hoffman <katierh@chromium.org> Reviewed-by: Katie Roberts-Hoffman <katierh@chromium.org> Tested-by: Katie Roberts-Hoffman <katierh@chromium.org>
-rw-r--r--board/pit/board.c7
-rw-r--r--chip/stm32/gpio-stm32l15x.c2
-rw-r--r--chip/stm32/spi.c37
3 files changed, 36 insertions, 10 deletions
diff --git a/board/pit/board.c b/board/pit/board.c
index e4b8eef624..7bd796f207 100644
--- a/board/pit/board.c
+++ b/board/pit/board.c
@@ -97,13 +97,6 @@ void board_config_post_gpio_init(void)
/* TIM2_CH2 on PB3 */
gpio_set_alternate_function(GPIO_B, (1 << 3), GPIO_ALT_TIM2);
-
- /* SPI1 on pins PA4-7 */
- gpio_set_alternate_function(GPIO_A,
- (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7),
- GPIO_ALT_SPI);
- /* 40 MHz pin speed */
- STM32_GPIO_OSPEEDR(GPIO_A) |= 0xff00;
}
#ifdef CONFIG_PMU_BOARD_INIT
diff --git a/chip/stm32/gpio-stm32l15x.c b/chip/stm32/gpio-stm32l15x.c
index 016161c5c2..8f7a0fc5f0 100644
--- a/chip/stm32/gpio-stm32l15x.c
+++ b/chip/stm32/gpio-stm32l15x.c
@@ -137,7 +137,7 @@ void gpio_set_alternate_function(int port, int mask, int func)
/* Return to normal GPIO function, defaulting to input. */
while (mask) {
bit = 31 - __builtin_clz(mask);
- moder &= ~(0x3 << (bit * 2 + 16));
+ moder &= ~(0x3 << (bit * 2));
mask &= ~(1 << bit);
}
STM32_GPIO_MODER(port) = moder;
diff --git a/chip/stm32/spi.c b/chip/stm32/spi.c
index ac844f198d..f488eee801 100644
--- a/chip/stm32/spi.c
+++ b/chip/stm32/spi.c
@@ -83,6 +83,7 @@ enum {
static uint8_t out_msg[EC_HOST_PARAM_SIZE + SPI_MSG_PROTO_LEN];
static uint8_t in_msg[EC_HOST_PARAM_SIZE + SPI_MSG_PROTO_LEN];
static uint8_t active;
+static uint8_t enabled;
static struct host_cmd_handler_args args;
/**
@@ -261,6 +262,10 @@ void spi_event(enum gpio_signal signal)
uint16_t *nss_reg;
uint32_t nss_mask;
+ /* If not enabled, ignore glitches on NSS */
+ if (!enabled)
+ return;
+
/*
* If NSS is rising, we have finished the transaction, so prepare
* for the next.
@@ -316,6 +321,9 @@ static void spi_init(void)
{
stm32_spi_regs_t *spi = STM32_SPI1_REGS;
+ /* 40 MHz pin speed */
+ STM32_GPIO_OSPEEDR(GPIO_A) |= 0xff00;
+
/* Enable clocks to SPI1 module */
STM32_RCC_APB2ENR |= 1 << 12;
@@ -325,8 +333,33 @@ static void spi_init(void)
/* Enable the SPI peripheral */
spi->ctrl1 |= CR1_SPE;
- setup_for_transaction();
-
gpio_enable_interrupt(GPIO_SPI1_NSS);
}
DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_DEFAULT);
+
+static void spi_chipset_startup(void)
+{
+ /* Enable pullup and interrupts on NSS */
+ gpio_set_flags(GPIO_SPI1_NSS, GPIO_INT_BOTH | GPIO_PULL_UP);
+
+ /* Set SPI pins to alternate function */
+ gpio_set_alternate_function(GPIO_A, 0xf0, GPIO_ALT_SPI);
+
+ /* Set up for next transaction */
+ setup_for_transaction();
+
+ enabled = 1;
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, spi_chipset_startup, HOOK_PRIO_DEFAULT);
+
+static void spi_chipset_shutdown(void)
+{
+ enabled = active = 0;
+
+ /* Disable pullup and interrupts on NSS */
+ gpio_set_flags(GPIO_SPI1_NSS, 0);
+
+ /* Set SPI pins to inputs so we don't leak power when AP is off */
+ gpio_set_alternate_function(GPIO_A, 0xf0, -1);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, spi_chipset_shutdown, HOOK_PRIO_DEFAULT);