forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes for emmc unreliability (sonic-net#270)
- Loading branch information
Showing
3 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
patch/driver-arista-mmcblk-not-working-on-AMD-platforms.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <rrendec@arista.com> | ||
Signed-off-by: Samuel Angebault <staphylo@arista.com> | ||
--- | ||
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; | ||
} |
70 changes: 70 additions & 0 deletions
70
patch/driver-arista-restrict-eMMC-drive-to-50Mhz-from-userland.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 <rrendec@arista.com> | ||
Signed-off-by: Samuel Angebault <staphylo@arista.com> | ||
--- | ||
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); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters