summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLei Wen <leiwen@marvell.com>2011-10-03 20:33:44 +0000
committerAndy Fleming <afleming@freescale.com>2011-11-03 02:14:58 -0500
commit02d3ad3e19fd1b21cae493edd1d2db5f674510d8 (patch)
tree74572e584e4eb035d5194a98eb7c0f7feec58a20 /drivers
parent02f3029f1810b99869254d0cf0a71946a008a728 (diff)
downloadu-boot-imx-02d3ad3e19fd1b21cae493edd1d2db5f674510d8.zip
u-boot-imx-02d3ad3e19fd1b21cae493edd1d2db5f674510d8.tar.gz
u-boot-imx-02d3ad3e19fd1b21cae493edd1d2db5f674510d8.tar.bz2
mmc: mv_sdhci: fix 8bus width access for 88SV331xV5
Marvell 88SV331xV5 platform's sdhci host control is not very standard with the spec in the 8bit handling. It need to set its private register to switch to the 8bit mode which is not included in the standard sdhci registers. This patch mainly hacks the writeb method, and set its private register if it find the driver is going to switch to the 8bit mode. Signed-off-by: Lei Wen <leiwen@marvell.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/mv_sdhci.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c
index 9e59951..f92caeb 100644
--- a/drivers/mmc/mv_sdhci.c
+++ b/drivers/mmc/mv_sdhci.c
@@ -2,6 +2,33 @@
#include <malloc.h>
#include <sdhci.h>
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+static struct sdhci_ops mv_ops;
+
+#if defined(CONFIG_SHEEVA_88SV331xV5)
+#define SD_CE_ATA_2 0xEA
+#define MMC_CARD 0x1000
+#define MMC_WIDTH 0x0100
+static inline void mv_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ struct mmc *mmc = host->mmc;
+ u32 ata = (u32)host->ioaddr + SD_CE_ATA_2;
+
+ if (!IS_SD(mmc) && reg == SDHCI_HOST_CONTROL) {
+ if (mmc->bus_width == 8)
+ writew(readw(ata) | (MMC_CARD | MMC_WIDTH), ata);
+ else
+ writew(readw(ata) & ~(MMC_CARD | MMC_WIDTH), ata);
+ }
+
+ writeb(val, host->ioaddr + reg);
+}
+
+#else
+#define mv_sdhci_writeb NULL
+#endif /* CONFIG_SHEEVA_88SV331xV5 */
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
+
static char *MVSDH_NAME = "mv_sdh";
int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
{
@@ -15,6 +42,12 @@ int mv_sdh_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
host->name = MVSDH_NAME;
host->ioaddr = (void *)regbase;
host->quirks = quirks;
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+ memset(&mv_ops, 0, sizeof(struct sdhci_ops));
+ if (mv_sdhci_writeb != NULL)
+ mv_ops.write_b = mv_sdhci_writeb;
+ host->ops = &mv_ops;
+#endif
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
add_sdhci(host, max_clk, min_clk);
return 0;