aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichardZhu <richard.zhu@linaro.org>2011-11-16 14:51:40 +0800
committerEric Miao <eric.miao@canonical.com>2011-12-05 16:49:56 +0800
commit8ff445dd2fb277263075ad3ff3bce8b28b07c221 (patch)
treee4389aaa404054495792407cacdf564e8001450c
parent18d2eb7446898373cdb729bee60b202a786d9aef (diff)
downloadlinux-linaro-8ff445dd2fb277263075ad3ff3bce8b28b07c221.tar.gz
mmc: sdhci-esdhc-imx: support 8 bit MMC
enable 8 bit MMC mode according to mmc stack. Signed-off-by: RichardZhu <richard.zhu@linaro.org>
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index bd1cb7910e4..19cb234d3af 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -29,11 +29,21 @@
#include "sdhci-esdhc.h"
#define SDHCI_CTRL_D3CD 0x08
+
+#define SDHCI_PROT_CTRL_DTW (3 << 1)
+#define SDHCI_PROT_CTRL_8BIT (2 << 1)
+#define SDHCI_PROT_CTRL_4BIT (1 << 1)
+#define SDHCI_PROT_CTRL_1BIT (0 << 1)
+
/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC 0xC0
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
#define SDHCI_WTMK_LVL 0x44
#define SDHCI_MIX_CTRL 0x48
+#define SDHCI_MIX_CTRL_EXE_TUNE (1 << 22)
+#define SDHCI_MIX_CTRL_SMPCLK_SEL (1 << 23)
+#define SDHCI_MIX_CTRL_AUTO_TUNE (1 << 24)
+#define SDHCI_MIX_CTRL_FBCLK_SEL (1 << 25)
/*
* There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
@@ -288,7 +298,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
if (is_imx6q_usdhc(imx_data)) {
u32 m = readl(host->ioaddr + SDHCI_MIX_CTRL);
- m = imx_data->scratchpad | (m & 0xffff0000);
+ m = imx_data->scratchpad | \
+ (m & (SDHCI_MIX_CTRL_EXE_TUNE | \
+ SDHCI_MIX_CTRL_SMPCLK_SEL | \
+ SDHCI_MIX_CTRL_AUTO_TUNE | \
+ SDHCI_MIX_CTRL_FBCLK_SEL));
writel(m, host->ioaddr + SDHCI_MIX_CTRL);
writel(val << 16,
host->ioaddr + SDHCI_TRANSFER_MODE);
@@ -376,6 +390,22 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
return -ENOSYS;
}
+static int plt_8bit_width(struct sdhci_host *host, int width)
+{
+ u32 reg = sdhci_readl(host, SDHCI_HOST_CONTROL);
+
+ reg &= ~SDHCI_PROT_CTRL_DTW;
+
+ if (width == MMC_BUS_WIDTH_8)
+ reg |= SDHCI_PROT_CTRL_8BIT;
+ else if (width == MMC_BUS_WIDTH_4)
+ reg |= SDHCI_PROT_CTRL_4BIT;
+
+ sdhci_writel(host, reg, SDHCI_HOST_CONTROL);
+
+ return 0;
+}
+
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
@@ -386,6 +416,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.get_max_clock = esdhc_pltfm_get_max_clock,
.get_min_clock = esdhc_pltfm_get_min_clock,
.get_ro = esdhc_pltfm_get_ro,
+ .platform_8bit_width = plt_8bit_width,
};
static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {