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:
parent
f9a40ea28f
commit
19e3d335bd
|
@ -21,6 +21,7 @@
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
#include <tpm.h>
|
||||||
|
|
||||||
#include "tpm.h"
|
#include "tpm.h"
|
||||||
|
|
||||||
|
@ -102,6 +103,39 @@ void tpm2_get_info(struct tpm2_info *info)
|
||||||
*info = tpm_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
|
* 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.
|
* 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;
|
uint8_t byte;
|
||||||
int i;
|
int i;
|
||||||
struct stopwatch sw;
|
struct stopwatch sw;
|
||||||
|
static int tpm_sync_needed;
|
||||||
|
|
||||||
/*
|
/* Wait for tpm to finish previous transaction if needed */
|
||||||
* Give it 10 ms. TODO(vbendeb): remove this once cr50 SPS TPM driver
|
if (tpm_sync_needed)
|
||||||
* performance is fixed.
|
tpm_sync();
|
||||||
*/
|
else
|
||||||
mdelay(10);
|
tpm_sync_needed = 1;
|
||||||
|
|
||||||
/* Try to wake cr50 if it is asleep. */
|
/* Try to wake cr50 if it is asleep. */
|
||||||
tpm_if.cs_assert(&tpm_if.slave);
|
tpm_if.cs_assert(&tpm_if.slave);
|
||||||
|
|
|
@ -64,4 +64,13 @@ int tis_sendrecv(const u8 *sendbuf, size_t send_size, u8 *recvbuf,
|
||||||
|
|
||||||
void init_tpm(int s3resume);
|
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_ */
|
#endif /* TPM_H_ */
|
||||||
|
|
Loading…
Reference in New Issue