From 4c2d4572cebc05222da515b1dcf08510197d9ae8 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Thu, 9 Feb 2023 10:03:09 -0800 Subject: [PATCH] Fixes for emmc unreliability (#270) --- ...-mmcblk-not-working-on-AMD-platforms.patch | 58 +++++++++++++++ ...ct-eMMC-drive-to-50Mhz-from-userland.patch | 70 +++++++++++++++++++ patch/series | 2 + 3 files changed, 130 insertions(+) create mode 100644 patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch create mode 100644 patch/driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch diff --git a/patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch b/patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch new file mode 100644 index 000000000000..7858eb60108a --- /dev/null +++ b/patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch @@ -0,0 +1,58 @@ +amd/mmc: mmcblk not working on some AMD platforms + +ADMA and ADMA-64 seem to be broken on AMD. This patch enables the +following quirks (for AMD only): + SDHCI_QUIRK_BROKEN_ADMA + SDHCI_QUIRK2_BROKEN_64_BIT_DMA + +This fixes issues that would manifest in the following fashion. + +mmc0: Timeout waiting for hardware interrupt. +sdhci: =========== REGISTER DUMP (mmc0)=========== +sdhci: Sys addr: 0x00000078 | Version: 0x00001002 +sdhci: Blk size: 0x00007200 | Blk cnt: 0x00000078 +sdhci: Argument: 0x000ab148 | Trn mode: 0x0000003b +sdhci: Present: 0x01ff0001 | Host ctl: 0x00000019 +sdhci: Power: 0x0000000f | Blk gap: 0x00000000 +sdhci: Wake-up: 0x00000000 | Clock: 0x0000fa07 +sdhci: Timeout: 0x0000000c | Int stat: 0x00000000 +sdhci: Int enab: 0x02ff008b | Sig enab: 0x02ff008b +sdhci: AC12 err: 0x00000002 | Slot int: 0x000000ff +sdhci: Caps: 0x75fec8b2 | Caps_1: 0x00002501 +sdhci: Cmd: 0x0000123a | Max curr: 0x00c80064 +sdhci: Host ctl2: 0x00000000 +sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x000000020f97b20c +sdhci: =========================================== +mmcblk0: error -110 sending status command, retrying +mmcblk0: error -110 sending status command, retrying +mmcblk0: error -110 sending status command, aborting +mmc0: cache flush error -110 +mmc0: tried to reset card, got error -110 +blk_update_request: I/O error, dev mmcblk0, sector 700744 +blk_update_request: I/O error, dev mmcblk0, sector 700752 + +Signed-off-by: Radu Rendec +Signed-off-by: Samuel Angebault +--- + drivers/mmc/host/sdhci-pci-core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c +index bf04a08ee..c10790dd6 100644 +--- a/drivers/mmc/host/sdhci-pci-core.c ++++ b/drivers/mmc/host/sdhci-pci-core.c +@@ -1791,8 +1791,13 @@ static int amd_probe(struct sdhci_pci_chip *chip) + } + } + +- if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) ++ dev_info(&chip->pdev->dev, "identified AMD generation %d chip\n", gen); ++ ++ if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) { ++ chip->quirks |= SDHCI_QUIRK_BROKEN_ADMA; ++ chip->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA; + chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; ++ } + + return 0; + } diff --git a/patch/driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch b/patch/driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch new file mode 100644 index 000000000000..5f49785421f1 --- /dev/null +++ b/patch/driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch @@ -0,0 +1,70 @@ +mmc: restrict eMMC drive to 50Mhz from userland + +This issue was fixed for kernel 3.18 by setting sdhci.debug_quirks2=0x40 +from Aboot boot0 (conditionally, for specific Aboot versions). + +For kernel 4.9, however, we need SDHCI_QUIRK2_BROKEN_64_BIT_DMA, which +is also in quirks2. The problem is that debug_quirks2 overwrites whatever +is written to host->quirks2 during device probing (see __sdhci_read_caps). +Since we set both SDHCI_QUIRK_BROKEN_DMA and +SDHCI_QUIRK2_BROKEN_64_BIT_DMA (but the former is in quirks while the +latter is in quirks2) and Aboot overwrites quirks2, we end up with only +SDHCI_QUIRK_BROKEN_DMA being set. This causes some strange behavior with +AMD devices, where the sdhci driver stalls for a while and eventually +falls back to PIO mode. We need both quirk flags to be set in order for +the controller to work in SDMA mode. + +This patch is a workaround for the quirks2 overwrite problem. It adds a +set of new sdhci module parameters (append_quirks and append_quirks2) +that *append* bits (i.e. logical "or") instead of overwriting the +values. Then Aboot can use these parameters instead in order to set +SDHCI_QUIRK2_BROKEN_HS200. Note that both quirk2 flags are set +conditionally and independently by Aboot and the sdhci-pci probe code. + +Advantages of this approach: +* This patch by itself doesn't change any kernel behavior: it just adds + two module parameters that default to zero and will have no effect + unless explicitly set to a different value from outside the driver. +* SDHCI_QUIRK2_BROKEN_HS200 can be still controlled from Aboot and + conditionally (depending on the Aboot version). +* SDHCI_QUIRK2_BROKEN_64_BIT_DMA can be set by the sdhci-pci probing + code, independently of Aboot. + +Signed-off-by: Radu Rendec +Signed-off-by: Samuel Angebault +--- + drivers/mmc/host/sdhci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index b1e1d327c..817934f04 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -45,6 +45,8 @@ + + #define MAX_TUNING_LOOP 40 + ++static unsigned int append_quirks; ++static unsigned int append_quirks2; + static unsigned int debug_quirks = 0; + static unsigned int debug_quirks2; + +@@ -3990,6 +3992,9 @@ void __sdhci_read_caps(struct sdhci_host *host, const u16 *ver, + + host->read_caps = true; + ++ host->quirks |= append_quirks; ++ host->quirks2 |= append_quirks2; ++ + if (debug_quirks) + host->quirks = debug_quirks; + +@@ -4850,6 +4855,8 @@ static void __exit sdhci_drv_exit(void) + module_init(sdhci_drv_init); + module_exit(sdhci_drv_exit); + ++module_param(append_quirks, uint, 0444); ++module_param(append_quirks2, uint, 0444); + module_param(debug_quirks, uint, 0444); + module_param(debug_quirks2, uint, 0444); + diff --git a/patch/series b/patch/series index f81628285d53..95f6679cca46 100755 --- a/patch/series +++ b/patch/series @@ -4,6 +4,8 @@ driver-arista-net-tg3-dma-mask-4g-sb800.patch driver-arista-net-tg3-disallow-broadcom-default-mac.patch driver-arista-net-tg3-access-regs-indirectly.patch driver-arista-pci-reassign-pref-mem.patch +driver-arista-mmcblk-not-working-on-AMD-platforms.patch +driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch driver-support-sff-8436-eeprom.patch driver-support-sff-8436-eeprom-update.patch driver-sff-8436-use-nvmem-framework.patch