summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorJeffy Chen <jeffy.chen@rock-chips.com>2017-03-03 18:24:02 +0800
committerFurquan Shaikh <furquan@google.com>2017-04-05 20:29:36 +0200
commit19e3d335bddb480a53e30242e72195dd5ae8e056 (patch)
treea3487ef4542b986d6ffd2cb1f1136504f331ffac /src/drivers
parentf9a40ea28f1c856289cd4adf04224fad096b4a4d (diff)
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/drivers')
-rw-r--r--src/drivers/spi/tpm/tpm.c45
1 files changed, 40 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);