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:
parent
db7f6fb752
commit
c788ae328e
|
@ -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(®_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1);
|
write32(®_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1);
|
||||||
write32(®_addr->i2c_mrxraddr, 0);
|
write32(®_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(®_addr->i2c_ipd, I2C_CLEANI);
|
write32(®_addr->i2c_ipd, I2C_CLEANI);
|
||||||
write32(®_addr->i2c_con, con);
|
write32(®_addr->i2c_con, con);
|
||||||
write32(®_addr->i2c_mrxcnt, bytes_transferred);
|
write32(®_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, ®_addr->rxdata, 4, 4);
|
||||||
rxdata = read32(®_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++) {
|
®_addr->txdata, 4, 4);
|
||||||
do {
|
data += size - prefsz;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
i2c_info("I2C Write::%zu bytes\n", size);
|
||||||
write32(®_addr->i2c_ipd, I2C_CLEANI);
|
write32(®_addr->i2c_ipd, I2C_CLEANI);
|
||||||
write32(®_addr->i2c_con,
|
write32(®_addr->i2c_con,
|
||||||
I2C_EN | I2C_MODE_TX | I2C_ACT2NAK);
|
I2C_EN | I2C_MODE_TX | I2C_ACT2NAK);
|
||||||
write32(®_addr->i2c_mtxcnt, bytes_transferred);
|
write32(®_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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(®s->rxflr) & RXFLR_LEVEL_MASK;
|
int w = use_16bit ? 2 : 1;
|
||||||
int val;
|
xferred = (read32(®s->rxflr) & RXFLR_LEVEL_MASK) * w;
|
||||||
|
buffer_from_fifo32(in_buf, xferred, ®s->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(®s->rxdr);
|
|
||||||
if (use_16bit) {
|
|
||||||
*in_buf++ = val & 0xff;
|
|
||||||
*in_buf++ = (val >> 8) & 0xff;
|
|
||||||
} else {
|
|
||||||
*in_buf++ = val & 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
min_xfer -= xferred;
|
min_xfer -= xferred;
|
||||||
|
|
Loading…
Reference in New Issue