]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mmc: dw_mmc: implement option for configuring DMA threshold
authorKaustabh Chakraborty <kauschluss@disroot.org>
Wed, 15 Apr 2026 15:02:08 +0000 (20:32 +0530)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 11 May 2026 14:25:01 +0000 (16:25 +0200)
Some controllers, such as certain Exynos SDIO ones, are unable to
perform DMA transfers of small amount of bytes properly. Following the
device tree schema, implement the property to define the DMA transfer
threshold (from a hard coded value of 16 bytes) so that lesser number of
bytes can be transferred safely skipping DMA in such controllers. The
value of 16 bytes stays as the default for controllers which do not
define it. This value can be overridden by implementation-specific init
sequences.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/dw_mmc.c
drivers/mmc/host/dw_mmc.h

index 20193ee7b73eb097d545e3e7a93ff9a896d43be2..3b4157f34d11f35858dae2c2202329e043ef5ade 100644 (file)
@@ -40,7 +40,6 @@
                                 SDMMC_INT_RESP_ERR | SDMMC_INT_HLE)
 #define DW_MCI_ERROR_FLAGS     (DW_MCI_DATA_ERROR_FLAGS | \
                                 DW_MCI_CMD_ERROR_FLAGS)
-#define DW_MCI_DMA_THRESHOLD   16
 
 #define DW_MCI_FREQ_MAX        200000000       /* unit: HZ */
 #define DW_MCI_FREQ_MIN        100000          /* unit: HZ */
@@ -821,7 +820,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
         * non-word-aligned buffers or lengths. Also, we don't bother
         * with all the DMA setup overhead for short transfers.
         */
-       if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
+       if (data->blocks * data->blksz < host->dma_threshold)
                return -EINVAL;
 
        if (data->blksz & 3)
@@ -3185,6 +3184,7 @@ struct dw_mci *dw_mci_alloc_host(struct device *dev)
        host = mmc_priv(mmc);
        host->mmc = mmc;
        host->dev = dev;
+       host->dma_threshold = 16;
 
        return host;
 }
index 14fb2b309c7c6b94cd104cd79c5adbb4e7bccd18..2ce8585e2c1e5c085d95789c54427cbe8551362e 100644 (file)
@@ -107,6 +107,7 @@ struct dw_mci_dma_slave {
  * @ciu_clk: Pointer to card interface unit clock instance.
  * @fifo_depth: depth of FIFO.
  * @data_addr_override: override fifo reg offset with this value.
+ * @dma_threshold: data threshold value in bytes to carry out a DMA transfer.
  * @wm_aligned: force fifo watermark equal with data length in PIO mode.
  *     Set as true if alignment is needed.
  * @data_shift: log2 of FIFO item size.
@@ -163,6 +164,7 @@ struct dw_mci {
        void __iomem            *regs;
        void __iomem            *fifo_reg;
        u32                     data_addr_override;
+       u32                     dma_threshold;
        bool                    wm_aligned;
 
        struct scatterlist      *sg;