[coreboot-gerrit] Patch set updated for coreboot: drivers/i2c/tpm: Allow sleep durations to be set by the chip

Duncan Laurie (dlaurie@chromium.org) gerrit at coreboot.org
Tue Sep 6 22:54:11 CEST 2016


Duncan Laurie (dlaurie at chromium.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16395

-gerrit

commit bf12ebf5af4d0405c436fee2a12da91fb78152e4
Author: Duncan Laurie <dlaurie at chromium.org>
Date:   Wed Aug 31 14:48:12 2016 -0700

    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 at chromium.org>
---
 src/drivers/i2c/tpm/tpm.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c
index 727feb6..0534c63 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);
 



More information about the coreboot-gerrit mailing list