diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2015-07-24 17:08:19 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-13 23:34:05 +0000 |
commit | 36ed861be833df5751c668fdc1b47fb00e3ebada (patch) | |
tree | b2c276900e100a9e9f528186d7bc87f9600e752a | |
parent | df2e760a93885c01bc86d6e5a7099b00df4c824b (diff) | |
download | chrome-ec-36ed861be833df5751c668fdc1b47fb00e3ebada.tar.gz |
cr50: sps: allow receive registration function set FIFO threshold
The default receive FIFO threshold of 8 (meaning that 9 bytes need to
be received before receive IRQ fires) is good for high volume
transfers, when the amount of transferred data greatly exceeds the
threshold.
But in case of TPM transactions, which start with a 4 byte header and
then stall while the device processes it, the default threshold
guarantees delays on every transaction, as the receiver does not start
processing the header until 5 idle bytes are transferred to bring the
total number to nine.
The suggested solution is to allow to specify the receive FIFO
interrupt request threshold at run time, by adding this value to the
receive function registration API.
BRANCH=none
BUG=chrome-os-partner:43025
TEST=verified that spstest still works fine.
Change-Id: I92517205a7d0d47893b702efa188eb524fb18a49
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/289331
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | chip/g/sps.c | 15 | ||||
-rw-r--r-- | chip/g/sps.h | 6 | ||||
-rw-r--r-- | chip/g/sps_hc.c | 2 | ||||
-rw-r--r-- | chip/g/sps_tpm.c | 6 |
4 files changed, 21 insertions, 8 deletions
diff --git a/chip/g/sps.c b/chip/g/sps.c index 92b4acf1e4..100f73c904 100644 --- a/chip/g/sps.c +++ b/chip/g/sps.c @@ -165,7 +165,8 @@ int sps_transmit(uint8_t *data, size_t data_size) * @param mode Clock polarity and phase mode (0 - 3) * */ -static void sps_configure(enum sps_mode mode, enum spi_clock_mode clk_mode) +static void sps_configure(enum sps_mode mode, enum spi_clock_mode clk_mode, + unsigned rx_fifo_threshold) { /* Disable All Interrupts */ GREG32(SPS, ICTRL) = 0; @@ -191,7 +192,7 @@ static void sps_configure(enum sps_mode mode, enum spi_clock_mode clk_mode) /* Do not enable TX FIFO until we have something to send. */ GWRITE_FIELD(SPS, FIFO_CTRL, RXFIFO_EN, 1); - GREG32(SPS, RXFIFO_THRESHOLD) = 8; + GREG32(SPS, RXFIFO_THRESHOLD) = rx_fifo_threshold; GWRITE_FIELD(SPS, ICTRL, RXFIFO_LVL, 1); @@ -206,13 +207,17 @@ static void sps_configure(enum sps_mode mode, enum spi_clock_mode clk_mode) */ static rx_handler_f sps_rx_handler; -int sps_register_rx_handler(enum sps_mode mode, rx_handler_f rx_handler) +int sps_register_rx_handler(enum sps_mode mode, rx_handler_f rx_handler, + unsigned rx_fifo_threshold) { if (sps_rx_handler) return -1; + if (!rx_fifo_threshold) + rx_fifo_threshold = 8; /* This is a sensible default. */ sps_rx_handler = rx_handler; - sps_configure(mode, SPI_CLOCK_MODE0); + + sps_configure(mode, SPI_CLOCK_MODE0, rx_fifo_threshold); task_enable_irq(GC_IRQNUM_SPS0_RXFIFO_LVL_INTR); task_enable_irq(GC_IRQNUM_SPS0_CS_DEASSERT_INTR); @@ -436,7 +441,7 @@ static int command_sps(int argc, char **argv) sps_tx_status(GC_SPS_DUMMY_WORD_DEFAULT); rx_state = spstrx_not_started; - sps_register_rx_handler(SPS_GENERIC_MODE, sps_receive_callback); + sps_register_rx_handler(SPS_GENERIC_MODE, sps_receive_callback, 0); if (argc > 1) { target = strtoi(argv[1], &e, 10); diff --git a/chip/g/sps.h b/chip/g/sps.h index 83505909f1..f7889b82bd 100644 --- a/chip/g/sps.h +++ b/chip/g/sps.h @@ -42,8 +42,12 @@ int sps_transmit(uint8_t *data, size_t data_size); * These functions return zero on success or non-zero on failure (attempt to * register a callback on top of existing one, or attempt to unregister * non-exitisng callback. + * + * rx_fifo_threshold value of zero means 'default'. */ -int sps_register_rx_handler(enum sps_mode mode, rx_handler_f rx_handler); +int sps_register_rx_handler(enum sps_mode mode, + rx_handler_f rx_handler, + unsigned rx_fifo_threshold); int sps_unregister_rx_handler(void); void sps_tx_status(uint8_t byte); unsigned sps_rx_fifo_wrptr(void); diff --git a/chip/g/sps_hc.c b/chip/g/sps_hc.c index d99e095ab9..5ddad59d34 100644 --- a/chip/g/sps_hc.c +++ b/chip/g/sps_hc.c @@ -254,7 +254,7 @@ static void sps_hc_enable(void) state = SPI_STATE_DISABLED; /* Ready to receive */ - sps_register_rx_handler(SPS_GENERIC_MODE, hc_rx_handler); + sps_register_rx_handler(SPS_GENERIC_MODE, hc_rx_handler, 0); /* Here we go */ discard_response = 0; diff --git a/chip/g/sps_tpm.c b/chip/g/sps_tpm.c index 5ce79a661f..0dea0ce4ed 100644 --- a/chip/g/sps_tpm.c +++ b/chip/g/sps_tpm.c @@ -250,7 +250,11 @@ static void tpm_rx_handler(uint8_t *data, size_t data_size, int cs_disabled) static void sps_tpm_enable(void) { - sps_register_rx_handler(SPS_GENERIC_MODE, tpm_rx_handler); + /* + * Let's make sure we get an interrupt as soon as the header is + * received. + */ + sps_register_rx_handler(SPS_GENERIC_MODE, tpm_rx_handler, 3); init_new_cycle(); } |