On Tue, 28 Jun 2022 14:49:24 +0800 Icenowy Zheng <u...@icenowy.me> wrote:
Hi Icenowy, many thanks for the patch! > The current detection of RX FIFO depth seems to be not reliable, and > XCH will self-clear when a transfer is done. > > Check XCH bit when polling for transfer finish. So as mentioned in the other reply, there are still issues in the SPI driver, some problems being more general. However this patch looks right, and seems like the more robust solution than counting bytes in the FIFO, so I will take it. > Signed-off-by: Icenowy Zheng <u...@icenowy.me> Reviewed-by: Andre Przywara <andre.przyw...@arm.com> Applied to sunxi/master. Thanks, Andre > --- > drivers/spi/spi-sunxi.c | 14 +++++--------- > 1 file changed, 5 insertions(+), 9 deletions(-) > > diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c > index 2f33337725..a424c6a98e 100644 > --- a/drivers/spi/spi-sunxi.c > +++ b/drivers/spi/spi-sunxi.c > @@ -83,7 +83,7 @@ DECLARE_GLOBAL_DATA_PTR; > #endif > #define SUN4I_SPI_MIN_RATE 3000 > #define SUN4I_SPI_DEFAULT_RATE 1000000 > -#define SUN4I_SPI_TIMEOUT_US 1000000 > +#define SUN4I_SPI_TIMEOUT_MS 1000 > > #define SPI_REG(priv, reg) ((priv)->base + \ > (priv)->variant->regs[reg]) > @@ -326,7 +326,6 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned > int bitlen, > struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); > > u32 len = bitlen / 8; > - u32 rx_fifocnt; > u8 nbytes; > int ret; > > @@ -364,13 +363,10 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned > int bitlen, > setbits_le32(SPI_REG(priv, SPI_TCR), > SPI_BIT(priv, SPI_TCR_XCH)); > > - /* Wait till RX FIFO to be empty */ > - ret = readl_poll_timeout(SPI_REG(priv, SPI_FSR), > - rx_fifocnt, > - (((rx_fifocnt & > - SPI_BIT(priv, SPI_FSR_RF_CNT_MASK)) >> > - SUN4I_FIFO_STA_RF_CNT_BITS) >= nbytes), > - SUN4I_SPI_TIMEOUT_US); > + /* Wait for the transfer to be done */ > + ret = wait_for_bit_le32((const void *)SPI_REG(priv, SPI_TCR), > + SPI_BIT(priv, SPI_TCR_XCH), > + false, SUN4I_SPI_TIMEOUT_MS, false); > if (ret < 0) { > printf("ERROR: sun4i_spi: Timeout transferring data\n"); > sun4i_spi_set_cs(bus, slave_plat->cs, false);