spi: sh-msiof: Double maximum DMA transfer size using two groups
authorGeert Uytterhoeven <geert+renesas@glider.be>
Fri, 16 May 2025 13:32:22 +0000 (15:32 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 19 May 2025 10:55:35 +0000 (11:55 +0100)
The maximum DMA transfer size is limited by the maximum values that can
be written to the word count fields (WDLENx) in the Transmit and Control
Data Registers (SITDR2/SIRDR2).  As all MSIOF variants support
transferring data of multiple (two or four) groups, the maximum size can
be doubled by using two groups instead of one, thus reducing setup
overhead for very large SPI transfers.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/bad522c76b8d225c195433977b22f95015cf2612.1747401908.git.geert+renesas@glider.be
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-sh-msiof.c

index 2b8c143b2121952134a9c42160210ccd64eabb74..4d9a44118e1c9d6c394ffb208c05ecc328fb671c 100644 (file)
@@ -767,10 +767,12 @@ static void sh_msiof_dma_complete(void *arg)
 }
 
 static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
-                            void *rx, unsigned int len)
+                            void *rx, unsigned int len,
+                            unsigned int max_wdlen)
 {
        u32 ier_bits = 0;
        struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
+       unsigned int words1, words2;
        dma_cookie_t cookie;
        int ret;
 
@@ -817,7 +819,9 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
                       FIELD_PREP(SIFCTR_RFWM, SIFCTR_RFWM_1));
 
        /* setup msiof transfer mode registers (32-bit words) */
-       sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4, 0);
+       words1 = min(len / 4, max_wdlen);
+       words2 = len / 4 - words1;
+       sh_msiof_spi_set_mode_regs(p, tx, rx, 32, words1, words2);
 
        sh_msiof_write(p, SIIER, ier_bits);
 
@@ -969,7 +973,7 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
                 *  DMA supports 32-bit words only, hence pack 8-bit and 16-bit
                 *  words, with byte resp. word swapping.
                 */
-               unsigned int l = min(round_down(len, 4), max_wdlen * 4);
+               unsigned int l = min(round_down(len, 4), 2 * max_wdlen * 4);
 
                if (bits <= 8) {
                        copy32 = copy_bswap32;
@@ -982,7 +986,7 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr,
                if (tx_buf)
                        copy32(p->tx_dma_page, tx_buf, l / 4);
 
-               ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l);
+               ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l, max_wdlen);
                if (ret == -EAGAIN) {
                        dev_warn_once(&p->pdev->dev,
                                "DMA not available, falling back to PIO\n");