Skip to contentSkip to conversation

mmc: sdhci-pci-gli: fix GL9750 DMA write corruption

PATCH Superseded Matthew Schwartz 3 participants 5 messages Feb 27 – Mar 2

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mmc: sdhci-pci-gli: fix GL9750 DMA write corruption

The GL9750 SD host controller has intermittent data corruption during DMA write operations. The GM_BURST register's R_OSRC_Lmt field (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver sets R_OSRC_Lmt to zero, limiting requests to the smallest unit.

Clear R_OSRC_Lmt to match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.

Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")

---
Link to RFC: https://lore.kernel.org/all/[email protected]/
Changes from RFC -> v1: use the proper name for the register field

---
 drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +8 -0
index b0f91cc9e40e4..7a7be3f7bee6b 100644
@@ -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_R_OSRC_LMT	    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 R_OSRC_Lmt to avoid DMA write corruption */
+	value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+	value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT;
+	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 */
Signature · 1 line
2.53.0
maintainer Acked-by on v1 1/1
#1 lore raw
Quoted 6 lines · Matthew Schwartz

The GL9750 SD host controller has intermittent data corruption during DMA write operations. The GM_BURST register's R_OSRC_Lmt field (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver sets R_OSRC_Lmt to zero, limiting requests to the smallest unit.

Quoted 8 lines

Clear R_OSRC_Lmt to match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.

Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")

Ben wrote "So I think your patch setting R_OSRC_Lmt to zero is reasonable." Can be have a Reviewed-by tag also?

Nevertheless:

Quoted 33 lines

---
Link to RFC: https://lore.kernel.org/all/[email protected]/
Changes from RFC -> v1: use the proper name for the register field

---
 drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +8 -0
index b0f91cc9e40e4..7a7be3f7bee6b 100644
@@ -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_R_OSRC_LMT	    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 R_OSRC_Lmt to avoid DMA write corruption */
+	value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+	value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT;
+	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 lore raw
Quoted 11 lines · Adrian Hunter
Quoted 10 lines · Matthew Schwartz

The GL9750 SD host controller has intermittent data corruption during DMA write operations. The GM_BURST register's R_OSRC_Lmt field (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver sets R_OSRC_Lmt to zero, limiting requests to the smallest unit.

Clear R_OSRC_Lmt to match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.

Quoted 7 lines
Quoted 4 lines
Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")

Ben wrote "So I think your patch setting R_OSRC_Lmt to zero is reasonable." Can be have a Reviewed-by tag also?

Wasn't sure about the etiquette of adding a Reviewed-by without an explicit tag in an email, but happy to re-spin a v2 and add that if it's wanted.

Quoted 39 lines

Nevertheless:

Quoted 33 lines

---
Link to RFC: https://lore.kernel.org/all/[email protected]/
Changes from RFC -> v1: use the proper name for the register field

---
 drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +8 -0
index b0f91cc9e40e4..7a7be3f7bee6b 100644
@@ -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_R_OSRC_LMT	    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 R_OSRC_Lmt to avoid DMA write corruption */
+	value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+	value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT;
+	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 */
#3 lore raw

Hi Matthew,

Quoted 61 lines

-----Original Message-----
From: Matthew Schwartz <[email protected]>
Sent: Saturday, February 28, 2026 9:27 AM
To: Adrian Hunter <[email protected]>; Ulf Hansson <[email protected]>; BenChuang[莊智量] <[email protected]>
Cc: [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH] mmc: sdhci-pci-gli: fix GL9750 DMA write corruption

Quoted 7 lines · Adrian Hunter
Quoted 6 lines · Matthew Schwartz

The GL9750 SD host controller has intermittent data corruption during DMA write operations. The GM_BURST register's R_OSRC_Lmt field (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver sets R_OSRC_Lmt to zero, limiting requests to the smallest unit.

Quoted 7 lines
Quoted 7 lines

Clear R_OSRC_Lmt to match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.

Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")

Closes:

https://lore.kernel.org/linux-mmc/33d12807-5c72-41c
e-8679-57aa11831fad%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7Cf7d89cd3b9ef4ee8f58 208de76687497%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639078388197698028%7CUnknown%7CTWFpb GZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0% 7C%7C%7C&sdata=xdnJIB74XZ4LQYBgHseMZWvDSwO1mg4x0jCNxqMMoco%3D&reserved=0

Quoted 4 lines
Quoted 1 line

Ben wrote "So I think your patch setting R_OSRC_Lmt to zero is reasonable." Can be have a Reviewed-by tag also?

Wasn't sure about the etiquette of adding a Reviewed-by without an explicit tag in an email, but happy to re-spin a v2 and add that if it's wanted.

Quoted 7 lines

Nevertheless:

Quoted 2 lines

---
Link to RFC:

https://lore.kernel.org/all/20260117234800.931664-1
-matthew.schwartz%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7Cf7d89cd3b9ef4ee8f58208 de76687497%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639078388197757693%7CUnknown%7CTWFpbGZsb 3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C% 7C%7C&sdata=hG%2FsvJa9fEfEPXIcB81%2FG33pbxg54SxC2SX5WuKxCZw%3D&reserved=0

Quoted 13 lines
Quoted 13 lines

Changes from RFC -> v1: use the proper name for the register field

---
 drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +0 -0
index b0f91cc9e40e4..7a7be3f7bee6b 100644
@@ -26,6 +26,9 @@
 #define   GLI_9750_WT_EN_ON           0x1
 #define   GLI_9750_WT_EN_OFF          0x0
 
Quoted 3 lines
Quoted 3 lines

drivers/mmc/host/sdhci-pci-gli.c line 31

Quoted 3 lines
drivers/mmc/host/sdhci-pci-gli.c +3 -0
+#define SDHCI_GLI_9750_GM_BURST_SIZE                0x510
+#define   SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT     GENMASK(17, 16)
+

Please move the definition of 0x510 register before the definition of 0x540 register. i.e.

 #define   GLI_9750_MISC_TX1_DLY_VALUE    0x5
 #define   SDHCI_GLI_9750_MISC_SSC_OFF    BIT(26)

+#define SDHCI_GLI_9750_GM_BURST_SIZE 0x510
+#define SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT GENMASK(17, 16)
+
#define SDHCI_GLI_9750_TUNING_CONTROL 0x540

 #define   SDHCI_GLI_9750_TUNING_CONTROL_EN          BIT(4)
 #define   GLI_9750_TUNING_CONTROL_EN_ON             0x1
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/mmc/host/sdhci-pci-gli.c +0 -0
 #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)
 
Quoted 7 lines
Quoted 7 lines

drivers/mmc/host/sdhci-pci-gli.c static void gl9750_hw_setting(struct sdhci_host *host) · line 639

Quoted 7 lines
drivers/mmc/host/sdhci-pci-gli.c +5 -0
   gl9750_wt_on(host);
 
+  /* clear R_OSRC_Lmt to avoid DMA write corruption */
+  value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+  value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT;
+  sdhci_writel(host, value, SDHCI_GLI_9750_GM_BURST_SIZE);
+

I recall that sdhci_reset() resets the 0x510 register to its default value. So please test this by removing the card and reinserting the card again, and see if the value still matches expectations. If not, perhaps the above code can be added to gli_set_9750().

Best regards,
Ben Chuang

Quoted 4 lines
Quoted 4 lines

drivers/mmc/host/sdhci-pci-gli.c static void gl9750_hw_setting(struct sdhci_host *host) · line 642

Quoted 3 lines
drivers/mmc/host/sdhci-pci-gli.c +0 -0
   value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
   value &= ~SDHCI_GLI_9750_CFG2_L1DLY;
   /* set ASPM L1 entry delay to 7.9us */

________________________________

Genesys Logic Email Confidentiality Notice:
This mail and any attachments may contain information that is confidential, proprietary, privileged or otherwise protected by law. The mail is intended solely for the named addressee (or a person responsible for delivering it to the addressee). If you are not the intended recipient of this mail, you are not authorized to read, print, copy or disseminate this mail.

If you have received this email in error, please notify us immediately by reply email and immediately delete this message and any attachments from your system. Please be noted that any unauthorized use, dissemination, distribution or copying of this email is strictly prohibited.
________________________________

#4 lore raw
Quoted 67 lines · BenChuang[莊智量]

Hi Matthew,

Quoted 61 lines

-----Original Message-----
From: Matthew Schwartz <[email protected]>
Sent: Saturday, February 28, 2026 9:27 AM
To: Adrian Hunter <[email protected]>; Ulf Hansson <[email protected]>; BenChuang[莊智量] <[email protected]>
Cc: [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH] mmc: sdhci-pci-gli: fix GL9750 DMA write corruption

Quoted 7 lines · Adrian Hunter
Quoted 6 lines · Matthew Schwartz

The GL9750 SD host controller has intermittent data corruption during DMA write operations. The GM_BURST register's R_OSRC_Lmt field (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver sets R_OSRC_Lmt to zero, limiting requests to the smallest unit.

Quoted 7 lines
Quoted 7 lines

Clear R_OSRC_Lmt to match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.

Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")

Closes:

https://lore.kernel.org/linux-mmc/33d12807-5c72-41c
e-8679-57aa11831fad%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7Cf7d89cd3b9ef4ee8f58 208de76687497%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639078388197698028%7CUnknown%7CTWFpb GZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0% 7C%7C%7C&sdata=xdnJIB74XZ4LQYBgHseMZWvDSwO1mg4x0jCNxqMMoco%3D&reserved=0

Quoted 4 lines
Quoted 1 line

Ben wrote "So I think your patch setting R_OSRC_Lmt to zero is reasonable." Can be have a Reviewed-by tag also?

Wasn't sure about the etiquette of adding a Reviewed-by without an explicit tag in an email, but happy to re-spin a v2 and add that if it's wanted.

Quoted 7 lines

Nevertheless:

Quoted 2 lines

---
Link to RFC:

https://lore.kernel.org/all/20260117234800.931664-1
-matthew.schwartz%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7Cf7d89cd3b9ef4ee8f58208 de76687497%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639078388197757693%7CUnknown%7CTWFpbGZsb 3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C% 7C%7C&sdata=hG%2FsvJa9fEfEPXIcB81%2FG33pbxg54SxC2SX5WuKxCZw%3D&reserved=0

Quoted 13 lines
Quoted 13 lines

Changes from RFC -> v1: use the proper name for the register field
---
drivers/mmc/host/sdhci-pci-gli.c | 8 ++++++++

1 file changed, 8 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +0 -0
index b0f91cc9e40e4..7a7be3f7bee6b 100644
@@ -26,6 +26,9 @@
 #define   GLI_9750_WT_EN_ON           0x1
 #define   GLI_9750_WT_EN_OFF          0x0
 
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines

drivers/mmc/host/sdhci-pci-gli.c line 31

Quoted 3 lines
drivers/mmc/host/sdhci-pci-gli.c +3 -0
+#define SDHCI_GLI_9750_GM_BURST_SIZE                0x510
+#define   SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT     GENMASK(17, 16)
+

Please move the definition of 0x510 register before the definition of 0x540 register.

Sure, I can move it.

Quoted 19 lines

i.e.

#define   GLI_9750_MISC_TX1_DLY_VALUE    0x5
#define   SDHCI_GLI_9750_MISC_SSC_OFF    BIT(26)
drivers/mmc/host/sdhci-pci-gli.c +3 -0
+#define        SDHCI_GLI_9750_GM_BURST_SIZE              0x510
+#define          SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT   GENMASK(17, 16)
+

#define SDHCI_GLI_9750_TUNING_CONTROL 0x540

#define   SDHCI_GLI_9750_TUNING_CONTROL_EN          BIT(4)
#define   GLI_9750_TUNING_CONTROL_EN_ON             0x1
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/mmc/host/sdhci-pci-gli.c +0 -0
 #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);
 
Quoted 10 lines
Quoted 5 lines
Quoted 5 lines

drivers/mmc/host/sdhci-pci-gli.c static void gl9750_hw_setting(struct sdhci_host *host) · line 639

Quoted 5 lines
drivers/mmc/host/sdhci-pci-gli.c +5 -0
+  /* clear R_OSRC_Lmt to avoid DMA write corruption */
+  value = sdhci_readl(host, SDHCI_GLI_9750_GM_BURST_SIZE);
+  value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT;
+  sdhci_writel(host, value, SDHCI_GLI_9750_GM_BURST_SIZE);
+

I recall that sdhci_reset() resets the 0x510 register to its default value. So please test this by removing the card and reinserting the card again, and see if the value still matches expectations. If not, perhaps the above code can be added to gli_set_9750().

I will double check this before sending out a V2 that addresses your earlier comment.

Thanks for the review,
Matt

Quoted 16 lines

Best regards,
Ben Chuang

Quoted 4 lines
Quoted 4 lines

drivers/mmc/host/sdhci-pci-gli.c static void gl9750_hw_setting(struct sdhci_host *host) · line 642

Quoted 3 lines
drivers/mmc/host/sdhci-pci-gli.c +0 -0
  value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
  value &= ~SDHCI_GLI_9750_CFG2_L1DLY;
  /* set ASPM L1 entry delay to 7.9us */

________________________________

Genesys Logic Email Confidentiality Notice:
This mail and any attachments may contain information that is confidential, proprietary, privileged or otherwise protected by law. The mail is intended solely for the named addressee (or a person responsible for delivering it to the addressee). If you are not the intended recipient of this mail, you are not authorized to read, print, copy or disseminate this mail.

If you have received this email in error, please notify us immediately by reply email and immediately delete this message and any attachments from your system. Please be noted that any unauthorized use, dissemination, distribution or copying of this email is strictly prohibited.
________________________________