diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2018-08-29 14:37:59 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-04 16:53:49 -0700 |
commit | 21bb2cbbe9ba18ae7a2065caff9836bb2d6558e7 (patch) | |
tree | 8407d5eab47a870a812189404f0cd17ca0ecbdc0 /chip/g/sps.h | |
parent | 6b28dab8239564dd8024abf36b22dcb4b179c113 (diff) | |
download | chrome-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.h | 1 |
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 |