]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spi: sunxi: wait for TX/RX fifo reset done
authorYixun Lan <dlan@gentoo.org>
Tue, 21 Apr 2026 04:47:50 +0000 (04:47 +0000)
committerAndre Przywara <andre.przywara@arm.com>
Thu, 30 Apr 2026 21:31:03 +0000 (23:31 +0200)
Once reset SPI TX or RX fifo, the underlying hardware need to take
some time to actually settle down, the two bits will automatically
clear to 0, so use a poll mechanism to check status bits to make sure
it's done correctly.

On Cubie A7A board which using A733 SoC, we encoutered a SPI nor flash
timeout issue, it turns out that the SPI fifo reset take a few time to
settle down, Add a loop to poll the status.

This was the error message shows on A7A board once this issue happened.

=> sf probe
ERROR: sun4i_spi: Timeout transferring data
Failed to initialize SPI flash at 0:0 (error -2)

Signed-off-by: Yixun Lan <dlan@gentoo.org>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Acked-by: Andre Przywara <andre.przywara@arm.com>
drivers/spi/spi-sunxi.c

index 0bdc112d249f6f800ced064e5ebbfdeb0b12bbc0..08b603f04a2d983dfe56f52bc5a4863e773fa179 100644 (file)
@@ -344,7 +344,7 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
        struct sun4i_spi_priv *priv = dev_get_priv(bus);
        struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
 
-       u32 len = bitlen / 8;
+       u32 rst, val, len = bitlen / 8;
        u8 nbytes;
        int ret;
 
@@ -360,8 +360,11 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
                sun4i_spi_set_cs(bus, slave_plat->cs[0], true);
 
        /* Reset FIFOs */
-       setbits_le32(SPI_REG(priv, SPI_FCR), SPI_BIT(priv, SPI_FCR_RF_RST) |
-                    SPI_BIT(priv, SPI_FCR_TF_RST));
+       rst = SPI_BIT(priv, SPI_FCR_RF_RST) | SPI_BIT(priv, SPI_FCR_TF_RST);
+       setbits_le32(SPI_REG(priv, SPI_FCR), rst);
+       ret = readl_poll_timeout(SPI_REG(priv, SPI_FCR), val, !(rst & val), 20);
+       if (ret)
+               return -EBUSY;
 
        while (len) {
                /* Setup the transfer now... */