diff --git a/packages/linux/patches/linux-3.2.19-611-RPi_mmc-fixes.patch b/packages/linux/patches/linux-3.2.19-611-RPi_mmc-fixes.patch new file mode 100644 index 0000000000..0e268a173a --- /dev/null +++ b/packages/linux/patches/linux-3.2.19-611-RPi_mmc-fixes.patch @@ -0,0 +1,285 @@ +From c6b53e85f5e9237b6649ae78965739665374aa78 Mon Sep 17 00:00:00 2001 +From: Paul Walmsley +Date: Mon, 12 Mar 2012 10:58:00 -0600 +Subject: [PATCH 1/7] mmc: use really long write timeout to deal with crappy + cards + +mmc: use really long write timeout to deal with crappy cards + +Several people have noticed that crappy SD cards take much longer to +complete multiple block writes than the 300ms that Linux specifies. +Try to work around this by using a three second write timeout instead. + +This is a generalized version of a patch from Chase Maupin +, whose patch description said: + +* With certain SD cards timeouts like the following have been seen + due to an improper calculation of the dto value: + mmcblk0: error -110 transferring data, sector 4126233, nr 8, + card status 0xc00 +* By removing the dto calculation and setting the timeout value + to the maximum specified by the SD card specification part A2 + section 2.2.15 these timeouts can be avoided. +* This change has been used by beagleboard users as well as the + Texas Instruments SDK without a negative impact. +* There are multiple discussion threads about this but the most + relevant ones are: + * http://talk.maemo.org/showthread.php?p=1000707#post1000707 + * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg42213.html +* Original proposal for this fix was done by Sukumar Ghoral of + Texas Instruments +* Tested using a Texas Instruments AM335x EVM + +Signed-off-by: Paul Walmsley +Tested-by: Tony Lindgren +Signed-off-by: Chris Ball +--- + drivers/mmc/core/core.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c +index 411a994..ad08933 100644 +--- a/drivers/mmc/core/core.c ++++ b/drivers/mmc/core/core.c +@@ -514,10 +514,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) + + if (data->flags & MMC_DATA_WRITE) + /* +- * The limit is really 250 ms, but that is +- * insufficient for some crappy cards. ++ * The MMC spec "It is strongly recommended ++ * for hosts to implement more than 500ms ++ * timeout value even if the card indicates ++ * the 250ms maximum busy length." Even the ++ * previous value of 300ms is known to be ++ * insufficient for some cards. + */ +- limit_us = 300000; ++ limit_us = 3000000; + else + limit_us = 100000; + +-- +1.7.10 + + +From 346266077685f95b633f7ba34665218fbd4759c6 Mon Sep 17 00:00:00 2001 +From: Grigori Goronzy +Date: Mon, 4 Jun 2012 04:27:48 +0200 +Subject: [PATCH 2/7] sdhci-bcm2708: speed up DMA sync + +Experiments show that it doesn't really take that long to sync, so we +can reduce the poll interval slightly. Might improve performance a bit. +--- + drivers/mmc/host/sdhci-bcm2708.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index 3fe165a..c5cf67f 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -822,7 +822,7 @@ static void sdhci_bcm2708_dma_complete_irq(struct sdhci_host *host, + while (0 != (sdhci_bcm2708_raw_readl(host, SDHCI_PRESENT_STATE) + & state_mask) && --timeout > 0) + { +- udelay(100); ++ udelay(30); + continue; + } + if (timeout <= 0) +-- +1.7.10 + + +From 445a298a9e0b4083a911a76922bfcdfb9ca5a2e7 Mon Sep 17 00:00:00 2001 +From: Grigori Goronzy +Date: Mon, 11 Jun 2012 18:52:04 +0200 +Subject: [PATCH 3/7] sdhci-bcm2708: remove custom clock handling + +The custom clock handling code is redundant and buggy. The MMC/SDHCI +subsystem does a better job than it, so remove it for good. +--- + drivers/mmc/host/sdhci-bcm2708.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index c5cf67f..e9ded27 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -328,12 +328,7 @@ void sdhci_bcm2708_writeb(struct sdhci_host *host, u8 val, int reg) + + static unsigned int sdhci_bcm2708_get_max_clock(struct sdhci_host *host) + { +- return 100000000; // this value is in Hz (100MHz/4) +-} +- +-static unsigned int sdhci_bcm2708_get_timeout_clock(struct sdhci_host *host) +-{ +- return 100000; // this value is in kHz (100MHz/4) ++ return BCM2708_EMMC_CLOCK_FREQ; + } + + /*****************************************************************************\ +@@ -1222,11 +1217,7 @@ static unsigned int sdhci_bcm2708_missing_status(struct sdhci_host *host) + #else + #error The BCM2708 SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set + #endif +- //.enable_dma = NULL, +- //.set_clock = NULL, + .get_max_clock = sdhci_bcm2708_get_max_clock, +- //.get_min_clock = NULL, +- .get_timeout_clock = sdhci_bcm2708_get_timeout_clock, + + .enable = sdhci_bcm2708_enable, + .disable = sdhci_bcm2708_disable, +-- +1.7.10 + + +From 2968818af9ad725df0ea0097cc65ee4b4b5c6cfd Mon Sep 17 00:00:00 2001 +From: Grigori Goronzy +Date: Mon, 11 Jun 2012 18:53:59 +0200 +Subject: [PATCH 4/7] sdhci-bcm2708: add additional quirks + +Some additional quirks are needed for correct operation. +There's no SDHCI capabilities register documented, and it always reads +zero, so add SDHCI_QUIRK_MISSING_CAPS. Apparently +SDHCI_QUIRK_NO_HISPD_BIT is needed for many cards to work correctly in +high-speed mode, so add it as well. +--- + drivers/mmc/host/sdhci-bcm2708.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index e9ded27..378182c 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -1278,7 +1278,11 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev) + host->irq = platform_get_irq(pdev, 0); + + host->quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | +- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; ++ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | ++ SDHCI_QUIRK_MISSING_CAPS | ++ SDHCI_QUIRK_NO_HISPD_BIT; ++ + #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA + host->flags = SDHCI_USE_PLATDMA; + #endif +-- +1.7.10 + + +From 64a3687bffa7da3fba3a813e54708574a92a38ae Mon Sep 17 00:00:00 2001 +From: Grigori Goronzy +Date: Mon, 11 Jun 2012 18:57:13 +0200 +Subject: [PATCH 5/7] sdhci-bcm2708: add allow_highspeed parameter + +Add a parameter to disable high-speed mode for the few cards that +still might have problems. High-speed mode is enabled by default. +--- + drivers/mmc/host/sdhci-bcm2708.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index 378182c..196c379 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -130,6 +130,8 @@ static inline unsigned long int since_ns(hptime_t t) + return (unsigned long)((hptime() - t) * HPTIME_CLK_NS); + } + ++static bool allow_highspeed = 1; ++ + #if 0 + static void hptime_test(void) + { +@@ -1349,6 +1351,9 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev) + host_priv->cb_base, (unsigned)host_priv->cb_handle, + host_priv->dma_chan, host_priv->dma_chan_base, + host_priv->dma_irq); ++ ++ if (allow_highspeed) ++ host->mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; + #endif + + ret = sdhci_add_host(host); +@@ -1454,8 +1459,12 @@ static void __exit sdhci_drv_exit(void) + module_init(sdhci_drv_init); + module_exit(sdhci_drv_exit); + ++module_param(allow_highspeed, bool, 0444); ++ + MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver"); + MODULE_AUTHOR("Broadcom "); + MODULE_LICENSE("GPL v2"); + MODULE_ALIAS("platform:"DRIVER_NAME); + ++MODULE_PARM_DESC(allow_highspeed, "Allow high speed transfers modes"); ++ +-- +1.7.10 + + +From 35dd4a448a662fbefd0f18eadcc6d108b8d30edb Mon Sep 17 00:00:00 2001 +From: Grigori Goronzy +Date: Mon, 11 Jun 2012 18:58:40 +0200 +Subject: [PATCH 6/7] sdhci-bcm2708: assume 50 MHz eMMC clock + +80 MHz clock isnt't suited well to be dividable to get SD clocks of 25 +MHz (default mode) or 50 MHz (high speed mode). 50 MHz are perfect to +drive the SD interface at ideal frequencies. +--- + drivers/mmc/host/sdhci-bcm2708.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c +index 196c379..8118f4a 100644 +--- a/drivers/mmc/host/sdhci-bcm2708.c ++++ b/drivers/mmc/host/sdhci-bcm2708.c +@@ -71,6 +71,9 @@ + + #define BCM2708_SDHCI_SLEEP_TIMEOUT 1000 /* msecs */ + ++/* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */ ++#define BCM2708_EMMC_CLOCK_FREQ 50000000 ++ + #define POWER_OFF 0 + #define POWER_LAZY_OFF 1 + #define POWER_ON 2 +-- +1.7.10 + + +From 35b98bbd5d240156f8d4d5cdc70050906b41e0e3 Mon Sep 17 00:00:00 2001 +From: Iain Paton +Date: Mon, 11 Jun 2012 18:38:25 +0100 +Subject: [PATCH 7/7] sdhci: disable 1.8v modes when voltage_broken is set + +this is the last hunk from +https://github.com/raspberrypi/linux/commit/7e8ae226fe6e95954df6b0dcdde40a53dbbc1a0b +--- + drivers/mmc/host/sdhci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index e147db2..4cfad2e 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -2927,8 +2927,11 @@ int sdhci_add_host(struct sdhci_host *host) + mmc->caps |= MMC_CAP_MAX_CURRENT_200; + } + +- if(host->ops->voltage_broken) ++ if(host->ops->voltage_broken) { + ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; ++ // Cannot support UHS modes is we are stuck at 3.3V; ++ mmc->caps &= ~(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50); ++ } + + mmc->ocr_avail = ocr_avail; + mmc->ocr_avail_sdio = ocr_avail; +-- +1.7.10 +