summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2018-12-20 09:21:18 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-01-28 14:17:14 -0800
commit847b2d12c55c135c3ac33c3c7811f32761375f76 (patch)
tree810f4ed24a999a70421d6047e3b23c001864d7b8 /board
parent2223f8723d0bb25e9637802b22232664e0d974af (diff)
downloadchrome-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