summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2015-07-24 17:08:19 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-13 23:34:05 +0000
commit36ed861be833df5751c668fdc1b47fb00e3ebada (patch)
treeb2c276900e100a9e9f528186d7bc87f9600e752a
parentdf2e760a93885c01bc86d6e5a7099b00df4c824b (diff)
downloadchrome-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.c15
-rw-r--r--chip/g/sps.h6
-rw-r--r--chip/g/sps_hc.c2
-rw-r--r--chip/g/sps_tpm.c6
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();
}