summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2016-08-31 14:48:12 -0700
committerDuncan Laurie <dlaurie@chromium.org>2016-09-06 22:58:06 +0200
commitefa579fdc217b92d0696b737cda76a69d1fe1433 (patch)
tree0b29ae8ba3c1390df75e7857b9797ed9b340e509 /src
parent40ae1706a447ca81fed31287ec30f28823504c01 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/i2c/tpm/tpm.c29
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);