Skip to content

Commit 7b40322

Browse files
larsclausenbroonie
authored andcommitted
spi: cadence: Detect transmit FIFO depth
The depth of the transmit FIFO for the Cadence SPI controller is currently hardcoded to 128. But the depth is a synthesis configuration parameter of the core and can vary between different SoCs. If the configured FIFO size is less than 128 the driver will busy loop in the cdns_spi_fill_tx_fifo() function waiting for FIFO space to become available. Depending on the length and speed of the transfer it can spin for a significant amount of time. The cdns_spi_fill_tx_fifo() function is called from the drivers interrupt handler, so it can leave interrupts disabled for a prolonged amount of time. In addition the read FIFO will also overflow and data will be discarded. To avoid this detect the actual size of the FIFO and use that rather than the hardcoded value. To detect the FIFO size the FIFO threshold register is used. The register is sized so that it can hold FIFO size - 1 as its maximum value. Bits that are not needed to hold the threshold value will always read 0. By writing 0xffff to the register and then reading back the value in the register we get the FIFO size. Signed-off-by: Lars-Peter Clausen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 21b511d commit 7b40322

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

drivers/spi/spi-cadence.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@
9393
#define CDNS_SPI_ER_ENABLE 0x00000001 /* SPI Enable Bit Mask */
9494
#define CDNS_SPI_ER_DISABLE 0x0 /* SPI Disable Bit Mask */
9595

96-
/* SPI FIFO depth in bytes */
97-
#define CDNS_SPI_FIFO_DEPTH 128
98-
9996
/* Default number of chip select lines */
10097
#define CDNS_SPI_DEFAULT_NUM_CS 4
10198

@@ -111,6 +108,7 @@
111108
* @rx_bytes: Number of bytes requested
112109
* @dev_busy: Device busy flag
113110
* @is_decoded_cs: Flag for decoder property set or not
111+
* @tx_fifo_depth: Depth of the TX FIFO
114112
*/
115113
struct cdns_spi {
116114
void __iomem *regs;
@@ -124,6 +122,7 @@ struct cdns_spi {
124122
int rx_bytes;
125123
u8 dev_busy;
126124
u32 is_decoded_cs;
125+
unsigned int tx_fifo_depth;
127126
};
128127

129128
/* Macros for the SPI controller read/write */
@@ -305,7 +304,7 @@ static void cdns_spi_fill_tx_fifo(struct cdns_spi *xspi)
305304
{
306305
unsigned long trans_cnt = 0;
307306

308-
while ((trans_cnt < CDNS_SPI_FIFO_DEPTH) &&
307+
while ((trans_cnt < xspi->tx_fifo_depth) &&
309308
(xspi->tx_bytes > 0)) {
310309

311310
/* When xspi in busy condition, bytes may send failed,
@@ -469,6 +468,24 @@ static int cdns_unprepare_transfer_hardware(struct spi_master *master)
469468
return 0;
470469
}
471470

471+
/**
472+
* cdns_spi_detect_fifo_depth - Detect the FIFO depth of the hardware
473+
* @xspi: Pointer to the cdns_spi structure
474+
*
475+
* The depth of the TX FIFO is a synthesis configuration parameter of the SPI
476+
* IP. The FIFO threshold register is sized so that its maximum value can be the
477+
* FIFO size - 1. This is used to detect the size of the FIFO.
478+
*/
479+
static void cdns_spi_detect_fifo_depth(struct cdns_spi *xspi)
480+
{
481+
/* The MSBs will get truncated giving us the size of the FIFO */
482+
cdns_spi_write(xspi, CDNS_SPI_THLD, 0xffff);
483+
xspi->tx_fifo_depth = cdns_spi_read(xspi, CDNS_SPI_THLD) + 1;
484+
485+
/* Reset to default */
486+
cdns_spi_write(xspi, CDNS_SPI_THLD, 0x1);
487+
}
488+
472489
/**
473490
* cdns_spi_probe - Probe method for the SPI driver
474491
* @pdev: Pointer to the platform_device structure
@@ -541,6 +558,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
541558
if (ret < 0)
542559
xspi->is_decoded_cs = 0;
543560

561+
cdns_spi_detect_fifo_depth(xspi);
562+
544563
/* SPI controller initializations */
545564
cdns_spi_init_hw(xspi);
546565

0 commit comments

Comments
 (0)