diff options
author | Raul E Rangel <rrangel@chromium.org> | 2018-12-20 09:21:18 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-28 14:17:14 -0800 |
commit | 847b2d12c55c135c3ac33c3c7811f32761375f76 (patch) | |
tree | 810f4ed24a999a70421d6047e3b23c001864d7b8 /board | |
parent | 2223f8723d0bb25e9637802b22232664e0d974af (diff) | |
download | chrome-ec-847b2d12c55c135c3ac33c3c7811f32761375f76.tar.gz |
g/i2cs: Sample SDA multiple times before considering the bus wedged
The cr50 tpm i2c protocol works as follows:
1. Master wants to read a register from the tpm. It writes the 1 byte
register address to the tpm.
2. Master completes the transaction then waits for AP_INT to fire.
3. i2c write complete isr fires on the tpm.
1. register data is pushed into the tx fifo
2. AP_INT is pulsed to notify the master that the write has been
processed, and the data is ready to be read.
3. tpm increments i2cs_read_irq_count
4. Master reads n bytes from the tpm.
5. Times passes
6a. Master decides to update a register on the TPM
1. Master writes n bytes to the tpm.
2. Master completes transaction then waits for AP_INT to fire.
3. i2c write complete isr fires on the tpm
1. tpm processes the write command
2. AP_INT is pulsed to notify the master that the read is ready.
4. Master receives AP_INT and continues issuing commands.
6b. Master decides to read a register from the TPM
1. goto 1
poll_read_state will currently poll SDA every 500 ms. If it sees that
there have been no write completions since the last polling period and
SDA is currently low, it assumes the bus is wedged and it resets the i2cs
controller. This logic has the potential to terminate in flight
transactions.
For example: The poller runs at step 4 and notices that a write
interrupt has occurred and it updates last_i2cs_read_irq_count. The master
waits 499.99 ms and then initiates a new transaction (6a or 6b). This
causes the master to start a new i2c write transaction.
The poller then runs again at 500ms and notices that the write complete
interrupt counter has not incremented and SDA is low because a 0 is
currently being written by the master. The poller then resets the i2cs
controller. This causes the master to receive a NAK.
This cl changes the logic so that the poller requires SDA to be low for
3 consecutive periods between write completes before it resets the
controller. See the comments in the code for the specifics.
BUG=b:113880780
BRANCH=none
TEST=Ran a reboot stress test for over 16 hours and did not see any
transaction failures. Also manually grounded SDA to see if
read_recovery_count incremented:
[585.024822 I2CS bus is stuck]
[585.475883 I2CS bus is stuck]
[585.926944 I2CS bus is stuck]
[586.378009 I2CS bus is stuck]
[586.829067 I2CS bus is stuck]
> i2cstpm
rd fifo adjust cnt = 0
wr mismatch cnt = 0
read recovered cnt = 5
Change-Id: I7b6f446ee75b43e9d66a6a5e51dd077c60108f90
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1387346
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board')
0 files changed, 0 insertions, 0 deletions