diff options
author | Jeffy Chen <jeffy.chen@rock-chips.com> | 2017-03-03 18:24:02 +0800 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2017-04-05 20:29:36 +0200 |
commit | 19e3d335bddb480a53e30242e72195dd5ae8e056 (patch) | |
tree | a3487ef4542b986d6ffd2cb1f1136504f331ffac /src | |
parent | f9a40ea28f1c856289cd4adf04224fad096b4a4d (diff) | |
download | coreboot-19e3d335bddb480a53e30242e72195dd5ae8e056.tar.xz |
drivers/spi/tpm: using tpm irq to sync tpm transaction
BUG=b:35647967
TEST=boot from bob
Change-Id: Ib64107b17fb6e93dbe626ce92f3bc9da8b84784e
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Reviewed-on: https://chromium-review.googlesource.com/452284
Commit-Ready: Caesar Wang <wxt@rock-chips.com>
Tested-by: Caesar Wang <wxt@rock-chips.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/19113
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/drivers/spi/tpm/tpm.c | 45 | ||||
-rw-r--r-- | src/include/tpm.h | 9 |
2 files changed, 49 insertions, 5 deletions
diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index 29b85c4716..cd1fbdf73b 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -21,6 +21,7 @@ #include <endian.h> #include <string.h> #include <timer.h> +#include <tpm.h> #include "tpm.h" @@ -102,6 +103,39 @@ void tpm2_get_info(struct tpm2_info *info) *info = tpm_info; } +__attribute__((weak)) int tis_plat_irq_status(void) +{ + static int warning_displayed; + + if (!warning_displayed) { + printk(BIOS_WARNING, "WARNING: tis_plat_irq_status() not implemented, wasting 10ms to wait on Cr50!\n"); + warning_displayed = 1; + } + mdelay(10); + + return 1; +} + +/* + * TPM may trigger a irq after finish processing previous transfer. + * Waiting for this irq to sync tpm status. + * + * Returns 1 on success, 0 on failure (timeout). + */ +static int tpm_sync(void) +{ + struct stopwatch sw; + + stopwatch_init_usecs_expire(&sw, 10 * 1000); + while (!tis_plat_irq_status()) { + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "Timeout wait for tpm irq!\n"); + return 0; + } + } + return 1; +} + /* * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte * header is sent to the TPM, the master waits til TPM is ready to continue. @@ -114,12 +148,13 @@ static int start_transaction(int read_write, size_t bytes, unsigned addr) uint8_t byte; int i; struct stopwatch sw; + static int tpm_sync_needed; - /* - * Give it 10 ms. TODO(vbendeb): remove this once cr50 SPS TPM driver - * performance is fixed. - */ - mdelay(10); + /* Wait for tpm to finish previous transaction if needed */ + if (tpm_sync_needed) + tpm_sync(); + else + tpm_sync_needed = 1; /* Try to wake cr50 if it is asleep. */ tpm_if.cs_assert(&tpm_if.slave); diff --git a/src/include/tpm.h b/src/include/tpm.h index b15ca6e76f..bd85b43844 100644 --- a/src/include/tpm.h +++ b/src/include/tpm.h @@ -64,4 +64,13 @@ int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf, void init_tpm(int s3resume); +/* + * tis_plat_irq_status() + * + * Check tpm irq and clear it. + * + * Returns 1 when irq pending or 0 when not. + */ +int tis_plat_irq_status(void); + #endif /* TPM_H_ */ |