Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdhci-of-arasan: Add quirk for unstable clocks

Some controllers immediately report SDHCI_CLOCK_INT_STABLE after
enabling the clock even when the clock is not stable. When used in
conjunction with older/slower cards, this can result in:

mmc0: error -84 whilst initialising SD card

When the stable reporting is known to be broken, we simply wait for the
maximum stabilization period.

Signed-off-by: Helmut Grohne <h.grohne@intenta.de>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Helmut Grohne and committed by
Ulf Hansson
3f2c7d5d 26c31228

+16
+16
drivers/mmc/host/sdhci-of-arasan.c
··· 102 102 103 103 /* Controller does not have CD wired and will not function normally without */ 104 104 #define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0) 105 + /* Controller immediately reports SDHCI_CLOCK_INT_STABLE after enabling the 106 + * internal clock even when the clock isn't stable */ 107 + #define SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE BIT(1) 105 108 }; 106 109 107 110 static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = { ··· 209 206 } 210 207 211 208 sdhci_set_clock(host, clock); 209 + 210 + if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) 211 + /* 212 + * Some controllers immediately report SDHCI_CLOCK_INT_STABLE 213 + * after enabling the clock even though the clock is not 214 + * stable. Trying to use a clock without waiting here results 215 + * in EILSEQ while detecting some older/slower cards. The 216 + * chosen delay is the maximum delay from sdhci_set_clock. 217 + */ 218 + msleep(20); 212 219 213 220 if (ctrl_phy) { 214 221 phy_power_on(sdhci_arasan->phy); ··· 770 757 771 758 if (of_property_read_bool(np, "xlnx,fails-without-test-cd")) 772 759 sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST; 760 + 761 + if (of_property_read_bool(np, "xlnx,int-clock-stable-broken")) 762 + sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE; 773 763 774 764 pltfm_host->clk = clk_xin; 775 765