Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: spi-cadence: Fix data corruption issues in slave mode

Remove 10us delay in cdns_spi_process_fifo() (called from cdns_spi_irq())
to fix data corruption issue on Master side when this driver
configured in Slave mode, as Slave is failed to prepare the date
on time due to above delay.

Add 10us delay before processing the RX FIFO as TX empty doesn't
guarantee valid data in RX FIFO.

Signed-off-by: Srinivas Goud <srinivas.goud@amd.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/1692610216-217644-1-git-send-email-srinivas.goud@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Srinivas Goud and committed by
Mark Brown
627d05a4 715dc9a1

+12 -7
+12 -7
drivers/spi/spi-cadence.c
··· 317 317 xspi->rx_bytes -= nrx; 318 318 319 319 while (ntx || nrx) { 320 - /* When xspi in busy condition, bytes may send failed, 321 - * then spi control did't work thoroughly, add one byte delay 322 - */ 323 - if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL) 324 - udelay(10); 325 - 326 320 if (ntx) { 327 321 if (xspi->txbuf) 328 322 cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); ··· 386 392 if (xspi->tx_bytes) { 387 393 cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt); 388 394 } else { 395 + /* Fixed delay due to controller limitation with 396 + * RX_NEMPTY incorrect status 397 + * Xilinx AR:65885 contains more details 398 + */ 399 + udelay(10); 389 400 cdns_spi_process_fifo(xspi, 0, trans_cnt); 390 401 cdns_spi_write(xspi, CDNS_SPI_IDR, 391 402 CDNS_SPI_IXR_DEFAULT); ··· 438 439 cdns_spi_setup_transfer(spi, transfer); 439 440 } else { 440 441 /* Set TX empty threshold to half of FIFO depth 441 - * only if TX bytes are more than half FIFO depth. 442 + * only if TX bytes are more than FIFO depth. 442 443 */ 443 444 if (xspi->tx_bytes > xspi->tx_fifo_depth) 444 445 cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1); 445 446 } 447 + 448 + /* When xspi in busy condition, bytes may send failed, 449 + * then spi control didn't work thoroughly, add one byte delay 450 + */ 451 + if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL) 452 + udelay(10); 446 453 447 454 cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0); 448 455 spi_transfer_delay_exec(transfer);