aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 4dc0028086a3..4557aa1567a5 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -34,6 +34,14 @@
34#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002 34#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
35 35
36/* 36/*
37 * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
38 * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design,
39 * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
40 * Define this macro DMA error INT for fsl eSDHC
41 */
42#define SDHCI_INT_VENDOR_SPEC_DMA_ERR 0x10000000
43
44/*
37 * The CMDTYPE of the CMD register (offset 0xE) should be set to 45 * The CMDTYPE of the CMD register (offset 0xE) should be set to
38 * "11" when the STOP CMD12 is issued on imx53 to abort one 46 * "11" when the STOP CMD12 is issued on imx53 to abort one
39 * open ended multi-blk IO. Otherwise the TC INT wouldn't 47 * open ended multi-blk IO. Otherwise the TC INT wouldn't
@@ -135,6 +143,27 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
135 val |= SDHCI_CARD_PRESENT; 143 val |= SDHCI_CARD_PRESENT;
136 } 144 }
137 145
146 if (unlikely(reg == SDHCI_CAPABILITIES)) {
147 /* In FSL esdhc IC module, only bit20 is used to indicate the
148 * ADMA2 capability of esdhc, but this bit is messed up on
149 * some SOCs (e.g. on MX25, MX35 this bit is set, but they
150 * don't actually support ADMA2). So set the BROKEN_ADMA
151 * uirk on MX25/35 platforms.
152 */
153
154 if (val & SDHCI_CAN_DO_ADMA1) {
155 val &= ~SDHCI_CAN_DO_ADMA1;
156 val |= SDHCI_CAN_DO_ADMA2;
157 }
158 }
159
160 if (unlikely(reg == SDHCI_INT_STATUS)) {
161 if (val & SDHCI_INT_VENDOR_SPEC_DMA_ERR) {
162 val &= ~SDHCI_INT_VENDOR_SPEC_DMA_ERR;
163 val |= SDHCI_INT_ADMA_ERROR;
164 }
165 }
166
138 return val; 167 return val;
139} 168}
140 169
@@ -179,6 +208,13 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
179 writel(v, host->ioaddr + SDHCI_VENDOR_SPEC); 208 writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
180 } 209 }
181 210
211 if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
212 if (val & SDHCI_INT_ADMA_ERROR) {
213 val &= ~SDHCI_INT_ADMA_ERROR;
214 val |= SDHCI_INT_VENDOR_SPEC_DMA_ERR;
215 }
216 }
217
182 writel(val, host->ioaddr + reg); 218 writel(val, host->ioaddr + reg);
183} 219}
184 220
@@ -311,9 +347,10 @@ static struct sdhci_ops sdhci_esdhc_ops = {
311}; 347};
312 348
313static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { 349static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
314 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA 350 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_HISPD_BIT
351 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
352 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
315 | SDHCI_QUIRK_BROKEN_CARD_DETECTION, 353 | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
316 /* ADMA has issues. Might be fixable */
317 .ops = &sdhci_esdhc_ops, 354 .ops = &sdhci_esdhc_ops,
318}; 355};
319 356
@@ -405,7 +442,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
405 442
406 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) 443 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
407 /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ 444 /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
408 host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; 445 host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK
446 | SDHCI_QUIRK_BROKEN_ADMA;
409 447
410 if (is_imx53_esdhc(imx_data)) 448 if (is_imx53_esdhc(imx_data))
411 imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT; 449 imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;