mmc: mv_sdhci: fix 8bus width access for 88SV331xV5
authorLei Wen <leiwen@marvell.com>
Mon, 3 Oct 2011 20:33:44 +0000 (20:33 +0000)
committerAndy Fleming <afleming@freescale.com>
Thu, 3 Nov 2011 07:14:58 +0000 (02:14 -0500)
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>
drivers/mmc/mv_sdhci.c

index 9e5995103c7da7e65d679ad2c85c7c55324991a9..f92caeb8fd5f43884e720f311fc9e3f58b03f6d2 100644 (file)
@@ -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;