summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@google.com>2020-04-14 23:31:51 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-29 22:10:41 +0000
commit5a60b3b215125e8d2c145e17867fcfaaae682dcd (patch)
treefc720d5911d6c67ba177cf842cdcb3dbc2c5e4d9
parent57e170c71339961ea0d411e3ffa7c6d8e50c8ea3 (diff)
downloadchrome-ec-5a60b3b215125e8d2c145e17867fcfaaae682dcd.tar.gz
apply INT_AP_L extension on I2CS interface
This patch applies INT_AP_L extension on I2CS. It uses GPIO_MONITOR_I2CS_SDA to detect a transaction start during INT_AP_L assertion and to deassert INT_AP_L. BUG=b:148691139 TEST=None Signed-off-by: Namyoon Woo <namyoon@google.com> Change-Id: Iedd59b488dfdfaaf71dd71eda6437f1a9402d3c4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2150517 Tested-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Commit-Queue: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--board/cr50/gpio.inc15
-rw-r--r--common/i2cs_tpm.c37
-rw-r--r--include/i2c.h7
3 files changed, 46 insertions, 13 deletions
diff --git a/board/cr50/gpio.inc b/board/cr50/gpio.inc
index 47c35fb2d2..e527f7815b 100644
--- a/board/cr50/gpio.inc
+++ b/board/cr50/gpio.inc
@@ -110,6 +110,15 @@ GPIO_INT(DETECT_TPM_RST_L_ASSERTED, PIN(1, 4), GPIO_INT_FALLING,
tpm_rst_asserted)
/*
+ * A GPIO to sample the current state of the I2CS SDA line, allowing to detect
+ * the 'wedged I2C bus' condition.
+ *
+ * Also, it works to detect an I2C transaction during extended INT_AP_L
+ * assertion.
+ */
+GPIO_INT(MONITOR_I2CS_SDA, PIN(1, 6), GPIO_INT_LOW, i2cs_sda_isr)
+
+/*
* These GPIOs are to enable or disable EC-CR50 communication.
* NOTE: If these are changed, you must update the information in board.c
* and ec_comm.c
@@ -188,12 +197,6 @@ GPIO(STRAP_B1, PIN(1, 15), GPIO_INPUT)
GPIO(UNWEDGE_I2CS_SCL, PIN(1, 5), GPIO_OUT_HIGH)
/*
- * A GPIO to sample the current state of the I2CS SDA line, allowing to detect
- * the 'wedged I2C bus' condition.
- */
-GPIO(MONITOR_I2CS_SDA, PIN(1, 6), GPIO_INPUT)
-
-/*
* If you change the names of EN_PP3300_INA_L, I2C_SCL_INA, or I2C_SDA_INA,
* you also need to update the usage in closed_source_set1.c
*/
diff --git a/common/i2cs_tpm.c b/common/i2cs_tpm.c
index cb893cf84f..d76befcbee 100644
--- a/common/i2cs_tpm.c
+++ b/common/i2cs_tpm.c
@@ -84,6 +84,8 @@ static uint32_t i2cs_fifo_adjust_count;
/* Used to track number of write mismatch errors */
static uint32_t i2cs_write_error_count;
+static bool int_ap_extension_enabled_;
+
static void process_read_access(uint16_t reg_size,
uint16_t tpm_reg, uint8_t *data)
{
@@ -202,6 +204,11 @@ static void wr_complete_handler(void *i2cs_data, size_t i2cs_data_size)
process_write_access(reg_size, tpm_reg,
data, i2cs_data_size);
+ if (assert_int_ap()) {
+ gpio_enable_interrupt(GPIO_MONITOR_I2CS_SDA);
+ return;
+ }
+
/*
* Since cr50 does not provide i2c clock stretching, we need some
* onther means of flow controlling the host. Let's generate a pulse
@@ -209,20 +216,23 @@ static void wr_complete_handler(void *i2cs_data, size_t i2cs_data_size)
*/
gpio_set_level(GPIO_INT_AP_L, 0);
- /*
- * This is to meet the AP requirement of minimum 4 usec
- * duration of INT_AP_L assertion.
- *
- * TODO(b/130515803): Ideally, this should be improved
- * to support any duration requirement in future.
- */
tick_delay(2);
gpio_set_level(GPIO_INT_AP_L, 1);
}
+void i2cs_sda_isr(enum gpio_signal signal)
+{
+ gpio_disable_interrupt(GPIO_MONITOR_I2CS_SDA);
+
+ deassert_int_ap();
+}
+
static void i2cs_if_stop(void)
{
+ if (int_ap_extension_enabled_)
+ int_ap_extension_stop_pulse();
+
i2cs_register_write_complete_handler(NULL);
}
@@ -231,6 +241,12 @@ static void i2cs_if_start(void)
i2cs_register_write_complete_handler(wr_complete_handler);
}
+/* Function that sets up for I2CS to enable INT_AP_L extension. */
+static void i2cs_int_ap_extension_enable_(void)
+{
+ int_ap_extension_enabled_ = true;
+}
+
static void i2cs_if_register(void)
{
if (!board_tpm_uses_i2c())
@@ -239,6 +255,13 @@ static void i2cs_if_register(void)
tpm_register_interface(i2cs_if_start, i2cs_if_stop);
i2cs_fifo_adjust_count = 0;
i2cs_write_error_count = 0;
+
+ int_ap_register(i2cs_int_ap_extension_enable_);
+
+ /*
+ * TODO: if TPM_BOARD_CFG has INT_AP extension enabled, then call
+ * int_ap_extension_enable(), and set int_ap_extension_enabled_ true.
+ */
}
DECLARE_HOOK(HOOK_INIT, i2cs_if_register, HOOK_PRIO_LAST);
diff --git a/include/i2c.h b/include/i2c.h
index 4be5472a11..c3fab8a723 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -519,4 +519,11 @@ void i2c_end_xfer_notify(const int port,
void i2c_trace_notify(int port, uint16_t slave_addr_flags,
int direction, const uint8_t *data, size_t size);
+/*
+ * Interrupt handler of GPIO_MONITOR_I2CS_SDA.
+ * Its role is to detect any transaction start during INT_AP_L
+ * assertion and to deassert INT_AP_L.
+ */
+void i2cs_sda_isr(enum gpio_signal signal);
+
#endif /* __CROS_EC_I2C_H */