]>
Commit | Line | Data |
---|---|---|
88a43f4c AF |
1 | commit 872a8ff772ded51403bd8a46f80b1bf9706b76cd |
2 | Author: Paul Walmsley <paul@pwsan.com> | |
3 | Date: Mon Mar 12 10:58:00 2012 -0600 | |
4 | ||
5 | mmc: use really long write timeout to deal with crappy cards | |
6 | ||
7 | mmc: use really long write timeout to deal with crappy cards | |
8 | ||
9 | Several people have noticed that crappy SD cards take much longer to | |
10 | complete multiple block writes than the 300ms that Linux specifies. | |
11 | Try to work around this by using a three second write timeout instead. | |
12 | ||
13 | This is a generalized version of a patch from Chase Maupin | |
14 | <Chase.Maupin@ti.com>, whose patch description said: | |
15 | ||
16 | * With certain SD cards timeouts like the following have been seen | |
17 | due to an improper calculation of the dto value: | |
18 | mmcblk0: error -110 transferring data, sector 4126233, nr 8, | |
19 | card status 0xc00 | |
20 | * By removing the dto calculation and setting the timeout value | |
21 | to the maximum specified by the SD card specification part A2 | |
22 | section 2.2.15 these timeouts can be avoided. | |
23 | * This change has been used by beagleboard users as well as the | |
24 | Texas Instruments SDK without a negative impact. | |
25 | * There are multiple discussion threads about this but the most | |
26 | relevant ones are: | |
27 | * http://talk.maemo.org/showthread.php?p=1000707#post1000707 | |
28 | * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg42213.html | |
29 | * Original proposal for this fix was done by Sukumar Ghoral of | |
30 | Texas Instruments | |
31 | * Tested using a Texas Instruments AM335x EVM | |
32 | ||
33 | Signed-off-by: Paul Walmsley <paul@pwsan.com> | |
34 | Tested-by: Tony Lindgren <tony@atomide.com> | |
35 | Signed-off-by: Chris Ball <cjb@laptop.org> | |
36 | ||
37 | diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c | |
38 | index d637982..a14ddf96 100644 | |
39 | --- a/drivers/mmc/core/core.c | |
40 | +++ b/drivers/mmc/core/core.c | |
41 | @@ -396,10 +396,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |
42 | ||
43 | if (data->flags & MMC_DATA_WRITE) | |
44 | /* | |
45 | - * The limit is really 250 ms, but that is | |
46 | - * insufficient for some crappy cards. | |
47 | + * The MMC spec "It is strongly recommended | |
48 | + * for hosts to implement more than 500ms | |
49 | + * timeout value even if the card indicates | |
50 | + * the 250ms maximum busy length." Even the | |
51 | + * previous value of 300ms is known to be | |
52 | + * insufficient for some cards. | |
53 | */ | |
54 | - limit_us = 300000; | |
55 | + limit_us = 3000000; | |
56 | else | |
57 | limit_us = 100000; | |
58 | ||
59 | The folowing sdhci fixes rebased from rasperry pi github tree to kernel 3.2 to use | |
60 | actial firmware that run emmc slot at 50Mhz. | |
61 | Author: Arne Fitzenreiter <arne.fitzenreiter@ipfire.org> | |
62 | ||
63 | diff -Naur linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c | |
64 | --- linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c 2012-06-12 00:18:23.000000000 +0200 | |
65 | +++ linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c 2012-06-14 09:33:42.448194435 +0200 | |
66 | @@ -328,12 +328,7 @@ | |
67 | ||
68 | static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host) | |
69 | { | |
70 | - return 100000000; // this value is in Hz (100MHz/4) | |
71 | -} | |
72 | - | |
73 | -static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host) | |
74 | -{ | |
75 | - return 100000; // this value is in kHz (100MHz/4) | |
76 | + return BCM2708_EMMC_CLOCK_FREQ; | |
77 | } | |
78 | ||
79 | /*****************************************************************************\ | |
80 | @@ -1222,12 +1217,7 @@ | |
81 | #else | |
82 | #error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set | |
83 | #endif | |
84 | - //.enable_dma = NULL, | |
85 | - //.set_clock = NULL, | |
86 | .get_max_clock = sdhci_bcm2708_get_max_clock, | |
87 | - //.get_min_clock = NULL, | |
88 | - .get_timeout_clock = sdhci_bcm2708_get_timeout_clock, | |
89 | - | |
90 | .enable = sdhci_bcm2708_enable, | |
91 | .disable = sdhci_bcm2708_disable, | |
92 | .set_plat_power = sdhci_bcm2708_set_plat_power, | |
93 | diff -Naur linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c | |
94 | --- linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c 2012-06-14 09:33:42.000000000 +0200 | |
95 | +++ linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c 2012-06-14 09:47:20.635695042 +0200 | |
96 | @@ -1277,7 +1277,10 @@ | |
97 | host->irq = platform_get_irq(pdev, 0); | |
98 | ||
99 | host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | |
100 | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; | |
101 | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | |
102 | + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | | |
103 | + SDHCI_QUIRK_MISSING_CAPS | | |
104 | + SDHCI_QUIRK_NO_HISPD_BIT; | |
105 | #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA | |
106 | host->flags = SDHCI_USE_PLATDMA; | |
107 | #endif | |
108 | diff -Naur linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c | |
109 | --- linux-3.2.20.org/drivers/mmc/host/sdhci-bcm2708.c 2012-06-14 10:03:31.000000000 +0200 | |
110 | +++ linux-3.2.20/drivers/mmc/host/sdhci-bcm2708.c 2012-06-14 10:15:44.909133194 +0200 | |
111 | @@ -71,6 +71,8 @@ | |
112 | ||
113 | #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ | |
114 | ||
115 | +#define BCM2708_EMMC_CLOCK_FREQ 50000000 | |
116 | + | |
117 | #define POWER_OFF 0 | |
118 | #define POWER_LAZY_OFF 1 | |
119 | #define POWER_ON 2 | |
120 | ||
121 | With the last revert Chris Boot has removed the UHS block at 3.3V | |
122 | so it is needed to readd it to use some cards (eg. Verbatim 8GB Class10) | |
123 | Author: Arne Fitzenreiter <arne.fitzenreiter@ipfire.org> | |
124 | ||
125 | diff -Naur linux-3.2.20.org/drivers/mmc/host/sdhci.c linux-3.2.20/drivers/mmc/host/sdhci.c | |
126 | --- linux-3.2.20.org/drivers/mmc/host/sdhci.c 2012-06-12 00:18:24.000000000 +0200 | |
127 | +++ linux-3.2.20/drivers/mmc/host/sdhci.c 2012-06-14 12:47:25.435538000 +0200 | |
128 | @@ -2930,6 +2930,10 @@ | |
129 | if(host->ops->voltage_broken) | |
130 | ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; | |
131 | ||
132 | + /* No UHS Modes at 3.3V */ | |
133 | + mmc->caps &= ~(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR104 | | |
134 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 ); | |
135 | + | |
136 | mmc->ocr_avail = ocr_avail; | |
137 | mmc->ocr_avail_sdio = ocr_avail; | |
138 | if (host->ocr_avail_sdio) |