mmc: sdhci-pci-gli: fix GL9750 DMA write corruption
Subsystems (3)
PATCH v2 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.
---
Changes in v2:
- Move GM_BURST register defines
- Clear R_OSRC_Lmt in gli_set_9750 instead of gl9750_hw_setting to survive resets
- Link to v1: https://lore.kernel.org/linux-mmc/[email protected]/
Changes in v1:
- Use the proper name for the register field
- Link to RFC: https://lore.kernel.org/linux-mmc/[email protected]/
--- drivers/mmc/host/sdhci-pci-gli.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/mmc/host/sdhci-pci-gli.c +9 -0
@@ -68,6 +68,9 @@#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
@@ -345,10 +348,16 @@ static void gli_set_9750(struct sdhci_host *host)u32 misc_value;u32 parameter_value;u32 control_value; +u32 burst_value;u16 ctrl2;gl9750_wt_on (host); +/* clear R_OSRC_Lmt to avoid DMA write corruption */ + burst_value =sdhci_readl (host,SDHCI_GLI_9750_GM_BURST_SIZE ); + burst_value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT ; +sdhci_writel (host, burst_value,SDHCI_GLI_9750_GM_BURST_SIZE ); + driving_value =sdhci_readl (host,SDHCI_GLI_9750_DRIVING ); pll_value =sdhci_readl (host,SDHCI_GLI_9750_PLL ); sw_ctrl_value =sdhci_readl (host,SDHCI_GLI_9750_SW_CTRL );
Signature · 1 line
2.53.0
Hi,
Quoted 21 lines
-----Original Message-----
From: Matthew Schwartz <[email protected]>
Sent: Tuesday, March 3, 2026 5:07 AM
To: Adrian Hunter <[email protected]>; Ulf Hansson <[email protected]>; BenChuang[莊智量] <[email protected]>
Cc: [email protected]; [email protected]; Matthew Schwartz <[email protected]>; [email protected]
Subject: [PATCH v2] mmc: sdhci-pci-gli: fix GL9750 DMA write corruptionThe GL9750 SD host controller has intermittent data corruption during DMA write operations. The
GM_BURSTregister'sR_OSRC_Lmtfield (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver setsR_OSRC_Lmtto zero, limiting requests to the smallest unit.Clear
R_OSRC_Lmtto 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")
Quoted 8 lines
Closes:
https://lore.kernel.org/linux-mmc/33d12807-5c72-41c
e-8679-57aa11831fad%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7C61a32c4425ce4cd353 8708de789fd213%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639080825000945593%7CUnknown%7CTWFpb GZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0% 7C%7C%7C&sdata=MESELcO0lcgV7gzD0guTA2ZiDU8hT6EcWDVGzt7S%2FPg%3D&reserved=0Acked-by Adrian Hunter <[email protected]>Signed-off-by Matthew Schwartz <[email protected]>
Well done. Thank you.
Best regards,
Ben Chuang
Quoted 55 lines
---
Changes in v2:
- MoveGM_BURSTregister defines
- ClearR_OSRC_Lmtingli_set_9750instead ofgl9750_hw_settingto survive resets
- Link to v1:
https://lore.kernel.org/linux-mmc/20260227075909.3
860183-1-matthew.schwartz%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7C61a32c4425ce4 cd3538708de789fd213%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639080825000991436%7CUnknown%7CT WFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D %7C0%7C%7C%7C&sdata=G7vE9uvdPWHadV38OuCMTDp8KNW5rHcd%2BPHwkuHfel0%3D&reserved=0Changes in v1:
- Use the proper name for the register field
- Link to RFC:
https://lore.kernel.org/linux-mmc/20260117234800.9
31664-1-matthew.schwartz%40linux.dev%2F&data=05%7C02%7Cben.chuang%40genesyslogic.com.tw%7C61a32c4425ce4c d3538708de789fd213%7C4e753840bf6b40a19645185818deeb52%7C0%7C0%7C639080825001035330%7CUnknown%7CT WFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D %7C0%7C%7C%7C&sdata=NsOcfdHskobh%2Ba3BSAZavs1E6uKtg0Sk2lbVi%2BvRLu0%3D&reserved=0--- drivers/mmc/host/sdhci-pci-gli.c | 9 +++++++++ 1 file changed, 9 insertions(+)drivers/mmc/host/sdhci-pci-gli.c +9
-1@@ -68,6 +68,9 @@#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@@ -345,10 +348,16 @@ static void gli_set_9750(struct sdhci_host *host)u32 misc_value;u32 parameter_value;u32 control_value; +u32 burst_value;u16 ctrl2;gl9750_wt_on (host); +/* clear R_OSRC_Lmt to avoid DMA write corruption */ + burst_value =sdhci_readl (host,SDHCI_GLI_9750_GM_BURST_SIZE ); + burst_value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT ; +sdhci_writel (host, burst_value,SDHCI_GLI_9750_GM_BURST_SIZE ); + driving_value =sdhci_readl (host,SDHCI_GLI_9750_DRIVING ); pll_value =sdhci_readl (host,SDHCI_GLI_9750_PLL ); sw_ctrl_value =sdhci_readl (host,SDHCI_GLI_9750_SW_CTRL ); --
Quoted 1 line
2.53.0
________________________________
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.
________________________________
Quoted 11 lines · Matthew Schwartz
The GL9750 SD host controller has intermittent data corruption during DMA write operations. The
GM_BURSTregister'sR_OSRC_Lmtfield (bits 17:16), which limits outstanding DMA read requests from system memory, is not being cleared during initialization. The Windows driver setsR_OSRC_Lmtto zero, limiting requests to the smallest unit.Clear
R_OSRC_Lmtto match the Windows driver behavior. This eliminates write corruption verified with f3write/f3read tests while maintaining DMA performance.
Quoted 5 lines
Fixes e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")Acked-by Adrian Hunter <[email protected]>Signed-off-by Matthew Schwartz <[email protected]>
Applied for fixes, thanks!
Kind regards
Uffe
Quoted 47 lines
---
Changes in v2:
- MoveGM_BURSTregister defines
- ClearR_OSRC_Lmtingli_set_9750instead ofgl9750_hw_settingto survive resets
- Link to v1: https://lore.kernel.org/linux-mmc/[email protected]/Changes in v1:
- Use the proper name for the register field
- Link to RFC: https://lore.kernel.org/linux-mmc/[email protected]/--- drivers/mmc/host/sdhci-pci-gli.c | 9 +++++++++ 1 file changed, 9 insertions(+)drivers/mmc/host/sdhci-pci-gli.c +9
-1@@ -68,6 +68,9 @@#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@@ -345,10 +348,16 @@ static void gli_set_9750(struct sdhci_host *host)u32 misc_value;u32 parameter_value;u32 control_value; +u32 burst_value;u16 ctrl2;gl9750_wt_on (host); +/* clear R_OSRC_Lmt to avoid DMA write corruption */ + burst_value =sdhci_readl (host,SDHCI_GLI_9750_GM_BURST_SIZE ); + burst_value &= ~SDHCI_GLI_9750_GM_BURST_SIZE_R_OSRC_LMT ; +sdhci_writel (host, burst_value,SDHCI_GLI_9750_GM_BURST_SIZE ); + driving_value =sdhci_readl (host,SDHCI_GLI_9750_DRIVING ); pll_value =sdhci_readl (host,SDHCI_GLI_9750_PLL ); sw_ctrl_value =sdhci_readl (host,SDHCI_GLI_9750_SW_CTRL ); --2.53.0