summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorShelley Chen <shchen@chromium.org>2017-11-07 14:24:19 -0800
committerShelley Chen <shchen@google.com>2017-11-16 06:06:45 +0000
commit85eb0311d2b556f8e293fda904c4cdfe2d0e24fa (patch)
tree095e30078f912514e7775f945e455872e0a37fbb /src/drivers
parent067031e0e195c4346255680821ff288b407e0b90 (diff)
downloadcoreboot-85eb0311d2b556f8e293fda904c4cdfe2d0e24fa.tar.xz
drivers/spi/tpm: Poll TPM_VALID bit until valid
In case the TPM is doing a long crypto operation the initial probe could be very delayed. Rather than end up in recovery make the delay long enough to accommodate the (current) long crypto times. This would add a maximum of 30 seconds to boot time. Mirroring changes done on i2c side in CL:756918 BUG=b:65867313, b:68729265 BRANCH=None TEST=Make sure fizz boots up Change-Id: Ie944bfb6fe33d6e9ee794439165716ab624be491 Signed-off-by: Shelley Chen <shchen@chromium.org> Reviewed-on: https://review.coreboot.org/22370 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/spi/tpm/tpm.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c
index 58bf842267..c09462e783 100644
--- a/src/drivers/spi/tpm/tpm.c
+++ b/src/drivers/spi/tpm/tpm.c
@@ -37,6 +37,8 @@
#define TPM_RID_REG (TPM_LOCALITY_0_SPI_BASE + 0xf04)
#define TPM_FW_VER (TPM_LOCALITY_0_SPI_BASE + 0xf90)
+#define CR50_TIMEOUT_INIT_MS 30000 /* Very long timeout for TPM init */
+
/* SPI slave structure for TPM device. */
static struct spi_slave g_spi_slave CAR_GLOBAL;
@@ -342,6 +344,7 @@ static void tpm2_write_access_reg(uint8_t cmd)
static int tpm2_claim_locality(void)
{
uint8_t access;
+ struct stopwatch sw;
access = tpm2_read_access_reg();
/*
@@ -353,6 +356,13 @@ static int tpm2_claim_locality(void)
access = tpm2_read_access_reg();
}
+ /*
+ * If cr50 is doing a long crypto operation, it can take up to
+ * 30 seconds to get a valid status value back
+ */
+ stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
+ while (!stopwatch_expired(&sw) && access != TPM_ACCESS_VALID)
+ access = tpm2_read_access_reg();
if (access != TPM_ACCESS_VALID) {
printk(BIOS_ERR, "Invalid reset status: %#x\n", access);
return 0;