diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-04-01 04:03:25 -0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-04-14 03:18:07 -0400 |
commit | 3fcb027d7fd749569665d34a79ce2a8e00bc2ed6 (patch) | |
tree | 154b65062a5e2c0ff94c9463c8dfe7bfc905affd /drivers/mmc | |
parent | f441b993101d4ee95222ccbaad1e0dd53ea90b64 (diff) |
ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling
MX3 SoCs have a silicon bug which corrupts CRC calculation of
multi-block transfers when connected SDIO peripheral doesn't drive the
BUSY line as required by the specs.
One way to prevent this is to only allow 1-bit transfers.
Another way is playing tricks with the DMA engine, but this isn't
mainline yet. So for now, we live with the performance drawback of 1-bit
transfers until a nicer solution is found.
This patch introduces a new host controller callback 'init_card' which
is for now only called from mmc_sdio_init_card().
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Volker Ernst <volker.ernst@txtr.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Michał Mirosław <mirqus@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/sdio.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/mxcmmc.c | 16 |
2 files changed, 22 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2dd4cfe7ca17..b9dee28ee7d0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -296,6 +296,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
296 | card->type = MMC_TYPE_SDIO; | 296 | card->type = MMC_TYPE_SDIO; |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * Call the optional HC's init_card function to handle quirks. | ||
300 | */ | ||
301 | if (host->ops->init_card) | ||
302 | host->ops->init_card(host, card); | ||
303 | |||
304 | /* | ||
299 | * For native busses: set card RCA and quit open drain mode. | 305 | * For native busses: set card RCA and quit open drain mode. |
300 | */ | 306 | */ |
301 | if (!powered_resume && !mmc_host_is_spi(host)) { | 307 | if (!powered_resume && !mmc_host_is_spi(host)) { |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 51e880c8f193..2c53024ee439 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -724,11 +724,27 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
724 | spin_unlock_irqrestore(&host->lock, flags); | 724 | spin_unlock_irqrestore(&host->lock, flags); |
725 | } | 725 | } |
726 | 726 | ||
727 | static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card) | ||
728 | { | ||
729 | /* | ||
730 | * MX3 SoCs have a silicon bug which corrupts CRC calculation of | ||
731 | * multi-block transfers when connected SDIO peripheral doesn't | ||
732 | * drive the BUSY line as required by the specs. | ||
733 | * One way to prevent this is to only allow 1-bit transfers. | ||
734 | */ | ||
735 | |||
736 | if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO) | ||
737 | host->caps &= ~MMC_CAP_4_BIT_DATA; | ||
738 | else | ||
739 | host->caps |= MMC_CAP_4_BIT_DATA; | ||
740 | } | ||
741 | |||
727 | static const struct mmc_host_ops mxcmci_ops = { | 742 | static const struct mmc_host_ops mxcmci_ops = { |
728 | .request = mxcmci_request, | 743 | .request = mxcmci_request, |
729 | .set_ios = mxcmci_set_ios, | 744 | .set_ios = mxcmci_set_ios, |
730 | .get_ro = mxcmci_get_ro, | 745 | .get_ro = mxcmci_get_ro, |
731 | .enable_sdio_irq = mxcmci_enable_sdio_irq, | 746 | .enable_sdio_irq = mxcmci_enable_sdio_irq, |
747 | .init_card = mxcmci_init_card, | ||
732 | }; | 748 | }; |
733 | 749 | ||
734 | static int mxcmci_probe(struct platform_device *pdev) | 750 | static int mxcmci_probe(struct platform_device *pdev) |