diff --git a/src/soc/rockchip/common/include/soc/spi.h b/src/soc/rockchip/common/include/soc/spi.h index 7e9e568e6d..dcaa4711d2 100644 --- a/src/soc/rockchip/common/include/soc/spi.h +++ b/src/soc/rockchip/common/include/soc/spi.h @@ -165,6 +165,13 @@ check_member(rockchip_spi, rxdr, 0x800); #define SPI_OMOD_SLAVE 0x01 /* --------Bit fields in CTRLR0--------end */ + +/* TXFLR bits */ +#define TXFLR_LEVEL_MASK 0x3f + +/* RXFLR bits */ +#define RXFLR_LEVEL_MASK 0x3f + /* Bit fields in SR, 7 bits */ #define SR_MASK 0x7f #define SR_BUSY (1 << 0) diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 6784f5b975..f35f91589f 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -235,11 +235,18 @@ static int do_xfer(struct rockchip_spi *regs, const void *dout, xferred = 1; } + /* + * Try to read as many bytes as are available in one go. + * Reading the status registers probably requires + * sychronizing with the SPI clock which is pretty slow. + */ if (*bytes_in && !(sr & SR_RF_EMPT)) { - *in_buf = read32(®s->rxdr) & 0xff; - in_buf++; - *bytes_in -= 1; - xferred = 1; + int todo = read32(®s->rxflr) & RXFLR_LEVEL_MASK; + + *bytes_in -= todo; + xferred = todo; + while (todo-- > 0) + *in_buf++ = read32(®s->rxdr) & 0xff; } min_xfer -= xferred;