summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2012-03-26 11:23:22 +0800
committerDong Aisheng <b29396@freescale.com>2012-03-29 11:24:47 +0800
commit45f8aab793e42597aee532dcdd78dea669b66abd (patch)
treefa4a6587504ee6d49ca93e259c847645fca37342 /drivers/mmc
parente56b1ca9a0ec1d90ddfd0591f5a925360cafa677 (diff)
ENGR00178290-1 Merge mmc: sdhci-esdhc-imx: Enable ADMA2
Add auto cmd23 fix. The original commit merged is: 97e4ba6a5 Subject: [PATCH 1/1] mmc: sdhci-esdhc-imx: Enable ADMA2 Eanble the ADMA2 mode for freescale esdhc imx driver, tested on MX25 3DS board, MX51 BBG board and MX53 LOCO board. This patch is only used to enable the ADMA2 for MX51/53 platforms. MX25/35 can't support the ADMA2 mode, set BROKEN_ADMA quirk on MX25/35 platforms. The ADMA mode supported or not can be distinguished by bit 20 of the Capability Register (offset 0x40) in the FSL eSDHC module. Signed-off-by: Richard Zhu <richard.zhu@linaro.org> Tested-and-acked-by: Eric Miao <eric.miao@linaro.org> Signed-off-by: Chris Ball <cjb@laptop.org> Signed-off-by: Dong Aisheng <b29396@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index e76ef23e1f2a..a65d6204a7e8 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,7 @@
#define SDHCI_VENDOR_SPEC 0xC0
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+#define SDHCI_MIX_CTRL_AC23EN (1 << 7)
#define SDHCI_MIX_CTRL_EXE_TUNE (1 << 22)
#define SDHCI_MIX_CTRL_SMPCLK_SEL (1 << 23)
#define SDHCI_MIX_CTRL_AUTO_TUNE (1 << 24)
@@ -68,6 +69,14 @@
#define SDHCI_PROT_CTRL_LCTL (1 << 0)
/*
+ * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
+ * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design,
+ * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
+ * Define this macro DMA error INT for fsl eSDHC
+ */
+#define SDHCI_INT_VENDOR_SPEC_DMA_ERR 0x10000000
+
+/*
* The CMDTYPE of the CMD register (offset 0xE) should be set to
* "11" when the STOP CMD12 is issued on imx53 to abort one
* open ended multi-blk IO. Otherwise the TC INT wouldn't
@@ -160,6 +169,27 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
val |= 0xFF << SDHCI_MAX_CURRENT_180_SHIFT;
}
+ if (unlikely(reg == SDHCI_CAPABILITIES)) {
+ /* In FSL esdhc IC module, only bit20 is used to indicate the
+ * ADMA2 capability of esdhc, but this bit is messed up on
+ * some SOCs (e.g. on MX25, MX35 this bit is set, but they
+ * don't actually support ADMA2). So set the BROKEN_ADMA
+ * uirk on MX25/35 platforms.
+ */
+
+ if (val & SDHCI_CAN_DO_ADMA1) {
+ val &= ~SDHCI_CAN_DO_ADMA1;
+ val |= SDHCI_CAN_DO_ADMA2;
+ }
+ }
+
+ if (unlikely(reg == SDHCI_INT_STATUS)) {
+ if (val & SDHCI_INT_VENDOR_SPEC_DMA_ERR) {
+ val &= ~SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+ val |= SDHCI_INT_ADMA_ERROR;
+ }
+ }
+
return val;
}
@@ -220,6 +250,13 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
}
+ if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
+ if (val & SDHCI_INT_ADMA_ERROR) {
+ val &= ~SDHCI_INT_ADMA_ERROR;
+ val |= SDHCI_INT_VENDOR_SPEC_DMA_ERR;
+ }
+ }
+
writel(val, host->ioaddr + reg);
}
@@ -395,6 +432,10 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
}
imx_data->scratchpad = val;
+
+ if (val & SDHCI_TRNS_AUTO_CMD23)
+ imx_data->scratchpad |= SDHCI_MIX_CTRL_AC23EN;
+
return;
case SDHCI_COMMAND:
if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
@@ -657,7 +698,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
if (cpu_is_mx25() || cpu_is_mx35())
/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
- host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK
+ | SDHCI_QUIRK_BROKEN_ADMA;
/* write_protect can't be routed to controller, use gpio */
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
@@ -775,7 +817,8 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
+ | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
| SDHCI_QUIRK_BROKEN_CARD_DETECTION
| SDHCI_QUIRK_NO_HISPD_BIT,
/* ADMA has issues. Might be fixable */