public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Configuring DMA threshold value for DW-MMC controllers
@ 2026-04-14  8:35 Kaustabh Chakraborty
  2026-04-14  8:36 ` [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold Kaustabh Chakraborty
  2026-04-14  8:36 ` [PATCH v2 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870 Kaustabh Chakraborty
  0 siblings, 2 replies; 5+ messages in thread
From: Kaustabh Chakraborty @ 2026-04-14  8:35 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jaehoon Chung, Shawn Lin, Krzysztof Kozlowski, Alim Akhtar
  Cc: linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, Kaustabh Chakraborty

In Samsung Exynos 7870 devices with Broadcom Wi-Fi, it has been observed
that small sized DMA transfers are unreliable and are not written
properly, which renders the cache incoherent.

Experimental observations say that DMA transfer sizes of somewhere
around 64 to 512 are intolerable. We must thus implement a mechanism to
fall back to PIO transfer in this case. One such approach, which this
series implements is allowing the DMA transfer threshold, which is
already defined in the driver, to be configurable.

Note that this patch is likely to be labelled as a workaround. These
smaller transfers seem to be successful from downstream kernels,
however efforts to figure out how so went in vain. It is also very
possible that the downstream Broadcom Wi-Fi SDIO driver uses PIO
transfers as well.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
Changes in v2:
- Remove dt-binding to set DMA threshold (Krzysztof Kozlowski)
- Add comment to describe struct dw_mci::dma_threshold (Shawn Lin)
- Set DMA threshold in Exynos 7870 DW-MMC driver (Krzysztof Kozlowski)
- Link to v1: https://lore.kernel.org/r/20260412-dwmmc-dma-thr-v1-0-75a2f658eee3@disroot.org

---
Kaustabh Chakraborty (2):
      mmc: dw_mmc: implement option for configuring DMA threshold
      mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870

 drivers/mmc/host/dw_mmc-exynos.c | 1 +
 drivers/mmc/host/dw_mmc.c        | 5 +++--
 drivers/mmc/host/dw_mmc.h        | 2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)
---
base-commit: 1c7cc4904160c6fc6377564140062d68a3dc93a0
change-id: 20260412-dwmmc-dma-thr-1090d8285ea7

Best regards,
-- 
Kaustabh Chakraborty <kauschluss@disroot.org>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
  2026-04-14  8:35 [PATCH v2 0/2] Configuring DMA threshold value for DW-MMC controllers Kaustabh Chakraborty
@ 2026-04-14  8:36 ` Kaustabh Chakraborty
  2026-04-14  8:50   ` Shawn Lin
  2026-04-14  8:36 ` [PATCH v2 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870 Kaustabh Chakraborty
  1 sibling, 1 reply; 5+ messages in thread
From: Kaustabh Chakraborty @ 2026-04-14  8:36 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jaehoon Chung, Shawn Lin, Krzysztof Kozlowski, Alim Akhtar
  Cc: linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, Kaustabh Chakraborty

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>
---
 drivers/mmc/host/dw_mmc.c | 5 +++--
 drivers/mmc/host/dw_mmc.h | 2 ++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 20193ee7b73eb..9dd9fed4ccf49 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -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)
@@ -3245,6 +3244,8 @@ int dw_mci_probe(struct dw_mci *host)
 		goto err_clk_ciu;
 	}
 
+	host->dma_threshold = 16;
+
 	if (host->rstc) {
 		reset_control_assert(host->rstc);
 		usleep_range(10, 50);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 42e58be74ce09..fc7601fba849f 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -164,6 +164,8 @@ struct dw_mci {
 	void __iomem		*fifo_reg;
 	u32			data_addr_override;
 	bool			wm_aligned;
+	/* Configurable data byte threshold value for DMA transfer. */
+	u32			dma_threshold;
 
 	struct scatterlist	*sg;
 	struct sg_mapping_iter	sg_miter;

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870
  2026-04-14  8:35 [PATCH v2 0/2] Configuring DMA threshold value for DW-MMC controllers Kaustabh Chakraborty
  2026-04-14  8:36 ` [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold Kaustabh Chakraborty
@ 2026-04-14  8:36 ` Kaustabh Chakraborty
  1 sibling, 0 replies; 5+ messages in thread
From: Kaustabh Chakraborty @ 2026-04-14  8:36 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jaehoon Chung, Shawn Lin, Krzysztof Kozlowski, Alim Akhtar
  Cc: linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc, Kaustabh Chakraborty

Exynos 7870 compatible controllers, such as SDIO ones are not able to
perform DMA transfers for small sizes of data (~16 to ~512 bytes),
resulting in cache issues in subsequent transfers. Increase the DMA
transfer threshold to 512 to allow the shorter transfers to take place,
bypassing DMA.

Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
 drivers/mmc/host/dw_mmc-exynos.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 261344d3a8cfe..4b76b997ddc15 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -141,6 +141,7 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
 		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) {
 		/* Quirk needed for certain Exynos SoCs */
 		host->quirks |= DW_MMC_QUIRK_FIFO64_32;
+		host->dma_threshold = 512;
 	}
 
 	if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
  2026-04-14  8:36 ` [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold Kaustabh Chakraborty
@ 2026-04-14  8:50   ` Shawn Lin
  2026-04-14 10:49     ` Kaustabh Chakraborty
  0 siblings, 1 reply; 5+ messages in thread
From: Shawn Lin @ 2026-04-14  8:50 UTC (permalink / raw)
  To: Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
	Krzysztof Kozlowski, Alim Akhtar
  Cc: shawn.lin, linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc

在 2026/04/14 星期二 16:36, Kaustabh Chakraborty 写道:
> 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>
> ---
>   drivers/mmc/host/dw_mmc.c | 5 +++--
>   drivers/mmc/host/dw_mmc.h | 2 ++
>   2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 20193ee7b73eb..9dd9fed4ccf49 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -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)
> @@ -3245,6 +3244,8 @@ int dw_mci_probe(struct dw_mci *host)
>   		goto err_clk_ciu;
>   	}
>   
> +	host->dma_threshold = 16;

I'd prefer to set it in dw_mci_alloc_host() instead of picking up
a random place to put it, for better code management.

> +
>   	if (host->rstc) {
>   		reset_control_assert(host->rstc);
>   		usleep_range(10, 50);
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 42e58be74ce09..fc7601fba849f 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -164,6 +164,8 @@ struct dw_mci {
>   	void __iomem		*fifo_reg;
>   	u32			data_addr_override;
>   	bool			wm_aligned;
> +	/* Configurable data byte threshold value for DMA transfer. */

No here, there is a long section of comment before struct dw_mci{ } that
describes each member of it, please add it there.

> +	u32			dma_threshold;
>   
>   	struct scatterlist	*sg;
>   	struct sg_mapping_iter	sg_miter;
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
  2026-04-14  8:50   ` Shawn Lin
@ 2026-04-14 10:49     ` Kaustabh Chakraborty
  0 siblings, 0 replies; 5+ messages in thread
From: Kaustabh Chakraborty @ 2026-04-14 10:49 UTC (permalink / raw)
  To: Shawn Lin, Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
	Krzysztof Kozlowski, Alim Akhtar
  Cc: linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc

On 2026-04-14 16:50 +08:00, Shawn Lin wrote:
> 在 2026/04/14 星期二 16:36, Kaustabh Chakraborty 写道:
>> 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>
>> ---
>>   drivers/mmc/host/dw_mmc.c | 5 +++--
>>   drivers/mmc/host/dw_mmc.h | 2 ++
>>   2 files changed, 5 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 20193ee7b73eb..9dd9fed4ccf49 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -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)
>> @@ -3245,6 +3244,8 @@ int dw_mci_probe(struct dw_mci *host)
>>   		goto err_clk_ciu;
>>   	}
>>   
>> +	host->dma_threshold = 16;
>
> I'd prefer to set it in dw_mci_alloc_host() instead of picking up
> a random place to put it, for better code management.

Okay, that function is in -next I see.

>
>> +
>>   	if (host->rstc) {
>>   		reset_control_assert(host->rstc);
>>   		usleep_range(10, 50);
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 42e58be74ce09..fc7601fba849f 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -164,6 +164,8 @@ struct dw_mci {
>>   	void __iomem		*fifo_reg;
>>   	u32			data_addr_override;
>>   	bool			wm_aligned;
>> +	/* Configurable data byte threshold value for DMA transfer. */
>
> No here, there is a long section of comment before struct dw_mci{ } that
> describes each member of it, please add it there.

Ah, you mean the documenting comment. Shouldn't have missed in either
way.

>
>> +	u32			dma_threshold;
>>   
>>   	struct scatterlist	*sg;
>>   	struct sg_mapping_iter	sg_miter;
>> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-04-14 10:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-14  8:35 [PATCH v2 0/2] Configuring DMA threshold value for DW-MMC controllers Kaustabh Chakraborty
2026-04-14  8:36 ` [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold Kaustabh Chakraborty
2026-04-14  8:50   ` Shawn Lin
2026-04-14 10:49     ` Kaustabh Chakraborty
2026-04-14  8:36 ` [PATCH v2 2/2] mmc: dw_mmc: exynos: increase DMA threshold value for exynos7870 Kaustabh Chakraborty

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox