mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 14:51:51 -04:00
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.
Cc: stable@vger.kernel.org
Fixes: e51df6ce66 ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support")
Closes: https://lore.kernel.org/linux-mmc/33d12807-5c72-41ce-8679-57aa11831fad@linux.dev/
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
committed by
Ulf Hansson
parent
901084c51a
commit
2b76e0cc78
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user