From: James Clark <james.clark@linaro.org>
To: Vladimir Oltean <olteanv@gmail.com>,
Mark Brown <broonie@kernel.org>,
Vladimir Oltean <vladimir.oltean@nxp.com>,
Arnd Bergmann <arnd@arndb.de>,
Larisa Grigore <larisa.grigore@nxp.com>,
Frank Li <Frank.li@nxp.com>, Christoph Hellwig <hch@lst.de>
Cc: linux-spi@vger.kernel.org, imx@lists.linux.dev,
linux-kernel@vger.kernel.org,
James Clark <james.clark@linaro.org>
Subject: [PATCH v4 5/6] spi: spi-fsl-dspi: Increase DMA buffer size
Date: Fri, 27 Jun 2025 11:21:41 +0100 [thread overview]
Message-ID: <20250627-james-nxp-spi-dma-v4-5-178dba20c120@linaro.org> (raw)
In-Reply-To: <20250627-james-nxp-spi-dma-v4-0-178dba20c120@linaro.org>
From: Larisa Grigore <larisa.grigore@nxp.com>
When the device is configured as a target, the host won't stop sending
data while we're draining the buffer which leads to FIFO underflows
and corruption.
Increase the DMA buffer size to the maximum words that edma can
transfer once to reduce the chance of this happening.
While we're here, also change the buffer size for host mode back to a
page as it was before commit a957499bd437 ("spi: spi-fsl-dspi: Fix
bits-per-word acceleration in DMA mode"). dma_alloc_noncoherent()
allocations are backed by a full page anyway, so we might as well use it
all.
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
drivers/spi/spi-fsl-dspi.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index e7856f9c9440..46d3cae9efed 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -493,6 +493,39 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi)
return cmd << 16 | data;
}
+static int dspi_dma_bufsize(struct fsl_dspi *dspi)
+{
+ if (spi_controller_is_target(dspi->ctlr)) {
+ /*
+ * In target mode we have to be ready to receive the maximum
+ * that can possibly be transferred at once by EDMA without any
+ * FIFO underflows. This is CITER * SSIZE, where SSIZE is a max
+ * of 4 when transferring to a peripheral.
+ */
+ return GENMASK(14, 0) * DMA_SLAVE_BUSWIDTH_4_BYTES;
+ }
+
+ return PAGE_SIZE;
+}
+
+static int dspi_dma_max_datawords(struct fsl_dspi *dspi)
+{
+ /*
+ * Transfers look like this 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(dspi) / DMA_SLAVE_BUSWIDTH_4_BYTES;
+}
+
static int dspi_dma_transfer_size(struct fsl_dspi *dspi)
{
return dspi->words_in_flight * DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -608,6 +641,7 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
static void dspi_dma_xfer(struct fsl_dspi *dspi)
{
struct spi_message *message = dspi->cur_msg;
+ int max_words = dspi_dma_max_datawords(dspi);
struct device *dev = &dspi->pdev->dev;
/*
@@ -619,8 +653,8 @@ static void dspi_dma_xfer(struct fsl_dspi *dspi)
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;
+ if (dspi->words_in_flight > max_words)
+ dspi->words_in_flight = max_words;
message->actual_length += dspi->words_in_flight *
dspi->oper_word_size;
@@ -635,7 +669,7 @@ 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;
+ int dma_bufsize = dspi_dma_bufsize(dspi);
struct device *dev = &dspi->pdev->dev;
struct dma_slave_config cfg;
struct fsl_dspi_dma *dma;
@@ -719,7 +753,7 @@ 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;
+ int dma_bufsize = dspi_dma_bufsize(dspi);
struct fsl_dspi_dma *dma = dspi->dma;
if (!dma)
--
2.34.1
next prev parent reply other threads:[~2025-06-27 10:22 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-27 10:21 [PATCH v4 0/6] spi: spi-fsl-dspi: Target mode improvements James Clark
2025-06-27 10:21 ` [PATCH v4 1/6] spi: spi-fsl-dspi: Clear completion counter before initiating transfer James Clark
2025-06-27 19:41 ` Frank Li
2025-06-27 10:21 ` [PATCH v4 2/6] spi: spi-fsl-dspi: Store status directly in cur_msg->status James Clark
2025-06-27 21:30 ` Vladimir Oltean
2025-06-30 12:54 ` James Clark
2025-06-30 20:41 ` Vladimir Oltean
2025-07-01 10:02 ` James Clark
2025-07-21 13:25 ` James Clark
2025-07-21 13:39 ` Vladimir Oltean
2025-07-21 14:02 ` James Clark
2025-07-21 14:04 ` Mark Brown
2025-06-27 10:21 ` [PATCH v4 3/6] spi: spi-fsl-dspi: Stub out DMA functions James Clark
2025-06-27 10:21 ` [PATCH v4 4/6] spi: spi-fsl-dspi: Use non-coherent memory for DMA James Clark
2025-06-27 19:38 ` Frank Li
2025-06-27 10:21 ` James Clark [this message]
2025-06-27 19:44 ` [PATCH v4 5/6] spi: spi-fsl-dspi: Increase DMA buffer size Frank Li
2025-06-30 8:59 ` James Clark
2025-07-01 14:47 ` Vladimir Oltean
2025-07-01 15:08 ` James Clark
2025-07-01 15:09 ` Arnd Bergmann
2025-06-27 10:21 ` [PATCH v4 6/6] spi: spi-fsl-dspi: Report FIFO overflows as errors James Clark
2025-06-27 19:56 ` Frank Li
2025-06-27 21:41 ` Mark Brown
2025-06-30 10:46 ` James Clark
2025-06-30 11:40 ` (subset) [PATCH v4 0/6] spi: spi-fsl-dspi: Target mode improvements Mark Brown
2025-06-30 15:26 ` Vladimir Oltean
2025-07-01 12:42 ` James Clark
2025-07-01 13:18 ` Mark Brown
2025-07-01 13:57 ` Vladimir Oltean
2025-07-01 14:36 ` Mark Brown
2025-07-01 14:53 ` Vladimir Oltean
2025-07-01 15:16 ` Mark Brown
2025-07-01 15:24 ` Vladimir Oltean
2025-07-01 15:30 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250627-james-nxp-spi-dma-v4-5-178dba20c120@linaro.org \
--to=james.clark@linaro.org \
--cc=Frank.li@nxp.com \
--cc=arnd@arndb.de \
--cc=broonie@kernel.org \
--cc=hch@lst.de \
--cc=imx@lists.linux.dev \
--cc=larisa.grigore@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-spi@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=vladimir.oltean@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).