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>
This commit is contained in:
Julius Werner 2019-08-09 16:57:20 -07:00 committed by Patrick Georgi
parent db7f6fb752
commit c788ae328e
2 changed files with 23 additions and 54 deletions

View File

@ -128,25 +128,21 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment)
uint8_t *data = segment.buf; uint8_t *data = segment.buf;
int timeout = I2C_TIMEOUT_US; int timeout = I2C_TIMEOUT_US;
unsigned int bytes_remaining = segment.len; 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 con = 0;
unsigned int i, j;
write32(&reg_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1); write32(&reg_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1);
write32(&reg_addr->i2c_mrxraddr, 0); write32(&reg_addr->i2c_mrxraddr, 0);
con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK; con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK;
while (bytes_remaining) { while (bytes_remaining) {
bytes_transferred = MIN(bytes_remaining, 32); size_t size = MIN(bytes_remaining, 32);
bytes_remaining -= bytes_transferred; bytes_remaining -= size;
if (!bytes_remaining) if (!bytes_remaining)
con |= I2C_EN | I2C_NAK; con |= I2C_EN | I2C_NAK;
words_transferred = ALIGN_UP(bytes_transferred, 4) / 4;
i2c_info("I2C Read::%zu bytes\n", size);
write32(&reg_addr->i2c_ipd, I2C_CLEANI); write32(&reg_addr->i2c_ipd, I2C_CLEANI);
write32(&reg_addr->i2c_con, con); write32(&reg_addr->i2c_con, con);
write32(&reg_addr->i2c_mrxcnt, bytes_transferred); write32(&reg_addr->i2c_mrxcnt, size);
timeout = I2C_TIMEOUT_US; timeout = I2C_TIMEOUT_US;
while (timeout--) { while (timeout--) {
@ -166,15 +162,8 @@ static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment)
return I2C_TIMEOUT; return I2C_TIMEOUT;
} }
for (i = 0; i < words_transferred; i++) { buffer_from_fifo32(data, size, &reg_addr->rxdata, 4, 4);
rxdata = read32(&reg_addr->rxdata[i]); data += size;
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;
}
}
con = I2C_MODE_RX | I2C_EN | I2C_ACT2NAK; con = I2C_MODE_RX | I2C_EN | I2C_ACT2NAK;
} }
return res; 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; uint8_t *data = segment.buf;
int timeout = I2C_TIMEOUT_US; int timeout = I2C_TIMEOUT_US;
int bytes_remaining = segment.len + 1; 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) { while (bytes_remaining) {
bytes_transferred = MIN(bytes_remaining, 32); size_t size = MIN(bytes_remaining, 32);
words_transferred = ALIGN_UP(bytes_transferred, 4) / 4; buffer_to_fifo32_prefix(data, prefix, prefsz, size,
for (i = 0; i < words_transferred; i++) { &reg_addr->txdata, 4, 4);
do { data += size - prefsz;
if ((i * 4 + j) == bytes_transferred)
break;
txdata |= (*data++) << (j * 8);
} while (++j < 4);
write32(&reg_addr->txdata[i], txdata);
j = 0;
i2c_info("I2c Write::TXDATA[%d] = 0x%x\n", i, txdata);
txdata = 0;
}
i2c_info("I2C Write::%zu bytes\n", size);
write32(&reg_addr->i2c_ipd, I2C_CLEANI); write32(&reg_addr->i2c_ipd, I2C_CLEANI);
write32(&reg_addr->i2c_con, write32(&reg_addr->i2c_con,
I2C_EN | I2C_MODE_TX | I2C_ACT2NAK); I2C_EN | I2C_MODE_TX | I2C_ACT2NAK);
write32(&reg_addr->i2c_mtxcnt, bytes_transferred); write32(&reg_addr->i2c_mtxcnt, size);
timeout = I2C_TIMEOUT_US; timeout = I2C_TIMEOUT_US;
while (timeout--) { while (timeout--) {
@ -232,7 +211,9 @@ static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment)
return I2C_TIMEOUT; return I2C_TIMEOUT;
} }
bytes_remaining -= bytes_transferred; bytes_remaining -= size;
prefsz = 0;
prefix = 0;
} }
return res; return res;
} }

View File

@ -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. * sychronizing with the SPI clock which is pretty slow.
*/ */
if (*bytes_in && !(sr & SR_RF_EMPT)) { if (*bytes_in && !(sr & SR_RF_EMPT)) {
int fifo = read32(&regs->rxflr) & RXFLR_LEVEL_MASK; int w = use_16bit ? 2 : 1;
int val; xferred = (read32(&regs->rxflr) & RXFLR_LEVEL_MASK) * w;
buffer_from_fifo32(in_buf, xferred, &regs->rxdr, 0, w);
if (use_16bit)
xferred = fifo * 2;
else
xferred = fifo;
*bytes_in -= xferred; *bytes_in -= xferred;
while (fifo-- > 0) { in_buf += xferred;
val = read32(&regs->rxdr);
if (use_16bit) {
*in_buf++ = val & 0xff;
*in_buf++ = (val >> 8) & 0xff;
} else {
*in_buf++ = val & 0xff;
}
}
} }
min_xfer -= xferred; min_xfer -= xferred;