mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 14:42:34 -04:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user