[PATCH sunxi/next] spi: sunxi: use XCH status to detect in-progress transfer

Andre Przywara andre.przywara at arm.com
Mon Jul 18 12:22:32 CEST 2022


On Tue, 28 Jun 2022 14:49:24 +0800
Icenowy Zheng <uwu at 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 <uwu at icenowy.me>

Reviewed-by: Andre Przywara <andre.przywara at 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);



More information about the U-Boot mailing list