diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-03-31 19:45:55 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-06 13:08:04 -0700 |
commit | 2d26e3807a6626b3b84e27f9c37089c8919ad367 (patch) | |
tree | 27f9089ca3f7aa8f06c6d839036c67f223020d54 | |
parent | 7abeeeaad2b101265a79e0304be9393755b056ae (diff) | |
download | chrome-ec-2d26e3807a6626b3b84e27f9c37089c8919ad367.tar.gz |
Cr50: SPI tests need to poke the target to wake it up
If the Cr50 is in deep sleep, it does a full warm boot when it
sees the SPS_CS_L assert. The master doesn't wait for it to
boot (because it doesn't know it has to) and starts clocking in
data bits right away. The Cr50 can't set up the SPS controller
quickly enough to capture those bits, so the first N bits/bytes
are lost and the master keeps clocking, waiting for the SPI
response which it will never get.
To be certain that the Cr50 is awake, this CL causes the
test (master) to assert SPS_CS_L briefly, then wait a little bit
for the Cr50 to wake up from deep sleep (50ms should be plenty),
and THEN it can send the rest of the SPI traffic.
The Cr50 won't enter deep sleep until it's been at least a second
since the last SPI activity, so we don't have to worry about it
going to sleep between SPI commands as long as they're not
terribly far apart.
The kernel driver will have to implement this same hack too,
since the SPI bus doesn't have a suspend/resume protocol like the
USB does. We've known this for some time. It would be nice if
this weren't needed, but it's a hardware constraint.
BUG=chrome-os-partner:49955, chrome-os-partner:52019, b:28018682
BRANCH=none
TEST=make buildall; test on Cr50
Ensure that the Cr50 invokes sleep or deep sleep when idle (refer
to previous commit messages for the setup required), then
cd test/tpm_test
make
./tpmtest.py
Before this CL, the test hung or failed because it couldn't get a
quick response from the Cr50. With this CL, the Cr50 wakes up and
the test passes.
Change-Id: I581475726313981a780beaaa37638e9c3b9ebec5
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/336837
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r-- | test/tpm_test/ftdi_spi_tpm.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/test/tpm_test/ftdi_spi_tpm.c b/test/tpm_test/ftdi_spi_tpm.c index 713a8d7ac9..752e80bed4 100644 --- a/test/tpm_test/ftdi_spi_tpm.c +++ b/test/tpm_test/ftdi_spi_tpm.c @@ -75,6 +75,19 @@ void FtdiStop(void) mpsse_ = NULL; } +/* + * If the TPM is asleep we may need to poke it once to wake it up. Just assert + * the CS briefly without sending any data, then wait a bit to be sure it's + * awake. + */ +static void FtdiSpiPoke(void) +{ + Start(mpsse_); + usleep(1000); + Stop(mpsse_); + usleep(60000); +} + static void StartTransaction(int read_write, size_t bytes, unsigned addr) { struct SpiFrameHeader header; @@ -210,6 +223,8 @@ int FtdiSpiInit(uint32_t freq, int enable_debug) /* Just in case, make sure bootsrap is not triggered. */ PinLow(mpsse_, GPIOL0); + FtdiSpiPoke(); + FtdiReadReg(TPM_DID_VID_REG, sizeof(did_vid), &did_vid); vid = did_vid & 0xffff; |