Skip to content

Commit

Permalink
spi: spi-cadence: Only overlap FIFO transactions in slave mode
Browse files Browse the repository at this point in the history
Commit b1b9051 ("spi: spi-cadence: Add support for Slave mode")
updated the code to trigger the IRQ when the FIFO was half empty,
overlapping filling more data into the FIFO and sending what is left.
This appears to cause regressions on the Zynq 7000, for transactions
longer than the FIFO size, below that no overlapping occurs.

It would appear from my testing that any attempt to put new data into
the FIFO whilst data is still transmitting causes data corruption
on both send and receive. If I am reading the commit message right
on commit 49530e6 ("spi: cadence: Add usleep_range() for
cdns_spi_fill_tx_fifo()"), that would also seem to imply this is the
case.

On the assumption that this isn't an issue on the platform
the original slave mode support was added for, update the
cdns_transfer_one to only set the watermark to 50% of the FIFO size
when in slave mode. There by retaining the new behaviour for slave
mode but reverting to the older behaviour when the SPI is used a
master.

Fixes: b1b9051 ("spi: spi-cadence: Add support for Slave mode")
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com
Link: https://lore.kernel.org/r/20230509164153.3907694-2-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org
  • Loading branch information
Charles Keepax authored and Mark Brown committed May 15, 2023
1 parent a84c11e commit a0eb7be
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions drivers/spi/spi-cadence.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,14 +438,15 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
xspi->tx_bytes = transfer->len;
xspi->rx_bytes = transfer->len;

if (!spi_controller_is_slave(ctlr))
if (!spi_controller_is_slave(ctlr)) {
cdns_spi_setup_transfer(spi, transfer);

/* Set TX empty threshold to half of FIFO depth
* only if TX bytes are more than half FIFO depth.
*/
if (xspi->tx_bytes > xspi->tx_fifo_depth)
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
} else {
/* Set TX empty threshold to half of FIFO depth
* only if TX bytes are more than half FIFO depth.
*/
if (xspi->tx_bytes > xspi->tx_fifo_depth)
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
}

cdns_spi_fill_tx_fifo(xspi, xspi->tx_fifo_depth);
spi_transfer_delay_exec(transfer);
Expand Down

0 comments on commit a0eb7be

Please sign in to comment.