diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2016-08-31 14:48:12 -0700 |
---|---|---|
committer | Duncan Laurie <dlaurie@chromium.org> | 2016-09-06 22:58:06 +0200 |
commit | efa579fdc217b92d0696b737cda76a69d1fe1433 (patch) | |
tree | 0b29ae8ba3c1390df75e7857b9797ed9b340e509 | |
parent | 40ae1706a447ca81fed31287ec30f28823504c01 (diff) | |
download | coreboot-efa579fdc217b92d0696b737cda76a69d1fe1433.tar.xz |
drivers/i2c/tpm: Allow sleep durations to be set by the chip
Allow the sleep durations used by the driver to be set by the
specific chip so they can be tuned appropriately.
Since we need to read the chip id to know the values use very
conservative defaults for the first command and then set it
to the current values by default.
Change-Id: Ic64159328b18a1471eb06fa8b52b589eec1e1ca2
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/16395
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins)
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
-rw-r--r-- | src/drivers/i2c/tpm/tpm.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c index 727feb618b..0534c63464 100644 --- a/src/drivers/i2c/tpm/tpm.c +++ b/src/drivers/i2c/tpm/tpm.c @@ -42,6 +42,8 @@ #define MAX_COUNT 3 #define SLEEP_DURATION 60 /* in usec */ +#define SLEEP_DURATION_LONG 210 /* in usec */ +#define SLEEP_DURATION_SAFE 750 /* in usec */ /* max. number of iterations after I2C NAK for 'long' commands * we need this especially for sending TPM_READY, since the cleanup after the @@ -50,8 +52,6 @@ */ #define MAX_COUNT_LONG 50 -#define SLEEP_DURATION_LONG 210 /* in usec */ - /* expected value for DIDVID register */ #define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L @@ -72,6 +72,8 @@ static const char * const chip_name[] = { struct tpm_inf_dev { int bus; unsigned int addr; + unsigned int sleep_short; /* Short sleep duration in usec */ + unsigned int sleep_long; /* Long sleep duration in usec */ uint8_t buf[TPM_BUFSIZE + sizeof(uint8_t)]; // max. buffer size + addr enum i2c_chip_type chip_type; }; @@ -109,7 +111,7 @@ static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len) if (rc == 0) break; /* success, break to skip sleep */ - udelay(SLEEP_DURATION); + udelay(tpm_dev->sleep_short); } if (rc) @@ -120,7 +122,7 @@ static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len) * retrieving the data */ for (count = 0; count < MAX_COUNT; count++) { - udelay(SLEEP_DURATION); + udelay(tpm_dev->sleep_short); rc = i2c_read_raw(tpm_dev->bus, tpm_dev->addr, buffer, len); if (rc == 0) @@ -143,12 +145,12 @@ static int iic_tpm_read(uint8_t addr, uint8_t *buffer, size_t len) i2c_transfer(tpm_dev->bus, &dseg, 1); if (rc == 0) break; /* break here to skip sleep */ - udelay(SLEEP_DURATION); + udelay(tpm_dev->sleep_short); } } /* take care of 'guard time' */ - udelay(SLEEP_DURATION); + udelay(tpm_dev->sleep_short); if (rc) return -1; @@ -184,7 +186,7 @@ static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len, } /* take care of 'guard time' */ - udelay(SLEEP_DURATION); + udelay(tpm_dev->sleep_short); if (rc) return -1; @@ -209,7 +211,8 @@ static int iic_tpm_write_generic(uint8_t addr, uint8_t *buffer, size_t len, */ static int iic_tpm_write(uint8_t addr, uint8_t *buffer, size_t len) { - return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION, + struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev); + return iic_tpm_write_generic(addr, buffer, len, tpm_dev->sleep_short, MAX_COUNT); } @@ -219,7 +222,8 @@ static int iic_tpm_write(uint8_t addr, uint8_t *buffer, size_t len) * */ static int iic_tpm_write_long(uint8_t addr, uint8_t *buffer, size_t len) { - return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG, + struct tpm_inf_dev *tpm_dev = car_get_var_ptr(&g_tpm_dev); + return iic_tpm_write_generic(addr, buffer, len, tpm_dev->sleep_long, MAX_COUNT_LONG); } @@ -494,6 +498,10 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned bus, uint32_t dev_addr) tpm_dev->bus = bus; tpm_dev->addr = dev_addr; + /* Use conservative values to read chip id */ + tpm_dev->sleep_short = SLEEP_DURATION_SAFE; + tpm_dev->sleep_long = SLEEP_DURATION_SAFE * 2; + memset(&chip->vendor, 0, sizeof(struct tpm_vendor_specific)); chip->is_open = 1; @@ -524,6 +532,9 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned bus, uint32_t dev_addr) goto out_err; } + tpm_dev->sleep_short = SLEEP_DURATION; + tpm_dev->sleep_long = SLEEP_DURATION_LONG; + printk(BIOS_DEBUG, "1.2 TPM (chip type %s device-id 0x%X)\n", chip_name[tpm_dev->chip_type], vendor >> 16); |