summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-03-31 19:45:55 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-04-06 13:08:04 -0700
commit2d26e3807a6626b3b84e27f9c37089c8919ad367 (patch)
tree27f9089ca3f7aa8f06c6d839036c67f223020d54
parent7abeeeaad2b101265a79e0304be9393755b056ae (diff)
downloadchrome-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.c15
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;