Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: sh-msiof: Double maximum DMA transfer size using two groups

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>

authored by

Geert Uytterhoeven and committed by
Mark Brown
acb47aa9 39d0856f

+8 -4
+8 -4
drivers/spi/spi-sh-msiof.c
··· 767 767 } 768 768 769 769 static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, 770 - void *rx, unsigned int len) 770 + void *rx, unsigned int len, 771 + unsigned int max_wdlen) 771 772 { 772 773 u32 ier_bits = 0; 773 774 struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; 775 + unsigned int words1, words2; 774 776 dma_cookie_t cookie; 775 777 int ret; 776 778 ··· 819 817 FIELD_PREP(SIFCTR_RFWM, SIFCTR_RFWM_1)); 820 818 821 819 /* setup msiof transfer mode registers (32-bit words) */ 822 - sh_msiof_spi_set_mode_regs(p, tx, rx, 32, len / 4, 0); 820 + words1 = min(len / 4, max_wdlen); 821 + words2 = len / 4 - words1; 822 + sh_msiof_spi_set_mode_regs(p, tx, rx, 32, words1, words2); 823 823 824 824 sh_msiof_write(p, SIIER, ier_bits); 825 825 ··· 973 969 * DMA supports 32-bit words only, hence pack 8-bit and 16-bit 974 970 * words, with byte resp. word swapping. 975 971 */ 976 - unsigned int l = min(round_down(len, 4), max_wdlen * 4); 972 + unsigned int l = min(round_down(len, 4), 2 * max_wdlen * 4); 977 973 978 974 if (bits <= 8) { 979 975 copy32 = copy_bswap32; ··· 986 982 if (tx_buf) 987 983 copy32(p->tx_dma_page, tx_buf, l / 4); 988 984 989 - ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l); 985 + ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l, max_wdlen); 990 986 if (ret == -EAGAIN) { 991 987 dev_warn_once(&p->pdev->dev, 992 988 "DMA not available, falling back to PIO\n");