Skip to content

Commit

Permalink
Fixes for emmc unreliability
Browse files Browse the repository at this point in the history
  • Loading branch information
Staphylo committed Feb 17, 2022
1 parent 755d089 commit 892e7a1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
32 changes: 32 additions & 0 deletions patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
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

Signed-off-by: Radu Rendec <[email protected]>
Signed-off-by: Samuel Angebault <[email protected]>
---
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;
}
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
Signed-off-by: Samuel Angebault <[email protected]>
---
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);

2 changes: 2 additions & 0 deletions patch/series
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 892e7a1

Please sign in to comment.