Vadim Bendebury has uploaded this change for review. ( https://review.coreboot.org/22321
Change subject: spi/tpm.c do not waste time on wake pulses unless necessary ......................................................................
spi/tpm.c do not waste time on wake pulses unless necessary
The Cr50 secure chip implementation is guaranteed not to fall asleep for 1 second after any SPI slave activity.
Let's not waste time on the wake up ping when it is not necessary.
BRANCH=cr50 BUG=b:68012381 TEST=using a protocol analyzer verified that the wake pulses are generated only when the new Coreboot stage or Depthcharge start, not on every SPI slave transaction.
Change-Id: Id8def1470ba3eab533075b9e7180f8a58e0b00b6 Signed-off-by: Vadim Bendebury vbendeb@chromium.org --- M src/drivers/spi/tpm/tpm.c 1 file changed, 28 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/21/22321/1
diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index 58bf842..c47b807 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -109,6 +109,9 @@ struct stopwatch sw; static int tpm_sync_needed CAR_GLOBAL; struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave); + int wakeup_needed = 1; + static long prev_us CAR_GLOBAL; + struct mono_time mt;
/* Wait for tpm to finish previous transaction if needed */ if (car_get_var(tpm_sync_needed)) @@ -116,11 +119,31 @@ else car_set_var(tpm_sync_needed, 1);
- /* Try to wake cr50 if it is asleep. */ - spi_claim_bus(spi_slave); - udelay(1); - spi_release_bus(spi_slave); - udelay(100); + if (IS_ENABLED(CONFIG_HAVE_MONOTONIC_TIMER)) { + timer_monotonic_get(&mt); + + if (car_get_var(prev_us)) + /* + * If there is a timestamp, check if SPI slave timeout + * has expired. + * + * The Cr50 on H1 does not go to sleep for 1 second + * after any SPI slave activity, let's be conservative + * and limit the window to 900 ms. + */ + if (mt.microseconds < + (car_get_var(prev_us) + 900 * 1000)) + wakeup_needed = 0; + car_set_var(prev_us, mt.microseconds); + } + + if (wakeup_needed) { + /* Just in case Cr50 is asleep. */ + spi_claim_bus(spi_slave); + udelay(1); + spi_release_bus(spi_slave); + udelay(100); + }
/* * The first byte of the frame header encodes the transaction type