diff options
author | Jes Klinke <jbk@google.com> | 2022-02-22 16:00:09 -0800 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2022-03-15 22:06:27 +0000 |
commit | 19baa9d51e4f1b36473dc750735eb6e5345bebda (patch) | |
tree | 60aada7f006fd73797b5c566d704e2b0ed5b728f /src/soc/rockchip | |
parent | ca82e6161af7a453b512f35dd695a98084a1d7cf (diff) |
i2c: Add configurable I2C transfer timeout
This patch introduces CONFIG_I2C_TRANSFER_TIMEOUT_US,
which controls how long to wait for an I2C devices to
produce/accept all the data bytes in a single transfer.
(The device can delay transfer by stretching the clock of
the ack bit.)
The default value of this new setting is 500ms. Existing
code had timeouts anywhere from tens of milliseconds to a
full second beween various drivers. Drivers can still have
their own shorter timeouts for setup/communication with the
I2C host controller (as opposed to transactions with I2C
devices on the bus.)
In general, the timeout is not meant to be reached except in
situations where there is already serious problem with the
boot, and serves to make sure that some useful diagnostic
output is produced on the console.
Change-Id: I6423122f32aad1dbcee0bfe240cdaa8cb512791f
Signed-off-by: Jes B. Klinke <jbk@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/62278
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'src/soc/rockchip')
-rw-r--r-- | src/soc/rockchip/common/i2c.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/src/soc/rockchip/common/i2c.c b/src/soc/rockchip/common/i2c.c index dbbfd3e041..a0498a52c7 100644 --- a/src/soc/rockchip/common/i2c.c +++ b/src/soc/rockchip/common/i2c.c @@ -114,7 +114,6 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) { int res = 0; uint8_t *data = segment.buf; - int timeout = I2C_TIMEOUT_US; unsigned int bytes_remaining = segment.len; unsigned int con = 0; @@ -122,6 +121,7 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) write32(®_addr->i2c_mrxraddr, 0); con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK; while (bytes_remaining) { + int timeout = CONFIG_I2C_TRANSFER_TIMEOUT_US; size_t size = MIN(bytes_remaining, 32); bytes_remaining -= size; if (!bytes_remaining) @@ -132,7 +132,6 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) write32(®_addr->i2c_con, con); write32(®_addr->i2c_mrxcnt, size); - timeout = I2C_TIMEOUT_US; while (timeout--) { if (read32(®_addr->i2c_ipd) & I2C_NAKRCVI) { write32(®_addr->i2c_mrxcnt, 0); @@ -161,7 +160,6 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) { int res = 0; uint8_t *data = segment.buf; - int timeout = I2C_TIMEOUT_US; int bytes_remaining = segment.len + 1; /* Prepend one byte for the slave address to the transfer. */ @@ -169,6 +167,7 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) int prefsz = 1; while (bytes_remaining) { + int timeout = CONFIG_I2C_TRANSFER_TIMEOUT_US; size_t size = MIN(bytes_remaining, 32); buffer_to_fifo32_prefix(data, prefix, prefsz, size, ®_addr->txdata, 4, 4); @@ -180,7 +179,6 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) I2C_EN | I2C_MODE_TX | I2C_ACT2NAK); write32(®_addr->i2c_mtxcnt, size); - timeout = I2C_TIMEOUT_US; while (timeout--) { if (read32(®_addr->i2c_ipd) & I2C_NAKRCVI) { write32(®_addr->i2c_mtxcnt, 0); |