diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2021-07-26 13:04:02 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-07-27 02:50:25 +0000 |
commit | 6653cb0f1f6cb504ba6c4221a0d39eb3145e9b5b (patch) | |
tree | c6739253d0573164e1788c344686ae451d3b73ad | |
parent | 9e0226bf02e94efd042b77ea6008ee9bfb08ed6f (diff) | |
download | chrome-ec-6653cb0f1f6cb504ba6c4221a0d39eb3145e9b5b.tar.gz |
zephyr: it8xxx2: shi: disable CPU FIFO access at transaction end
AP will de-assert CS to stop a SPI transaction due to timeout (1 second)
of waiting for a valid packet response from the EC.
Under the above condition, EC should ensure its SPI module is back at
the state where Rx FIFO is ready to clock in data from AP. So EC will
be ready to handle next transaction from AP.
BRANCH=none
BUG=b:192564057
TEST=Slow down host command task to hit the timeout. EC still can handle
next transaction correctly.
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Change-Id: I1401175fe329dbba9730848f0eccdd722dcf136b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3053136
Reviewed-by: Tim2 Lin <tim2.lin@ite.corp-partner.google.com>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
-rw-r--r-- | zephyr/drivers/cros_shi/cros_shi_it8xxx2.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c index ba2bb9ba5e..49184cb6fd 100644 --- a/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c +++ b/zephyr/drivers/cros_shi/cros_shi_it8xxx2.c @@ -106,25 +106,36 @@ static void spi_bad_received_data(int count) static void spi_response_host_data(uint8_t *out_msg_addr, int tx_size) { - /* Tx FIFO reset and count monitor reset */ - IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR; - /* CPU Tx FIFO1 and FIFO2 access */ - IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA; - - for (int i = 0; i < tx_size; i += 4) { - /* Write response data from out_msg buffer to Tx FIFO */ - IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i); - } - /* - * After writing data to Tx FIFO is finished, this bit will - * be to indicate the SPI slave controller. + * Protect sequence of filling response packet for host. + * This will ensure CPU access FIFO is disabled at SPI end interrupt no + * matter the interrupt is triggered before or after the sequence. */ - IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS; - /* End Tx FIFO access */ - IT83XX_SPI_TXRXFAR = 0; - /* SPI slave read Tx FIFO */ - IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF; + unsigned int key = irq_lock(); + + if (shi_state == SPI_STATE_PROCESSING) { + /* Tx FIFO reset and count monitor reset */ + IT83XX_SPI_TXFCR = IT83XX_SPI_TXFR | IT83XX_SPI_TXFCMR; + /* CPU Tx FIFO1 and FIFO2 access */ + IT83XX_SPI_TXRXFAR = IT83XX_SPI_CPUTFA; + + for (int i = 0; i < tx_size; i += 4) { + /* Write response data from out_msg buffer to Tx FIFO */ + IT83XX_SPI_CPUWTFDB0 = *(uint32_t *)(out_msg_addr + i); + } + + /* + * After writing data to Tx FIFO is finished, this bit will + * be to indicate the SPI slave controller. + */ + IT83XX_SPI_TXFCR = IT83XX_SPI_TXFS; + /* End Tx FIFO access */ + IT83XX_SPI_TXRXFAR = 0; + /* SPI slave read Tx FIFO */ + IT83XX_SPI_FCR = IT83XX_SPI_SPISRTXF; + } + + irq_unlock(key); } /* @@ -214,9 +225,6 @@ static void spi_parse_header(void) spi_packet.response_size = 0; spi_packet.driver_result = EC_RES_SUCCESS; - /* Move to processing state */ - spi_set_state(SPI_STATE_PROCESSING); - /* Go to common-layer to handle request */ host_packet_receive(&spi_packet); } else { @@ -235,6 +243,8 @@ static void shi_ite_int_handler(const void *arg) * EC responded data, then AP ended the transaction. */ if (IT83XX_SPI_ISR & IT83XX_SPI_ENDDETECTINT) { + /* Disable CPU access Rx FIFO to clock in data from AP again */ + IT83XX_SPI_TXRXFAR = 0; /* Ready to receive */ spi_set_state(SPI_STATE_READY_TO_RECV); /* @@ -255,10 +265,11 @@ static void shi_ite_int_handler(const void *arg) if (IT83XX_SPI_RX_VLISR & IT83XX_SPI_RVLI) { /* write clear slave status */ IT83XX_SPI_RX_VLISR = IT83XX_SPI_RVLI; + /* Move to processing state */ + spi_set_state(SPI_STATE_PROCESSING); /* Parse header for version of spi-protocol */ spi_parse_header(); } - } void spi_event(enum gpio_signal signal) |