spi: sunxi: use XCH status to detect in-progress transfer
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. Signed-off-by: Icenowy Zheng <uwu@icenowy.me> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:

committed by
Andre Przywara

parent
68655e6ce1
commit
56e497eba1
@@ -75,7 +75,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
#define SUN4I_SPI_MAX_RATE 24000000
|
#define SUN4I_SPI_MAX_RATE 24000000
|
||||||
#define SUN4I_SPI_MIN_RATE 3000
|
#define SUN4I_SPI_MIN_RATE 3000
|
||||||
#define SUN4I_SPI_DEFAULT_RATE 1000000
|
#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 + \
|
#define SPI_REG(priv, reg) ((priv)->base + \
|
||||||
(priv)->variant->regs[reg])
|
(priv)->variant->regs[reg])
|
||||||
@@ -262,7 +262,6 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
|||||||
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
|
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
|
||||||
|
|
||||||
u32 len = bitlen / 8;
|
u32 len = bitlen / 8;
|
||||||
u32 rx_fifocnt;
|
|
||||||
u8 nbytes;
|
u8 nbytes;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -300,13 +299,10 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
|||||||
setbits_le32(SPI_REG(priv, SPI_TCR),
|
setbits_le32(SPI_REG(priv, SPI_TCR),
|
||||||
SPI_BIT(priv, SPI_TCR_XCH));
|
SPI_BIT(priv, SPI_TCR_XCH));
|
||||||
|
|
||||||
/* Wait till RX FIFO to be empty */
|
/* Wait for the transfer to be done */
|
||||||
ret = readl_poll_timeout(SPI_REG(priv, SPI_FSR),
|
ret = wait_for_bit_le32((const void *)SPI_REG(priv, SPI_TCR),
|
||||||
rx_fifocnt,
|
SPI_BIT(priv, SPI_TCR_XCH),
|
||||||
(((rx_fifocnt &
|
false, SUN4I_SPI_TIMEOUT_MS, false);
|
||||||
SPI_BIT(priv, SPI_FSR_RF_CNT_MASK)) >>
|
|
||||||
SUN4I_FIFO_STA_RF_CNT_BITS) >= nbytes),
|
|
||||||
SUN4I_SPI_TIMEOUT_US);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("ERROR: sun4i_spi: Timeout transferring data\n");
|
printf("ERROR: sun4i_spi: Timeout transferring data\n");
|
||||||
sun4i_spi_set_cs(bus, slave_plat->cs, false);
|
sun4i_spi_set_cs(bus, slave_plat->cs, false);
|
||||||
|
Reference in New Issue
Block a user