Patchwork [U-Boot] Marvell SheevaPlug v2013.04 Refresh (ask for review)

login
register
mail settings
Submitter DrEagle
Date July 2, 2013, 9:17 p.m.
Message ID <51D3437F.9040000@doukki.net>
Download mbox | patch
Permalink /patch/256514/
State New
Delegated to: Prafulla Wadaskar
Headers show

Comments

DrEagle - July 2, 2013, 9:17 p.m.
Hi,

I have started to rework all the MVSDIO driver, and some more enhancements, to make a cool updated and workable SheevaPlug.
I have take the v2013.04 denx uBoot to base my patchs.

If you can take a look inside and give me needed feedback.

I want to precise that I do not easily practice GIT features.

Regards,
Gérald
Albert ARIBAUD - July 5, 2013, 9:08 p.m.
Hi Gérald,

On Tue, 02 Jul 2013 23:17:51 +0200, DrEagle <dreagle@doukki.net> wrote:

> Hi,
> 
> I have started to rework all the MVSDIO driver, and some more enhancements, to make a cool updated and workable SheevaPlug.
> I have take the v2013.04 denx uBoot to base my patchs.
> 
> If you can take a look inside and give me needed feedback.
> 
> I want to precise that I do not easily practice GIT features.

Pease submit patch according to the patch submission guidelines at
<http://www.denx.de/wiki/U-Boot/Patches>. Especially, do not send
patches to the list as attachments; instead, use 'git format-patch' and
'git send-email'. Also, put the relevant custodians and/or maintainers
in Cc: of your mail.

> Regards,
> Gérald

Amicalement,
DrEagle - July 7, 2013, 11:41 p.m.
Le 05/07/2013 23:08, Albert ARIBAUD a écrit :
> Hi Gérald,

Hello,

> On Tue, 02 Jul 2013 23:17:51 +0200, DrEagle <dreagle@doukki.net> wrote:
> 
>> Hi,
>>
>> I have started to rework all the MVSDIO driver, and some more enhancements, to make a cool updated and workable SheevaPlug.
>> I have take the v2013.04 denx uBoot to base my patchs.
>>
>> If you can take a look inside and give me needed feedback.
>>
>> I want to precise that I do not easily practice GIT features.
> 
> Pease submit patch according to the patch submission guidelines at
> <http://www.denx.de/wiki/U-Boot/Patches>. Especially, do not send
> patches to the list as attachments; instead, use 'git format-patch' and
> 'git send-email'. Also, put the relevant custodians and/or maintainers
> in Cc: of your mail.

I'll try to get it rewrote according rules.

I do not get git send-email working.

So I have take appart the patch and will send them separatly.

Regards,
Gérald
DrEagle - July 7, 2013, 11:43 p.m.
This serie of patch :
    - add kirkwood_id to detect supported devices and revisions
    - update supported devices and revisions
    - add kw88f6282 support
    - add SDIO/MMC generic driver v3
    - add SDIO/MMC driver support to Kirkwood SoC
    - add SDIO/MMC support to Sheevaplug board
    - add MVSATA sheevaplug support
    - update sheevaplug defaults config

    Signed-off-by: drEagle <uboot@doukki.net>
Albert ARIBAUD - July 8, 2013, 9:46 a.m.
Hi DrEagle,

On Mon, 08 Jul 2013 01:41:38 +0200, DrEagle <dreagle@doukki.net> wrote:

> Le 05/07/2013 23:08, Albert ARIBAUD a écrit :
> > Hi Gérald,
> 
> Hello,
> 
> > On Tue, 02 Jul 2013 23:17:51 +0200, DrEagle <dreagle@doukki.net> wrote:
> > 
> >> Hi,
> >>
> >> I have started to rework all the MVSDIO driver, and some more enhancements, to make a cool updated and workable SheevaPlug.
> >> I have take the v2013.04 denx uBoot to base my patchs.
> >>
> >> If you can take a look inside and give me needed feedback.
> >>
> >> I want to precise that I do not easily practice GIT features.
> > 
> > Pease submit patch according to the patch submission guidelines at
> > <http://www.denx.de/wiki/U-Boot/Patches>. Especially, do not send
> > patches to the list as attachments; instead, use 'git format-patch' and
> > 'git send-email'. Also, put the relevant custodians and/or maintainers
> > in Cc: of your mail.
> 
> I'll try to get it rewrote according rules.

Among these rules, please run your patches through checkpatch, or
through patman. Several lines are way beyond 80 chars, for instance,
and either tool would have spotted this.

> I do not get git send-email working.
>
> So I have take appart the patch and will send them separatly.

You should investigate why git send-email fails and try to fix it.

> Regards,
> Gérald

Amicalement,

Patch

 arch/arm/cpu/arm926ejs/kirkwood/cpu.c          |  58 ++++
 arch/arm/include/asm/arch-kirkwood/config.h    |   2 +
 arch/arm/include/asm/arch-kirkwood/cpu.h       |   2 +
 arch/arm/include/asm/arch-kirkwood/kirkwood.h  |  24 ++
 arch/arm/include/asm/arch-kirkwood/kw88f6282.h |  39 +++
 board/Marvell/sheevaplug/sheevaplug.c          |  11 +
 drivers/mmc/Makefile                           |   1 +
 drivers/mmc/mrvl_mmc.c                         | 446 +++++++++++++++++++++++++
 include/configs/mv-common.h                    |  19 +-
 include/configs/sheevaplug.h                   |  91 +++--
 include/mmc.h                                  |   2 +-
 include/mrvl_mmc.h                             | 266 +++++++++++++++
 12 files changed, 935 insertions(+), 26 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
index fba5e01..720fccf 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/cpu.c
@@ -350,6 +350,64 @@  int arch_cpu_init(void)
 }
 #endif /* CONFIG_ARCH_CPU_INIT */
 
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+#if defined(CONFIG_ARCH_DEV_ID)
+
+void kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+	*dev = (readl(KW_REG_PCIE_DEVID) >> 16) & 0xffff;
+	*rev = readl(KW_REG_PCIE_REVID) & 0xff;
+}
+
+/*
+ * Identify device ID and revision.
+ */
+char *kirkwood_id(void)
+{
+	u32 dev, rev;
+
+	kirkwood_pcie_id(&dev, &rev);
+
+	if (dev == MV88F6281_DEV_ID) {
+		if (rev == MV88F6281_REV_Z0)
+			return "MV88F6281-Z0";
+		else if (rev == MV88F6281_REV_A0)
+			return "MV88F6281-A0";
+		else if (rev == MV88F6281_REV_A1)
+			return "MV88F6281-A1";
+		else
+			return "MV88F6281-Rev-Unsupported";
+	} else if (dev == MV88F6192_DEV_ID) {
+		if (rev == MV88F6192_REV_Z0)
+			return "MV88F6192-Z0";
+		else if (rev == MV88F6192_REV_A0)
+			return "MV88F6192-A0";
+		else if (rev == MV88F6192_REV_A1)
+			return "MV88F6192-A1";
+		else
+			return "MV88F6192-Rev-Unsupported";
+	} else if (dev == MV88F6180_DEV_ID) {
+		if (rev == MV88F6180_REV_A0)
+			return "MV88F6180-Rev-A0";
+		else if (rev == MV88F6180_REV_A1)
+			return "MV88F6180-Rev-A1";
+		else
+			return "MV88F6180-Rev-Unsupported";
+	} else if (dev == MV88F6282_DEV_ID) {
+		if (rev == MV88F6282_REV_A0)
+			return "MV88F6282-Rev-A0";
+		else if (rev == MV88F6282_REV_A1)
+			return "MV88F6282-Rev-A1";
+		else
+			return "MV88F6282-Rev-Unsupported";
+	} else {
+		return "Device-Unknown";
+	}
+}
+#endif /* CONFIG_ARCH_DEV_ID */
+
 /*
  * SOC specific misc init
  */
diff --git a/arch/arm/include/asm/arch-kirkwood/config.h b/arch/arm/include/asm/arch-kirkwood/config.h
index a9499b7..210cc3f 100644
--- a/arch/arm/include/asm/arch-kirkwood/config.h
+++ b/arch/arm/include/asm/arch-kirkwood/config.h
@@ -35,6 +35,8 @@ 
 #include <asm/arch/kw88f6281.h>
 #elif defined (CONFIG_KW88F6192)
 #include <asm/arch/kw88f6192.h>
+#elif defined (CONFIG_KW88F6182)
+#include <asm/arch/kw88f6182.h>
 #else
 #error "SOC Name not defined"
 #endif /* CONFIG_KW88F6281 */
diff --git a/arch/arm/include/asm/arch-kirkwood/cpu.h b/arch/arm/include/asm/arch-kirkwood/cpu.h
index 009a6bb..34957a2 100644
--- a/arch/arm/include/asm/arch-kirkwood/cpu.h
+++ b/arch/arm/include/asm/arch-kirkwood/cpu.h
@@ -167,5 +167,7 @@  int kw_config_mpp(unsigned int mpp0_7, unsigned int mpp8_15,
 		unsigned int mpp32_39, unsigned int mpp40_47,
 		unsigned int mpp48_55);
 unsigned int kw_winctrl_calcsize(unsigned int sizeval);
+void kirkwood_pcie_id(u32 *dev, u32 *rev);
+char *kirkwood_id(void);
 #endif /* __ASSEMBLY__ */
 #endif /* _KWCPU_H */
diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
index 47771d5..c696dc4 100644
--- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
@@ -55,6 +55,7 @@ 
 #define KW_EGIGA0_BASE			(KW_REGISTER(0x72000))
 #define KW_EGIGA1_BASE			(KW_REGISTER(0x76000))
 #define KW_SATA_BASE			(KW_REGISTER(0x80000))
+#define KW_SDIO_BASE			(KW_REGISTER(0x90000))
 
 /* Kirkwood Sata controller has two ports */
 #define KW_SATA_PORT0_OFFSET		0x2000
@@ -77,10 +78,33 @@ 
 #define MVCPU_WIN_ENABLE	KWCPU_WIN_ENABLE
 #define MVCPU_WIN_DISABLE	KWCPU_WIN_DISABLE
 
+/*
+ * Supported devices and revisions.
+ */
+#define MV88F6281_DEV_ID	0x6281
+#define MV88F6281_REV_Z0	0
+#define MV88F6281_REV_A0	2
+#define MV88F6281_REV_A1	3
+
+#define MV88F6192_DEV_ID	0x6192
+#define MV88F6192_REV_Z0	0
+#define MV88F6192_REV_A0	2
+#define MV88F6192_REV_A1	3
+
+#define MV88F6180_DEV_ID	0x6180
+#define MV88F6180_REV_A0	2
+#define MV88F6180_REV_A1	3
+
+#define MV88F6282_DEV_ID	0x6282
+#define MV88F6282_REV_A0	0
+#define MV88F6282_REV_A1	1
+
 #if defined (CONFIG_KW88F6281)
 #include <asm/arch/kw88f6281.h>
 #elif defined (CONFIG_KW88F6192)
 #include <asm/arch/kw88f6192.h>
+#elif defined (CONFIG_KW88F6182)
+#include <asm/arch/kw88f6182.h>
 #else
 #error "SOC Name not defined"
 #endif /* CONFIG_KW88F6281 */
diff --git a/arch/arm/include/asm/arch-kirkwood/kw88f6282.h b/arch/arm/include/asm/arch-kirkwood/kw88f6282.h
new file mode 100644
index 0000000..22d10f1
--- /dev/null
+++ b/arch/arm/include/asm/arch-kirkwood/kw88f6282.h
@@ -0,0 +1,39 @@ 
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * Header file for Feroceon CPU core 88FR131 Based KW88F6281 SOC.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _ASM_ARCH_KW88F6281_H
+#define _ASM_ARCH_KW88F6281_H
+
+/* SOC specific definitions */
+#define KW88F6281_REGS_PHYS_BASE	0xf1000000
+#define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
+
+/* TCLK Core Clock definition */
+#ifndef CONFIG_SYS_TCLK
+#define CONFIG_SYS_TCLK	200000000 /* 200MHz */
+#endif
+
+#endif /* _ASM_ARCH_KW88F6281_H */
diff --git a/board/Marvell/sheevaplug/sheevaplug.c b/board/Marvell/sheevaplug/sheevaplug.c
index 16efe64..2bd2568 100644
--- a/board/Marvell/sheevaplug/sheevaplug.c
+++ b/board/Marvell/sheevaplug/sheevaplug.c
@@ -28,6 +28,9 @@ 
 #include <asm/arch/kirkwood.h>
 #include <asm/arch/mpp.h>
 #include "sheevaplug.h"
+#ifdef CONFIG_MRVL_MMC
+#include <mrvl_mmc.h>
+#endif /* CONFIG_MRVL_MMC */
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -147,3 +150,11 @@  void reset_phy(void)
 	printf("88E1116 Initialized on %s\n", name);
 }
 #endif /* CONFIG_RESET_PHY_R */
+
+#ifdef CONFIG_MRVL_MMC
+int board_mmc_init(bd_t *bis)
+{
+	mrvl_mmc_initialize(bis);
+	return 0;
+}
+#endif /* CONFIG_MRVL_MMC */
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 1d6faa2..2a2745d 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -37,6 +37,7 @@  COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
+COBJS-$(CONFIG_MRVL_MMC) += mrvl_mmc.o
 COBJS-$(CONFIG_MV_SDHCI) += mv_sdhci.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
 COBJS-$(CONFIG_MXS_MMC) += mxsmmc.o
diff --git a/drivers/mmc/mrvl_mmc.c b/drivers/mmc/mrvl_mmc.c
new file mode 100644
index 0000000..b0571cf
--- /dev/null
+++ b/drivers/mmc/mrvl_mmc.c
@@ -0,0 +1,446 @@ 
+/*
+ * Driver for Marvell SDIO/MMC controller
+ *
+ * (C) Copyright 2012
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Gérald Kerma <uboot@doukki.net>
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#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 <mrvl_mmc.h>
+
+#define DRIVER_NAME	"mvsdio"
+
+static int maxfreq = MRVL_MMC_CLOCKRATE_MAX;
+
+#define mvsd_write(offs, val)	writel(val, CONFIG_SYS_MMC_BASE + (offs))
+#define mvsd_read(offs)			readl(CONFIG_SYS_MMC_BASE + (offs))
+
+#define MRVL_MMC_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
+
+static int mrvl_mmc_setup_data(struct mmc_data *data)
+{
+	u32 ctrl_reg;
+
+#ifdef DEBUG
+	printf("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME,
+		(data->flags & MMC_DATA_READ) ? "read" : "write",
+		data->blocks, data->blocksize);
+#endif
+
+	/* default to maximum timeout */
+	ctrl_reg = mvsd_read(SDIO_HOST_CTRL);
+	ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+	mvsd_write(SDIO_HOST_CTRL, ctrl_reg);
+
+	if (data->flags & MMC_DATA_READ) {
+		mvsd_write(SDIO_SYS_ADDR_LOW,(u32)data->dest & 0xffff);
+		mvsd_write(SDIO_SYS_ADDR_HI,(u32)data->dest >> 16);
+	} else {
+		mvsd_write(SDIO_SYS_ADDR_LOW,(u32)data->src & 0xffff);
+		mvsd_write(SDIO_SYS_ADDR_HI,(u32)data->src >> 16);
+	}
+
+	mvsd_write(SDIO_BLK_COUNT, data->blocks);
+	mvsd_write(SDIO_BLK_SIZE, data->blocksize);
+
+	return 0;
+}
+
+static int mrvl_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;
+
+#ifdef CONFIG_MMC_DEBUG
+	printf("cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", cmd->cmdidx, cmd->resp_type, cmd->cmdarg);
+#endif
+
+	udelay(10*1000);
+
+#ifdef CONFIG_MMC_DEBUG
+	printf("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME,
+		cmd->cmdidx, mvsd_read(SDIO_HW_STATE));
+#endif
+
+	/* Checking if card is busy */
+	while ((mvsd_read(SDIO_HW_STATE) & CARD_BUSY)) {
+		if (timeout == 0) {
+			printf("%s: card busy!\n", DRIVER_NAME);
+			return -1;
+		}
+		timeout--;
+		udelay(1000);
+	}
+
+	/* Set up for a data transfer if we have one */
+	if (data) {
+		int err = mrvl_mmc_setup_data(data);
+		if (err)
+			return err;
+	}
+
+	resptype = SDIO_CMD_INDEX(cmd->cmdidx);
+
+	/* Analyzing resptype/xfertype/waittype for the command */
+	if (cmd->resp_type & MMC_RSP_BUSY)
+		resptype |= SDIO_CMD_RSP_48BUSY;
+	else if (cmd->resp_type & MMC_RSP_136)
+		resptype |= SDIO_CMD_RSP_136;
+	else if (cmd->resp_type & MMC_RSP_PRESENT)
+		resptype |= SDIO_CMD_RSP_48;
+	else
+		resptype |= SDIO_CMD_RSP_NONE;
+
+	if (cmd->resp_type & MMC_RSP_CRC)
+		resptype |= SDIO_CMD_CHECK_CMDCRC;
+
+	if (cmd->resp_type & MMC_RSP_OPCODE)
+		resptype |= SDIO_CMD_INDX_CHECK;
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		resptype |= SDIO_UNEXPECTED_RESP;
+		waittype |= SDIO_NOR_UNEXP_RSP;
+	}
+
+	if (data) {
+		resptype |= SDIO_CMD_DATA_PRESENT | SDIO_CMD_CHECK_DATACRC16;
+		xfertype |= SDIO_XFER_MODE_HW_WR_DATA_EN;
+		if (data->flags & MMC_DATA_READ) {
+			xfertype |= SDIO_XFER_MODE_TO_HOST;
+			waittype = SDIO_NOR_DMA_INI;
+		} else
+			waittype |= SDIO_NOR_XFER_DONE;
+	} else {
+		waittype |= SDIO_NOR_CMD_DONE;
+	}
+
+	/* Setting cmd arguments */
+	mvsd_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff);
+	mvsd_write(SDIO_ARG_HI, cmd->cmdarg >> 16 );
+
+	/* Setting Xfer mode */
+	mvsd_write(SDIO_XFER_MODE, xfertype);
+
+	mvsd_write(SDIO_NOR_INTR_STATUS, ~SDIO_NOR_CARD_INT);
+	mvsd_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+
+	/* Sending command */
+	mvsd_write(SDIO_CMD, resptype);
+/*
+	mvsd_write(SDIO_CMD, MRVL_MMC_MAKE_CMD(cmd->cmdidx, resptype));
+*/
+
+	mvsd_write(SDIO_NOR_INTR_EN, SDIO_POLL_MASK);
+	mvsd_write(SDIO_ERR_INTR_EN, SDIO_POLL_MASK);
+
+	/* Waiting for completion */
+	timeout = 1000000;
+
+	while (!((mvsd_read(SDIO_NOR_INTR_STATUS)) & waittype)) {
+		if (mvsd_read(SDIO_NOR_INTR_STATUS) & SDIO_NOR_ERROR) {
+#ifdef DEBUG
+			printf("%s: mrvl_mmc_send_cmd: error! cmdidx : %d, err reg: %04x\n", DRIVER_NAME, cmd->cmdidx, mvsd_read(SDIO_ERR_INTR_STATUS));
+#endif
+			if (mvsd_read(SDIO_ERR_INTR_STATUS) & (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT))
+				return TIMEOUT;
+			return COMM_ERR;
+		}
+
+		timeout--;
+		udelay(1);
+		if (timeout <= 0) {
+			printf("%s: command timed out\n", DRIVER_NAME);
+			return TIMEOUT;
+		}
+	}
+
+	/* Handling response */
+	if (cmd->resp_type & MMC_RSP_136) {
+		uint response[8];
+		for (resp_indx = 0; resp_indx < 8; resp_indx++)
+			response[resp_indx] = mvsd_read(SDIO_RSP(resp_indx));
+
+		cmd->response[0] =		((response[0] & 0x03ff) << 22) |
+								((response[1] & 0xffff) << 6) |
+								((response[2] & 0xfc00) >> 10);
+		cmd->response[1] =		((response[2] & 0x03ff) << 22) |
+								((response[3] & 0xffff) << 6) |
+								((response[4] & 0xfc00) >> 10);
+		cmd->response[2] =		((response[4] & 0x03ff) << 22) |
+								((response[5] & 0xffff) << 6) |
+								((response[6] & 0xfc00) >> 10);
+		cmd->response[3] =		((response[6] & 0x03ff) << 22) |
+								((response[7] & 0x3fff) << 8);
+	} else if (cmd->resp_type & MMC_RSP_PRESENT) {
+		uint response[3];
+		for (resp_indx = 0; resp_indx < 3; resp_indx++)
+			response[resp_indx] = mvsd_read(SDIO_RSP(resp_indx));
+
+		cmd->response[0] = 		((response[2] & 0x003f) << (8 - 8))		|
+								((response[1] & 0xffff) << (14 - 8))	|
+								((response[0] & 0x03ff) << (30 - 8));
+		cmd->response[1] = 		((response[0] & 0xfc00) >> 10);
+		cmd->response[2] =		0;
+		cmd->response[3] =		0;
+	}
+
+#ifdef CONFIG_MMC_DEBUG
+	printf("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type);
+	printf("[0x%x] ", cmd->response[0]);
+	printf("[0x%x] ", cmd->response[1]);
+	printf("[0x%x] ", cmd->response[2]);
+	printf("[0x%x] ", cmd->response[3]);
+	printf("\n");
+#endif
+
+	return 0;
+}
+
+static void mvsd_power_up(void)
+{
+#ifdef DEBUG
+	printf("%s: power up\n", DRIVER_NAME);
+#endif
+	/* disable interrupts */
+	mvsd_write(SDIO_NOR_INTR_EN, 0);
+	mvsd_write(SDIO_ERR_INTR_EN, 0);
+
+	/* SW reset */
+	mvsd_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
+
+	mvsd_write(SDIO_XFER_MODE, 0);
+
+	/* enable status */
+	mvsd_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
+	mvsd_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
+
+	/* enable interrupts status */
+	mvsd_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
+	mvsd_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+}
+
+static void mvsd_power_down(void)
+{
+#ifdef DEBUG
+	printf("%s: power down\n", DRIVER_NAME);
+#endif
+	/* disable interrupts */
+	mvsd_write(SDIO_NOR_INTR_EN, 0);
+	mvsd_write(SDIO_ERR_INTR_EN, 0);
+
+	/* SW reset */
+	mvsd_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
+
+	mvsd_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
+
+	/* disable status */
+	mvsd_write(SDIO_NOR_STATUS_EN, 0);
+	mvsd_write(SDIO_ERR_STATUS_EN, 0);
+
+	/* enable interrupts status */
+	mvsd_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK);
+	mvsd_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK);
+}
+
+static u32 mrvl_mmc_get_base_clock(void)
+{
+	u32 devid;
+	u32 revid;
+
+	if (0) {
+		kirkwood_pcie_id(&devid, &revid);
+
+#ifdef DEBUG
+		printf("%s: board devid[0x%x] devid[0x%x]\n", DRIVER_NAME, devid, revid);
+#endif
+
+		if (revid == 0 && devid != MV88F6282_DEV_ID){
+	 /* catch all Kirkwood Z0's */
+#ifdef DEBUG
+			printf("%s: Kirkwood Z0's base clock = %d\n", DRIVER_NAME, MRVL_MMC_BASE_FAST_CLK_100);
+#endif
+			return MRVL_MMC_BASE_FAST_CLK_100;
+		}else{
+#ifdef DEBUG
+			printf("%s: base clock = %d\n", DRIVER_NAME, MRVL_MMC_BASE_FAST_CLK_200);
+#endif
+			return MRVL_MMC_BASE_FAST_CLK_200;
+		}
+	}
+	return MRVL_MMC_BASE_FAST_CLOCK;
+}
+
+static void mrvl_mmc_set_clk(unsigned int clock)
+{
+	unsigned int m;
+
+	if (clock == 0){
+#ifdef DEBUG
+		printf("%s: clock off\n", DRIVER_NAME);
+#endif
+		mvsd_write(SDIO_XFER_MODE, SDIO_XFER_MODE_STOP_CLK);
+		mvsd_write(SDIO_CLK_DIV, MRVL_MMC_BASE_DIV_MAX);
+	}else{
+		m = MRVL_MMC_BASE_FAST_CLOCK/(2*clock) - 1;
+		if (m > MRVL_MMC_BASE_DIV_MAX)
+			m = MRVL_MMC_BASE_DIV_MAX;
+#ifdef DEBUG
+		printf("%s: mrvl_mmc_set_clk: base = %d dividor = 0x%x clock=%d\n", DRIVER_NAME, mrvl_mmc_get_base_clock(), m, clock);
+#endif
+		mvsd_write(SDIO_CLK_DIV, m & MRVL_MMC_BASE_DIV_MAX);
+	}
+	udelay(10*1000);
+}
+
+static void mrvl_mmc_set_bus(unsigned int bus)
+{
+	u32 ctrl_reg = 0;
+
+	ctrl_reg = mvsd_read(SDIO_HOST_CTRL);
+	ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+	switch (bus) {
+		case 4:
+			ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_4_BITS;
+			break;
+		case 1:
+		default:
+			ctrl_reg |= SDIO_HOST_CTRL_DATA_WIDTH_1_BIT;
+	}
+	/* default transfer mode */
+	ctrl_reg |= SDIO_HOST_CTRL_BIG_ENDIAN;
+	ctrl_reg &= ~SDIO_HOST_CTRL_LSB_FIRST;
+
+	/* default to maximum timeout */
+	ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX);
+
+	ctrl_reg |= SDIO_HOST_CTRL_PUSH_PULL_EN;
+
+	ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY;
+
+	/*
+	 * The HI_SPEED_EN bit is causing trouble with many (but not all)
+	 * high speed SD, SDHC and SDIO cards.  Not enabling that bit
+	 * makes all cards work.  So let's just ignore that bit for now
+	 * and revisit this issue if problems for not enabling this bit
+	 * are ever reported.
+	 */
+#if 0
+	if (ios->timing == MMC_TIMING_MMC_HS ||
+	    ios->timing == MMC_TIMING_SD_HS)
+		ctrl_reg |= SDIO_HOST_CTRL_HI_SPEED_EN;
+#endif
+
+#ifdef DEBUG
+	printf("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg,
+		(ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ?
+			"push-pull" : "open-drain",
+		(ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+			"4bit-width" : "1bit-width",
+		(ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ?
+			"high-speed" : "");
+#endif
+
+	mvsd_write(SDIO_HOST_CTRL, ctrl_reg);
+	udelay(10*1000);
+}
+
+static void mrvl_mmc_set_ios(struct mmc *mmc)
+{
+#ifdef DEBUG
+	printf("%s: bus[%d] clock[%d]\n", DRIVER_NAME, mmc->bus_width, mmc->clock);
+#endif
+	mrvl_mmc_set_bus(mmc->bus_width);
+	mrvl_mmc_set_clk(mmc->clock);
+}
+
+static int mrvl_mmc_init(struct mmc *mmc)
+{
+#ifdef DEBUG
+	printf("%s: mrvl_mmc_init\n", DRIVER_NAME);
+#endif
+
+/*
+ * Setting host parameters
+ * Initial Host Ctrl : Timeout : max , Normal Speed mode, 4-bit data mode
+ * Big Endian, SD memory Card, Push_pull CMD Line
+ */
+	mvsd_write(SDIO_HOST_CTRL,
+		SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX) |
+		SDIO_HOST_CTRL_DATA_WIDTH_4_BITS |
+		SDIO_HOST_CTRL_BIG_ENDIAN |
+		SDIO_HOST_CTRL_PUSH_PULL_EN |
+		SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY );
+
+	mvsd_write(SDIO_CLK_CTRL, 0);
+
+	/* enable status */
+	mvsd_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK);
+	mvsd_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK);
+
+	/* disable interrupts */
+	mvsd_write(SDIO_NOR_INTR_EN, 0);
+	mvsd_write(SDIO_ERR_INTR_EN, 0);
+
+	/* SW reset */
+	mvsd_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW);
+
+	udelay(10*1000);
+	return 0;
+}
+
+int mrvl_mmc_initialize(bd_t *bis)
+{
+	struct mmc *mmc = NULL;
+
+#ifdef DEBUG
+	printf("%s: %s base_clock = %d\n", DRIVER_NAME, kirkwood_id(), mrvl_mmc_get_base_clock());
+#endif
+	mmc = malloc(sizeof(struct mmc));
+	if (!mmc)
+		return -1;
+
+	sprintf(mmc->name, DRIVER_NAME);
+	mmc->send_cmd = mrvl_mmc_send_cmd;
+	mmc->set_ios = mrvl_mmc_set_ios;
+	mmc->init = mrvl_mmc_init;
+	
+	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
+
+	mmc->f_min = MRVL_MMC_BASE_FAST_CLOCK/MRVL_MMC_BASE_DIV_MAX;
+	mmc->f_max = maxfreq;
+
+	mmc_register(mmc);
+
+	return 0;
+}
+
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index 405a842..e917e6f 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -72,7 +72,10 @@ 
 #define CONFIG_BAUDRATE			115200
 #define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, \
 					  115200,230400, 460800, 921600 }
-/* auto boot */
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_ENV_OVERWRITE
 #define CONFIG_BOOTDELAY	3	/* default enable autoboot */
 
 /*
@@ -98,6 +101,7 @@ 
  * Other required minimal configurations
  */
 #define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER		/* use "hush" command parser */
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_CMDLINE_EDITING
 #define CONFIG_CONSOLE_INFO_QUIET	/* some code reduction */
@@ -142,6 +146,19 @@ 
 #endif
 
 /*
+ * SATA driver configuration
+ */
+#ifdef CONFIG_CMD_IDE
+#define __io
+#define CONFIG_IDE_PREINIT
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MVSATA_IDE_USE_PORT0
+#define CONFIG_MVSATA_IDE_USE_PORT1
+#define CONFIG_SYS_ATA_IDE0_OFFSET	MV_SATA_PORT0_OFFSET
+#define CONFIG_SYS_ATA_IDE1_OFFSET	MV_SATA_PORT1_OFFSET
+#endif /* CONFIG_CMD_IDE */
+
+/*
  * Common USB/EHCI configuration
  */
 #ifdef CONFIG_CMD_USB
diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index 83dd8ff..270fd56 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -28,7 +28,8 @@ 
 /*
  * Version number information
  */
-#define CONFIG_IDENT_STRING	"\nMarvell-Sheevaplug"
+
+#define CONFIG_IDENT_STRING	"\nMarvell-Sheevaplug - eSATA - SD/MMC"
 
 /*
  * High Level Configuration Options (easy to change)
@@ -39,17 +40,24 @@ 
 #define CONFIG_MACH_SHEEVAPLUG	/* Machine type */
 #define CONFIG_SKIP_LOWLEVEL_INIT	/* disable board lowlevel_init */
 
+#define CONFIG_ARCH_DEV_ID	1
+
 /*
  * Commands configuration
  */
+
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
+#define CONFIG_SYS_MVFS
 #include <config_cmd_default.h>
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_ENV
+#define CONFIG_CMD_IDE
 #define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_USB
+
 /*
  * mv-common.h should be defined after CMD configs since it used them
  * to enable certain macros
@@ -57,6 +65,11 @@ 
 #include "mv-common.h"
 
 /*
+ * Miscellaneous configurable options
+ */
+#undef CONFIG_CONSOLE_INFO_QUIET
+
+/*
  *  Environment variables configurations
  */
 #ifdef CONFIG_CMD_NAND
@@ -65,29 +78,56 @@ 
 #else
 #define CONFIG_ENV_IS_NOWHERE		1	/* if env in SDRAM */
 #endif
+
 /*
  * max 4k env size is enough, but in case of nand
  * it has to be rounded to sector size
  */
 #define CONFIG_ENV_SIZE			0x20000	/* 128k */
-#define CONFIG_ENV_ADDR			0x60000
-#define CONFIG_ENV_OFFSET		0x60000	/* env starts here */
+#define CONFIG_ENV_ADDR			0x80000
+#define CONFIG_ENV_OFFSET		0x80000	/* env starts here */
 
 /*
  * Default environment variables
  */
-#define CONFIG_BOOTCOMMAND		"${x_bootcmd_kernel}; "	\
-	"setenv bootargs ${x_bootargs} ${x_bootargs_root}; "	\
-	"${x_bootcmd_usb}; bootm 0x6400000;"
+#define CONFIG_BOOTCOMMAND \
+	"run x_bootcmd; run z_bootstrap; reset;"
 
-#define CONFIG_MTDPARTS		"orion_nand:512k(uboot),"	\
-	"3m@1m(kernel),1m@4m(psm),13m@5m(rootfs) rw\0"
+#define CONFIG_MTDPARTS						\
+	"mtdparts=orion_nand:"					\
+	"768k(uboot),256k(uboot_env),"				\
+	"11m@1m(kernel),-@12m(rootfs)\0"
 
-#define CONFIG_EXTRA_ENV_SETTINGS	"x_bootargs=console"	\
-	"=ttyS0,115200 mtdparts="CONFIG_MTDPARTS	\
-	"x_bootcmd_kernel=nand read 0x6400000 0x100000 0x300000\0" \
-	"x_bootcmd_usb=usb start\0" \
-	"x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0"
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	"console=console=ttyS0,115200n8\0"				\
+	"mtdids=nand0=orion_nand\0"					\
+	"mtdparts="CONFIG_MTDPARTS					\
+	"kerneladdr=0x00800000\0"					\
+	"kernelfile=/boot/uImage.bin\0"					\
+	"scriptaddr=0x00800000\0"					\
+	"scriptfile=/boot/boot.scr\0"					\
+	"x_bootargs=console=ttyS0,115200n8 "CONFIG_MTDPARTS		\
+	"x_bootargs_root=root=LABEL=plug-rootfs rw rootwait panic=5\0"	\
+	"x_bootcmd=${x_bootcmd_kernel}; setenv bootargs ${x_bootargs}"	\
+	" ${x_bootargs_root}; run z_bootinit;\0"			\
+	"x_bootcmd_kernel=echo ====== BootStrap start ======\0"		\
+	"x_bootstrap_scr=for device in \"mmc usb ide\"; do for fs in"	\
+	" \"ext2 fat\"; do setenv loadcmd \"${fs}load ${device} 0:1\";"	\
+	" if ${loadcmd} ${scriptaddr} ${scriptfile}; then;"		\
+	" run z_bootscr; fi; done; done;\0"				\
+	"x_bootstrap_cmd=for device in \"mmc usb ide\"; do for fs in"	\
+	" \"ext2 fat\"; do setenv loadcmd \"${fs}load ${device} 0:1\";"	\
+	" if ${loadcmd} ${kerneladdr} ${kernelfile}; then;"		\
+	" run z_bootcmd; fi; done; done;\0"				\
+	"x_bootcmd_mtd=nand read.e ${kerneladdr} kernel 0x00b00000;\0"	\
+	"z_bootinit=mmc rescan; usb reset; ide reset;\0"		\
+	"z_bootcmd=if imi ${kerneladdr}; then; bootm ${kerneladdr};"	\
+	" else; echo --- next bootcmd device try ---; fi;\0"		\
+	"z_bootscr=if imi ${scriptaddr}; then; autoscr ${scriptaddr};"	\
+	" else; echo --- next bootscr device try ---; fi;\0"		\
+	"z_bootstrap=run z_bootinit; run x_bootstrap_scr;"		\
+	" run x_bootstrap_cmd; run x_bootcmd_mtd; run z_bootfail;\0"	\
+	"z_bootfail=echo ====== BootStrap end ======\0"
 
 /*
  * Ethernet Driver configuration
@@ -98,17 +138,20 @@ 
 #endif /* CONFIG_CMD_NET */
 
 /*
- * File system
+ * RTC driver configuration
+ */
+#ifdef CONFIG_CMD_DATE
+#define CONFIG_RTC_MV
+#endif /* CONFIG_CMD_DATE */
+
+/*
+ * SDIO/MMC Card Configuration
  */
-#define CONFIG_CMD_EXT2
-#define CONFIG_CMD_FAT
-#define CONFIG_CMD_JFFS2
-#define CONFIG_CMD_UBI
-#define CONFIG_CMD_UBIFS
-#define CONFIG_RBTREE
-#define CONFIG_MTD_DEVICE               /* needed for mtdparts commands */
-#define CONFIG_MTD_PARTITIONS
-#define CONFIG_CMD_MTDPARTS
-#define CONFIG_LZO
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MRVL_MMC
+#define CONFIG_SYS_MMC_BASE KW_SDIO_BASE
+#endif /* CONFIG_CMD_MMC */
 
 #endif /* _CONFIG_SHEEVAPLUG_H */
diff --git a/include/mmc.h b/include/mmc.h
index f0d4820..b103ff4 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -52,7 +52,7 @@ 
 #define MMC_MODE_4BIT		0x100
 #define MMC_MODE_8BIT		0x200
 #define MMC_MODE_SPI		0x400
-#define MMC_MODE_HC		0x800
+#define MMC_MODE_HC			0x800
 
 #define MMC_MODE_MASK_WIDTH_BITS (MMC_MODE_4BIT | MMC_MODE_8BIT)
 #define MMC_MODE_WIDTH_BITS_SHIFT 8
diff --git a/include/mrvl_mmc.h b/include/mrvl_mmc.h
new file mode 100644
index 0000000..b5fa91c
--- /dev/null
+++ b/include/mrvl_mmc.h
@@ -0,0 +1,266 @@ 
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * (C) Copyright 2012
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: Gérald Kerma <uboot@doukki.net>
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __MRVL_MMC_H__
+#define __MRVL_MMC_H__
+
+/*
+ * Clock rates
+ */
+
+#define MRVL_MMC_CLOCKRATE_MAX			50000000
+#define MRVL_MMC_BASE_DIV_MAX			0x7ff
+#define MRVL_MMC_BASE_FAST_CLOCK		CONFIG_SYS_TCLK
+#define MRVL_MMC_BASE_FAST_CLK_100		100000000
+#define MRVL_MMC_BASE_FAST_CLK_200		200000000
+
+/* SDIO register */
+#define SDIO_SYS_ADDR_LOW			0x000
+#define SDIO_SYS_ADDR_HI			0x004
+#define SDIO_BLK_SIZE				0x008
+#define SDIO_BLK_COUNT				0x00c
+#define SDIO_ARG_LOW				0x010
+#define SDIO_ARG_HI					0x014
+#define SDIO_XFER_MODE				0x018
+#define SDIO_CMD					0x01c
+#define SDIO_RSP(i)					(0x020 + ((i)<<2))
+#define SDIO_RSP0					0x020
+#define SDIO_RSP1					0x024
+#define SDIO_RSP2					0x028
+#define SDIO_RSP3					0x02c
+#define SDIO_RSP4					0x030
+#define SDIO_RSP5					0x034
+#define SDIO_RSP6					0x038
+#define SDIO_RSP7					0x03c
+#define SDIO_BUF_DATA_PORT			0x040
+#define SDIO_RSVED					0x044
+#define SDIO_HW_STATE				0x048
+#define SDIO_PRESENT_STATE0			0x048
+#define SDIO_PRESENT_STATE1			0x04c
+#define SDIO_HOST_CTRL				0x050
+#define SDIO_BLK_GAP_CTRL			0x054
+#define SDIO_CLK_CTRL				0x058
+#define SDIO_SW_RESET				0x05c
+#define SDIO_NOR_INTR_STATUS		0x060
+#define SDIO_ERR_INTR_STATUS		0x064
+#define SDIO_NOR_STATUS_EN			0x068
+#define SDIO_ERR_STATUS_EN			0x06c
+#define SDIO_NOR_INTR_EN			0x070
+#define SDIO_ERR_INTR_EN			0x074
+#define SDIO_AUTOCMD12_ERR_STATUS	0x078
+#define SDIO_CURR_BYTE_LEFT			0x07c
+#define SDIO_CURR_BLK_LEFT			0x080
+#define SDIO_AUTOCMD12_ARG_LOW		0x084
+#define SDIO_AUTOCMD12_ARG_HI		0x088
+#define SDIO_AUTOCMD12_INDEX		0x08c
+#define SDIO_AUTO_RSP(i)			(0x090 + ((i)<<2))
+#define SDIO_AUTO_RSP0				0x090
+#define SDIO_AUTO_RSP1				0x094
+#define SDIO_AUTO_RSP2				0x098
+#define SDIO_CLK_DIV				0x128
+
+#define WINDOW_CTRL(i)				(0x108 + ((i) << 3))
+#define WINDOW_BASE(i)				(0x10c + ((i) << 3))
+
+/* SDIO_PRESENT_STATE */
+#define CARD_BUSY				(1 << 1)
+#define CMD_INHIBIT				(1 << 0)
+#define CMD_TXACTIVE			(1 << 8)
+#define CMD_RXACTIVE			(1 << 9)
+#define CMD_AUTOCMD12ACTIVE		(1 << 14)
+#define CMD_BUS_BUSY			(CMD_AUTOCMD12ACTIVE |	\
+								CMD_RXACTIVE |	\
+								CMD_TXACTIVE |	\
+								CMD_INHIBIT |	\
+								CARD_BUSY)
+
+/*
+ * SDIO_CMD
+ */
+
+#define SDIO_CMD_RSP_NONE				(0 << 0)
+#define SDIO_CMD_RSP_136				(1 << 0)
+#define SDIO_CMD_RSP_48					(2 << 0)
+#define SDIO_CMD_RSP_48BUSY				(3 << 0)
+
+#define SDIO_CMD_CHECK_DATACRC16		(1 << 2)
+#define SDIO_CMD_CHECK_CMDCRC			(1 << 3)
+#define SDIO_CMD_INDX_CHECK				(1 << 4)
+#define SDIO_CMD_DATA_PRESENT			(1 << 5)
+#define SDIO_UNEXPECTED_RESP			(1 << 7)
+
+#define SDIO_CMD_INDEX(x)				((x) << 8)
+
+/*
+ * SDIO_XFER_MODE
+ */
+
+#define SDIO_XFER_MODE_STOP_CLK			(1 << 5)
+#define SDIO_XFER_MODE_HW_WR_DATA_EN	(1 << 1)
+#define SDIO_XFER_MODE_AUTO_CMD12		(1 << 2)
+#define SDIO_XFER_MODE_INT_CHK_EN		(1 << 3)
+#define SDIO_XFER_MODE_TO_HOST			(1 << 4)
+#define SDIO_XFER_MODE_DMA				(0 << 6)
+
+/*
+ * SDIO_HOST_CTRL
+ */
+
+#define SDIO_HOST_CTRL_PUSH_PULL_EN 		(1 << 0)
+
+#define SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY 	(0 << 1)
+#define SDIO_HOST_CTRL_CARD_TYPE_IO_ONLY 	(1 << 1)
+#define SDIO_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO 	(2 << 1)
+#define SDIO_HOST_CTRL_CARD_TYPE_IO_MMC 	(3 << 1)
+#define SDIO_HOST_CTRL_CARD_TYPE_MASK	 	(3 << 1)
+
+#define SDIO_HOST_CTRL_BIG_ENDIAN 		(1 << 3)
+#define SDIO_HOST_CTRL_LSB_FIRST 		(1 << 4)
+#define SDIO_HOST_CTRL_DATA_WIDTH_1_BIT 	(0 << 9)
+#define SDIO_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define SDIO_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+#define SDIO_HOST_CTRL_TMOUT_MAX 		0xf
+#define SDIO_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define SDIO_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+/*
+ * SDIO_SW_RESET
+ */
+
+#define SDIO_SW_RESET_NOW			(1 << 8)
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define SDIO_NOR_ERROR				(1 << 15)
+#define SDIO_NOR_UNEXP_RSP			(1 << 14)
+#define SDIO_NOR_AUTOCMD12_DONE		(1 << 13)
+#define SDIO_NOR_SUSPEND_ON			(1 << 12)
+#define SDIO_NOR_LMB_FF_8W_AVAIL	(1 << 11)
+#define SDIO_NOR_LMB_FF_8W_FILLED	(1 << 10)
+#define SDIO_NOR_READ_WAIT_ON		(1 << 9)
+#define SDIO_NOR_CARD_INT			(1 << 8)
+#define SDIO_NOR_READ_READY			(1 << 5)
+#define SDIO_NOR_WRITE_READY		(1 << 4)
+#define SDIO_NOR_DMA_INI			(1 << 3)
+#define SDIO_NOR_BLK_GAP_EVT		(1 << 2)
+#define SDIO_NOR_XFER_DONE			(1 << 1)
+#define SDIO_NOR_CMD_DONE			(1 << 0)
+
+/*
+ * Error status bits
+ */
+
+#define SDIO_ERR_CRC_STATUS			(1 << 14)
+#define SDIO_ERR_CRC_STARTBIT		(1 << 13)
+#define SDIO_ERR_CRC_ENDBIT			(1 << 12)
+#define SDIO_ERR_RESP_TBIT			(1 << 11)
+#define SDIO_ERR_XFER_SIZE			(1 << 10)
+#define SDIO_ERR_CMD_STARTBIT		(1 << 9)
+#define SDIO_ERR_AUTOCMD12			(1 << 8)
+#define SDIO_ERR_DATA_ENDBIT		(1 << 6)
+#define SDIO_ERR_DATA_CRC			(1 << 5)
+#define SDIO_ERR_DATA_TIMEOUT		(1 << 4)
+#define SDIO_ERR_CMD_INDEX			(1 << 3)
+#define SDIO_ERR_CMD_ENDBIT			(1 << 2)
+#define SDIO_ERR_CMD_CRC			(1 << 1)
+#define SDIO_ERR_CMD_TIMEOUT		(1 << 0)
+#define SDIO_POLL_MASK 				0xffff /* enable all for polling */
+
+#define MMC_BLOCK_SIZE                  512
+
+/*
+ * CMD12 error status bits
+ */
+
+#define SDIO_AUTOCMD12_ERR_NOTEXE		(1 << 0)
+#define SDIO_AUTOCMD12_ERR_TIMEOUT		(1 << 1)
+#define SDIO_AUTOCMD12_ERR_CRC			(1 << 2)
+#define SDIO_AUTOCMD12_ERR_ENDBIT		(1 << 3)
+#define SDIO_AUTOCMD12_ERR_INDEX		(1 << 4)
+#define SDIO_AUTOCMD12_ERR_RESP_T_BIT		(1 << 5)
+#define SDIO_AUTOCMD12_ERR_RESP_STARTBIT	(1 << 6)
+
+#define MMC_RSP_PRESENT	(1 << 0)
+#define MMC_RSP_136	(1 << 1)		/* 136 bit response */
+#define MMC_RSP_CRC	(1 << 2)		/* expect valid crc */
+#define MMC_RSP_BUSY	(1 << 3)		/* card may send busy */
+#define MMC_RSP_OPCODE	(1 << 4)		/* response contains opcode */
+
+#define MMC_BUSMODE_OPENDRAIN	1
+#define MMC_BUSMODE_PUSHPULL	2
+
+#define MMC_BUS_WIDTH_1		0
+#define MMC_BUS_WIDTH_4		2
+#define MMC_BUS_WIDTH_8		3
+
+#define MMC_CAP_4_BIT_DATA	(1 << 0)	/* Can the host do 4 bit transfers */
+#define MMC_CAP_MMC_HIGHSPEED	(1 << 1)	/* Can do MMC high-speed timing */
+#define MMC_CAP_SD_HIGHSPEED	(1 << 2)	/* Can do SD high-speed timing */
+#define MMC_CAP_SDIO_IRQ	(1 << 3)	/* Can signal pending SDIO IRQs */
+#define MMC_CAP_SPI		(1 << 4)	/* Talks only SPI protocols */
+#define MMC_CAP_NEEDS_POLL	(1 << 5)	/* Needs polling for card-detection */
+#define MMC_CAP_8_BIT_DATA	(1 << 6)	/* Can the host do 8 bit transfers */
+
+#define MMC_CAP_NONREMOVABLE	(1 << 8)	/* Nonremovable e.g. eMMC */
+#define MMC_CAP_WAIT_WHILE_BUSY	(1 << 9)	/* Waits while card is busy */
+#define MMC_CAP_ERASE		(1 << 10)	/* Allow erase/trim commands */
+#define MMC_CAP_1_8V_DDR	(1 << 11)	/* can support */
+						/* DDR mode at 1.8V */
+#define MMC_CAP_1_2V_DDR	(1 << 12)	/* can support */
+						/* DDR mode at 1.2V */
+#define MMC_CAP_POWER_OFF_CARD	(1 << 13)	/* Can power off after boot */
+#define MMC_CAP_BUS_WIDTH_TEST	(1 << 14)	/* CMD14/CMD19 bus width ok */
+#define MMC_CAP_UHS_SDR12	(1 << 15)	/* Host supports UHS SDR12 mode */
+#define MMC_CAP_UHS_SDR25	(1 << 16)	/* Host supports UHS SDR25 mode */
+#define MMC_CAP_UHS_SDR50	(1 << 17)	/* Host supports UHS SDR50 mode */
+#define MMC_CAP_UHS_SDR104	(1 << 18)	/* Host supports UHS SDR104 mode */
+#define MMC_CAP_UHS_DDR50	(1 << 19)	/* Host supports UHS DDR50 mode */
+#define MMC_CAP_DRIVER_TYPE_A	(1 << 23)	/* Host supports Driver Type A */
+#define MMC_CAP_DRIVER_TYPE_C	(1 << 24)	/* Host supports Driver Type C */
+#define MMC_CAP_DRIVER_TYPE_D	(1 << 25)	/* Host supports Driver Type D */
+#define MMC_CAP_CMD23		(1 << 30)	/* CMD23 supported. */
+#define MMC_CAP_HW_RESET	(1 << 31)	/* Hardware reset */
+
+/*
+ * Functions prototypes
+ */
+
+static int mrvl_mmc_setup_data(struct mmc_data *data);
+static int mrvl_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data);
+static void mvsd_power_up(void);
+static void mvsd_power_down(void);
+static u32 mrvl_mmc_get_base_clock(void);
+static void mrvl_mmc_set_clk(uint clock);
+static void mrvl_mmc_set_bus(unsigned int bus);
+static void mrvl_mmc_set_ios(struct mmc *mmc);
+static int mrvl_mmc_init(struct mmc *mmc);
+int mrvl_mmc_initialize(bd_t *bis);
+
+#endif /* __MRVL_MMC_H__ */