This patch add Marvell kirkwood MVSDIO/MMC driver
and enable it for Sheevaplugs and OpenRD boards.
Signed-off-by: Gerald Kerma drea...@doukki.net
---
Changes in v7:
- removed unrelated stuff
- minor code cleaning
Changes in v6:
- rename driver to mvebu_mmc
- renames constants and functions
- move mmc_init to kirkwood/cpu
- code cleaning
Changes in v5:
- purge uneeded code
- remove some extra debug
Changes in v4:
- rename drivers files to MVSDIO
- fix MMC clock init which now use dev ID
- clean debug strings
- remove MVSDIO_TWEAK_NOSDHS quirk
- remove dead code
Changes in v3:
- Add MVSDIO_TWEAK_NOSDHS quirk
- Minor clean
Changes in v2:
- Fix some typo and missing lines from patch import
arch/arm/cpu/arm926ejs/kirkwood/cpu.c | 9 +
arch/arm/include/asm/arch-kirkwood/kirkwood.h | 1 +
drivers/mmc/Makefile | 1 +
drivers/mmc/mvebu_mmc.c | 361 ++
include/configs/openrd.h | 8 +
include/configs/sheevaplug.h | 11 +
include/mvebu_mmc.h | 278
7 files changed, 669 insertions(+)
create mode 100644 drivers/mmc/mvebu_mmc.c
create mode 100644 include/mvebu_mmc.h
diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
index da80240..881e2de 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
@@ -13,6 +13,7 @@
#include asm/io.h
#include asm/arch/cpu.h
#include asm/arch/kirkwood.h
+#include mvebu_mmc.h
#define BUFLEN 16
@@ -377,3 +378,11 @@ int cpu_eth_init(bd_t *bis)
return 0;
}
#endif
+
+#ifdef CONFIG_MVEBU_MMC
+int board_mmc_init(bd_t *bis)
+{
+ mvebu_mmc_init(bis);
+ return 0;
+}
+#endif /* CONFIG_MVEBU_MMC */
diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
index bc207f5..3ea51d7 100644
--- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
@@ -39,6 +39,7 @@
#define KW_EGIGA0_BASE (KW_REGISTER(0x72000))
#define KW_EGIGA1_BASE (KW_REGISTER(0x76000))
#define KW_SATA_BASE (KW_REGISTER(0x8))
+#define KW_SDIO_BASE (KW_REGISTER(0x9))
/* Kirkwood Sata controller has two ports */
#define KW_SATA_PORT0_OFFSET 0x2000
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 34febf5..f5be96f 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
else
obj-$(CONFIG_GENERIC_MMC) += mmc_write.o
endif
+obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o
diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c
new file mode 100644
index 000..9759198
--- /dev/null
+++ b/drivers/mmc/mvebu_mmc.c
@@ -0,0 +1,361 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * (C) Copyright 2012
+ * Marvell Semiconductor www.marvell.com
+ * Written-by: Maen Suleiman, Gerald Kerma
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include common.h
+#include malloc.h
+#include part.h
+#include mmc.h
+#include asm/io.h
+#include asm/arch/cpu.h
+#include asm/arch/kirkwood.h
+#include mvebu_mmc.h
+
+#define DRIVER_NAME MVEBU_MMC
+
+static void mvebu_mmc_write(u32 offs, u32 val)
+{
+ writel(val, CONFIG_SYS_MMC_BASE + (offs));
+}
+
+static u32 mvebu_mmc_read(u32 offs)
+{
+ return readl(CONFIG_SYS_MMC_BASE + (offs));
+}
+
+static int mvebu_mmc_setup_data(struct mmc_data *data)
+{
+ u32 ctrl_reg;
+
+ debug(%s, data %s : blocks=%d blksz=%d\n, DRIVER_NAME,
+ (data-flags MMC_DATA_READ) ? read : write,
+ data-blocks, data-blocksize);
+
+ /* default to maximum timeout */
+ ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL);
+ ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+ mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg);
+
+ if (data-flags MMC_DATA_READ) {
+ mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data-dest 0x);
+ mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data-dest 16);
+ } else {
+ mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data-src 0x);
+ mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data-src 16);
+ }
+
+ mvebu_mmc_write(SDIO_BLK_COUNT, data-blocks);
+ mvebu_mmc_write(SDIO_BLK_SIZE, data-blocksize);
+
+ return 0;
+}
+
+static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ int timeout = 10;
+ ushort waittype = 0;
+ ushort resptype = 0;
+ ushort xfertype = 0;
+ ushort resp_indx = 0;
+
+ debug(cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n,
+ cmd-cmdidx, cmd-resp_type, cmd-cmdarg);
+
+ udelay(10*1000);
+
+ debug(%s: cmd %d (hw state 0x%04x)\n, DRIVER_NAME,
+ cmd-cmdidx,