diff options
author | Namyoon Woo <namyoon@google.com> | 2020-04-14 23:31:51 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-29 22:10:41 +0000 |
commit | 5a60b3b215125e8d2c145e17867fcfaaae682dcd (patch) | |
tree | fc720d5911d6c67ba177cf842cdcb3dbc2c5e4d9 | |
parent | 57e170c71339961ea0d411e3ffa7c6d8e50c8ea3 (diff) | |
download | chrome-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.inc | 15 | ||||
-rw-r--r-- | common/i2cs_tpm.c | 37 | ||||
-rw-r--r-- | include/i2c.h | 7 |
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 */ |