spi: spi-fsl-dspi: Use whole page for DMA buffers

dma_alloc_noncoherent() allocations are backed by a full page anyway, so
use it all.

VF610 devices used to use the full page before commit a957499bd4
("spi: spi-fsl-dspi: Fix bits-per-word acceleration in DMA mode"), but
others still used the FIFO size. After that commit, all devices used the
FIFO size. Now all devices use the full page.

Signed-off-by: James Clark <james.clark@linaro.org>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Message-ID: <20250902-james-nxp-spi-dma-v6-5-f7aa2c5e56e2@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
James Clark
2025-09-02 13:44:57 +01:00
committed by Mark Brown
parent 36db0b03d3
commit fbb618e11f

View File

@@ -331,6 +331,8 @@ struct fsl_dspi_dma {
dma_addr_t rx_dma_phys;
struct completion cmd_rx_complete;
struct dma_async_tx_descriptor *rx_desc;
size_t bufsize;
};
struct fsl_dspi {
@@ -493,6 +495,24 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi)
return cmd << 16 | data;
}
static size_t dspi_dma_max_datawords(struct fsl_dspi *dspi)
{
/*
* Transfers look like one of these, so we always use a full DMA word
* regardless of SPI word size:
*
* 31 16 15 0
* -----------------------------------------
* | CONTROL WORD | 16-bit DATA |
* -----------------------------------------
* or
* -----------------------------------------
* | CONTROL WORD | UNUSED | 8-bit DATA |
* -----------------------------------------
*/
return dspi->dma->bufsize / DMA_SLAVE_BUSWIDTH_4_BYTES;
}
static size_t dspi_dma_transfer_size(struct fsl_dspi *dspi)
{
return dspi->words_in_flight * DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -620,9 +640,8 @@ static void dspi_dma_xfer(struct fsl_dspi *dspi)
/* Figure out operational bits-per-word for this chunk */
dspi_setup_accel(dspi);
dspi->words_in_flight = dspi->len / dspi->oper_word_size;
if (dspi->words_in_flight > dspi->devtype_data->fifo_size)
dspi->words_in_flight = dspi->devtype_data->fifo_size;
dspi->words_in_flight = min(dspi->len / dspi->oper_word_size,
dspi_dma_max_datawords(dspi));
message->actual_length += dspi->words_in_flight *
dspi->oper_word_size;
@@ -637,7 +656,6 @@ static void dspi_dma_xfer(struct fsl_dspi *dspi)
static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
{
int dma_bufsize = dspi->devtype_data->fifo_size * 2;
struct device *dev = &dspi->pdev->dev;
struct dma_slave_config cfg;
struct fsl_dspi_dma *dma;
@@ -657,8 +675,10 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
goto err_tx_channel;
}
dma->bufsize = PAGE_SIZE;
dma->tx_dma_buf = dma_alloc_noncoherent(dma->chan_tx->device->dev,
dma_bufsize, &dma->tx_dma_phys,
dma->bufsize, &dma->tx_dma_phys,
DMA_TO_DEVICE, GFP_KERNEL);
if (!dma->tx_dma_buf) {
ret = -ENOMEM;
@@ -666,7 +686,7 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
}
dma->rx_dma_buf = dma_alloc_noncoherent(dma->chan_rx->device->dev,
dma_bufsize, &dma->rx_dma_phys,
dma->bufsize, &dma->rx_dma_phys,
DMA_FROM_DEVICE, GFP_KERNEL);
if (!dma->rx_dma_buf) {
ret = -ENOMEM;
@@ -702,11 +722,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
return 0;
err_slave_config:
dma_free_noncoherent(dma->chan_rx->device->dev, dma_bufsize,
dma_free_noncoherent(dma->chan_rx->device->dev, dma->bufsize,
dma->rx_dma_buf, dma->rx_dma_phys,
DMA_FROM_DEVICE);
err_rx_dma_buf:
dma_free_noncoherent(dma->chan_tx->device->dev, dma_bufsize,
dma_free_noncoherent(dma->chan_tx->device->dev, dma->bufsize,
dma->tx_dma_buf, dma->tx_dma_phys, DMA_TO_DEVICE);
err_tx_dma_buf:
dma_release_channel(dma->chan_tx);
@@ -721,21 +741,20 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
static void dspi_release_dma(struct fsl_dspi *dspi)
{
int dma_bufsize = dspi->devtype_data->fifo_size * 2;
struct fsl_dspi_dma *dma = dspi->dma;
if (!dma)
return;
if (dma->chan_tx) {
dma_free_noncoherent(dma->chan_tx->device->dev, dma_bufsize,
dma_free_noncoherent(dma->chan_tx->device->dev, dma->bufsize,
dma->tx_dma_buf, dma->tx_dma_phys,
DMA_TO_DEVICE);
dma_release_channel(dma->chan_tx);
}
if (dma->chan_rx) {
dma_free_noncoherent(dma->chan_rx->device->dev, dma_bufsize,
dma_free_noncoherent(dma->chan_rx->device->dev, dma->bufsize,
dma->rx_dma_buf, dma->rx_dma_phys,
DMA_FROM_DEVICE);
dma_release_channel(dma->chan_rx);