summaryrefslogtreecommitdiff
path: root/chip/g/sps.h
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-08-29 14:37:59 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-09-04 16:53:49 -0700
commit21bb2cbbe9ba18ae7a2065caff9836bb2d6558e7 (patch)
tree8407d5eab47a870a812189404f0cd17ca0ecbdc0 /chip/g/sps.h
parent6b28dab8239564dd8024abf36b22dcb4b179c113 (diff)
downloadchrome-ec-21bb2cbbe9ba18ae7a2065caff9836bb2d6558e7.tar.gz
cr50: fix sps driver sync problems
TPM SPI hardware flow control mechanism allows the slave to stall the master until slave is ready to receive more data or has prepared data to return to the master. While stalling, the slave keeps sending zeros in the LSB of the bytes on the MISO line until it is ready to proceed. As implemented before this patch this presents a challenge when processing write transactions: by looking at the SPI frame header the Cr50 detects that master intends to write, removes the stall bit, and then tries to determine how many bytes are already there in the receive buffer (those extra bytes were sent while Cr50 was stalling the master), so that it can discard the extra bytes and know exactly where in the buffer the actual data will start once stalling condition is removed. To make this determination the code is looking at the controller's RX FIFO write pointer. It turns out that this pointer change is happening slower with slower SPI bus clocking, and this causes occasional errors in detecting the boundary in the receive buffer at slower SPI clock rates. Come to think of it, all this complexity is unnecessary in the first place: the master will finish transmitting of the write transaction after stall is removed and all required data bytes have been transferred and then remove the CS. At this point the Cr50 can look at the received data, which would consist of a 4 byte header, variable number of bytes sent while stalling was active, and then the rest of the SPI frame. The number of data bytes in the SPI frame is in fact included in the 4 byte header. So, all there is to do is to pass upstack these tail bytes of the received frame (the register address these bytes are written into is derived from the SPI frame header). This patch implements the new scheme and cleans up the low level driver, namely removes a now unused accessor function and ediits a few comments. BRANCH=cr50, cr50-mp BUG=b:113082214 TEST=modified Cr50 code to add a 32 bit scratch register the master could write and read. Modified Scarlet AP firmware to keep writing ever incrementing value to this register and read it back. Before this fix when clocking at 300 KHz this would fail after second or third write attempt, with the fix there is no problems for thousands of transactions on both 300 KHz and 1.5 MHz clocks. Change-Id: I845d2d18dc054e2a0ca2c8afd9f62bec37ad6ad9 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1194621 Tested-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org>
Diffstat (limited to 'chip/g/sps.h')
-rw-r--r--chip/g/sps.h1
1 files changed, 0 insertions, 1 deletions
diff --git a/chip/g/sps.h b/chip/g/sps.h
index 5f49d8d092..b9684c4b90 100644
--- a/chip/g/sps.h
+++ b/chip/g/sps.h
@@ -50,6 +50,5 @@ int sps_register_rx_handler(enum sps_mode mode,
unsigned rx_fifo_threshold);
int sps_unregister_rx_handler(void);
void sps_tx_status(uint8_t byte);
-unsigned sps_rx_fifo_wrptr(void);
#endif