summaryrefslogtreecommitdiff
path: root/src/drivers/i2c/tpm
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/i2c/tpm')
-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);