diff options
author | Julius Werner <jwerner@chromium.org> | 2019-08-09 16:57:20 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-08-22 10:36:31 +0000 |
commit | c788ae328eb3708923623ff15a8aa27f686c84f8 (patch) | |
tree | f468c5b5b1418b010eed41d1689549d85845c983 | |
parent | db7f6fb75282a305c2b0f5540d2f7be939f20dde (diff) |
rockchip: Use new buffer_to/from_fifo32(_prefix) helpers
This patch changes the Rockchip SPI and I2C drivers to use the new
buffer_from_fifo32()/buffer_to_fifo32_prefix() helpers when accessing
their FIFOs (mostly just to demonstrate that/how the helpers work).
Change-Id: Ifcf37c6d56f949f620c347df05439b05c3b8d77d
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/34817
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
-rw-r--r-- | src/soc/rockchip/common/i2c.c | 57 | ||||
-rw-r--r-- | src/soc/rockchip/common/spi.c | 20 |
2 files changed, 23 insertions, 54 deletions
diff --git a/src/soc/rockchip/common/i2c.c b/src/soc/rockchip/common/i2c.c index e5f5a9a9bf..cd0ed9b94f 100644 --- a/src/soc/rockchip/common/i2c.c +++ b/src/soc/rockchip/common/i2c.c @@ -128,25 +128,21 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) uint8_t *data = segment.buf; int timeout = I2C_TIMEOUT_US; unsigned int bytes_remaining = segment.len; - unsigned int bytes_transferred = 0; - unsigned int words_transferred = 0; - unsigned int rxdata = 0; unsigned int con = 0; - unsigned int i, j; write32(®_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1); write32(®_addr->i2c_mrxraddr, 0); con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK; while (bytes_remaining) { - bytes_transferred = MIN(bytes_remaining, 32); - bytes_remaining -= bytes_transferred; + size_t size = MIN(bytes_remaining, 32); + bytes_remaining -= size; if (!bytes_remaining) con |= I2C_EN | I2C_NAK; - words_transferred = ALIGN_UP(bytes_transferred, 4) / 4; + i2c_info("I2C Read::%zu bytes\n", size); write32(®_addr->i2c_ipd, I2C_CLEANI); write32(®_addr->i2c_con, con); - write32(®_addr->i2c_mrxcnt, bytes_transferred); + write32(®_addr->i2c_mrxcnt, size); timeout = I2C_TIMEOUT_US; while (timeout--) { @@ -166,15 +162,8 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) return I2C_TIMEOUT; } - for (i = 0; i < words_transferred; i++) { - rxdata = read32(®_addr->rxdata[i]); - i2c_info("I2c Read::RXDATA[%d] = 0x%x\n", i, rxdata); - for (j = 0; j < 4; j++) { - if ((i * 4 + j) == bytes_transferred) - break; - *data++ = (rxdata >> (j * 8)) & 0xff; - } - } + buffer_from_fifo32(data, size, ®_addr->rxdata, 4, 4); + data += size; con = I2C_MODE_RX | I2C_EN | I2C_ACT2NAK; } return res; @@ -186,32 +175,22 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) uint8_t *data = segment.buf; int timeout = I2C_TIMEOUT_US; int bytes_remaining = segment.len + 1; - int bytes_transferred = 0; - int words_transferred = 0; - unsigned int i; - unsigned int j = 1; - u32 txdata = 0; - txdata |= (segment.slave << 1); + /* Prepend one byte for the slave address to the transfer. */ + u32 prefix = segment.slave << 1; + int prefsz = 1; + while (bytes_remaining) { - bytes_transferred = MIN(bytes_remaining, 32); - words_transferred = ALIGN_UP(bytes_transferred, 4) / 4; - for (i = 0; i < words_transferred; i++) { - do { - if ((i * 4 + j) == bytes_transferred) - break; - txdata |= (*data++) << (j * 8); - } while (++j < 4); - write32(®_addr->txdata[i], txdata); - j = 0; - i2c_info("I2c Write::TXDATA[%d] = 0x%x\n", i, txdata); - txdata = 0; - } + size_t size = MIN(bytes_remaining, 32); + buffer_to_fifo32_prefix(data, prefix, prefsz, size, + ®_addr->txdata, 4, 4); + data += size - prefsz; + i2c_info("I2C Write::%zu bytes\n", size); write32(®_addr->i2c_ipd, I2C_CLEANI); write32(®_addr->i2c_con, I2C_EN | I2C_MODE_TX | I2C_ACT2NAK); - write32(®_addr->i2c_mtxcnt, bytes_transferred); + write32(®_addr->i2c_mtxcnt, size); timeout = I2C_TIMEOUT_US; while (timeout--) { @@ -232,7 +211,9 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) return I2C_TIMEOUT; } - bytes_remaining -= bytes_transferred; + bytes_remaining -= size; + prefsz = 0; + prefix = 0; } return res; } diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 7bde4333ea..0307e24d35 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -221,23 +221,11 @@ static int do_xfer(struct rockchip_spi *regs, bool use_16bit, const void *dout, * sychronizing with the SPI clock which is pretty slow. */ if (*bytes_in && !(sr & SR_RF_EMPT)) { - int fifo = read32(®s->rxflr) & RXFLR_LEVEL_MASK; - int val; - - if (use_16bit) - xferred = fifo * 2; - else - xferred = fifo; + int w = use_16bit ? 2 : 1; + xferred = (read32(®s->rxflr) & RXFLR_LEVEL_MASK) * w; + buffer_from_fifo32(in_buf, xferred, ®s->rxdr, 0, w); *bytes_in -= xferred; - while (fifo-- > 0) { - val = read32(®s->rxdr); - if (use_16bit) { - *in_buf++ = val & 0xff; - *in_buf++ = (val >> 8) & 0xff; - } else { - *in_buf++ = val & 0xff; - } - } + in_buf += xferred; } min_xfer -= xferred; |