summaryrefslogtreecommitdiff
path: root/src/drivers/i2c/tpm/tis.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/i2c/tpm/tis.c')
-rw-r--r--src/drivers/i2c/tpm/tis.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/drivers/i2c/tpm/tis.c b/src/drivers/i2c/tpm/tis.c
index 696634d9d7..d9a7651008 100644
--- a/src/drivers/i2c/tpm/tis.c
+++ b/src/drivers/i2c/tpm/tis.c
@@ -29,6 +29,7 @@
#include <device/i2c.h>
#include <tpm.h>
#include "tpm.h"
+#include <timer.h>
#include <console/console.h>
@@ -37,6 +38,7 @@ struct tpm_chip g_chip;
#define TPM_CMD_COUNT_BYTE 2
#define TPM_CMD_ORDINAL_BYTE 6
+#define TPM_VALID_STATUS (1 << 7)
int tis_open(void)
{
@@ -74,12 +76,33 @@ int tis_init(void)
{
int bus = CONFIG_DRIVER_TPM_I2C_BUS;
int chip = CONFIG_DRIVER_TPM_I2C_ADDR;
+ struct stopwatch sw;
+ uint8_t buf = 0;
+ int ret;
+ long sw_run_duration = 750;
/*
- * Probe TPM twice; the first probing might fail because TPM is asleep,
- * and the probing can wake up TPM.
+ * Probe TPM. Check if the TPM_ACCESS register's ValidSts bit is set(1)
+ * If the bit remains clear(0) then claim that init has failed.
*/
- if (i2c_writeb(bus, chip, 0, 0) && i2c_writeb(bus, chip, 0, 0))
+ stopwatch_init_msecs_expire(&sw, sw_run_duration);
+ do {
+ ret = i2c_readb(bus, chip, 0, &buf);
+ if (!ret && (buf & TPM_VALID_STATUS)) {
+ sw_run_duration = stopwatch_duration_msecs(&sw);
+ break;
+ }
+ } while (!stopwatch_expired(&sw));
+
+ printk(BIOS_INFO,
+ "%s: ValidSts bit %s(%d) in TPM_ACCESS register after %ld ms\n",
+ __func__, (buf & TPM_VALID_STATUS) ? "set" : "clear",
+ (buf & TPM_VALID_STATUS) >> 7, sw_run_duration);
+
+ /*
+ * Claim failure if the ValidSts (bit 7) is clear.
+ */
+ if (!(buf & TPM_VALID_STATUS))
return -1;
return 0;