Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some emmc unreliability seen on older AMD CPUs #270

Merged
merged 1 commit into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 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,58 @@
amd/mmc: mmcblk not working on some AMD platforms
Staphylo marked this conversation as resolved.
Show resolved Hide resolved

ADMA and ADMA-64 seem to be broken on AMD. This patch enables the
Staphylo marked this conversation as resolved.
Show resolved Hide resolved
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 <[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).
Staphylo marked this conversation as resolved.
Show resolved Hide resolved

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