From 71c8dac9ca9915b7f954c33e128b022f0381dd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 6 Jul 2023 06:20:31 +0300 Subject: drivers/pc80/tpm: Fix tis_readresponse() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TPM_RDRESP_NEED_DELAY was introduced in 2018 in CB:25322 after observing errors with SLB9635 by Infineon. It has been confirmed also SLB9670 and SLB9672 require a fix or delay here. Presumably, prior to CB:4388 SLB9635 did not have this problem, as this particular TPM shipped with samsung/lumpy Chromebook since 2011. In CB:4388 the code changed from polling the status register (+burst_count) using a 32bit read to separated 8bit reads. So far, experiments on samsung/lumpy and SLB9635 indicate that it would be sufficient to add a single tpm_read_status() call to see TIS_STS_DATA_AVAILABLE as set at the time of evaluating the loop exit condition. Change-Id: If5c3e93c7946ebf8226f7bba47b38253f6920c61 Signed-off-by: Kyösti Mälkki Co-authored-by: Bill XIE Reviewed-on: https://review.coreboot.org/c/coreboot/+/76315 Tested-by: build bot (Jenkins) Reviewed-by: Bill XIE Reviewed-by: Matt DeVillier --- src/drivers/pc80/tpm/tis.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/drivers/pc80/tpm/tis.c') diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c index 3f863a36da..93cb2a6163 100644 --- a/src/drivers/pc80/tpm/tis.c +++ b/src/drivers/pc80/tpm/tis.c @@ -286,6 +286,14 @@ static inline tpm_result_t tis_wait_valid_data(int locality) static inline int tis_has_valid_data(int locality) { const u8 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID; + + /* + * Certain TPMs require a small delay here, as they have set + * TIS_STS_VALID first and TIS_STS_DATA_AVAILABLE few clocks later. + */ + if ((tpm_read_status(locality) & has_data) == has_data) + return 1; + return (tpm_read_status(locality) & has_data) == has_data; } @@ -635,14 +643,6 @@ static tpm_result_t tis_readresponse(u8 *buffer, size_t *len) if (offset == expected_count) break; /* We got all we need */ - /* - * Certain TPMs seem to need some delay between tis_wait_valid() - * and tis_has_valid_data(), or some race-condition-related - * issue will occur. - */ - if (CONFIG(TPM_RDRESP_NEED_DELAY)) - udelay(10); - } while (tis_has_valid_data(locality)); /* * Make sure we indeed read all there was. */ -- cgit v1.2.3