[RFC PATCH] mmc: sdhci-pci-gli: fix GL9750 DMA write corruption

Matthew Schwartz posted 1 patch 3 weeks ago
drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
1 file changed, 8 insertions(+)
[RFC PATCH] mmc: sdhci-pci-gli: fix GL9750 DMA write corruption
Posted by Matthew Schwartz 3 weeks ago
The GL9750 SD host controller has intermittent data corruption during
DMA write operations, which has been traced to an incorrect burst
configuration. This was discovered by comparing initialization sequences
between the working GL9767 controller and GL9750 and seeing that the
GM_BURST register was handled differently.

Clearing bits 16-17 eliminates the corruption with f3write/f3read tests
while maintaining full DMA write/read performance.

Fixes: e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")
Closes: https://lore.kernel.org/linux-mmc/33d12807-5c72-41ce-8679-57aa11831fad@linux.dev/
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---

Hi all,

I arrived at this after a whole bunch of guesswork based on the other
Genesys card readers in the kernel that do work, like GL9767. I landed on
register 0x510 which appears to be "GM_BURST_SIZE" and ended up going
through each bit and either setting it or masking it. Eventually, I
arrived at masking bits 16-17 which seemed to stabilize writes completely.

Could someone at Genesys confirm what this register is for on GL9750, and
what those bits are? At least locally, I have been able to run 50GB of
f3write/f3read without any corruption while before even 1GB would corrupt.
This also maintains the same read/write speed as before this change. I
tried searching online but was unable to find any relevant docs, and I'd
like to confirm the purpose of those bits before sending this out as v1.

Thanks,
Matt

---
 drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
index b0f91cc9e40e4..a06b0cf11f12d 100644
--- a/drivers/mmc/host/sdhci-pci-gli.c
+++ b/drivers/mmc/host/sdhci-pci-gli.c
@@ -26,6 +26,9 @@
 #define   GLI_9750_WT_EN_ON	    0x1
 #define   GLI_9750_WT_EN_OFF	    0x0
 
+#define SDHCI_GLI_9750_GM_BURST_SIZE		  0x510
+#define   SDHCI_GLI_9750_GM_BURST_SIZE_MASK	    GENMASK(17, 16)
+
 #define SDHCI_GLI_9750_CFG2          0x848
 #define   SDHCI_GLI_9750_CFG2_L1DLY    GENMASK(28, 24)
 #define   GLI_9750_CFG2_L1DLY_VALUE    0x1F
@@ -629,6 +632,11 @@ static void gl9750_hw_setting(struct sdhci_host *host)
 
 	gl9750_wt_on(host);
 
+	/* clear GM_BURST bits to avoid corruption with DMA writes */
+	value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+	value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_MASK;
+	sdhci_writel(host, value, SDHCI_GLI_9750_GM_BURST_SIZE);
+
 	value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
 	value &= ~SDHCI_GLI_9750_CFG2_L1DLY;
 	/* set ASPM L1 entry delay to 7.9us */
-- 
2.52.0
Re: [RFC PATCH] mmc: sdhci-pci-gli: fix GL9750 DMA write corruption
Posted by Adrian Hunter 1 week, 2 days ago
Genesys folks : Any comment on this?

On 18/01/2026 01:48, Matthew Schwartz wrote:
> The GL9750 SD host controller has intermittent data corruption during
> DMA write operations, which has been traced to an incorrect burst
> configuration. This was discovered by comparing initialization sequences
> between the working GL9767 controller and GL9750 and seeing that the
> GM_BURST register was handled differently.
> 
> Clearing bits 16-17 eliminates the corruption with f3write/f3read tests
> while maintaining full DMA write/read performance.
> 
> Fixes: e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")
> Closes: https://lore.kernel.org/linux-mmc/33d12807-5c72-41ce-8679-57aa11831fad@linux.dev/
> Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
> ---
> 
> Hi all,
> 
> I arrived at this after a whole bunch of guesswork based on the other
> Genesys card readers in the kernel that do work, like GL9767. I landed on
> register 0x510 which appears to be "GM_BURST_SIZE" and ended up going
> through each bit and either setting it or masking it. Eventually, I
> arrived at masking bits 16-17 which seemed to stabilize writes completely.
> 
> Could someone at Genesys confirm what this register is for on GL9750, and
> what those bits are? At least locally, I have been able to run 50GB of
> f3write/f3read without any corruption while before even 1GB would corrupt.
> This also maintains the same read/write speed as before this change. I
> tried searching online but was unable to find any relevant docs, and I'd
> like to confirm the purpose of those bits before sending this out as v1.
> 
> Thanks,
> Matt
> 
> ---
>  drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
> index b0f91cc9e40e4..a06b0cf11f12d 100644
> --- a/drivers/mmc/host/sdhci-pci-gli.c
> +++ b/drivers/mmc/host/sdhci-pci-gli.c
> @@ -26,6 +26,9 @@
>  #define   GLI_9750_WT_EN_ON	    0x1
>  #define   GLI_9750_WT_EN_OFF	    0x0
>  
> +#define SDHCI_GLI_9750_GM_BURST_SIZE		  0x510
> +#define   SDHCI_GLI_9750_GM_BURST_SIZE_MASK	    GENMASK(17, 16)
> +
>  #define SDHCI_GLI_9750_CFG2          0x848
>  #define   SDHCI_GLI_9750_CFG2_L1DLY    GENMASK(28, 24)
>  #define   GLI_9750_CFG2_L1DLY_VALUE    0x1F
> @@ -629,6 +632,11 @@ static void gl9750_hw_setting(struct sdhci_host *host)
>  
>  	gl9750_wt_on(host);
>  
> +	/* clear GM_BURST bits to avoid corruption with DMA writes */
> +	value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
> +	value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_MASK;
> +	sdhci_writel(host, value, SDHCI_GLI_9750_GM_BURST_SIZE);
> +
>  	value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
>  	value &= ~SDHCI_GLI_9750_CFG2_L1DLY;
>  	/* set ASPM L1 entry delay to 7.9us */