spi: sunxi: wait for TX/RX fifo reset done

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>
This commit is contained in:
Yixun Lan
2026-04-21 04:47:50 +00:00
committed by Andre Przywara
parent 7ad8e387d6
commit 11b5cd22ba

View 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... */