summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2018-04-02 14:36:11 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-04-17 18:44:38 +0000
commitea06fe340b849a047165faae1ff974e44e4198d8 (patch)
tree67de4b48e90452c07b25eadb690e81a44048fcd4
parent5a6cef6a9311d827ddd49a3729d5870a0a24d8ba (diff)
downloadchrome-ec-ea06fe340b849a047165faae1ff974e44e4198d8.tar.gz
cr50: add support for enabling terminations on ap suspend
rk3399 systems need terminations on the SPI signals in S3 and all other low power states. Add support for enabling the pulldowns and pullups on the correct pins. With this change, if BOARD_NEEDS_S3_TERM is set in the board properties, cr50 will enable a pulldown on the AP TX Cr50 RX signal and a pulldown on all of the SPS signals. To keep the pulldowns from interfering with the sps peripheral, s3_term will also disable the input for those signals. BUG=b:62200096 BRANCH=cr50 TEST=Flash onto bob. Make sure cr50 enables and disables terminations when the AP suspends/resumes. Flash onto reef. Make sure it doesn't do anything. Change-Id: I4adaf6d66160bab1eb3cf3d343d4a79524ccf883 Signed-off-by: Mary Ruthven <mruthven@google.com> Reviewed-on: https://chromium-review.googlesource.com/991338 Commit-Ready: Mary Ruthven <mruthven@chromium.org> Tested-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit cfcac78e626ce08ccc1c45c91c61127b6088e80f) Reviewed-on: https://chromium-review.googlesource.com/1015618 Tested-by: Vadim Bendebury <vbendeb@chromium.org> Commit-Queue: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/ap_uart_state.c6
-rw-r--r--board/cr50/board.c5
-rw-r--r--board/cr50/board.h4
-rw-r--r--board/cr50/build.mk1
-rw-r--r--board/cr50/rdd.c16
-rw-r--r--board/cr50/s3_term.c88
-rw-r--r--board/cr50/scratch_reg1.h5
7 files changed, 124 insertions, 1 deletions
diff --git a/board/cr50/ap_uart_state.c b/board/cr50/ap_uart_state.c
index 42e2feeab4..c21e8b518c 100644
--- a/board/cr50/ap_uart_state.c
+++ b/board/cr50/ap_uart_state.c
@@ -21,6 +21,12 @@ void print_ap_uart_state(void)
ccprintf("AP UART: %s\n", device_state_name(state));
}
+int ap_is_suspended(void)
+{
+ /* When the AP uart is off, that means the device is suspended. */
+ return state == DEVICE_STATE_OFF;
+}
+
int ap_uart_is_on(void)
{
/* Debouncing and on are both still on */
diff --git a/board/cr50/board.c b/board/cr50/board.c
index 3a3eaf6d5a..b01b3571a3 100644
--- a/board/cr50/board.c
+++ b/board/cr50/board.c
@@ -149,6 +149,11 @@ int board_rst_pullup_needed(void)
return !!(board_properties & BOARD_NEEDS_SYS_RST_PULL_UP);
}
+int board_needs_s3_term(void)
+{
+ return !!(board_properties & BOARD_NEEDS_S3_TERM);
+}
+
int board_tpm_uses_i2c(void)
{
return !!(board_properties & BOARD_SLAVE_CONFIG_I2C);
diff --git a/board/cr50/board.h b/board/cr50/board.h
index c87cd3e651..75f25cc533 100644
--- a/board/cr50/board.h
+++ b/board/cr50/board.h
@@ -262,6 +262,9 @@ int board_tpm_uses_spi(void);
int board_id_is_mismatched(void);
/* Allow for deep sleep to be enabled on AP shutdown */
int board_deep_sleep_allowed(void);
+int board_needs_s3_term(void);
+int board_s3_term_is_enabled(void);
+void board_s3_term(int enable);
void power_button_record(void);
@@ -282,6 +285,7 @@ void print_servo_state(void);
int ap_is_on(void);
int ap_uart_is_on(void);
+int ap_is_suspended(void);
int ec_is_on(void);
int ec_is_rx_allowed(void);
int servo_is_connected(void);
diff --git a/board/cr50/build.mk b/board/cr50/build.mk
index 049e29eafc..c245920bcd 100644
--- a/board/cr50/build.mk
+++ b/board/cr50/build.mk
@@ -39,6 +39,7 @@ board-${CONFIG_RDD} += rdd.o
board-${CONFIG_USB_SPI} += usb_spi.o
board-${CONFIG_USB_I2C} += usb_i2c.o
board-y += recovery_button.o
+board-y += s3_term.o
board-y += tpm2/NVMem.o
board-y += tpm2/aes.o
board-y += tpm2/ecc.o
diff --git a/board/cr50/rdd.c b/board/cr50/rdd.c
index d59ca7d803..15173ba70a 100644
--- a/board/cr50/rdd.c
+++ b/board/cr50/rdd.c
@@ -145,6 +145,9 @@ enum ccd_state_flag {
/* SPI port is enabled for AP and/or EC flash */
CCD_ENABLE_SPI = (1 << 6),
+
+ /* S3 Terminations are enabled */
+ CCD_ENABLE_S3_TERM = (1 << 7),
};
int console_is_restricted(void)
@@ -179,6 +182,9 @@ static uint32_t get_state_flags(void)
if (ccd_usb_spi.state->enabled_device)
flags_now |= CCD_ENABLE_SPI;
+ if (board_s3_term_is_enabled())
+ flags_now |= CCD_ENABLE_S3_TERM;
+
return flags_now;
}
@@ -204,6 +210,8 @@ static void print_state_flags(enum console_channel channel, uint32_t flags)
cprintf(channel, " I2C");
if (flags & CCD_ENABLE_SPI)
cprintf(channel, " SPI");
+ if (flags & CCD_ENABLE_S3_TERM)
+ cprintf(channel, " S3_TERM");
}
static void ccd_state_change_hook(void)
@@ -242,6 +250,10 @@ static void ccd_state_change_hook(void)
CCD_ENABLE_UART_EC_BITBANG | CCD_ENABLE_I2C |
CCD_ENABLE_SPI);
+ /* Enable S3 Terminations */
+ if (ap_is_suspended() && board_needs_s3_term())
+ flags_want |= CCD_ENABLE_S3_TERM;
+
/* Disable based on capabilities */
if (!ccd_is_cap_enabled(CCD_CAP_GSC_RX_AP_TX))
flags_want &= ~CCD_ENABLE_UART_AP;
@@ -305,6 +317,8 @@ static void ccd_state_change_hook(void)
usb_i2c_board_disable();
if (delta & CCD_ENABLE_SPI)
usb_spi_enable(&ccd_usb_spi, 0);
+ if (delta & CCD_ENABLE_S3_TERM)
+ board_s3_term(0);
/* Handle turning things on */
delta = flags_want & ~flags_now;
@@ -324,6 +338,8 @@ static void ccd_state_change_hook(void)
usb_i2c_board_enable();
if (delta & CCD_ENABLE_SPI)
usb_spi_enable(&ccd_usb_spi, 1);
+ if (delta & CCD_ENABLE_S3_TERM)
+ board_s3_term(1);
}
DECLARE_DEFERRED(ccd_state_change_hook);
diff --git a/board/cr50/s3_term.c b/board/cr50/s3_term.c
new file mode 100644
index 0000000000..bb486d207e
--- /dev/null
+++ b/board/cr50/s3_term.c
@@ -0,0 +1,88 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "console.h"
+#include "registers.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
+
+#define AP_TX_TERM (1 << 0)
+#define SPS_TERM (1 << 1)
+
+int term_enabled;
+
+static void update_term_state(int term, int enable)
+{
+ if (enable)
+ term_enabled |= term;
+ else
+ term_enabled &= ~term;
+}
+
+int board_s3_term_is_enabled(void)
+{
+ return term_enabled;
+}
+
+static void ap_tx_term_enable(int term_enable)
+{
+ /* Add a pulldown to AP TX Cr50 RX */
+ GWRITE_FIELD(PINMUX, DIOA3_CTL, PD, term_enable);
+ update_term_state(AP_TX_TERM, term_enable);
+}
+
+static void sps_enable_pd(int term_enable)
+{
+ GWRITE_FIELD(PINMUX, DIOA2_CTL, PD, term_enable); /* SPS_MOSI */
+ GWRITE_FIELD(PINMUX, DIOA6_CTL, PD, term_enable); /* SPS_CLK */
+ GWRITE_FIELD(PINMUX, DIOA10_CTL, PD, term_enable); /* SPS_MISO */
+ GWRITE_FIELD(PINMUX, DIOA12_CTL, PD, term_enable); /* SPS_CS_L */
+}
+
+static void sps_enable_inputs(int input_enable)
+{
+ GWRITE_FIELD(PINMUX, DIOA2_CTL, IE, input_enable); /* SPS_MOSI */
+ GWRITE_FIELD(PINMUX, DIOA6_CTL, IE, input_enable); /* SPS_CLK */
+ GWRITE_FIELD(PINMUX, DIOA10_CTL, IE, 0); /* SPS_MISO */
+ GWRITE_FIELD(PINMUX, DIOA12_CTL, IE, input_enable); /* SPS_CS_L */
+}
+
+static void sps_term_enable(int term_enable)
+{
+ /* Disable the sps inputs before enabling the pulldowns */
+ if (!term_enable)
+ sps_enable_inputs(!term_enable);
+
+ /* Control the pulldowns on the SPS signals */
+ sps_enable_pd(term_enable);
+
+ /* Reenable the sps inputs after enabling the pulldowns */
+ if (term_enable)
+ sps_enable_inputs(!term_enable);
+ update_term_state(SPS_TERM, term_enable);
+}
+
+void board_s3_term(int term_enable)
+{
+ if (!board_needs_s3_term() || (!term_enable == !term_enabled))
+ return;
+ CPRINTS("%sable S3 signal terminations", term_enable ? "En" : "Dis");
+
+ ap_tx_term_enable(term_enable);
+
+ if (!board_tpm_uses_i2c())
+ sps_term_enable(term_enable);
+}
+
+static int command_s3term(int argc, char **argv)
+{
+ ccprintf("Terminations:%s%s\n",
+ term_enabled & AP_TX_TERM ? " AP" : "",
+ term_enabled & SPS_TERM ? " SPS" : "");
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(s3term, command_s3term, "",
+ "Get the state of the S3 termination signals");
diff --git a/board/cr50/scratch_reg1.h b/board/cr50/scratch_reg1.h
index 4462212941..8802a9f5c5 100644
--- a/board/cr50/scratch_reg1.h
+++ b/board/cr50/scratch_reg1.h
@@ -49,12 +49,15 @@
#define BOARD_DEEP_SLEEP_DISABLED (1 << 13)
/* Use Cr50_RX_AP_TX to determine if the AP is off or on */
#define BOARD_DETECT_AP_WITH_UART (1 << 14)
+/* Add terminations to signals in S3 */
+#define BOARD_NEEDS_S3_TERM (1 << 15)
/*
* Macro to capture all properties related to board strapping pins. This must be
* updated if additional strap related properties are added.
*/
#define BOARD_ALL_PROPERTIES (BOARD_SLAVE_CONFIG_SPI | BOARD_SLAVE_CONFIG_I2C \
| BOARD_NEEDS_SYS_RST_PULL_UP | BOARD_USE_PLT_RESET | \
- BOARD_DEEP_SLEEP_DISABLED | BOARD_DETECT_AP_WITH_UART)
+ BOARD_DEEP_SLEEP_DISABLED | BOARD_DETECT_AP_WITH_UART | \
+ BOARD_NEEDS_S3_TERM)
#endif /* ! __EC_BOARD_CR50_SCRATCH_REG1_H */