diff options
author | Mark Brown <broonie@kernel.org> | 2020-03-04 18:28:57 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-03-04 18:28:57 +0000 |
commit | cb71d8efd74c588fc68cce2180a4861091e8fe8a (patch) | |
tree | 2d7591ae4fe588e1a14e4d2d6101a54f5f27db40 /drivers/spi | |
parent | 4709d86ca3c8f845ff653690b0a97ad19dc5ba18 (diff) | |
parent | 50b62071deab48c1a69c471f9a7d0c8ff9ef23eb (diff) |
Merge series "Compatible string consolidation for NXP DSPI driver" from Vladimir Oltean <olteanv@gmail.com>:
This series makes room in the driver for differentiation between the
controllers which currently operate in TCFQ mode. Most of these are
actually capable of a lot more in terms of throughput. This is in
preparation of a second series which will convert the remaining users of
TCFQ mode altogether to XSPI mode with command cycling.
Vladimir Oltean (6):
doc: spi-fsl-dspi: Add specific compatibles for all Layerscape SoCs
spi: spi-fsl-dspi: Use specific compatible strings for all SoC
instantiations
spi: spi-fsl-dspi: Parameterize the FIFO size and DMA buffer size
spi: spi-fsl-dspi: LS2080A and LX2160A support XSPI mode
spi: spi-fsl-dspi: Support SPI software timestamping in all non-DMA
modes
spi: spi-fsl-dspi: Convert the instantiations that support it to DMA
.../devicetree/bindings/spi/spi-fsl-dspi.txt | 17 +-
drivers/spi/spi-fsl-dspi.c | 162 +++++++++++++-----
2 files changed, 128 insertions(+), 51 deletions(-)
--
2.17.1
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 162 |
1 files changed, 117 insertions, 45 deletions
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 6ec2dcb8c57a..c357c3247232 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -20,13 +20,6 @@ #define DRIVER_NAME "fsl-dspi" -#ifdef CONFIG_M5441x -#define DSPI_FIFO_SIZE 16 -#else -#define DSPI_FIFO_SIZE 4 -#endif -#define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024) - #define SPI_MCR 0x00 #define SPI_MCR_MASTER BIT(31) #define SPI_MCR_PCSIS (0x3F << 16) @@ -129,35 +122,87 @@ enum dspi_trans_mode { struct fsl_dspi_devtype_data { enum dspi_trans_mode trans_mode; u8 max_clock_factor; - bool ptp_sts_supported; bool xspi_mode; + int fifo_size; + int dma_bufsize; }; -static const struct fsl_dspi_devtype_data vf610_data = { - .trans_mode = DSPI_DMA_MODE, - .max_clock_factor = 2, -}; - -static const struct fsl_dspi_devtype_data ls1021a_v1_data = { - .trans_mode = DSPI_TCFQ_MODE, - .max_clock_factor = 8, - .ptp_sts_supported = true, - .xspi_mode = true, -}; - -static const struct fsl_dspi_devtype_data ls2085a_data = { - .trans_mode = DSPI_TCFQ_MODE, - .max_clock_factor = 8, - .ptp_sts_supported = true, +enum { + LS1021A, + LS1012A, + LS1043A, + LS1046A, + LS2080A, + LS2085A, + LX2160A, + MCF5441X, + VF610, }; -static const struct fsl_dspi_devtype_data coldfire_data = { - .trans_mode = DSPI_EOQ_MODE, - .max_clock_factor = 8, +static const struct fsl_dspi_devtype_data devtype_data[] = { + [VF610] = { + .trans_mode = DSPI_DMA_MODE, + .max_clock_factor = 2, + .dma_bufsize = 4096, + .fifo_size = 4, + }, + [LS1021A] = { + /* Has A-011218 DMA erratum */ + .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 4, + }, + [LS1012A] = { + /* Has A-011218 DMA erratum */ + .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 16, + }, + [LS1043A] = { + /* Has A-011218 DMA erratum */ + .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 16, + }, + [LS1046A] = { + /* Has A-011218 DMA erratum */ + .trans_mode = DSPI_TCFQ_MODE, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 16, + }, + [LS2080A] = { + .trans_mode = DSPI_DMA_MODE, + .dma_bufsize = 8, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 4, + }, + [LS2085A] = { + .trans_mode = DSPI_DMA_MODE, + .dma_bufsize = 8, + .max_clock_factor = 8, + .fifo_size = 4, + }, + [LX2160A] = { + .trans_mode = DSPI_DMA_MODE, + .dma_bufsize = 8, + .max_clock_factor = 8, + .xspi_mode = true, + .fifo_size = 4, + }, + [MCF5441X] = { + .trans_mode = DSPI_EOQ_MODE, + .max_clock_factor = 8, + .fifo_size = 16, + }, }; struct fsl_dspi_dma { - /* Length of transfer in words of DSPI_FIFO_SIZE */ + /* Length of transfer in words of dspi->fifo_size */ u32 curr_xfer_len; u32 *tx_dma_buf; @@ -358,7 +403,8 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi) int ret = 0; curr_remaining_bytes = dspi->len; - bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; + bytes_per_buffer = dspi->devtype_data->dma_bufsize / + dspi->devtype_data->fifo_size; while (curr_remaining_bytes) { /* Check if current transfer fits the DMA buffer */ dma->curr_xfer_len = curr_remaining_bytes @@ -410,14 +456,14 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) goto err_tx_channel; } - dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, + dma->tx_dma_buf = dma_alloc_coherent(dev, dspi->devtype_data->dma_bufsize, &dma->tx_dma_phys, GFP_KERNEL); if (!dma->tx_dma_buf) { ret = -ENOMEM; goto err_tx_dma_buf; } - dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE, + dma->rx_dma_buf = dma_alloc_coherent(dev, dspi->devtype_data->dma_bufsize, &dma->rx_dma_phys, GFP_KERNEL); if (!dma->rx_dma_buf) { ret = -ENOMEM; @@ -454,11 +500,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) return 0; err_slave_config: - dma_free_coherent(dev, DSPI_DMA_BUFSIZE, - dma->rx_dma_buf, dma->rx_dma_phys); + dma_free_coherent(dev, dspi->devtype_data->dma_bufsize, + dma->rx_dma_buf, dma->rx_dma_phys); err_rx_dma_buf: - dma_free_coherent(dev, DSPI_DMA_BUFSIZE, - dma->tx_dma_buf, dma->tx_dma_phys); + dma_free_coherent(dev, dspi->devtype_data->dma_bufsize, + dma->tx_dma_buf, dma->tx_dma_phys); err_tx_dma_buf: dma_release_channel(dma->chan_tx); err_tx_channel: @@ -480,13 +526,15 @@ static void dspi_release_dma(struct fsl_dspi *dspi) if (dma->chan_tx) { dma_unmap_single(dev, dma->tx_dma_phys, - DSPI_DMA_BUFSIZE, DMA_TO_DEVICE); + dspi->devtype_data->dma_bufsize, + DMA_TO_DEVICE); dma_release_channel(dma->chan_tx); } if (dma->chan_rx) { dma_unmap_single(dev, dma->rx_dma_phys, - DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE); + dspi->devtype_data->dma_bufsize, + DMA_FROM_DEVICE); dma_release_channel(dma->chan_rx); } } @@ -618,7 +666,7 @@ static void dspi_tcfq_read(struct fsl_dspi *dspi) static void dspi_eoq_write(struct fsl_dspi *dspi) { - int fifo_size = DSPI_FIFO_SIZE; + int fifo_size = dspi->devtype_data->fifo_size; u16 xfer_cmd = dspi->tx_cmd; /* Fill TX FIFO with as many transfers as possible */ @@ -628,7 +676,7 @@ static void dspi_eoq_write(struct fsl_dspi *dspi) if (dspi->len == dspi->bytes_per_word || fifo_size == 0) dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ; /* Clear transfer count for first transfer in FIFO */ - if (fifo_size == (DSPI_FIFO_SIZE - 1)) + if (fifo_size == (dspi->devtype_data->fifo_size - 1)) dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; /* Write combined TX FIFO and CMD FIFO entry */ fifo_write(dspi); @@ -637,7 +685,7 @@ static void dspi_eoq_write(struct fsl_dspi *dspi) static void dspi_eoq_read(struct fsl_dspi *dspi) { - int fifo_size = DSPI_FIFO_SIZE; + int fifo_size = dspi->devtype_data->fifo_size; /* Read one FIFO entry and push to rx buffer */ while ((dspi->rx < dspi->rx_end) && fifo_size--) @@ -909,9 +957,31 @@ static void dspi_cleanup(struct spi_device *spi) } static const struct of_device_id fsl_dspi_dt_ids[] = { - { .compatible = "fsl,vf610-dspi", .data = &vf610_data, }, - { .compatible = "fsl,ls1021a-v1.0-dspi", .data = &ls1021a_v1_data, }, - { .compatible = "fsl,ls2085a-dspi", .data = &ls2085a_data, }, + { + .compatible = "fsl,vf610-dspi", + .data = &devtype_data[VF610], + }, { + .compatible = "fsl,ls1021a-v1.0-dspi", + .data = &devtype_data[LS1021A], + }, { + .compatible = "fsl,ls1012a-dspi", + .data = &devtype_data[LS1012A], + }, { + .compatible = "fsl,ls1043a-dspi", + .data = &devtype_data[LS1043A], + }, { + .compatible = "fsl,ls1046a-dspi", + .data = &devtype_data[LS1046A], + }, { + .compatible = "fsl,ls2080a-dspi", + .data = &devtype_data[LS2080A], + }, { + .compatible = "fsl,ls2085a-dspi", + .data = &devtype_data[LS2085A], + }, { + .compatible = "fsl,lx2160a-dspi", + .data = &devtype_data[LX2160A], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids); @@ -1064,7 +1134,8 @@ static int dspi_probe(struct platform_device *pdev) ctlr->num_chipselect = pdata->cs_num; ctlr->bus_num = pdata->bus_num; - dspi->devtype_data = &coldfire_data; + /* Only Coldfire uses platform data */ + dspi->devtype_data = &devtype_data[MCF5441X]; } else { ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); @@ -1174,7 +1245,8 @@ poll_mode: ctlr->max_speed_hz = clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor; - ctlr->ptp_sts_supported = dspi->devtype_data->ptp_sts_supported; + if (dspi->devtype_data->trans_mode != DSPI_DMA_MODE) + ctlr->ptp_sts_supported = true; platform_set_drvdata(pdev, ctlr); |