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

Matthew Schwartz
2026-01-30T11:06:49Z

﻿

> On Jan 30, 2026, at 2:53 AM, Adrian Hunter <adrian.hunter@intel.com> wrote:
>
> ﻿Genesys folks : Any comment on this?

As an update on my end, I’ve heard positive feedback from several users testing this out saying it’s the first time they have not had issues writing data to an SD card with GL9750. They were able to install games that would previously fail with file integrity errors and then game off the SD card.

I was planning on sending this out as a v1 before I leave on vacation next week unless there were any further comments here.

>
>> 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 */