diff options
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 44 |
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 | ||
313 | static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { | 349 | static 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; |