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>
This commit is contained in:
Jeffy Chen 2017-03-03 18:24:02 +08:00 committed by Furquan Shaikh
parent f9a40ea28f
commit 19e3d335bd
2 changed files with 49 additions and 5 deletions

View File

@ -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);

View File

@ -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_ */