Skip to content

Commit 6afe2ae

Browse files
charleskeepaxbroonie
authored andcommitted
spi: spi-cadence: Interleave write of TX and read of RX FIFO
When working in slave mode it seems the timing is exceedingly tight. The TX FIFO can never empty, because the master is driving the clock so zeros would be sent for those bytes where the FIFO is empty. Return to interleaving the writing of the TX FIFO and the reading of the RX FIFO to try to ensure the data is available when required. Fixes: a84c11e ("spi: spi-cadence: Avoid read of RX FIFO before its ready") Signed-off-by: Charles Keepax <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 445164e commit 6afe2ae

File tree

1 file changed

+30
-34
lines changed

1 file changed

+30
-34
lines changed

drivers/spi/spi-cadence.c

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/gpio/consumer.h>
1313
#include <linux/interrupt.h>
1414
#include <linux/io.h>
15+
#include <linux/kernel.h>
1516
#include <linux/module.h>
1617
#include <linux/of_irq.h>
1718
#include <linux/of_address.h>
@@ -301,47 +302,43 @@ static int cdns_spi_setup_transfer(struct spi_device *spi,
301302
}
302303

303304
/**
304-
* cdns_spi_fill_tx_fifo - Fills the TX FIFO with as many bytes as possible
305+
* cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO
305306
* @xspi: Pointer to the cdns_spi structure
307+
* @ntx: Number of bytes to pack into the TX FIFO
308+
* @nrx: Number of bytes to drain from the RX FIFO
306309
*/
307-
static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi, unsigned int avail)
310+
static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx)
308311
{
309-
unsigned long trans_cnt = 0;
312+
ntx = clamp(ntx, 0, xspi->tx_bytes);
313+
nrx = clamp(nrx, 0, xspi->rx_bytes);
310314

311-
while ((trans_cnt < avail) && (xspi->tx_bytes > 0)) {
315+
xspi->tx_bytes -= ntx;
316+
xspi->rx_bytes -= nrx;
317+
318+
while (ntx || nrx) {
312319
/* When xspi in busy condition, bytes may send failed,
313320
* then spi control did't work thoroughly, add one byte delay
314321
*/
315-
if (cdns_spi_read(xspi, CDNS_SPI_ISR) &
316-
CDNS_SPI_IXR_TXFULL)
322+
if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL)
317323
udelay(10);
318324

319-
if (xspi->txbuf)
320-
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
321-
else
322-
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
325+
if (ntx) {
326+
if (xspi->txbuf)
327+
cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++);
328+
else
329+
cdns_spi_write(xspi, CDNS_SPI_TXD, 0);
323330

324-
xspi->tx_bytes--;
325-
trans_cnt++;
326-
}
327-
}
331+
ntx--;
332+
}
328333

329-
/**
330-
* cdns_spi_read_rx_fifo - Reads the RX FIFO with as many bytes as possible
331-
* @xspi: Pointer to the cdns_spi structure
332-
* @count: Read byte count
333-
*/
334-
static void cdns_spi_read_rx_fifo(struct cdns_spi *xspi, unsigned long count)
335-
{
336-
u8 data;
337-
338-
/* Read out the data from the RX FIFO */
339-
while (count > 0) {
340-
data = cdns_spi_read(xspi, CDNS_SPI_RXD);
341-
if (xspi->rxbuf)
342-
*xspi->rxbuf++ = data;
343-
xspi->rx_bytes--;
344-
count--;
334+
if (nrx) {
335+
u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD);
336+
337+
if (xspi->rxbuf)
338+
*xspi->rxbuf++ = data;
339+
340+
nrx--;
341+
}
345342
}
346343
}
347344

@@ -391,11 +388,10 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
391388
if (xspi->tx_bytes < xspi->tx_fifo_depth >> 1)
392389
cdns_spi_write(xspi, CDNS_SPI_THLD, 1);
393390

394-
cdns_spi_read_rx_fifo(xspi, trans_cnt);
395-
396391
if (xspi->tx_bytes) {
397-
cdns_spi_fill_tx_fifo(xspi, trans_cnt);
392+
cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt);
398393
} else {
394+
cdns_spi_process_fifo(xspi, 0, trans_cnt);
399395
cdns_spi_write(xspi, CDNS_SPI_IDR,
400396
CDNS_SPI_IXR_DEFAULT);
401397
spi_finalize_current_transfer(ctlr);
@@ -448,7 +444,7 @@ static int cdns_transfer_one(struct spi_controller *ctlr,
448444
cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1);
449445
}
450446

451-
cdns_spi_fill_tx_fifo(xspi, xspi->tx_fifo_depth);
447+
cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0);
452448
spi_transfer_delay_exec(transfer);
453449

454450
cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT);

0 commit comments

Comments
 (0)