public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
@ 2010-08-28 22:37 Gérald Kerma
  2010-11-18  1:00 ` Clint Adams
  2010-11-18  4:04 ` Prafulla Wadaskar
  0 siblings, 2 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-08-28 22:37 UTC (permalink / raw)
  To: u-boot

    Add mvsdio driver to Kirkwood SoC
    Add SDIO support to SHEEVAPLUG
    Fix environments for SHEEVAPLUG

Signed-off-by: G?rald Kerma <geraker@gmail.com>
---
Changes in v1:
 * Fix errors from SD/SDHC detect
 * Minor fixes in boot env

 arch/arm/cpu/arm926ejs/kirkwood/timer.c       |   23 +
 arch/arm/include/asm/arch-kirkwood/kirkwood.h |    1 +
 drivers/mmc/Makefile                          |    1 +
 drivers/mmc/mv_sdio.c                         |  747
+++++++++++++++++++++++++
 drivers/mmc/mv_sdio.h                         |  296 ++++++++++
 include/configs/sheevaplug.h                  |   65 ++-
 6 files changed, 1124 insertions(+), 9 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/kirkwood/timer.c
b/arch/arm/cpu/arm926ejs/kirkwood/timer.c
index 2ec6a93..c8f932b 100644
--- a/arch/arm/cpu/arm926ejs/kirkwood/timer.c
+++ b/arch/arm/cpu/arm926ejs/kirkwood/timer.c
@@ -166,3 +166,26 @@ int timer_init(void)

 	return 0;
 }
+
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk (void)
+{
+	ulong tbclk;
+
+	tbclk = CONFIG_SYS_HZ;
+	return tbclk;
+}
+
diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
index 0104418..4f9fe7e 100644
--- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
@@ -60,6 +60,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
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 8dfd8a3..f1e7db6 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -31,6 +31,7 @@ COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
+COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o
 COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
 COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o

diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c
new file mode 100644
index 0000000..aa8df10
--- /dev/null
+++ b/drivers/mmc/mv_sdio.c
@@ -0,0 +1,747 @@
+/*
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
+ * Copyright (C) 2010 G?rald Kerma <geraker@gmail.com>
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include "mv_sdio.h"
+#include <asm/errno.h>
+#include <part.h>
+#include <asm/io.h>
+#include <asm/arch/kirkwood.h>
+
+#ifdef CONFIG_MMC
+
+#define DRIVER_NAME "mv-sdio"
+
+//#define DEBUG
+
+//static int maxfreq = MVSD_CLOCKRATE_MAX;
+//static int nodma;
+
+static int is_sdhc;
+
+extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+
+static block_dev_desc_t mmc_dev;
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+	return ((block_dev_desc_t *)&mmc_dev);
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+static uchar mmc_buf[MMC_BLOCK_SIZE];
+static mv_mmc_csd_t mv_mmc_csd;
+static int mmc_ready = 0;
+
+/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
+   that expects it to be shifted. */
+static u_int16_t rca = 0;
+
+static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd)
+{
+	u_int32_t block_len, mult, blocknr;
+
+	block_len = csd->read_bl_len << 12;
+	mult = csd->c_size_mult1 << 8;
+	blocknr = (csd->c_size+1) * mult;
+
+	return blocknr * block_len;
+}
+
+static int isprint (unsigned char ch)
+{
+	if (ch >= 32 && ch < 127)
+		return (1);
+
+	return (0);
+}
+
+static int toprint(char *dst, char c)
+{
+	if (isprint(c)) {
+		*dst = c;
+		return 1;
+	}
+
+	return sprintf(dst,"\\x%02x", c);
+
+}
+
+static void print_mmc_cid(mv_mmc_cid_t *cid)
+{
+	printf("MMC found. Card desciption is:\n");
+	printf("Manufacturer ID = %02x%02x%02x\n",
+		cid->id[0], cid->id[1], cid->id[2]);
+	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
+	cid->hwrev = cid->fwrev = 0;	/* null terminate string */
+	printf("Product Name = %s\n",cid->name);
+	printf("Serial Number = %02x%02x%02x\n",
+		cid->sn[0], cid->sn[1], cid->sn[2]);
+	printf("Month = %d\n",cid->month);
+	printf("Year = %d\n",1997 + cid->year);
+}
+
+static void print_sd_cid(mv_sd_cid_t *cid)
+{
+	int len;
+	char tbuf[64];
+
+	printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":"");
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->oid_0);
+	len += toprint(&tbuf[len], cid->oid_1);
+	tbuf[len] = 0;
+
+	printf("Manufacturer:       0x%02x, OEM \"%s\"\n",
+	    cid->mid, tbuf);
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->pnm_0);
+	len += toprint(&tbuf[len], cid->pnm_1);
+	len += toprint(&tbuf[len], cid->pnm_2);
+	len += toprint(&tbuf[len], cid->pnm_3);
+	len += toprint(&tbuf[len], cid->pnm_4);
+	tbuf[len] = 0;
+
+	printf("Product name:       \"%s\", revision %d.%d\n",
+		tbuf,
+	    cid->prv >> 4, cid->prv & 15);
+
+	printf("Serial number:      %u\n",
+	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
+	    cid->psn_3);
+	printf("Manufacturing date: %d/%d\n",
+	    cid->mdt_1 & 15,
+	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
+
+	printf("CRC:                0x%02x, b0 = %d\n",
+	    cid->crc >> 1, cid->crc & 1);
+}
+
+static void mvsdio_set_clock(unsigned int clock)
+{
+	unsigned int m;
+
+	m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1;
+
+	debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n",
+		      m, clock);
+
+
+	SDIO_REG_WRITE32(SDIO_CLK_DIV, m & 0x7ff);
+
+	if (isprint(1))
+	udelay(10*1000);
+}
+
+/****************************************************/
+static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort
resptype, ushort waittype)
+/****************************************************/
+{
+	static ulong resp[4];
+	ushort done ;
+	int err = 0 ;
+	ulong curr, start, diff, hz;
+	ushort response[8], resp_indx = 0;
+
+	debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n"
+	, (unsigned int)cmd, (unsigned int)arg, xfermode, resptype, waittype);
+
+
+	//clear status
+	SDIO_REG_WRITE16(SDIO_NOR_INTR_STATUS, 0xffff);
+	SDIO_REG_WRITE16(SDIO_ERR_INTR_STATUS, 0xffff);
+
+	start = get_ticks();
+	hz = get_tbclk();
+
+	while((SDIO_REG_READ16(SDIO_PRESENT_STATE0) & CARD_BUSY)) {
+		curr = get_ticks();
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			// 3 seconds timeout, card busy, can't sent cmd
+			printf("card too busy \n");
+			return 0;
+		}
+	}
+
+	SDIO_REG_WRITE16(SDIO_ARG_LOW, (ushort)(arg&0xffff) );
+   	SDIO_REG_WRITE16(SDIO_ARG_HI, (ushort)(arg>>16) );
+	SDIO_REG_WRITE16(SDIO_XFER_MODE, xfermode);
+	if( (cmd == MMC_CMD_READ_BLOCK) || (cmd == 25) )
+	{
+		SDIO_REG_WRITE16(SDIO_CMD, ((cmd << 8) | resptype | 0x3c ) );
+	debug("cmd reg : %x\n", SDIO_REG_READ16( SDIO_CMD )) ;
+
+	}
+	else
+	{
+		SDIO_REG_WRITE16(SDIO_CMD, ((cmd << 8) | resptype ) );
+	}
+
+	done = SDIO_REG_READ16(SDIO_NOR_INTR_STATUS) & waittype;
+	start = get_ticks();
+
+	while( done!=waittype)
+	{
+		done = SDIO_REG_READ16(SDIO_NOR_INTR_STATUS) & waittype;
+
+		if( SDIO_REG_READ16(SDIO_NOR_INTR_STATUS) & 0x8000 )
+		{		
+			debug("Error! cmd : %d, err : %04x\n", (unsigned int)cmd,
SDIO_REG_READ16(SDIO_ERR_INTR_STATUS) ) ;
+
+			return 0 ;	// error happen
+		}
+
+		curr = get_ticks();
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			debug("cmd timeout, status : %04x\n",
SDIO_REG_READ16(SDIO_NOR_INTR_STATUS));
+			debug("xfer mode : %04x\n", SDIO_REG_READ16(SDIO_XFER_MODE));
+
+			err = 1 ;
+			break;
+		}
+	}
+
+	for (resp_indx = 0 ; resp_indx < 8; resp_indx++)
+		response[resp_indx] = SDIO_REG_READ16(SDIO_RSP(resp_indx));
+
+	memset(resp, 0, sizeof(resp));
+
+	switch (resptype & 0x3) {
+		case SDIO_CMD_RSP_48:
+		case SDIO_CMD_RSP_48BUSY:
+			resp[0] = ((response[2] & 0x3f) << (8 - 8)) |
+				((response[1] & 0xffff) << (14 - 8)) |
+				((response[0] & 0x3ff) << (30 - 8));
+			resp[1] = ((response[0] & 0xfc00) >> 10);
+			break;
+
+		case SDIO_CMD_RSP_136:
+			resp[3] = ((response[7] & 0x3fff) << 8)	|
+				((response[6] & 0x3ff) << 22);
+			resp[2] = ((response[6] & 0xfc00) >> 10)	|
+				((response[5] & 0xffff) << 6)	|
+				((response[4] & 0x3ff) << 22);
+			resp[1] = ((response[4] & 0xfc00) >> 10)	|
+				((response[3] & 0xffff) << 6)	|
+				((response[2] & 0x3ff) << 22);
+			resp[0] = ((response[2] & 0xfc00) >> 10)	|
+				((response[1] & 0xffff) << 6)	|
+				((response[0] & 0x3ff) << 22);
+			break;
+		default:
+			return 0;
+	}
+	int i;
+	debug("MMC resp :");
+	for (i=0; i<4; ++i ) {
+		debug(" %08x", (unsigned int)resp[i]);
+	}
+	debug("\n");
+	if( err )
+		return NULL ;
+	else
+		return resp;
+}
+
+/****************************************************/
+static int mv_mmc_block_read(uchar *dst, ulong src, ulong len)
+/****************************************************/
+{
+	ulong *resp;
+	//ushort argh, argl;
+	//ulong status;
+
+	if (len == 0) {
+		return 0;
+	}
+
+	if (is_sdhc) {
+		/* SDHC: use block address */
+		src >>= 9;
+	}
+
+	debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, (int)len);
+
+	// prepare for dma transfer
+	SDIO_REG_WRITE16(SDIO_SYS_ADDR_LOW,((ulong)(dst))&0xffff);
+	SDIO_REG_WRITE16(SDIO_SYS_ADDR_HI,(((ulong)dst)>>16)&0xffff);
+	SDIO_REG_WRITE16(SDIO_BLK_SIZE,len);
+	SDIO_REG_WRITE16(SDIO_BLK_COUNT,1);
+	
+	/* send read command */
+	resp = mv_mmc_cmd(MMC_CMD_READ_BLOCK, src, 0x10 , // 0x12,
+			SDIO_CMD_RSP_48, SDIO_NOR_XFER_DONE);
+	if (!resp) {
+		debug("mv_mmc_block_read: mmc read block cmd fails\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/****************************************************/
+static int mv_mmc_block_write(ulong dst, uchar *src, int len)
+/****************************************************/
+{
+	return -1 ;
+}
+
+/****************************************************/
+int mv_mmc_read(ulong src, uchar *dst, int size)
+/****************************************************/
+{
+	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+	ulong mmc_block_size, mmc_block_address;
+
+	if (size == 0) {
+		return 0;
+	}
+
+	if (!mmc_ready) {
+		printf("Please initial the MMC first\n");
+		return -1;
+	}
+
+	mmc_block_size = MMC_BLOCK_SIZE;
+	mmc_block_address = ~(mmc_block_size - 1);
+
+	end = src + size;
+	part_start = ~mmc_block_address & src;
+	part_end = ~mmc_block_address & end;
+	aligned_start = mmc_block_address & src;
+	aligned_end = mmc_block_address & end;
+
+	/* all block aligned accesses */
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_start) {
+		part_len = mmc_block_size - part_start;
+		debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf+part_start, part_len);
+		dst += part_len;
+		src += part_len;
+	}
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	for (; src < aligned_end; aligned_start +=mmc_block_size, src +=
mmc_block_size, dst += mmc_block_size) {
+		debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+		 	printf("mmc block read error\n");
+			return -1;
+		}
+		//printf("mem copy from %x to %x, size %d\n", (ulong)mmc_buf,
(ulong)dst, mmc_block_size );
+		memcpy(dst, mmc_buf, mmc_block_size);
+	}
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_end && src < end) {
+		debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf, part_end);
+	}
+	return 0;
+}
+
+/****************************************************/
+static int mv_mmc_write(uchar *src, ulong dst, int size)
+/****************************************************/
+{
+	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+	ulong mmc_block_size, mmc_block_address;
+
+	if (size == 0) {
+		return 0;
+	}
+
+	if (!mmc_ready) {
+		printf("Please initial the MMC first\n");
+		return -1;
+	}
+
+	mmc_block_size = MMC_BLOCK_SIZE;
+	mmc_block_address = ~(mmc_block_size - 1);
+
+	end = dst + size;
+	part_start = ~mmc_block_address & dst;
+	part_end = ~mmc_block_address & end;
+	aligned_start = mmc_block_address & dst;
+	aligned_end = mmc_block_address & end;
+
+	/* all block aligned accesses */
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_start) {
+		part_len = mmc_block_size - part_start;
+		debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(mmc_buf+part_start, src, part_len);
+		if ((mv_mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0) {
+			return -1;
+		}
+		dst += part_len;
+		src += part_len;
+	}
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
+		debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0) {
+			return -1;
+		}
+	}
+	debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_end && dst < end) {
+		debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(mmc_buf, src, part_end);
+		if ((mv_mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/****************************************************/
+static ulong mv_mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong
*dst)
+/****************************************************/
+{
+	int mmc_block_size = MMC_BLOCK_SIZE;
+	ulong src = blknr * mmc_block_size;
+
+	mv_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
+	return blkcnt;
+}
+
+/****************************************************/
+int mmc_legacy_init(int verbose)
+/****************************************************/
+{
+	int retries, rc = -ENODEV;
+	ulong *resp;
+	int sd_ver20;
+	int is_sd;
+	ushort reg;
+	uchar cidbuf[64];
+
+	sd_ver20 = 0;
+	is_sdhc = 0;
+	is_sd = 0;
+
+	// Initial Host Ctrl : Timeout : max , Normal Speed mode, 4-bit data mode
+	// Big Endian, SD memory Card, Push_pull CMD Line
+	SDIO_REG_WRITE16(SDIO_HOST_CTRL,
+		SDIO_HOST_CTRL_TMOUT(0xf) |
+		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 );
+
+	SDIO_REG_WRITE16(SDIO_CLK_CTRL, 0);
+
+	//enable status
+	SDIO_REG_WRITE16(SDIO_NOR_STATUS_EN, 0xffff);
+	SDIO_REG_WRITE16(SDIO_ERR_STATUS_EN, 0xffff);
+
+	//disable interrupts
+	SDIO_REG_WRITE16(SDIO_NOR_INTR_EN, 0);
+	SDIO_REG_WRITE16(SDIO_ERR_INTR_EN, 0);
+
+	SDIO_REG_WRITE16(SDIO_SW_RESET,0x100);
+	udelay(10000);
+
+	mv_mmc_csd.c_size = 0;
+
+	/* reset */
+	retries = 10;
+	//mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort resptype,
ushort waittype);
+	resp = mv_mmc_cmd(0, 0, 0, SDIO_CMD_RSP_NONE, SDIO_NOR_CMD_DONE );
+	debug("cmd 0 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	debug ("trying to detect SD card version\n");
+
+	resp = mv_mmc_cmd(8, 0x000001aa, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	debug("cmd 8 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp && (resp[0] & 0x1ff)==0x1aa) {
+		debug ("SD version 2.0 card detected\n");
+
+		sd_ver20 = 1;
+	}
+
+	if (sd_ver20)
+		retries = 50;
+	else
+		retries = 10;
+
+	while (retries--) {
+		resp = mv_mmc_cmd(55, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		debug("cmd 55 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (sd_ver20)
+			resp = mv_mmc_cmd(41, 0x40300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		else
+			resp = mv_mmc_cmd(41, 0x00300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+
+		debug("cmd 41 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (resp && (resp[0] & 0x80000000)) {
+			debug ("detected SD card\n");
+
+			is_sd = 1;
+			break;
+		}
+
+		udelay(100*1000);
+	}
+
+	if (retries <= 0 && !is_sd) {
+		debug ("failed to detect SD card, trying MMC\n");
+
+		retries = 10;
+		while (retries--) {
+			resp = mv_mmc_cmd(1, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+			debug("cmd 01 resp : %08x %08x %08x %08x\n",
+			(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+			if (resp && (resp[0] & 0x80000000)) {
+				printf ("detected MMC card\n");
+				reg = SDIO_REG_READ16(SDIO_HOST_CTRL);
+				reg &= ~(0x3<<1);
+				reg |= SDIO_HOST_CTRL_CARD_TYPE_IO_MMC;
+				SDIO_REG_WRITE16(SDIO_HOST_CTRL, reg);
+				break;
+			}
+
+			udelay(100*1000);
+		}
+	}
+		
+	if (retries <= 0) {
+		debug ("detect fails\n");
+
+		return -ENODEV;
+	}
+
+	/* try to get card id */
+	resp = mv_mmc_cmd(2, 0, 0, SDIO_CMD_RSP_136, SDIO_NOR_CMD_DONE );
+	debug("cmd 2 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (resp == NULL) {
+		debug ("read cid fails\n");
+
+		return -ENODEV;
+	}
+
+	if (is_sd) {
+		mv_sd_cid_t *cid = (mv_sd_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x OEM %c%c \"%c%c%c%c%c\"",
+			cid->mid, cid->oid_0, cid->oid_1,
+			cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4);
+
+		sprintf((char *) mmc_dev.product, "%d",
+			(cid->psn_0 << 24) | (cid->psn_1 <<16) | (cid->psn_2 << 8) |
(cid->psn_3 << 8));
+		
+		sprintf((char *) mmc_dev.revision, "%d.%d", cid->prv>>4, cid->prv &
0xff);
+		
+	} else {
+		/* TODO configure mmc driver depending on card attributes */
+		mv_mmc_cid_t *cid = (mv_mmc_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x%02x%02x Snr %02x%02x%02x",
+			cid->id[0], cid->id[1], cid->id[2],
+			cid->sn[0], cid->sn[1], cid->sn[2]);
+		sprintf((char *) mmc_dev.product, "%s", cid->name);
+		sprintf((char *) mmc_dev.revision, "%x %x", cid->hwrev, cid->fwrev);
+	}
+	
+	/* fill in device description */
+	mmc_dev.if_type = IF_TYPE_MMC;
+	mmc_dev.part_type = PART_TYPE_DOS;
+	mmc_dev.dev = 0;
+	mmc_dev.lun = 0;
+	mmc_dev.type = 0;
+
+	/* FIXME fill in the correct size (is set to 128MByte) */
+	mmc_dev.blksz = MMC_BLOCK_SIZE;
+	mmc_dev.lba = 0x10000;
+
+	mmc_dev.removable = 0;
+	mmc_dev.block_read = mv_mmc_bread;
+
+	/* MMC exists, get CSD too */
+	resp = mv_mmc_cmd(MMC_CMD_SET_RCA, 0, 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+	if (resp == NULL) {
+		debug ("set rca fails\n");
+
+		return -ENODEV;
+	}
+	debug("cmd3 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	if (is_sd)
+		rca = resp[0] >> 16;
+	else
+		rca = 0;
+
+	resp = mv_mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, 0,
SDIO_CMD_RSP_136,SDIO_NOR_CMD_DONE );
+	debug("cmd 9 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp == NULL) {
+		debug ("read csd fails\n");
+
+		return -ENODEV;
+	}
+
+	memcpy(&mv_mmc_csd, (mv_mmc_csd_t *) resp, sizeof(mv_mmc_csd_t));
+	rc = 0;
+	mmc_ready = 1;
+
+	/* FIXME add verbose printout for csd */
+	debug ("size = %u\n", mv_mmc_size(&mv_mmc_csd));
+
+
+	resp = mv_mmc_cmd(7, rca<<16, 0, SDIO_CMD_RSP_48BUSY, SDIO_NOR_CMD_DONE);
+	if (resp == NULL) {
+		debug ("select card fails\n");
+
+		return -ENODEV;
+	}
+	debug("cmd 7 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (is_sd) {
+		resp = mv_mmc_cmd(55, rca<<16, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+		debug("cmd55 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+		resp = mv_mmc_cmd(6, (rca<<16) | 0x2 , 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+	debug("cmd6 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+	}
+
+	resp = (ulong *) &mv_mmc_csd;
+	debug("csd: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	/* check SDHC */
+	if ((resp[0]&0xf0000000)==0x40000000)
+		is_sdhc = 1;
+
+	/* set block len */
+	resp = mv_mmc_cmd(MMC_CMD_SET_BLOCKLEN, MMC_BLOCK_SIZE, 0,
SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	if (!resp) {
+		debug("mv_mmc_block_read: set blk len fails\n");
+	 	return -ENODEV;
+	}
+
+	if (verbose) {
+		if (is_sd)
+			print_sd_cid((mv_sd_cid_t *) cidbuf);
+		else
+			print_mmc_cid((mv_mmc_cid_t *) cidbuf);
+	}
+
+	mvsdio_set_clock(CONFIG_SYS_MMC_CLK_PP);
+
+	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
+
+	return 0;
+}
+
+#endif	/* CONFIG_MMC */
+
diff --git a/drivers/mmc/mv_sdio.h b/drivers/mmc/mv_sdio.h
new file mode 100644
index 0000000..bb7d39c
--- /dev/null
+++ b/drivers/mmc/mv_sdio.h
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
+ * Copyright (C) 2010 G?rald Kerma <gerald.kerma@gk2.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MVSDIO_INCLUDE
+#define _MVSDIO_INCLUDE
+
+#define SDIO_REG(x) (KW_SDIO_BASE + (x))
+
+#define SDIO_REG_WRITE32(offset,value) writel(value,SDIO_REG(offset))
+#define SDIO_REG_READ32(offset) readl(SDIO_REG(offset))
+
+#define SDIO_REG_WRITE16(offset,value) writew(value,SDIO_REG(offset))
+#define SDIO_REG_READ16(offset) readw(SDIO_REG(offset))
+
+#define MVSDMMC_DMA_SIZE			65536
+#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX			50000000
+#define MVSD_BASE_DIV_MAX			0x7ff
+
+#define CONFIG_SYS_MMC_CLK_PP			25000000
+
+/*
+ * The base MMC clock rate
+ */
+
+#define MVSDMMC_CLOCKRATE_MIN			100000
+#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
+#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
+
+
+/*
+ * 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_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)
+
+
+/*
+ * 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)
+
+
+/*
+ * 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_ID_MODE_LOW_FREQ 	(1 << 5)
+#define SDIO_HOST_CTRL_HALF_SPEED 		(1 << 6)
+#define SDIO_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define SDIO_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+
+#define SDIO_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT_MAX 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define SDIO_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+#define SDIO_HOST_CTRL_DFAULT_OPEN_DRAIN 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf))
+#define SDIO_HOST_CTRL_DFAULT_PUSH_PULL 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf) | SDIO_HOST_CTRL_PUSH_PULL_EN)
+
+
+/*
+ * NOR 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)
+
+
+/*
+ * ERR 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_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_ERR_INTR_MASK			0xFFFF
+
+
+#define MMC_BLOCK_SIZE                  512
+#define MMC_CMD_RESET                   0
+#define MMC_CMD_SEND_OP_COND            1
+#define MMC_CMD_ALL_SEND_CID            2
+#define MMC_CMD_SET_RCA                 3
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_CSD                9
+#define MMC_CMD_SEND_CID                10
+#define MMC_CMD_SEND_STATUS             13
+#define MMC_CMD_SET_BLOCKLEN            16
+#define MMC_CMD_READ_BLOCK              17
+#define MMC_CMD_RD_BLK_MULTI            18
+#define MMC_CMD_WRITE_BLOCK             24
+#define MMC_MAX_BLOCK_SIZE              512
+
+typedef struct mv_mmc_cid
+{
+	/* FIXME: BYTE_ORDER */
+	uchar year:4,
+	month:4;
+	uchar sn[3];
+	uchar fwrev:4,
+	hwrev:4;
+	uchar name[6];
+	uchar id[3];
+} mv_mmc_cid_t;
+
+typedef struct mv_mmc_csd
+{
+	uchar   ecc:2,
+		file_format:2,
+		tmp_write_protect:1,
+		perm_write_protect:1,
+		copy:1,
+		file_format_grp:1;
+	uint64_t content_prot_app:1,
+		rsvd3:4,
+		write_bl_partial:1,
+		write_bl_len:4,
+		r2w_factor:3,
+		default_ecc:2,
+		wp_grp_enable:1,
+		wp_grp_size:5,
+		erase_grp_mult:5,
+		erase_grp_size:5,
+		c_size_mult1:3,
+		vdd_w_curr_max:3,
+		vdd_w_curr_min:3,
+		vdd_r_curr_max:3,
+		vdd_r_curr_min:3,
+		c_size:12,
+		rsvd2:2,
+		dsr_imp:1,
+		read_blk_misalign:1,
+		write_blk_misalign:1,
+		read_bl_partial:1;
+	ushort  read_bl_len:4,
+		ccc:12;
+	uchar   tran_speed;
+	uchar   nsac;
+	uchar   taac;
+	uchar   rsvd1:2,
+		spec_vers:4,
+		csd_structure:2;
+} mv_mmc_csd_t;
+
+typedef struct {
+	char		pnm_0;	/* product name */
+	char		oid_1;	/* OEM/application ID */
+	char		oid_0;
+	uint8_t		mid;	/* manufacturer ID */
+	char		pnm_4;
+	char		pnm_3;
+	char		pnm_2;
+	char		pnm_1;
+	uint8_t		psn_2;	/* product serial number */
+	uint8_t		psn_1;
+	uint8_t		psn_0;	/* MSB */
+	uint8_t		prv;	/* product revision */
+	uint8_t		crc;	/* CRC7 checksum, b0 is unused and set to 1 */
+	uint8_t		mdt_1;	/* manufacturing date, LSB, RRRRyyyy yyyymmmm */
+	uint8_t		mdt_0;	/* MSB */
+	uint8_t		psn_3;	/* LSB */
+} mv_sd_cid_t;
+
+#endif /* _MVSDIO_INCLUDE */
diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index c5de86e..7b7e5e8 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -25,10 +25,12 @@
 #ifndef _CONFIG_SHEEVAPLUG_H
 #define _CONFIG_SHEEVAPLUG_H

+//#define DEBUG 1
+
 /*
  * 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)
@@ -94,7 +96,9 @@
 #define CONFIG_CMD_AUTOSCRIPT
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_USB
@@ -132,16 +136,23 @@
  */
 #define CONFIG_BOOTCOMMAND		"${x_bootcmd_kernel}; "	\
 	"setenv bootargs ${x_bootargs} ${x_bootargs_root}; "	\
-	"${x_bootcmd_usb}; bootm 0x6400000;"
+	"${x_bootcmd_usb}; ${x_bootcmd_sata}; bootm 0x6400000;"
+
+#define CONFIG_MTDPARTS		"orion_nand:"	\
+	"512k(uboot),4m at 1m(kernel),507m at 5m(rootfs) rw\0"

-#define CONFIG_MTDPARTS		"orion_nand:512k(uboot),"	\
-	"3m at 1m(kernel),1m at 4m(psm),13m@5m(rootfs) rw\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	"x_bootargs=console"		\
+	"=ttyS0,115200 mtdparts="CONFIG_MTDPARTS			\
+	"x_bootcmd_kernel=nand read 0x6400000 0x100000 0x400000\0" 	\
+	"x_bootcmd_usb=usb start;\0" 					\
+	"x_bootcmd_sata=ide reset;\0" 					\
+	"x_bootargs_root=ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs\0"

 /*
  * Size of malloc() pool
@@ -183,6 +194,42 @@
 #endif /* CONFIG_CMD_NET */

 /*
+ * SDIO/MMC Card Configuration
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_MV_SDIO
+#endif /* CONFIG_CMD_MMC */
+
+/*
  * USB/EHCI
  */
 #ifdef CONFIG_CMD_USB

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
  2010-08-28 22:37 [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug Gérald Kerma
@ 2010-11-18  1:00 ` Clint Adams
  2010-11-18  3:32   ` Prafulla Wadaskar
  2010-11-20 11:42   ` Gérald Kerma
  2010-11-18  4:04 ` Prafulla Wadaskar
  1 sibling, 2 replies; 22+ messages in thread
From: Clint Adams @ 2010-11-18  1:00 UTC (permalink / raw)
  To: u-boot

On Sun, Aug 29, 2010 at 12:37:16AM +0200, G?rald Kerma wrote:
>     Add mvsdio driver to Kirkwood SoC
>     Add SDIO support to SHEEVAPLUG

G?rald, can this be adapted for GuruPlug?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
  2010-11-18  1:00 ` Clint Adams
@ 2010-11-18  3:32   ` Prafulla Wadaskar
  2010-11-20 11:42   ` Gérald Kerma
  1 sibling, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-18  3:32 UTC (permalink / raw)
  To: u-boot

First of all Thanks for pinging on this. 
Yes, we can, but this needs some more modifications.
I will provide review comments for this patch ASAP

Regards..
Prafulla . .

> -----Original Message-----
> From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de]
> On Behalf Of Clint Adams
> Sent: Thursday, November 18, 2010 6:31 AM
> To: G?rald Kerma
> Cc: u-boot at lists.denx.de
> Subject: Re: [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
> 
> On Sun, Aug 29, 2010 at 12:37:16AM +0200, G?rald Kerma wrote:
> >     Add mvsdio driver to Kirkwood SoC
> >     Add SDIO support to SHEEVAPLUG
> 
> G?rald, can this be adapted for GuruPlug?
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
  2010-08-28 22:37 [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug Gérald Kerma
  2010-11-18  1:00 ` Clint Adams
@ 2010-11-18  4:04 ` Prafulla Wadaskar
  2010-11-19 16:10   ` [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
  2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
  1 sibling, 2 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-18  4:04 UTC (permalink / raw)
  To: u-boot

Hi Gerald
Sorry for late feedback, please find my comments inlined.

> -----Original Message-----
> From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de]
> On Behalf Of G?rald Kerma
> Sent: Sunday, August 29, 2010 4:07 AM
> To: u-boot at lists.denx.de
> Subject: [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
> 
>     Add mvsdio driver to Kirkwood SoC
>     Add SDIO support to SHEEVAPLUG
>     Fix environments for SHEEVAPLUG

You should break this patch into small pieces as per functionalities like-
1. Kirkwood: add more timer functions
2. Kirkwood: pre-requisite for SDIO driver support
3. mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
4. Sheevaplug: Add MMC/SDIO support
5. Sheevaplug: Fix environments for <specify problem>
6. Guruplug: Add MMC/SDIO support (as Clint suggested- Optional)

> 
> Signed-off-by: G?rald Kerma <geraker@gmail.com>
> ---
> Changes in v1:
>  * Fix errors from SD/SDHC detect
>  * Minor fixes in boot env
> 
>  arch/arm/cpu/arm926ejs/kirkwood/timer.c       |   23 +
>  arch/arm/include/asm/arch-kirkwood/kirkwood.h |    1 +
>  drivers/mmc/Makefile                          |    1 +
>  drivers/mmc/mv_sdio.c                         |  747
> +++++++++++++++++++++++++
>  drivers/mmc/mv_sdio.h                         |  296 ++++++++++
>  include/configs/sheevaplug.h                  |   65 ++-
>  6 files changed, 1124 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/kirkwood/timer.c
> b/arch/arm/cpu/arm926ejs/kirkwood/timer.c
> index 2ec6a93..c8f932b 100644
> --- a/arch/arm/cpu/arm926ejs/kirkwood/timer.c
> +++ b/arch/arm/cpu/arm926ejs/kirkwood/timer.c
> @@ -166,3 +166,26 @@ int timer_init(void)
> 
>  	return 0;
>  }
> +
> +
> +/*
> + * This function is derived from PowerPC code (read timebase as long
> long).
> + * On ARM it just returns the timer value.
> + */
> +unsigned long long get_ticks(void)
> +{
> +	return get_timer(0);
> +}

This is not needed, you can directly use get_timer(0) wherever needed

> +
> +/*
> + * This function is derived from PowerPC code (timebase clock frequency).
> + * On ARM it returns the number of timer ticks per second.
> + */
> +ulong get_tbclk (void)
> +{
> +	ulong tbclk;
> +
> +	tbclk = CONFIG_SYS_HZ;
> +	return tbclk;
> +}

Ditto, 

> +
> diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> index 0104418..4f9fe7e 100644
> --- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> +++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> @@ -60,6 +60,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
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index 8dfd8a3..f1e7db6 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -31,6 +31,7 @@ COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
>  COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
>  COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
>  COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
> +COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o

Please maintain order here

>  COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
>  COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
> 
> diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c
> new file mode 100644
> index 0000000..aa8df10
> --- /dev/null
> +++ b/drivers/mmc/mv_sdio.c
> @@ -0,0 +1,747 @@
> +/*
> + * (C) Copyright 2003
> + * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
> + * Copyright (C) 2010 G?rald Kerma <geraker@gmail.com>
> + *
> + * 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 <config.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <mmc.h>
> +#include "mv_sdio.h"
> +#include <asm/errno.h>
> +#include <part.h>
> +#include <asm/io.h>

Please use #ifdef CONFIG_KIRKWOOD here since driver name is generic and not Kirkwood specific

> +#include <asm/arch/kirkwood.h>

> +
> +#ifdef CONFIG_MMC
> +
> +#define DRIVER_NAME "mv-sdio"
> +
> +//#define DEBUG
> +
> +//static int maxfreq = MVSD_CLOCKRATE_MAX;
> +//static int nodma;

Remove dead code, please post clean code

> +
> +static int is_sdhc;
> +
> +extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
> +
> +static block_dev_desc_t mmc_dev;
> +
> +block_dev_desc_t * mmc_get_dev(int dev)
> +{
> +	return ((block_dev_desc_t *)&mmc_dev);
> +}
> +
> +/*
> + * FIXME needs to read cid and csd info to determine block size
> + * and other parameters
> + */
> +static uchar mmc_buf[MMC_BLOCK_SIZE];
> +static mv_mmc_csd_t mv_mmc_csd;
> +static int mmc_ready = 0;
> +
> +/* MMC_DEFAULT_RCA should probably be just 1, but this may break other
> code
> +   that expects it to be shifted. */
> +static u_int16_t rca = 0;
> +
> +static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd)
> +{
> +	u_int32_t block_len, mult, blocknr;
> +
> +	block_len = csd->read_bl_len << 12;
> +	mult = csd->c_size_mult1 << 8;
> +	blocknr = (csd->c_size+1) * mult;
> +
> +	return blocknr * block_len;
> +}
> +
> +static int isprint (unsigned char ch)
> +{
> +	if (ch >= 32 && ch < 127)
> +		return (1);
> +
> +	return (0);
> +}
> +
> +static int toprint(char *dst, char c)
> +{
> +	if (isprint(c)) {
> +		*dst = c;
> +		return 1;
> +	}
> +
> +	return sprintf(dst,"\\x%02x", c);
> +
> +}
> +
> +static void print_mmc_cid(mv_mmc_cid_t *cid)
> +{
> +	printf("MMC found. Card desciption is:\n");
> +	printf("Manufacturer ID = %02x%02x%02x\n",
> +		cid->id[0], cid->id[1], cid->id[2]);
> +	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
> +	cid->hwrev = cid->fwrev = 0;	/* null terminate string */
> +	printf("Product Name = %s\n",cid->name);
> +	printf("Serial Number = %02x%02x%02x\n",
> +		cid->sn[0], cid->sn[1], cid->sn[2]);
> +	printf("Month = %d\n",cid->month);
> +	printf("Year = %d\n",1997 + cid->year);
> +}
> +
> +static void print_sd_cid(mv_sd_cid_t *cid)
> +{
> +	int len;
> +	char tbuf[64];
> +
> +	printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":"");
> +
> +	len = 0;
> +	len += toprint(&tbuf[len], cid->oid_0);
> +	len += toprint(&tbuf[len], cid->oid_1);
> +	tbuf[len] = 0;
> +
> +	printf("Manufacturer:       0x%02x, OEM \"%s\"\n",
> +	    cid->mid, tbuf);
> +
> +	len = 0;
> +	len += toprint(&tbuf[len], cid->pnm_0);
> +	len += toprint(&tbuf[len], cid->pnm_1);
> +	len += toprint(&tbuf[len], cid->pnm_2);
> +	len += toprint(&tbuf[len], cid->pnm_3);
> +	len += toprint(&tbuf[len], cid->pnm_4);
> +	tbuf[len] = 0;
> +
> +	printf("Product name:       \"%s\", revision %d.%d\n",
> +		tbuf,
> +	    cid->prv >> 4, cid->prv & 15);
> +
> +	printf("Serial number:      %u\n",
> +	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
> +	    cid->psn_3);
> +	printf("Manufacturing date: %d/%d\n",
> +	    cid->mdt_1 & 15,
> +	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
> +
> +	printf("CRC:                0x%02x, b0 = %d\n",
> +	    cid->crc >> 1, cid->crc & 1);
> +}
> +
> +static void mvsdio_set_clock(unsigned int clock)
> +{
> +	unsigned int m;
> +
> +	m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1;
> +
> +	debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n",
> +		      m, clock);
> +
> +
> +	SDIO_REG_WRITE32(SDIO_CLK_DIV, m & 0x7ff);
> +
> +	if (isprint(1))
> +	udelay(10*1000);
> +}
> +
> +/****************************************************/
> +static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort
> resptype, ushort waittype)
> +/****************************************************/
> +{
> +	static ulong resp[4];
> +	ushort done ;
> +	int err = 0 ;
> +	ulong curr, start, diff, hz;
> +	ushort response[8], resp_indx = 0;
> +
> +	debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n"
> +	, (unsigned int)cmd, (unsigned int)arg, xfermode, resptype,
> waittype);
> +
> +
> +	//clear status

Please no c++ style of comments

> +	SDIO_REG_WRITE16(SDIO_NOR_INTR_STATUS, 0xffff);
> +	SDIO_REG_WRITE16(SDIO_ERR_INTR_STATUS, 0xffff);

Please use reads/writes everywhere

...snip...
> diff --git a/drivers/mmc/mv_sdio.h b/drivers/mmc/mv_sdio.h
> new file mode 100644
> index 0000000..bb7d39c
> --- /dev/null
> +++ b/drivers/mmc/mv_sdio.h
> @@ -0,0 +1,296 @@
> +/*
> + * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
> + * Copyright (C) 2010 G?rald Kerma <gerald.kerma@gk2.net>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#ifndef _MVSDIO_INCLUDE
> +#define _MVSDIO_INCLUDE
> +
> +#define SDIO_REG(x) (KW_SDIO_BASE + (x))
> +
> +#define SDIO_REG_WRITE32(offset,value) writel(value,SDIO_REG(offset))
> +#define SDIO_REG_READ32(offset) readl(SDIO_REG(offset))
> +
> +#define SDIO_REG_WRITE16(offset,value) writew(value,SDIO_REG(offset))
> +#define SDIO_REG_READ16(offset) readw(SDIO_REG(offset))

It makes more sense to use readl/writel macros directly, the used macros increases code size.

> +
> +#define MVSDMMC_DMA_SIZE			65536
> +#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
> +
> +/*
> + * Clock rates
> + */
> +
> +#define MVSD_CLOCKRATE_MAX			50000000
> +#define MVSD_BASE_DIV_MAX			0x7ff
> +
> +#define CONFIG_SYS_MMC_CLK_PP			25000000
> +
> +/*
> + * The base MMC clock rate
> + */
> +
> +#define MVSDMMC_CLOCKRATE_MIN			100000
> +#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
> +#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
> +
> +
> +/*
> + * SDIO register
> + */

Please use c-struct for register definations

> +
> +#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_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

Overall, the code looks too bulky
Please try to make use of CONFIG_GENERIC_MMC, check if you can use mmc.c and reduce mv_mmc.c code size and complications. Ref: omap4_sdp4430 board

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
  2010-11-18  4:04 ` Prafulla Wadaskar
@ 2010-11-19 16:10   ` Gérald Kerma
  2010-11-20 21:33     ` Prafulla Wadaskar
  2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
  1 sibling, 1 reply; 22+ messages in thread
From: Gérald Kerma @ 2010-11-19 16:10 UTC (permalink / raw)
  To: u-boot

---
 arch/arm/include/asm/arch-kirkwood/kirkwood.h     |    1 +
 arch/arm/include/asm/arch-kirkwood/mmc_host_def.h |  292 +++++++++
 drivers/mmc/Makefile                              |    1 +
 drivers/mmc/mv_sdio.c                             |  663
+++++++++++++++++++++
 4 files changed, 957 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
index 0104418..4f9fe7e 100644
--- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
@@ -60,6 +60,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
diff --git a/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
b/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
new file mode 100644
index 0000000..4327c93
--- /dev/null
+++ b/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
+ * Copyright (C) 2010 G?rald Kerma <gerald.kerma@gk2.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _MVSDIO_INCLUDE
+#define _MVSDIO_INCLUDE
+
+#define SDIO_REG(x) (KW_SDIO_BASE + (x))
+
+#define MVSDMMC_DMA_SIZE			65536
+#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX			50000000
+#define MVSD_BASE_DIV_MAX			0x7ff
+
+#define CONFIG_SYS_MMC_CLK_PP			25000000
+
+/*
+ * The base MMC clock rate
+ */
+
+#define MVSDMMC_CLOCKRATE_MIN			100000
+#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
+#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
+
+
+/*
+ * SDIO register
+ */
+
+#define SDIO_SYS_ADDR				0x000
+#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				0x010
+#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_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)
+
+
+/*
+ * 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)
+
+
+/*
+ * 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_ID_MODE_LOW_FREQ 	(1 << 5)
+#define SDIO_HOST_CTRL_HALF_SPEED 		(1 << 6)
+#define SDIO_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define SDIO_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+
+#define SDIO_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT_MAX 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define SDIO_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+#define SDIO_HOST_CTRL_DFAULT_OPEN_DRAIN 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf))
+#define SDIO_HOST_CTRL_DFAULT_PUSH_PULL 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf) | SDIO_HOST_CTRL_PUSH_PULL_EN)
+
+
+/*
+ * NOR 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)
+
+
+/*
+ * ERR 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_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_ERR_INTR_MASK			0xFFFF
+
+
+#define MMC_BLOCK_SIZE                  512
+#define MMC_CMD_RESET                   0
+#define MMC_CMD_SEND_OP_COND            1
+#define MMC_CMD_ALL_SEND_CID            2
+#define MMC_CMD_SET_RCA                 3
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_CSD                9
+#define MMC_CMD_SEND_CID                10
+#define MMC_CMD_SEND_STATUS             13
+#define MMC_CMD_SET_BLOCKLEN            16
+#define MMC_CMD_READ_BLOCK              17
+#define MMC_CMD_RD_BLK_MULTI            18
+#define MMC_CMD_WRITE_BLOCK             24
+#define MMC_MAX_BLOCK_SIZE              512
+
+typedef struct mv_mmc_cid
+{
+	/* FIXME: BYTE_ORDER */
+	uchar year:4,
+	month:4;
+	uchar sn[3];
+	uchar fwrev:4,
+	hwrev:4;
+	uchar name[6];
+	uchar id[3];
+} mv_mmc_cid_t;
+
+typedef struct mv_mmc_csd
+{
+	uchar   ecc:2,
+		file_format:2,
+		tmp_write_protect:1,
+		perm_write_protect:1,
+		copy:1,
+		file_format_grp:1;
+	uint64_t content_prot_app:1,
+		rsvd3:4,
+		write_bl_partial:1,
+		write_bl_len:4,
+		r2w_factor:3,
+		default_ecc:2,
+		wp_grp_enable:1,
+		wp_grp_size:5,
+		erase_grp_mult:5,
+		erase_grp_size:5,
+		c_size_mult1:3,
+		vdd_w_curr_max:3,
+		vdd_w_curr_min:3,
+		vdd_r_curr_max:3,
+		vdd_r_curr_min:3,
+		c_size:12,
+		rsvd2:2,
+		dsr_imp:1,
+		read_blk_misalign:1,
+		write_blk_misalign:1,
+		read_bl_partial:1;
+	ushort  read_bl_len:4,
+		ccc:12;
+	uchar   tran_speed;
+	uchar   nsac;
+	uchar   taac;
+	uchar   rsvd1:2,
+		spec_vers:4,
+		csd_structure:2;
+} mv_mmc_csd_t;
+
+typedef struct {
+	char		pnm_0;	/* product name */
+	char		oid_1;	/* OEM/application ID */
+	char		oid_0;
+	uint8_t		mid;	/* manufacturer ID */
+	char		pnm_4;
+	char		pnm_3;
+	char		pnm_2;
+	char		pnm_1;
+	uint8_t		psn_2;	/* product serial number */
+	uint8_t		psn_1;
+	uint8_t		psn_0;	/* MSB */
+	uint8_t		prv;	/* product revision */
+	uint8_t		crc;	/* CRC7 checksum, b0 is unused and set to 1 */
+	uint8_t		mdt_1;	/* manufacturing date, LSB, RRRRyyyy yyyymmmm */
+	uint8_t		mdt_0;	/* MSB */
+	uint8_t		psn_3;	/* LSB */
+} mv_sd_cid_t;
+
+#endif /* _MVSDIO_INCLUDE */
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 68afd30..2a4e1d4 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -30,6 +30,7 @@ COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
+COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c
new file mode 100644
index 0000000..593250f
--- /dev/null
+++ b/drivers/mmc/mv_sdio.c
@@ -0,0 +1,663 @@
+/*
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net
+ * Copyright (C) 2010 G?rald Kerma <geraker@gmail.com>
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <part.h>
+#include <asm/io.h>
+#ifdef CONFIG_KIRKWOOD
+#include <asm/arch/kirkwood.h>
+#endif
+#include <asm/arch/mmc_host_def.h>
+
+#ifdef CONFIG_MMC
+
+#define DRIVER_NAME "mv-sdio"
+
+#ifdef DEBUG
+#define pr_debug(fmt, args...) printf(fmt, ##args)
+#else
+#define pr_debug(...) do { } while(0)
+#endif
+
+static int is_sdhc;
+extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+static block_dev_desc_t mmc_dev;
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+	return ((block_dev_desc_t *)&mmc_dev);
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+static uchar mmc_buf[MMC_BLOCK_SIZE];
+static mv_mmc_csd_t mv_mmc_csd;
+static int mmc_ready = 0;
+
+/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
+   that expects it to be shifted. */
+static u_int16_t rca = 0;
+
+/* used for debug */
+static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd)
+{
+	u_int32_t block_len, mult, blocknr;
+
+	block_len = csd->read_bl_len << 12;
+	mult = csd->c_size_mult1 << 8;
+	blocknr = (csd->c_size+1) * mult;
+
+	return blocknr * block_len;
+}
+
+static int isprint (unsigned char ch)
+{
+	if (ch >= 32 && ch < 127)
+		return (1);
+
+	return (0);
+}
+
+static int toprint(char *dst, char c)
+{
+	if (isprint(c)) {
+		*dst = c;
+		return 1;
+	}
+
+	return sprintf(dst,"\\x%02x", c);
+
+}
+
+static void print_mmc_cid(mv_mmc_cid_t *cid)
+{
+	printf("MMC found. Card desciption is:\n");
+	printf("Manufacturer ID = %02x%02x%02x\n",
+		cid->id[0], cid->id[1], cid->id[2]);
+	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
+	cid->hwrev = cid->fwrev = 0;	/* null terminate string */
+	printf("Product Name = %s\n",cid->name);
+	printf("Serial Number = %02x%02x%02x\n",
+		cid->sn[0], cid->sn[1], cid->sn[2]);
+	printf("Month = %d\n",cid->month);
+	printf("Year = %d\n",1997 + cid->year);
+}
+
+static void print_sd_cid(mv_sd_cid_t *cid)
+{
+	int len;
+	char tbuf[64];
+
+	printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":"");
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->oid_0);
+	len += toprint(&tbuf[len], cid->oid_1);
+	tbuf[len] = 0;
+
+	printf("Manufacturer:       0x%02x, OEM \"%s\"\n",
+	    cid->mid, tbuf);
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->pnm_0);
+	len += toprint(&tbuf[len], cid->pnm_1);
+	len += toprint(&tbuf[len], cid->pnm_2);
+	len += toprint(&tbuf[len], cid->pnm_3);
+	len += toprint(&tbuf[len], cid->pnm_4);
+	tbuf[len] = 0;
+
+	printf("Product name:       \"%s\", revision %d.%d\n",
+		tbuf,
+	    cid->prv >> 4, cid->prv & 15);
+
+	printf("Serial number:      %u\n",
+	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
+	    cid->psn_3);
+	printf("Manufacturing date: %d/%d\n",
+	    cid->mdt_1 & 15,
+	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
+
+	printf("CRC:                0x%02x, b0 = %d\n",
+	    cid->crc >> 1, cid->crc & 1);
+}
+
+static void mvsdio_set_clock(unsigned int clock)
+{
+	unsigned int m;
+
+	m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1;
+
+	pr_debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n",
+		      m, clock);
+
+
+	writew(m & 0x7ff, SDIO_REG(SDIO_CLK_DIV));
+
+	if (isprint(1))
+	udelay(10*1000);
+}
+
+/****************************************************/
+static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort
resptype, ushort waittype)
+/****************************************************/
+{
+	static ulong resp[4];
+	ushort done ;
+	int err = 0 ;
+	ulong curr, start, diff, hz;
+	ushort response[8], resp_indx = 0;
+
+	pr_debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n"
+	, (unsigned int)cmd, (unsigned int)arg, xfermode, resptype, waittype);
+
+
+	/* clear status */
+	writew(0xffff, SDIO_REG(SDIO_NOR_INTR_STATUS));
+	writew(0xffff, SDIO_REG(SDIO_ERR_INTR_STATUS));
+
+	start = get_timer(0);
+	hz = CONFIG_SYS_HZ;
+
+	while((readw(SDIO_REG(SDIO_PRESENT_STATE0)) & CARD_BUSY)) {
+		curr = get_timer(0);
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			/* 3 seconds timeout, card busy, can't sent cmd */
+			printf("card too busy \n");
+			return 0;
+		}
+	}
+
+	writew((ushort)(arg&0xffff), SDIO_REG(SDIO_ARG_LOW));
+	writew((ushort)(arg>>16), SDIO_REG(SDIO_ARG_HI));
+	writew(xfermode, SDIO_REG(SDIO_XFER_MODE));
+	if( (cmd == MMC_CMD_READ_BLOCK) || (cmd == 25) )
+	{
+		writew(((cmd << 8) | resptype | 0x3c ) , SDIO_REG(SDIO_CMD));
+	pr_debug("cmd reg : %x\n", readw(SDIO_REG(SDIO_CMD) )) ;
+
+	}
+	else
+	{
+		writew(((cmd << 8) | resptype ), SDIO_REG(SDIO_CMD));
+	}
+
+	done = readw(SDIO_REG(SDIO_NOR_INTR_STATUS)) & waittype;
+	start = get_timer(0);
+
+	while( done!=waittype)
+	{
+		done = readw(SDIO_REG(SDIO_NOR_INTR_STATUS)) & waittype;
+
+		if( readw(SDIO_REG(SDIO_NOR_INTR_STATUS)) & 0x8000 )
+		{		
+			pr_debug("Error! cmd : %d, err : %04x\n", (unsigned int)cmd,
readw(SDIO_REG(SDIO_ERR_INTR_STATUS))) ;
+
+			return 0 ;	/* error happen */
+		}
+
+		curr = get_timer(0);
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			pr_debug("cmd timeout, status : %04x\n",
readw(SDIO_REG(SDIO_NOR_INTR_STATUS)));
+			pr_debug("xfer mode : %04x\n", readw(SDIO_REG(SDIO_XFER_MODE)));
+
+			err = 1 ;
+			break;
+		}
+	}
+
+	for (resp_indx = 0 ; resp_indx < 8; resp_indx++)
+		response[resp_indx] = readw(SDIO_REG(SDIO_RSP(resp_indx)));
+
+	memset(resp, 0, sizeof(resp));
+
+	switch (resptype & 0x3) {
+		case SDIO_CMD_RSP_48:
+		case SDIO_CMD_RSP_48BUSY:
+			resp[0] = ((response[2] & 0x3f) << (8 - 8)) |
+				((response[1] & 0xffff) << (14 - 8)) |
+				((response[0] & 0x3ff) << (30 - 8));
+			resp[1] = ((response[0] & 0xfc00) >> 10);
+			break;
+
+		case SDIO_CMD_RSP_136:
+			resp[3] = ((response[7] & 0x3fff) << 8)	|
+				((response[6] & 0x3ff) << 22);
+			resp[2] = ((response[6] & 0xfc00) >> 10)	|
+				((response[5] & 0xffff) << 6)	|
+				((response[4] & 0x3ff) << 22);
+			resp[1] = ((response[4] & 0xfc00) >> 10)	|
+				((response[3] & 0xffff) << 6)	|
+				((response[2] & 0x3ff) << 22);
+			resp[0] = ((response[2] & 0xfc00) >> 10)	|
+				((response[1] & 0xffff) << 6)	|
+				((response[0] & 0x3ff) << 22);
+			break;
+		default:
+			return 0;
+	}
+	int i;
+	pr_debug("MMC resp :");
+	for (i=0; i<4; ++i ) {
+		pr_debug(" %08x", (unsigned int)resp[i]);
+	}
+	pr_debug("\n");
+	if( err )
+		return NULL ;
+	else
+		return resp;
+}
+
+/****************************************************/
+static int mv_mmc_block_read(uchar *dst, ulong src, ulong len)
+/****************************************************/
+{
+	ulong *resp;
+
+	if (len == 0) {
+		return 0;
+	}
+
+	if (is_sdhc) {
+		/* SDHC: use block address */
+		src >>= 9;
+	}
+
+	pr_debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src,
(int)len);
+
+	/* prepare for dma transfer */
+	writew(((ulong)(dst))&0xffff,SDIO_REG(SDIO_SYS_ADDR_LOW));
+	writew(((ulong)(dst)>>16)&0xffff,SDIO_REG(SDIO_SYS_ADDR_HI));
+	writew(len,SDIO_REG(SDIO_BLK_SIZE));
+	writew(1,SDIO_REG(SDIO_BLK_COUNT));
+	
+	/* send read command */
+	resp = mv_mmc_cmd(MMC_CMD_READ_BLOCK, src, 0x10 ,
+			SDIO_CMD_RSP_48, SDIO_NOR_XFER_DONE);
+	if (!resp) {
+		pr_debug("mv_mmc_block_read: mmc read block cmd fails\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/****************************************************/
+int mv_mmc_read(ulong src, uchar *dst, int size)
+/****************************************************/
+{
+	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+	ulong mmc_block_size, mmc_block_address;
+
+	if (size == 0) {
+		return 0;
+	}
+
+	if (!mmc_ready) {
+		printf("Please initial the MMC first\n");
+		return -1;
+	}
+
+	mmc_block_size = MMC_BLOCK_SIZE;
+	mmc_block_address = ~(mmc_block_size - 1);
+
+	end = src + size;
+	part_start = ~mmc_block_address & src;
+	part_end = ~mmc_block_address & end;
+	aligned_start = mmc_block_address & src;
+	aligned_end = mmc_block_address & end;
+
+	/* all block aligned accesses */
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_start) {
+		part_len = mmc_block_size - part_start;
+		pr_debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf+part_start, part_len);
+		dst += part_len;
+		src += part_len;
+	}
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	for (; src < aligned_end; aligned_start +=mmc_block_size, src +=
mmc_block_size, dst += mmc_block_size) {
+		pr_debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+		 	printf("mmc block read error\n");
+			return -1;
+		}
+		memcpy(dst, mmc_buf, mmc_block_size);
+	}
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_end && src < end) {
+		pr_debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf, part_end);
+	}
+	return 0;
+}
+
+/****************************************************/
+static ulong mv_mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong
*dst)
+/****************************************************/
+{
+	int mmc_block_size = MMC_BLOCK_SIZE;
+	ulong src = blknr * mmc_block_size;
+
+	mv_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
+	return blkcnt;
+}
+
+/****************************************************/
+int mmc_legacy_init(int verbose)
+/****************************************************/
+{
+	int retries, rc = -ENODEV;
+	ulong *resp;
+	int sd_ver20;
+	int is_sd;
+	ushort reg;
+	uchar cidbuf[64];
+
+	sd_ver20 = 0;
+	is_sdhc = 0;
+	is_sd = 0;
+
+	/* Initial Host Ctrl : Timeout : max , Normal Speed mode, 4-bit data
mode */
+	/* Big Endian, SD memory Card, Push_pull CMD Line */
+	writew( SDIO_HOST_CTRL_TMOUT(0xf) |
+		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 ,
+		SDIO_REG(SDIO_HOST_CTRL));
+
+	writew( 0, SDIO_REG(SDIO_CLK_CTRL));
+
+	/* enable status */
+	writew( 0xffff, SDIO_REG(SDIO_NOR_STATUS_EN));
+	writew( 0xffff, SDIO_REG(SDIO_ERR_STATUS_EN));
+
+	/* disable interrupts */
+	writew( 0, SDIO_REG(SDIO_NOR_INTR_EN));
+	writew( 0, SDIO_REG(SDIO_ERR_INTR_EN));
+
+	writew( 0x100, SDIO_REG(SDIO_SW_RESET));
+	udelay(10000);
+
+	mv_mmc_csd.c_size = 0;
+
+	/* reset */
+	retries = 10;
+	resp = mv_mmc_cmd(0, 0, 0, SDIO_CMD_RSP_NONE, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 0 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	pr_debug ("trying to detect SD card version\n");
+
+	resp = mv_mmc_cmd(8, 0x000001aa, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 8 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp && (resp[0] & 0x1ff)==0x1aa) {
+		pr_debug ("SD version 2.0 card detected\n");
+
+		sd_ver20 = 1;
+	}
+
+	if (sd_ver20)
+		retries = 50;
+	else
+		retries = 10;
+
+	while (retries--) {
+		resp = mv_mmc_cmd(55, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		pr_debug("cmd 55 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (sd_ver20)
+			resp = mv_mmc_cmd(41, 0x40300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		else
+			resp = mv_mmc_cmd(41, 0x00300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+
+		pr_debug("cmd 41 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (resp && (resp[0] & 0x80000000)) {
+			pr_debug ("detected SD card\n");
+
+			is_sd = 1;
+			break;
+		}
+
+		udelay(100*1000);
+	}
+
+	if (retries <= 0 && !is_sd) {
+		pr_debug ("failed to detect SD card, trying MMC\n");
+
+		retries = 10;
+		while (retries--) {
+			resp = mv_mmc_cmd(1, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+			pr_debug("cmd 01 resp : %08x %08x %08x %08x\n",
+			(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+			if (resp && (resp[0] & 0x80000000)) {
+				printf ("detected MMC card\n");
+				reg = readw(SDIO_REG(SDIO_HOST_CTRL));
+				reg &= ~(0x3<<1);
+				reg |= SDIO_HOST_CTRL_CARD_TYPE_IO_MMC;
+				writew( reg, SDIO_REG(SDIO_HOST_CTRL));
+				break;
+			}
+
+			udelay(100*1000);
+		}
+	}
+		
+	if (retries <= 0) {
+		pr_debug ("detect fails\n");
+
+		return -ENODEV;
+	}
+
+	/* try to get card id */
+	resp = mv_mmc_cmd(2, 0, 0, SDIO_CMD_RSP_136, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 2 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (resp == NULL) {
+		pr_debug ("read cid fails\n");
+
+		return -ENODEV;
+	}
+
+	if (is_sd) {
+		mv_sd_cid_t *cid = (mv_sd_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x OEM %c%c \"%c%c%c%c%c\"",
+			cid->mid, cid->oid_0, cid->oid_1,
+			cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4);
+
+		sprintf((char *) mmc_dev.product, "%d",
+			(cid->psn_0 << 24) | (cid->psn_1 <<16) | (cid->psn_2 << 8) |
(cid->psn_3 << 8));
+		
+		sprintf((char *) mmc_dev.revision, "%d.%d", cid->prv>>4, cid->prv &
0xff);
+		
+	} else {
+		/* TODO configure mmc driver depending on card attributes */
+		mv_mmc_cid_t *cid = (mv_mmc_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x%02x%02x Snr %02x%02x%02x",
+			cid->id[0], cid->id[1], cid->id[2],
+			cid->sn[0], cid->sn[1], cid->sn[2]);
+		sprintf((char *) mmc_dev.product, "%s", cid->name);
+		sprintf((char *) mmc_dev.revision, "%x %x", cid->hwrev, cid->fwrev);
+	}
+	
+	/* fill in device description */
+	mmc_dev.if_type = IF_TYPE_MMC;
+	mmc_dev.part_type = PART_TYPE_DOS;
+	mmc_dev.dev = 0;
+	mmc_dev.lun = 0;
+	mmc_dev.type = 0;
+
+	/* FIXME fill in the correct size (is set to 128MByte) */
+	mmc_dev.blksz = MMC_BLOCK_SIZE;
+	mmc_dev.lba = 0x10000;
+
+	mmc_dev.removable = 0;
+	mmc_dev.block_read = (unsigned long) mv_mmc_bread;
+
+	/* MMC exists, get CSD too */
+	resp = mv_mmc_cmd(MMC_CMD_SET_RCA, 0, 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+	if (resp == NULL) {
+		pr_debug ("set rca fails\n");
+
+		return -ENODEV;
+	}
+	pr_debug("cmd3 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	if (is_sd)
+		rca = resp[0] >> 16;
+	else
+		rca = 0;
+
+	resp = mv_mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, 0,
SDIO_CMD_RSP_136,SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 9 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp == NULL) {
+		pr_debug ("read csd fails\n");
+
+		return -ENODEV;
+	}
+
+	memcpy(&mv_mmc_csd, (mv_mmc_csd_t *) resp, sizeof(mv_mmc_csd_t));
+	rc = 0;
+	mmc_ready = 1;
+
+	/* FIXME add verbose printout for csd */
+	pr_debug ("size = %u\n", mv_mmc_size(&mv_mmc_csd));
+
+
+	resp = mv_mmc_cmd(7, rca<<16, 0, SDIO_CMD_RSP_48BUSY, SDIO_NOR_CMD_DONE);
+	if (resp == NULL) {
+		pr_debug ("select card fails\n");
+
+		return -ENODEV;
+	}
+	pr_debug("cmd 7 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (is_sd) {
+		resp = mv_mmc_cmd(55, rca<<16, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			pr_debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+		pr_debug("cmd55 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+		resp = mv_mmc_cmd(6, (rca<<16) | 0x2 , 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			pr_debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+	pr_debug("cmd6 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+	}
+
+	resp = (ulong *) &mv_mmc_csd;
+	pr_debug("csd: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	/* check SDHC */
+	if ((resp[0]&0xf0000000)==0x40000000)
+		is_sdhc = 1;
+
+	/* set block len */
+	resp = mv_mmc_cmd(MMC_CMD_SET_BLOCKLEN, MMC_BLOCK_SIZE, 0,
SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	if (!resp) {
+		pr_debug("mv_mmc_block_read: set blk len fails\n");
+	 	return -ENODEV;
+	}
+
+	if (verbose) {
+		if (is_sd)
+			print_sd_cid((mv_sd_cid_t *) cidbuf);
+		else
+			print_mmc_cid((mv_mmc_cid_t *) cidbuf);
+	}
+
+	mvsdio_set_clock(CONFIG_SYS_MMC_CLK_PP);
+
+	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
+
+	return 0;
+}
+
+#endif	/* CONFIG_MMC */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
  2010-11-18  4:04 ` Prafulla Wadaskar
  2010-11-19 16:10   ` [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
@ 2010-11-19 16:11   ` Gérald Kerma
  2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
                       ` (2 more replies)
  1 sibling, 3 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-11-19 16:11 UTC (permalink / raw)
  To: u-boot

---
 include/configs/sheevaplug.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index 83dd8ff..b944ec7 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -47,6 +47,7 @@
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_USB
@@ -90,6 +91,14 @@
 	"x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0"

 /*
+ * SDIO/MMC Card Configuration
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_MV_SDIO
+#endif /* CONFIG_CMD_MMC */
+
+/*
  * Ethernet Driver configuration
  */
 #ifdef CONFIG_CMD_NET
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support
  2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
@ 2010-11-19 16:55     ` Gérald Kerma
  2010-11-19 16:56       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system Gérald Kerma
  2010-11-20 21:33       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Prafulla Wadaskar
  2010-11-20 15:17     ` [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support Ludovic Courtès
  2010-11-20 21:33     ` Prafulla Wadaskar
  2 siblings, 2 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-11-19 16:55 UTC (permalink / raw)
  To: u-boot

---
 include/configs/sheevaplug.h |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index b944ec7..82e49c0 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -46,6 +46,7 @@
 #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
@@ -107,6 +108,34 @@
 #endif /* CONFIG_CMD_NET */

 /*
+ * IDE Support on SATA port0
+ */
+#ifdef CONFIG_CMD_IDE
+#define __io
+#define CONFIG_CMD_EXT2
+#define CONFIG_MVSATA_IDE
+#define CONFIG_IDE_PREINIT
+#define CONFIG_MVSATA_IDE_USE_PORT0
+/* Needs byte-swapping for ATA data register */
+#define CONFIG_IDE_SWAP_IO
+/* Data, registers and alternate blocks are at the same offset */
+#define CONFIG_SYS_ATA_DATA_OFFSET	(0x0100)
+#define CONFIG_SYS_ATA_REG_OFFSET	(0x0100)
+#define CONFIG_SYS_ATA_ALT_OFFSET	(0x0100)
+/* Each 8-bit ATA register is aligned to a 4-bytes address */
+#define CONFIG_SYS_ATA_STRIDE		4
+/* Controller supports 48-bits LBA addressing */
+#define CONFIG_LBA48
+/* CONFIG_CMD_IDE requires some #defines for ATA registers */
+#define CONFIG_SYS_IDE_MAXBUS		1
+#define CONFIG_SYS_IDE_MAXDEVICE	1
+/* ATA registers base is at SATA controller base */
+#define CONFIG_SYS_ATA_BASE_ADDR	KW_SATA_BASE
+/* ATA bus 0 is Kirkwood port 1 on sheevaplug */
+#define CONFIG_SYS_ATA_IDE0_OFFSET	KW_SATA_PORT1_OFFSET
+#endif /* CONFIG_CMD_IDE */
+
+/*
  * File system
  */
 #define CONFIG_CMD_EXT2
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system
  2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
@ 2010-11-19 16:56       ` Gérald Kerma
  2010-11-20 21:32         ` Prafulla Wadaskar
  2010-11-20 21:33       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Prafulla Wadaskar
  1 sibling, 1 reply; 22+ messages in thread
From: Gérald Kerma @ 2010-11-19 16:56 UTC (permalink / raw)
  To: u-boot

---
 include/configs/sheevaplug.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index 82e49c0..9f5f122 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -83,13 +83,13 @@
 	"${x_bootcmd_usb}; bootm 0x6400000;"

 #define CONFIG_MTDPARTS		"orion_nand:512k(uboot),"	\
-	"3m at 1m(kernel),1m at 4m(psm),13m at 5m(rootfs) rw\0"
+	"3m at 1m(kernel),1m at 4m(psm),507m at 5m(rootfs) rw\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"
+	"x_bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs\0"

 /*
  * SDIO/MMC Card Configuration
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug
  2010-11-18  1:00 ` Clint Adams
  2010-11-18  3:32   ` Prafulla Wadaskar
@ 2010-11-20 11:42   ` Gérald Kerma
  1 sibling, 0 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-11-20 11:42 UTC (permalink / raw)
  To: u-boot

Hye Clint,

Le 18/11/2010 02:00, Clint Adams a ?crit :
> On Sun, Aug 29, 2010 at 12:37:16AM +0200, G?rald Kerma wrote:
>>     Add mvsdio driver to Kirkwood SoC
>>     Add SDIO support to SHEEVAPLUG
> 
> G?rald, can this be adapted for GuruPlug?

It is not needed at all.
The ?SD card reader of the GuruPlug is viewed as an USB device.

A patch had already been commit to support the ?SD of the GuruPlug by
Ludovic Court?s

I have done a quick test of the current uBoot :
a 1G microSD is correctly detected in a GuruPlug Server Plus.

Regards,
-- 
G.K

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 554 bytes
Desc: OpenPGP digital signature
Url : http://lists.denx.de/pipermail/u-boot/attachments/20101120/ee815c2c/attachment.pgp 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
  2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
  2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
@ 2010-11-20 15:17     ` Ludovic Courtès
  2010-11-20 21:42       ` Prafulla Wadaskar
  2010-11-20 21:33     ` Prafulla Wadaskar
  2 siblings, 1 reply; 22+ messages in thread
From: Ludovic Courtès @ 2010-11-20 15:17 UTC (permalink / raw)
  To: u-boot

Hi,

G?rald Kerma <geraker@gmail.com> writes:

>  /*
> + * SDIO/MMC Card Configuration
> + */
> +#ifdef CONFIG_CMD_MMC
> +#define CONFIG_MMC
> +#define CONFIG_MV_SDIO
> +#endif /* CONFIG_CMD_MMC */
> +

Speaking of this, I suggested enabling MMC, ext2, and other features by
default for the GuruPlug [0], but my understanding was that this was
being factorized between the SheevaPlug and GuruPlug.

What?s the status of this refactoring effort?

Thanks,
Ludo?.

[0] http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/85857

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system
  2010-11-19 16:56       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system Gérald Kerma
@ 2010-11-20 21:32         ` Prafulla Wadaskar
  0 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:32 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Friday, November 19, 2010 10:27 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Clint Adams
> Subject: [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail
> system
> 
> ---
>  include/configs/sheevaplug.h |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
> index 82e49c0..9f5f122 100644
> --- a/include/configs/sheevaplug.h
> +++ b/include/configs/sheevaplug.h
> @@ -83,13 +83,13 @@
>  	"${x_bootcmd_usb}; bootm 0x6400000;"
> 
>  #define CONFIG_MTDPARTS		"orion_nand:512k(uboot),"	\
> -	"3m at 1m(kernel),1m at 4m(psm),13m at 5m(rootfs) rw\0"
> +	"3m at 1m(kernel),1m at 4m(psm),507m at 5m(rootfs) rw\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"
> +	"x_bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs\0"

Ack, except, Null patch description, please repost with describing objective of this patch

Regards..
Prafulla .. 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
  2010-11-19 16:10   ` [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
@ 2010-11-20 21:33     ` Prafulla Wadaskar
  2010-11-21 11:05       ` [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug Gérald Kerma
  0 siblings, 1 reply; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:33 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Friday, November 19, 2010 9:41 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Clint Adams
> Subject: [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
> 

There should be some patch explanation here and 

> ---
Changelog info here..
You can refer some other patches for this, because rest other make it pure driver add patch and this file is pre-requisite requirement by kirkwood SoC to support it, also the patches may be applied by different custodians

(these comments are applicable for all your patches in this patch series)

>  arch/arm/include/asm/arch-kirkwood/kirkwood.h     |    1 +
This should be separate patch 

>  arch/arm/include/asm/arch-kirkwood/mmc_host_def.h |  292 +++++++++
Please move this file to drivers/mmc/ and rename it as mv_sdio.h

>  drivers/mmc/Makefile                              |    1 +
>  drivers/mmc/mv_sdio.c                             |  663
> +++++++++++++++++++++
>  4 files changed, 957 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> index 0104418..4f9fe7e 100644
> --- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> +++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> @@ -60,6 +60,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
> diff --git a/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
> b/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
> new file mode 100644
> index 0000000..4327c93
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-kirkwood/mmc_host_def.h
> @@ -0,0 +1,292 @@
> +/*
> + * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
> + * Copyright (C) 2010 G?rald Kerma <gerald.kerma@gk2.net>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.

Software license is wrong here, it should be v2 or latter, please refer some recent files added in some other commits Or other Kirkwood files

> + *
> + */
> +
> +#ifndef _MVSDIO_INCLUDE
> +#define _MVSDIO_INCLUDE
> +
> +#define SDIO_REG(x) (KW_SDIO_BASE + (x))
> +
> +#define MVSDMMC_DMA_SIZE			65536
> +#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
> +
> +/*
> + * Clock rates
> + */
> +
> +#define MVSD_CLOCKRATE_MAX			50000000
> +#define MVSD_BASE_DIV_MAX			0x7ff
> +
> +#define CONFIG_SYS_MMC_CLK_PP			25000000
> +
> +/*
> + * The base MMC clock rate
> + */
> +
> +#define MVSDMMC_CLOCKRATE_MIN			100000
> +#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
> +#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
> +
> +
> +/*
> + * SDIO register
> + */
> +
> +#define SDIO_SYS_ADDR				0x000
> +#define SDIO_SYS_ADDR_LOW			0x000
> +#define SDIO_SYS_ADDR_HI			0x004

NAK, these are not acceptable, please use c-struct for register definitions.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
  2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
  2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
  2010-11-20 15:17     ` [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support Ludovic Courtès
@ 2010-11-20 21:33     ` Prafulla Wadaskar
  2 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:33 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Friday, November 19, 2010 9:42 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Clint Adams
> Subject: [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
> 
> ---
>  include/configs/sheevaplug.h |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)
> 
> diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
> index 83dd8ff..b944ec7 100644
> --- a/include/configs/sheevaplug.h
> +++ b/include/configs/sheevaplug.h
> @@ -47,6 +47,7 @@
>  #define CONFIG_CMD_DHCP
>  #define CONFIG_CMD_ENV
>  #define CONFIG_CMD_MII
> +#define CONFIG_CMD_MMC
>  #define CONFIG_CMD_NAND
>  #define CONFIG_CMD_PING
>  #define CONFIG_CMD_USB
> @@ -90,6 +91,14 @@
>  	"x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0"
> 
>  /*
> + * SDIO/MMC Card Configuration
> + */
> +#ifdef CONFIG_CMD_MMC
> +#define CONFIG_MMC
> +#define CONFIG_MV_SDIO
> +#endif /* CONFIG_CMD_MMC */

Please move this to mv-common.h, I think you have not synced with latest u-boot.

Regards..
Prafulla .. 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support
  2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
  2010-11-19 16:56       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system Gérald Kerma
@ 2010-11-20 21:33       ` Prafulla Wadaskar
  1 sibling, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:33 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Friday, November 19, 2010 10:26 PM
> To: Prafulla Wadaskar
> Cc: u-boot at lists.denx.de; Clint Adams
> Subject: [PATCH v2 1/1] Sheevaplug: Add mvsata support
> 
> ---
>  include/configs/sheevaplug.h |   29 +++++++++++++++++++++++++++++
>  1 files changed, 29 insertions(+), 0 deletions(-)
> 
> diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
> index b944ec7..82e49c0 100644
> --- a/include/configs/sheevaplug.h
> +++ b/include/configs/sheevaplug.h
> @@ -46,6 +46,7 @@
>  #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
> @@ -107,6 +108,34 @@
>  #endif /* CONFIG_CMD_NET */
> 
>  /*
> + * IDE Support on SATA port0
> + */

This is not needed, pls sync your code with latest u-boot

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
  2010-11-20 15:17     ` [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support Ludovic Courtès
@ 2010-11-20 21:42       ` Prafulla Wadaskar
  0 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:42 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de]
> On Behalf Of Ludovic Court?s
> Sent: Saturday, November 20, 2010 8:47 PM
> To: u-boot at lists.denx.de
> Subject: Re: [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support
> 
> Hi,
> 
> G?rald Kerma <geraker@gmail.com> writes:
> 
> >  /*
> > + * SDIO/MMC Card Configuration
> > + */
> > +#ifdef CONFIG_CMD_MMC
> > +#define CONFIG_MMC
> > +#define CONFIG_MV_SDIO
> > +#endif /* CONFIG_CMD_MMC */
> > +
> 
> Speaking of this, I suggested enabling MMC, ext2, and other features by
> default for the GuruPlug [0], but my understanding was that this was
> being factorized between the SheevaPlug and GuruPlug.
> 
> What's the status of this refactoring effort?

Guruplug and Sheevaplug are two different boards with h/w diffs, 
We have introduced mv-common.h for this,

There are some early sheevaplug versions (without wifi), this patch may help for it.

Regards..
Prafulla .. 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system
@ 2010-11-20 21:46 Prafulla Wadaskar
  0 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-20 21:46 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Prafulla Wadaskar
> Sent: Sunday, November 21, 2010 3:02 AM
> To: 'G?rald Kerma'
> Cc: u-boot at lists.denx.de; Clint Adams; Ashish Karkare; Prabhanjan Sarnaik
> Subject: RE: [PATCH v2 1/1] Sheevaplug: Fix environments for booting
> retail system
> 
> 
> 
> > -----Original Message-----
> > From: G?rald Kerma [mailto:geraker at gmail.com]
> > Sent: Friday, November 19, 2010 10:27 PM
> > To: Prafulla Wadaskar
> > Cc: u-boot at lists.denx.de; Clint Adams
> > Subject: [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail
> > system
> >
> > ---
> >  include/configs/sheevaplug.h |    4 ++--
> >  1 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
> > index 82e49c0..9f5f122 100644
> > --- a/include/configs/sheevaplug.h
> > +++ b/include/configs/sheevaplug.h
> > @@ -83,13 +83,13 @@
> >  	"${x_bootcmd_usb}; bootm 0x6400000;"
> >
> >  #define CONFIG_MTDPARTS		"orion_nand:512k(uboot),"	\
> > -	"3m at 1m(kernel),1m at 4m(psm),13m at 5m(rootfs) rw\0"
> > +	"3m at 1m(kernel),1m at 4m(psm),507m at 5m(rootfs) rw\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"
> > +	"x_bootargs_root=ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs\0"
> 
> Ack, except, Null patch description, please repost with describing
> objective of this patch

And yes, this should be standalone patch

Regards..
Prafulla . .. 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug
  2010-11-20 21:33     ` Prafulla Wadaskar
@ 2010-11-21 11:05       ` Gérald Kerma
  2010-11-21 11:06         ` [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support Gérald Kerma
                           ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-11-21 11:05 UTC (permalink / raw)
  To: u-boot


    pre-requisite for SDIO driver support for Marvell SoCs (Kirkwood)
    Add SDIO legacy driver for Marvell SoCs (Kirkwood)
    Add MMC-SDIO support for Sheevaplug

Signed-off-by: G?rald Kerma <geraker@gmail.com>
---
TODO:
 * Rewrite the SDIO driver as generic MMC driver

v3:
 * GNU Software License compliance
 * Patch more readable

v2:
 * Code cleaning

v1:
 * Fix errors from SD/SDHC detect

G?rald KERMA (3):
  Kirkwood: pre-requisite for SDIO driver support
  mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
  Sheevaplug: Add MMC/SDIO support

 arch/arm/include/asm/arch-kirkwood/kirkwood.h |    1 +
 drivers/mmc/Makefile                          |    1 +
 drivers/mmc/mv_sdio.c                         |  675
+++++++++++++++++++++++++
 drivers/mmc/mv_sdio.h                         |  310 ++++++++++++
 include/configs/mv-common.h                   |    9 +
 include/configs/sheevaplug.h                  |    2 +
 6 files changed, 1001 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mmc/mv_sdio.c
 create mode 100644 drivers/mmc/mv_sdio.h

-- 
G.K

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support
  2010-11-21 11:05       ` [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug Gérald Kerma
@ 2010-11-21 11:06         ` Gérald Kerma
  2010-11-21 15:36           ` Prafulla Wadaskar
  2010-11-21 11:07         ` [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
  2010-11-21 11:08         ` [U-Boot] [PATCH v3 3/3] Sheevaplug: Add MMC/SDIO support Gérald Kerma
  2 siblings, 1 reply; 22+ messages in thread
From: Gérald Kerma @ 2010-11-21 11:06 UTC (permalink / raw)
  To: u-boot


    pre-requisite for SDIO driver support for Marvell SoCs (Kirkwood)

Signed-off-by: G?rald Kerma <geraker@gmail.com>
---
 arch/arm/include/asm/arch-kirkwood/kirkwood.h |    1 +
 include/configs/mv-common.h                   |    9 +++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
index 0104418..4f9fe7e 100644
--- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
@@ -60,6 +60,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
diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
index de0121e..62ef0b9 100644
--- a/include/configs/mv-common.h
+++ b/include/configs/mv-common.h
@@ -63,6 +63,7 @@

 #define CONFIG_I2C_MVTWSI_BASE	KW_TWSI_BASE
 #define MV_UART0_BASE		KW_UART0_BASE
+#define MV_SDIO_BASE		KW_SDIO_BASE
 #define MV_SATA_BASE		KW_SATA_BASE
 #define MV_SATA_PORT0_OFFSET	KW_SATA_PORT0_OFFSET
 #define MV_SATA_PORT1_OFFSET	KW_SATA_PORT1_OFFSET
@@ -182,6 +183,14 @@
 #endif /* CONFIG_CMD_NET */

 /*
+ * SDIO/MMC Card Configuration
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_MV_SDIO
+#endif /* CONFIG_CMD_MMC */
+
+/*
  * USB/EHCI
  */
 #ifdef CONFIG_CMD_USB
-- 
1.7.1

-- 
G.K

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
  2010-11-21 11:05       ` [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug Gérald Kerma
  2010-11-21 11:06         ` [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support Gérald Kerma
@ 2010-11-21 11:07         ` Gérald Kerma
  2010-11-21 15:31           ` Prafulla Wadaskar
  2010-11-21 11:08         ` [U-Boot] [PATCH v3 3/3] Sheevaplug: Add MMC/SDIO support Gérald Kerma
  2 siblings, 1 reply; 22+ messages in thread
From: Gérald Kerma @ 2010-11-21 11:07 UTC (permalink / raw)
  To: u-boot


    Add SDIO legacy driver for Marvell SoCs (Kirkwood)

Signed-off-by: G?rald Kerma <geraker@gmail.com>
---
v3:
 * GNU Software License compliance
 * Patch more readable

v2:
 * Code cleaning

v1:
 * Fix errors from SD/SDHC detect

---
 drivers/mmc/Makefile  |    1 +
 drivers/mmc/mv_sdio.c |  675
+++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/mv_sdio.h |  313 +++++++++++++++++++++++
 3 files changed, 989 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 68afd30..2a4e1d4 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -30,6 +30,7 @@ COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
+COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c
new file mode 100644
index 0000000..35969d3
--- /dev/null
+++ b/drivers/mmc/mv_sdio.c
@@ -0,0 +1,675 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: G?rald Kerma <geraker@gmail.com>
+ *
+ * (C) Copyright 2003
+ * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <part.h>
+#include <asm/io.h>
+#ifdef CONFIG_KIRKWOOD
+#include <asm/arch/kirkwood.h>
+#endif
+#include "mv_sdio.h"
+
+#ifdef CONFIG_MMC
+
+#define DRIVER_NAME "mv-sdio"
+
+#ifdef DEBUG
+#define pr_debug(fmt, args...) printf(fmt, ##args)
+#else
+#define pr_debug(...) do { } while(0)
+#endif
+
+//static mv_sdio_t *mvsd = (mv_sdio_t *)mmc->priv;
+static mv_sdio_t *mvsd = (mv_sdio_t *)MV_SDIO_BASE;
+	
+static int is_sdhc;
+extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
+static block_dev_desc_t mmc_dev;
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+	return ((block_dev_desc_t *)&mmc_dev);
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+static uchar mmc_buf[MMC_BLOCK_SIZE];
+static mv_mmc_csd_t mv_mmc_csd;
+static int mmc_ready = 0;
+
+/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
+   that expects it to be shifted. */
+static u_int16_t rca = 0;
+
+/* used for debug */
+static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd)
+{
+	u_int32_t block_len, mult, blocknr;
+
+	block_len = csd->read_bl_len << 12;
+	mult = csd->c_size_mult1 << 8;
+	blocknr = (csd->c_size+1) * mult;
+
+	return blocknr * block_len;
+}
+
+static int isprint (unsigned char ch)
+{
+	if (ch >= 32 && ch < 127)
+		return (1);
+
+	return (0);
+}
+
+static int toprint(char *dst, char c)
+{
+	if (isprint(c)) {
+		*dst = c;
+		return 1;
+	}
+
+	return sprintf(dst,"\\x%02x", c);
+
+}
+
+static void print_mmc_cid(mv_mmc_cid_t *cid)
+{
+	printf("MMC found. Card desciption is:\n");
+	printf("Manufacturer ID = %02x%02x%02x\n",
+		cid->id[0], cid->id[1], cid->id[2]);
+	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
+	cid->hwrev = cid->fwrev = 0;	/* null terminate string */
+	printf("Product Name = %s\n",cid->name);
+	printf("Serial Number = %02x%02x%02x\n",
+		cid->sn[0], cid->sn[1], cid->sn[2]);
+	printf("Month = %d\n",cid->month);
+	printf("Year = %d\n",1997 + cid->year);
+}
+
+static void print_sd_cid(mv_sd_cid_t *cid)
+{
+	int len;
+	char tbuf[64];
+
+	printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":"");
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->oid_0);
+	len += toprint(&tbuf[len], cid->oid_1);
+	tbuf[len] = 0;
+
+	printf("Manufacturer:       0x%02x, OEM \"%s\"\n",
+	    cid->mid, tbuf);
+
+	len = 0;
+	len += toprint(&tbuf[len], cid->pnm_0);
+	len += toprint(&tbuf[len], cid->pnm_1);
+	len += toprint(&tbuf[len], cid->pnm_2);
+	len += toprint(&tbuf[len], cid->pnm_3);
+	len += toprint(&tbuf[len], cid->pnm_4);
+	tbuf[len] = 0;
+
+	printf("Product name:       \"%s\", revision %d.%d\n",
+		tbuf,
+	    cid->prv >> 4, cid->prv & 15);
+
+	printf("Serial number:      %u\n",
+	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
+	    cid->psn_3);
+	printf("Manufacturing date: %d/%d\n",
+	    cid->mdt_1 & 15,
+	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
+
+	printf("CRC:                0x%02x, b0 = %d\n",
+	    cid->crc >> 1, cid->crc & 1);
+}
+
+static void mvsdio_set_clock(unsigned int clock)
+{
+	unsigned int m;
+
+	m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1;
+
+	pr_debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n",
+		      m, clock);
+
+
+	writew(m & 0x7ff, &mvsd->CLK_DIV);
+
+	if (isprint(1))
+	udelay(10*1000);
+}
+
+/****************************************************/
+static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort
resptype, ushort waittype)
+/****************************************************/
+{
+	static ulong resp[4];
+	ushort done ;
+	int err = 0 ;
+	ulong curr, start, diff, hz;
+	ushort response[8];
+
+	pr_debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n"
+	, (unsigned int)cmd, (unsigned int)arg, xfermode, resptype, waittype);
+
+
+	/* clear status */
+	writew(0xffff, &mvsd->NOR_INTR_STATUS);
+	writew(0xffff, &mvsd->ERR_INTR_STATUS);
+
+	start = get_timer(0);
+	hz = CONFIG_SYS_HZ;
+
+	while((readw(&mvsd->PRESENT_STATE0) & CARD_BUSY)) {
+		curr = get_timer(0);
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			/* 3 seconds timeout, card busy, can't sent cmd */
+			printf("card too busy \n");
+			return 0;
+		}
+	}
+
+	writew((ushort)(arg&0xffff), &mvsd->ARG_LOW);
+	writew((ushort)(arg>>16), &mvsd->ARG_HI);
+	writew(xfermode, &mvsd->XFER_MODE);
+	if( (cmd == MMC_CMD_READ_BLOCK) || (cmd == 25) )
+	{
+		writew(((cmd << 8) | resptype | 0x3c ) , &mvsd->CMD);
+	pr_debug("cmd reg : %x\n", readw(&mvsd->CMD)) ;
+
+	}
+	else
+	{
+		writew(((cmd << 8) | resptype ), &mvsd->CMD);
+	}
+
+	done = readw(&mvsd->NOR_INTR_STATUS) & waittype;
+	start = get_timer(0);
+
+	while( done!=waittype)
+	{
+		done = readw(&mvsd->NOR_INTR_STATUS) & waittype;
+
+		if( readw(&mvsd->NOR_INTR_STATUS) & 0x8000 )
+		{		
+			pr_debug("Error! cmd : %d, err : %04x\n", (unsigned int)cmd,
readw(&mvsd->ERR_INTR_STATUS)) ;
+
+			return 0 ;	/* error happen */
+		}
+
+		curr = get_timer(0);
+		diff = (long) curr - (long) start;
+		if (diff > (3*hz))
+		{
+			pr_debug("cmd timeout, status : %04x\n", readw(&mvsd->NOR_INTR_STATUS));
+			pr_debug("xfer mode : %04x\n", readw(&mvsd->XFER_MODE));
+
+			err = 1 ;
+			break;
+		}
+	}
+
+	response[0] = readw(&mvsd->RSP0);
+	response[1] = readw(&mvsd->RSP1);
+	response[2] = readw(&mvsd->RSP2);
+	response[3] = readw(&mvsd->RSP3);
+	response[4] = readw(&mvsd->RSP4);
+	response[5] = readw(&mvsd->RSP5);
+	response[6] = readw(&mvsd->RSP6);
+	response[7] = readw(&mvsd->RSP7);
+
+	memset(resp, 0, sizeof(resp));
+
+	switch (resptype & 0x3) {
+		case SDIO_CMD_RSP_48:
+		case SDIO_CMD_RSP_48BUSY:
+			resp[0] = ((response[2] & 0x3f) << (8 - 8)) |
+				((response[1] & 0xffff) << (14 - 8)) |
+				((response[0] & 0x3ff) << (30 - 8));
+			resp[1] = ((response[0] & 0xfc00) >> 10);
+			break;
+
+		case SDIO_CMD_RSP_136:
+			resp[3] = ((response[7] & 0x3fff) << 8)	|
+				((response[6] & 0x3ff) << 22);
+			resp[2] = ((response[6] & 0xfc00) >> 10)	|
+				((response[5] & 0xffff) << 6)	|
+				((response[4] & 0x3ff) << 22);
+			resp[1] = ((response[4] & 0xfc00) >> 10)	|
+				((response[3] & 0xffff) << 6)	|
+				((response[2] & 0x3ff) << 22);
+			resp[0] = ((response[2] & 0xfc00) >> 10)	|
+				((response[1] & 0xffff) << 6)	|
+				((response[0] & 0x3ff) << 22);
+			break;
+		default:
+			return 0;
+	}
+	int i;
+	pr_debug("MMC resp :");
+	for (i=0; i<4; ++i ) {
+		pr_debug(" %08x", (unsigned int)resp[i]);
+	}
+	pr_debug("\n");
+	if( err )
+		return NULL ;
+	else
+		return resp;
+}
+
+/****************************************************/
+static int mv_mmc_block_read(uchar *dst, ulong src, ulong len)
+/****************************************************/
+{
+	ulong *resp;
+
+	if (len == 0) {
+		return 0;
+	}
+
+	if (is_sdhc) {
+		/* SDHC: use block address */
+		src >>= 9;
+	}
+
+	pr_debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src,
(int)len);
+
+	/* prepare for dma transfer */
+	writew(((ulong)(dst))&0xffff,&mvsd->SYS_ADDR_LOW);
+	writew(((ulong)(dst)>>16)&0xffff,&mvsd->SYS_ADDR_HI);
+	writew(len,&mvsd->BLK_SIZE);
+	writew(1,&mvsd->BLK_COUNT);
+	
+	/* send read command */
+	resp = mv_mmc_cmd(MMC_CMD_READ_BLOCK, src, 0x10 ,
+			SDIO_CMD_RSP_48, SDIO_NOR_XFER_DONE);
+	if (!resp) {
+		pr_debug("mv_mmc_block_read: mmc read block cmd fails\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/****************************************************/
+int mv_mmc_read(ulong src, uchar *dst, int size)
+/****************************************************/
+{
+	ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+	ulong mmc_block_size, mmc_block_address;
+
+	if (size == 0) {
+		return 0;
+	}
+
+	if (!mmc_ready) {
+		printf("Please initial the MMC first\n");
+		return -1;
+	}
+
+	mmc_block_size = MMC_BLOCK_SIZE;
+	mmc_block_address = ~(mmc_block_size - 1);
+
+	end = src + size;
+	part_start = ~mmc_block_address & src;
+	part_end = ~mmc_block_address & end;
+	aligned_start = mmc_block_address & src;
+	aligned_end = mmc_block_address & end;
+
+	/* all block aligned accesses */
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_start) {
+		part_len = mmc_block_size - part_start;
+		pr_debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf+part_start, part_len);
+		dst += part_len;
+		src += part_len;
+	}
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	for (; src < aligned_end; aligned_start +=mmc_block_size, src +=
mmc_block_size, dst += mmc_block_size) {
+		pr_debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) {
+		 	printf("mmc block read error\n");
+			return -1;
+		}
+		memcpy(dst, mmc_buf, mmc_block_size);
+	}
+	pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend
%lx\n",
+	(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+	if (part_end && src < end) {
+		pr_debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx
aend %lx\n",
+		(long unsigned int)src,(ulong)dst, end, part_start, part_end,
aligned_start, aligned_end);
+
+		if ((mv_mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) {
+			return -1;
+		}
+		memcpy(dst, mmc_buf, part_end);
+	}
+	return 0;
+}
+
+/****************************************************/
+static ulong mv_mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong
*dst)
+/****************************************************/
+{
+	int mmc_block_size = MMC_BLOCK_SIZE;
+	ulong src = blknr * mmc_block_size;
+
+	mv_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size);
+	return blkcnt;
+}
+
+/****************************************************/
+int mmc_legacy_init(int verbose)
+/****************************************************/
+{
+	int retries, rc = -ENODEV;
+	ulong *resp;
+	int sd_ver20;
+	int is_sd;
+	ushort reg;
+	uchar cidbuf[64];
+
+	sd_ver20 = 0;
+	is_sdhc = 0;
+	is_sd = 0;
+
+	/* Initial Host Ctrl : Timeout : max , Normal Speed mode, 4-bit data
mode */
+	/* Big Endian, SD memory Card, Push_pull CMD Line */
+	writew( SDIO_HOST_CTRL_TMOUT(0xf) |
+		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->HOST_CTRL);
+
+	writew( 0, &mvsd->CLK_CTRL);
+
+	/* enable status */
+	writew( 0xffff, &mvsd->NOR_STATUS_EN);
+	writew( 0xffff, &mvsd->ERR_STATUS_EN);
+
+	/* disable interrupts */
+	writew( 0, &mvsd->NOR_INTR_EN);
+	writew( 0, &mvsd->ERR_INTR_EN);
+
+	writew( 0x100, &mvsd->SW_RESET);
+	udelay(10000);
+
+	mv_mmc_csd.c_size = 0;
+
+	/* reset */
+	retries = 10;
+	resp = mv_mmc_cmd(0, 0, 0, SDIO_CMD_RSP_NONE, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 0 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	pr_debug ("trying to detect SD card version\n");
+
+	resp = mv_mmc_cmd(8, 0x000001aa, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 8 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp && (resp[0] & 0x1ff)==0x1aa) {
+		pr_debug ("SD version 2.0 card detected\n");
+
+		sd_ver20 = 1;
+	}
+
+	if (sd_ver20)
+		retries = 50;
+	else
+		retries = 10;
+
+	while (retries--) {
+		resp = mv_mmc_cmd(55, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		pr_debug("cmd 55 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (sd_ver20)
+			resp = mv_mmc_cmd(41, 0x40300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		else
+			resp = mv_mmc_cmd(41, 0x00300000, 0,  SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+
+		pr_debug("cmd 41 resp : %08x %08x %08x %08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+		if (resp && (resp[0] & 0x80000000)) {
+			pr_debug ("detected SD card\n");
+
+			is_sd = 1;
+			break;
+		}
+
+		udelay(100*1000);
+	}
+
+	if (retries <= 0 && !is_sd) {
+		pr_debug ("failed to detect SD card, trying MMC\n");
+
+		retries = 10;
+		while (retries--) {
+			resp = mv_mmc_cmd(1, 0, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+			pr_debug("cmd 01 resp : %08x %08x %08x %08x\n",
+			(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+			if (resp && (resp[0] & 0x80000000)) {
+				printf ("detected MMC card\n");
+				reg = readw(&mvsd->HOST_CTRL);
+				reg &= ~(0x3<<1);
+				reg |= SDIO_HOST_CTRL_CARD_TYPE_IO_MMC;
+				writew( reg, &mvsd->HOST_CTRL);
+				break;
+			}
+
+			udelay(100*1000);
+		}
+	}
+		
+	if (retries <= 0) {
+		pr_debug ("detect fails\n");
+
+		return -ENODEV;
+	}
+
+	/* try to get card id */
+	resp = mv_mmc_cmd(2, 0, 0, SDIO_CMD_RSP_136, SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 2 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (resp == NULL) {
+		pr_debug ("read cid fails\n");
+
+		return -ENODEV;
+	}
+
+	if (is_sd) {
+		mv_sd_cid_t *cid = (mv_sd_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x OEM %c%c \"%c%c%c%c%c\"",
+			cid->mid, cid->oid_0, cid->oid_1,
+			cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4);
+
+		sprintf((char *) mmc_dev.product, "%d",
+			(cid->psn_0 << 24) | (cid->psn_1 <<16) | (cid->psn_2 << 8) |
(cid->psn_3 << 8));
+		
+		sprintf((char *) mmc_dev.revision, "%d.%d", cid->prv>>4, cid->prv &
0xff);
+		
+	} else {
+		/* TODO configure mmc driver depending on card attributes */
+		mv_mmc_cid_t *cid = (mv_mmc_cid_t *) resp;
+
+		memcpy(cidbuf, resp, sizeof(mv_sd_cid_t));
+
+
+		sprintf((char *) mmc_dev.vendor,
+			"Man %02x%02x%02x Snr %02x%02x%02x",
+			cid->id[0], cid->id[1], cid->id[2],
+			cid->sn[0], cid->sn[1], cid->sn[2]);
+		sprintf((char *) mmc_dev.product, "%s", cid->name);
+		sprintf((char *) mmc_dev.revision, "%x %x", cid->hwrev, cid->fwrev);
+	}
+	
+	/* fill in device description */
+	mmc_dev.if_type = IF_TYPE_MMC;
+	mmc_dev.part_type = PART_TYPE_DOS;
+	mmc_dev.dev = 0;
+	mmc_dev.lun = 0;
+	mmc_dev.type = 0;
+
+	/* FIXME fill in the correct size (is set to 128MByte) */
+	mmc_dev.blksz = MMC_BLOCK_SIZE;
+	mmc_dev.lba = 0x10000;
+
+	mmc_dev.removable = 0;
+	mmc_dev.block_read = (unsigned long) mv_mmc_bread;
+
+	/* MMC exists, get CSD too */
+	resp = mv_mmc_cmd(MMC_CMD_SET_RCA, 0, 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+	if (resp == NULL) {
+		pr_debug ("set rca fails\n");
+
+		return -ENODEV;
+	}
+	pr_debug("cmd3 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	if (is_sd)
+		rca = resp[0] >> 16;
+	else
+		rca = 0;
+
+	resp = mv_mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, 0,
SDIO_CMD_RSP_136,SDIO_NOR_CMD_DONE );
+	pr_debug("cmd 9 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+	if (resp == NULL) {
+		pr_debug ("read csd fails\n");
+
+		return -ENODEV;
+	}
+
+	memcpy(&mv_mmc_csd, (mv_mmc_csd_t *) resp, sizeof(mv_mmc_csd_t));
+	rc = 0;
+	mmc_ready = 1;
+
+	/* FIXME add verbose printout for csd */
+	pr_debug ("size = %u\n", mv_mmc_size(&mv_mmc_csd));
+
+
+	resp = mv_mmc_cmd(7, rca<<16, 0, SDIO_CMD_RSP_48BUSY, SDIO_NOR_CMD_DONE);
+	if (resp == NULL) {
+		pr_debug ("select card fails\n");
+
+		return -ENODEV;
+	}
+	pr_debug("cmd 7 resp : %08x %08x %08x %08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3] );
+
+
+	if (is_sd) {
+		resp = mv_mmc_cmd(55, rca<<16, 0,  SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			pr_debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+		pr_debug("cmd55 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+		resp = mv_mmc_cmd(6, (rca<<16) | 0x2 , 0, SDIO_CMD_RSP_48,
SDIO_NOR_CMD_DONE );
+		if (resp == NULL) {
+			pr_debug ("cmd55 fails\n");
+
+			return -ENODEV;
+		}
+	pr_debug("cmd6 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+	}
+
+	resp = (ulong *) &mv_mmc_csd;
+	pr_debug("csd: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+	(unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2],
(unsigned int)resp[3]);
+
+
+	/* check SDHC */
+	if ((resp[0]&0xf0000000)==0x40000000)
+		is_sdhc = 1;
+
+	/* set block len */
+	resp = mv_mmc_cmd(MMC_CMD_SET_BLOCKLEN, MMC_BLOCK_SIZE, 0,
SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE );
+	if (!resp) {
+		pr_debug("mv_mmc_block_read: set blk len fails\n");
+	 	return -ENODEV;
+	}
+
+	if (verbose) {
+		if (is_sd)
+			print_sd_cid((mv_sd_cid_t *) cidbuf);
+		else
+			print_mmc_cid((mv_mmc_cid_t *) cidbuf);
+	}
+
+	mvsdio_set_clock(CONFIG_SYS_MMC_CLK_PP);
+
+	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
+
+	return 0;
+}
+
+#endif	/* CONFIG_MMC */
diff --git a/drivers/mmc/mv_sdio.h b/drivers/mmc/mv_sdio.h
new file mode 100644
index 0000000..3383c3d
--- /dev/null
+++ b/drivers/mmc/mv_sdio.h
@@ -0,0 +1,313 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Written-by: G?rald Kerma <geraker@gmail.com>
+ *
+ * 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 _MVSDIO_INCLUDE
+#define _MVSDIO_INCLUDE
+
+//#define SDIO_REG(x) (MV_SDIO_BASE + (x))
+
+#define MVSDMMC_DMA_SIZE			65536
+#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX			50000000
+#define MVSD_BASE_DIV_MAX			0x7ff
+
+#define CONFIG_SYS_MMC_CLK_PP			25000000
+
+/*
+ * The base MMC clock rate
+ */
+
+#define MVSDMMC_CLOCKRATE_MIN			100000
+#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
+#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
+
+
+/*
+ * SDIO register
+ */
+#ifndef __ASSEMBLY__
+
+/*
+ * Structure for struct SoC access.
+ * Names starting with '_' are fillers.
+ */
+typedef struct mv_sdio {
+	/*	reg			Offset */
+	u32	SYS_ADDR_LOW;		/* 0x00 */
+	u32	SYS_ADDR_HI;		/* 0x04 */
+	u32	BLK_SIZE;		/* 0x08 */
+	u32	BLK_COUNT;		/* 0x0c */
+	u32	ARG_LOW;		/* 0x10 */
+	u32	ARG_HI;			/* 0x14 */
+	u32	XFER_MODE;		/* 0x18 */
+	u32	CMD;			/* 0x1c */
+	u32	RSP0;			/* 0x20 */
+	u32	RSP1;			/* 0x24 */
+	u32	RSP2;			/* 0x28 */
+	u32	RSP3;			/* 0x2c */
+	u32	RSP4;			/* 0x30 */
+	u32	RSP5;			/* 0x34 */
+	u32	RSP6;			/* 0x38 */
+	u32	RSP7;			/* 0x3c */
+	u32	BUF_DATA_PORT;		/* 0x40 */
+	u32	RSVED;			/* 0x44 */
+	u32	PRESENT_STATE0;		/* 0x48 */
+	u32	PRESENT_STATE1;		/* 0x4c */
+	u32	HOST_CTRL;		/* 0x50 */
+	u32	BLK_GAP_CTRL;		/* 0x54 */
+	u32	CLK_CTRL;		/* 0x58 */
+	u32	SW_RESET;		/* 0x5c */
+	u32	NOR_INTR_STATUS;	/* 0x60 */
+	u32	ERR_INTR_STATUS;	/* 0x64 */
+	u32	NOR_STATUS_EN;		/* 0x68 */
+	u32	ERR_STATUS_EN;		/* 0x6c */
+	u32	NOR_INTR_EN;		/* 0x70 */
+	u32	ERR_INTR_EN;		/* 0x74 */
+	u32	AUTOCMD12_ERR_STATUS;	/* 0x78 */
+	u32	CURR_BYTE_LEFT;		/* 0x7c */
+	u32	CURR_BLK_LEFT;		/* 0x80 */
+	u32	AUTOCMD12_ARG_LOW;	/* 0x84 */
+	u32	AUTOCMD12_ARG_HI;	/* 0x88 */
+	u32	AUTOCMD12_INDEX;	/* 0x8c */
+	u32	AUTO_RSP0;		/* 0x90 */
+	u32	AUTO_RSP1;		/* 0x94 */
+	u32	AUTO_RSP2;		/* 0x98 */
+	u32	_9c;			/* 0x9c */
+	u32	_a0[0x78];		/* 0xa0 */
+	u32	CLK_DIV;		/* 0x128 */
+
+} mv_sdio_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * 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)
+
+
+/*
+ * 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)
+
+
+/*
+ * 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_ID_MODE_LOW_FREQ 	(1 << 5)
+#define SDIO_HOST_CTRL_HALF_SPEED 		(1 << 6)
+#define SDIO_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define SDIO_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+
+#define SDIO_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT_MAX 		(0xf << 11)
+#define SDIO_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define SDIO_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+#define SDIO_HOST_CTRL_DFAULT_OPEN_DRAIN 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf))
+#define SDIO_HOST_CTRL_DFAULT_PUSH_PULL 	\
+		(SDIO_HOST_CTRL_TMOUT(x)(0xf) | SDIO_HOST_CTRL_PUSH_PULL_EN)
+
+
+/*
+ * NOR 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)
+
+
+/*
+ * ERR 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_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_ERR_INTR_MASK			0xFFFF
+
+
+#define MMC_BLOCK_SIZE                  512
+#define MMC_CMD_RESET                   0
+#define MMC_CMD_SEND_OP_COND            1
+#define MMC_CMD_ALL_SEND_CID            2
+#define MMC_CMD_SET_RCA                 3
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_CSD                9
+#define MMC_CMD_SEND_CID                10
+#define MMC_CMD_SEND_STATUS             13
+#define MMC_CMD_SET_BLOCKLEN            16
+#define MMC_CMD_READ_BLOCK              17
+#define MMC_CMD_RD_BLK_MULTI            18
+#define MMC_CMD_WRITE_BLOCK             24
+#define MMC_MAX_BLOCK_SIZE              512
+
+typedef struct mv_mmc_cid
+{
+	/* FIXME: BYTE_ORDER */
+	uchar year:4,
+	month:4;
+	uchar sn[3];
+	uchar fwrev:4,
+	hwrev:4;
+	uchar name[6];
+	uchar id[3];
+} mv_mmc_cid_t;
+
+typedef struct mv_mmc_csd
+{
+	uchar   ecc:2,
+		file_format:2,
+		tmp_write_protect:1,
+		perm_write_protect:1,
+		copy:1,
+		file_format_grp:1;
+	uint64_t content_prot_app:1,
+		rsvd3:4,
+		write_bl_partial:1,
+		write_bl_len:4,
+		r2w_factor:3,
+		default_ecc:2,
+		wp_grp_enable:1,
+		wp_grp_size:5,
+		erase_grp_mult:5,
+		erase_grp_size:5,
+		c_size_mult1:3,
+		vdd_w_curr_max:3,
+		vdd_w_curr_min:3,
+		vdd_r_curr_max:3,
+		vdd_r_curr_min:3,
+		c_size:12,
+		rsvd2:2,
+		dsr_imp:1,
+		read_blk_misalign:1,
+		write_blk_misalign:1,
+		read_bl_partial:1;
+	ushort  read_bl_len:4,
+		ccc:12;
+	uchar   tran_speed;
+	uchar   nsac;
+	uchar   taac;
+	uchar   rsvd1:2,
+		spec_vers:4,
+		csd_structure:2;
+} mv_mmc_csd_t;
+
+typedef struct {
+	char		pnm_0;	/* product name */
+	char		oid_1;	/* OEM/application ID */
+	char		oid_0;
+	uint8_t		mid;	/* manufacturer ID */
+	char		pnm_4;
+	char		pnm_3;
+	char		pnm_2;
+	char		pnm_1;
+	uint8_t		psn_2;	/* product serial number */
+	uint8_t		psn_1;
+	uint8_t		psn_0;	/* MSB */
+	uint8_t		prv;	/* product revision */
+	uint8_t		crc;	/* CRC7 checksum, b0 is unused and set to 1 */
+	uint8_t		mdt_1;	/* manufacturing date, LSB, RRRRyyyy yyyymmmm */
+	uint8_t		mdt_0;	/* MSB */
+	uint8_t		psn_3;	/* LSB */
+} mv_sd_cid_t;
+
+#endif /* _MVSDIO_INCLUDE */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 3/3] Sheevaplug: Add MMC/SDIO support
  2010-11-21 11:05       ` [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug Gérald Kerma
  2010-11-21 11:06         ` [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support Gérald Kerma
  2010-11-21 11:07         ` [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
@ 2010-11-21 11:08         ` Gérald Kerma
  2 siblings, 0 replies; 22+ messages in thread
From: Gérald Kerma @ 2010-11-21 11:08 UTC (permalink / raw)
  To: u-boot


    Add MMC-SDIO support for Sheevaplug

Signed-off-by: G?rald Kerma <geraker@gmail.com>
---
 include/configs/sheevaplug.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h
index 83dd8ff..5448718 100644
--- a/include/configs/sheevaplug.h
+++ b/include/configs/sheevaplug.h
@@ -1,3 +1,4 @@
+
 /*
  * (C) Copyright 2009
  * Marvell Semiconductor <www.marvell.com>
@@ -47,6 +48,7 @@
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_USB
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
  2010-11-21 11:07         ` [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
@ 2010-11-21 15:31           ` Prafulla Wadaskar
  0 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-21 15:31 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Sunday, November 21, 2010 4:38 PM
> To: u-boot at lists.denx.de
> Cc: Prafulla Wadaskar; Ashish Karkare; Prabhanjan Sarnaik
> Subject: [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood)
> 
> 
>     Add SDIO legacy driver for Marvell SoCs (Kirkwood)
> 
> Signed-off-by: G?rald Kerma <geraker@gmail.com>
> ---
> v3:
>  * GNU Software License compliance
>  * Patch more readable
> 
> v2:
>  * Code cleaning
> 
> v1:
>  * Fix errors from SD/SDHC detect
> 
> ---
>  drivers/mmc/Makefile  |    1 +
>  drivers/mmc/mv_sdio.c |  675
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/mmc/mv_sdio.h |  313 +++++++++++++++++++++++

Can you make use of drivers/mmc/mmc.c to reduce code in this file?

>  3 files changed, 989 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index 68afd30..2a4e1d4 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -30,6 +30,7 @@ COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
>  COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
>  COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
>  COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
> +COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o
>  COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
>  COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
>  COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
> diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c
> new file mode 100644
> index 0000000..35969d3
> --- /dev/null
> +++ b/drivers/mmc/mv_sdio.c
> @@ -0,0 +1,675 @@
> +/*
> + * (C) Copyright 2009

It should be 2010

> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: G?rald Kerma <geraker@gmail.com>
> + *
> + * (C) Copyright 2003
> + * Kyle Harris, Nexus Technologies, Inc. kharris at nexus-tech.net

Are these two lines required here?

> + *
> + * 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
> + */
> +
> +#include <config.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <mmc.h>
> +#include <asm/errno.h>
> +#include <part.h>
> +#include <asm/io.h>
> +#ifdef CONFIG_KIRKWOOD
> +#include <asm/arch/kirkwood.h>
> +#endif
> +#include "mv_sdio.h"
> +
> +#ifdef CONFIG_MMC
> +
> +#define DRIVER_NAME "mv-sdio"
> +
> +#ifdef DEBUG
> +#define pr_debug(fmt, args...) printf(fmt, ##args)
> +#else
> +#define pr_debug(...) do { } while(0)
> +#endif

Please remove all above and simply use debug macros instead of pr_debug in your code, that will make it simple and in sync with other drivers

> +
> +//static mv_sdio_t *mvsd = (mv_sdio_t *)mmc->priv;
> +static mv_sdio_t *mvsd = (mv_sdio_t *)MV_SDIO_BASE;
> +
> +static int is_sdhc;
> +extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no);
> +static block_dev_desc_t mmc_dev;
> +block_dev_desc_t * mmc_get_dev(int dev)
> +{
> +	return ((block_dev_desc_t *)&mmc_dev);
> +}
> +
> +/*
> + * FIXME needs to read cid and csd info to determine block size
> + * and other parameters
> + */
> +static uchar mmc_buf[MMC_BLOCK_SIZE];
> +static mv_mmc_csd_t mv_mmc_csd;
> +static int mmc_ready = 0;
> +
> +/* MMC_DEFAULT_RCA should probably be just 1, but this may break other
> code
> +   that expects it to be shifted. */
> +static u_int16_t rca = 0;
> +
> +/* used for debug */
> +static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd)
> +{
> +	u_int32_t block_len, mult, blocknr;
> +
> +	block_len = csd->read_bl_len << 12;
> +	mult = csd->c_size_mult1 << 8;
> +	blocknr = (csd->c_size+1) * mult;
> +
> +	return blocknr * block_len;
> +}
> +
> +static int isprint (unsigned char ch)
> +{
> +	if (ch >= 32 && ch < 127)
> +		return (1);
> +
> +	return (0);
> +}
> +
> +static int toprint(char *dst, char c)
> +{
> +	if (isprint(c)) {
> +		*dst = c;
> +		return 1;
> +	}
> +
> +	return sprintf(dst,"\\x%02x", c);
> +
> +}
> +
> +static void print_mmc_cid(mv_mmc_cid_t *cid)
> +{
> +	printf("MMC found. Card desciption is:\n");
> +	printf("Manufacturer ID = %02x%02x%02x\n",
> +		cid->id[0], cid->id[1], cid->id[2]);
> +	printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
> +	cid->hwrev = cid->fwrev = 0;	/* null terminate string */
> +	printf("Product Name = %s\n",cid->name);
> +	printf("Serial Number = %02x%02x%02x\n",
> +		cid->sn[0], cid->sn[1], cid->sn[2]);
> +	printf("Month = %d\n",cid->month);
> +	printf("Year = %d\n",1997 + cid->year);
> +}
> +
> +static void print_sd_cid(mv_sd_cid_t *cid)
> +{
> +	int len;
> +	char tbuf[64];
> +
> +	printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":"");
> +
> +	len = 0;
> +	len += toprint(&tbuf[len], cid->oid_0);
> +	len += toprint(&tbuf[len], cid->oid_1);
> +	tbuf[len] = 0;
> +
> +	printf("Manufacturer:       0x%02x, OEM \"%s\"\n",
> +	    cid->mid, tbuf);
> +
> +	len = 0;
> +	len += toprint(&tbuf[len], cid->pnm_0);
> +	len += toprint(&tbuf[len], cid->pnm_1);
> +	len += toprint(&tbuf[len], cid->pnm_2);
> +	len += toprint(&tbuf[len], cid->pnm_3);
> +	len += toprint(&tbuf[len], cid->pnm_4);
> +	tbuf[len] = 0;
> +
> +	printf("Product name:       \"%s\", revision %d.%d\n",
> +		tbuf,
> +	    cid->prv >> 4, cid->prv & 15);
> +
> +	printf("Serial number:      %u\n",
> +	    cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
> +	    cid->psn_3);
> +	printf("Manufacturing date: %d/%d\n",
> +	    cid->mdt_1 & 15,
> +	    2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
> +
> +	printf("CRC:                0x%02x, b0 = %d\n",
> +	    cid->crc >> 1, cid->crc & 1);
> +}
> +
> +static void mvsdio_set_clock(unsigned int clock)
> +{
> +	unsigned int m;
> +
> +	m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1;
> +
> +	pr_debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n",
> +		      m, clock);
> +
> +
> +	writew(m & 0x7ff, &mvsd->CLK_DIV);
> +
> +	if (isprint(1))
> +	udelay(10*1000);
> +}
> +
> +/****************************************************/
> +static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort
> resptype, ushort waittype)
> +/****************************************************/
> +{
> +	static ulong resp[4];
> +	ushort done ;
> +	int err = 0 ;
> +	ulong curr, start, diff, hz;
> +	ushort response[8];
> +
> +	pr_debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n"
> +	, (unsigned int)cmd, (unsigned int)arg, xfermode, resptype,
> waittype);
> +
> +
> +	/* clear status */
> +	writew(0xffff, &mvsd->NOR_INTR_STATUS);

It looks ugly register names in upper case, please define them in lowercase

...snip...
> +#endif	/* CONFIG_MMC */
> diff --git a/drivers/mmc/mv_sdio.h b/drivers/mmc/mv_sdio.h
> new file mode 100644
> index 0000000..3383c3d
> --- /dev/null
> +++ b/drivers/mmc/mv_sdio.h
> @@ -0,0 +1,313 @@
> +/*
> + * (C) Copyright 2009


Ditto

> + * Marvell Semiconductor <www.marvell.com>
> + * Written-by: G?rald Kerma <geraker@gmail.com>
> + *
> + * 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 _MVSDIO_INCLUDE
> +#define _MVSDIO_INCLUDE
> +
> +//#define SDIO_REG(x) (MV_SDIO_BASE + (x))

Please remove dead code

> +
> +#define MVSDMMC_DMA_SIZE			65536
> +#define MVSDMMC_CMD_TIMEOUT			2 /* 100 usec*/
> +
> +/*
> + * Clock rates
> + */
> +
> +#define MVSD_CLOCKRATE_MAX			50000000

Please maintain common syntax between all definations.

I suggest to to prefix MVSD for all macros and avoid MVSDMMC and MMC

> +#define MVSD_BASE_DIV_MAX			0x7ff
> +
> +#define CONFIG_SYS_MMC_CLK_PP			25000000
> +
> +/*
> + * The base MMC clock rate
> + */
> +
> +#define MVSDMMC_CLOCKRATE_MIN			100000
> +#define MVSDMMC_CLOCKRATE_MAX			MVSD_CLOCKRATE_MAX
> +#define MVSDMMC_BASE_FAST_CLOCK			CONFIG_SYS_TCLK
> +
> +
> +/*
> + * SDIO register
> + */
> +#ifndef __ASSEMBLY__

Do you need this, is this file get called from any assembly code?

> +
> +/*
> + * Structure for struct SoC access.
> + * Names starting with '_' are fillers.
> + */
> +typedef struct mv_sdio {

Better to use simple c-struct, avoid typedefs so far it is possible

> +	/*	reg			Offset */
> +	u32	SYS_ADDR_LOW;		/* 0x00 */

Please use lowercase 

> +	u32	SYS_ADDR_HI;		/* 0x04 */
> +	u32	BLK_SIZE;		/* 0x08 */
> +	u32	BLK_COUNT;		/* 0x0c */
> +	u32	ARG_LOW;		/* 0x10 */
> +	u32	ARG_HI;			/* 0x14 */
> +	u32	XFER_MODE;		/* 0x18 */
> +	u32	CMD;			/* 0x1c */
> +	u32	RSP0;			/* 0x20 */
> +	u32	RSP1;			/* 0x24 */
> +	u32	RSP2;			/* 0x28 */
> +	u32	RSP3;			/* 0x2c */
> +	u32	RSP4;			/* 0x30 */
> +	u32	RSP5;			/* 0x34 */
> +	u32	RSP6;			/* 0x38 */
> +	u32	RSP7;			/* 0x3c */
> +	u32	BUF_DATA_PORT;		/* 0x40 */
> +	u32	RSVED;			/* 0x44 */
> +	u32	PRESENT_STATE0;		/* 0x48 */
> +	u32	PRESENT_STATE1;		/* 0x4c */
> +	u32	HOST_CTRL;		/* 0x50 */
> +	u32	BLK_GAP_CTRL;		/* 0x54 */
> +	u32	CLK_CTRL;		/* 0x58 */
> +	u32	SW_RESET;		/* 0x5c */
> +	u32	NOR_INTR_STATUS;	/* 0x60 */
> +	u32	ERR_INTR_STATUS;	/* 0x64 */
> +	u32	NOR_STATUS_EN;		/* 0x68 */
> +	u32	ERR_STATUS_EN;		/* 0x6c */
> +	u32	NOR_INTR_EN;		/* 0x70 */
> +	u32	ERR_INTR_EN;		/* 0x74 */
> +	u32	AUTOCMD12_ERR_STATUS;	/* 0x78 */
> +	u32	CURR_BYTE_LEFT;		/* 0x7c */
> +	u32	CURR_BLK_LEFT;		/* 0x80 */
> +	u32	AUTOCMD12_ARG_LOW;	/* 0x84 */
> +	u32	AUTOCMD12_ARG_HI;	/* 0x88 */
> +	u32	AUTOCMD12_INDEX;	/* 0x8c */
> +	u32	AUTO_RSP0;		/* 0x90 */
> +	u32	AUTO_RSP1;		/* 0x94 */
> +	u32	AUTO_RSP2;		/* 0x98 */
> +	u32	_9c;			/* 0x9c */
> +	u32	_a0[0x78];		/* 0xa0 */

You should use pad0, pad1[xx] here instead of _9c

> +	u32	CLK_DIV;		/* 0x128 */
> +
> +} mv_sdio_t;
> +
> +#endif /* __ASSEMBLY__ */
> +
> +/*
> + * 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)


MVSD_ as suggested above is better to use for SDIO_

Once again check if you can use code from drives/mmc/mmc.c enabling CONFIG_GENERIC_MMC


Regards..
Prafulla .. 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support
  2010-11-21 11:06         ` [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support Gérald Kerma
@ 2010-11-21 15:36           ` Prafulla Wadaskar
  0 siblings, 0 replies; 22+ messages in thread
From: Prafulla Wadaskar @ 2010-11-21 15:36 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: G?rald Kerma [mailto:geraker at gmail.com]
> Sent: Sunday, November 21, 2010 4:37 PM
> To: u-boot at lists.denx.de
> Cc: Prafulla Wadaskar; Ashish Karkare; Prabhanjan Sarnaik
> Subject: [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support
> 
> 
>     pre-requisite for SDIO driver support for Marvell SoCs (Kirkwood)
> 
> Signed-off-by: G?rald Kerma <geraker@gmail.com>
> ---
>  arch/arm/include/asm/arch-kirkwood/kirkwood.h |    1 +
>  include/configs/mv-common.h                   |    9 +++++++++
>  2 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> index 0104418..4f9fe7e 100644
> --- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> +++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h
> @@ -60,6 +60,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
> diff --git a/include/configs/mv-common.h b/include/configs/mv-common.h
> index de0121e..62ef0b9 100644
> --- a/include/configs/mv-common.h
> +++ b/include/configs/mv-common.h
> @@ -63,6 +63,7 @@
> 
>  #define CONFIG_I2C_MVTWSI_BASE	KW_TWSI_BASE
>  #define MV_UART0_BASE		KW_UART0_BASE
> +#define MV_SDIO_BASE		KW_SDIO_BASE
>  #define MV_SATA_BASE		KW_SATA_BASE
>  #define MV_SATA_PORT0_OFFSET	KW_SATA_PORT0_OFFSET
>  #define MV_SATA_PORT1_OFFSET	KW_SATA_PORT1_OFFSET
> @@ -182,6 +183,14 @@
>  #endif /* CONFIG_CMD_NET */
> 
>  /*
> + * SDIO/MMC Card Configuration
> + */
> +#ifdef CONFIG_CMD_MMC
> +#define CONFIG_MMC

Please check if you can define CONFIG_GENERIC_MMC here and reduce code in driver file.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2010-11-21 15:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-28 22:37 [U-Boot] [PATCH v1] add mv_sdio driver for sheevaplug Gérald Kerma
2010-11-18  1:00 ` Clint Adams
2010-11-18  3:32   ` Prafulla Wadaskar
2010-11-20 11:42   ` Gérald Kerma
2010-11-18  4:04 ` Prafulla Wadaskar
2010-11-19 16:10   ` [U-Boot] [PATCH v2 1/2] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
2010-11-20 21:33     ` Prafulla Wadaskar
2010-11-21 11:05       ` [U-Boot] [PATCH v3 0/3] Add SD/MMC Support to Sheevaplug Gérald Kerma
2010-11-21 11:06         ` [U-Boot] [PATCH v3 1/3] Kirkwood: pre-requisite for SDIO driver support Gérald Kerma
2010-11-21 15:36           ` Prafulla Wadaskar
2010-11-21 11:07         ` [U-Boot] [PATCH v3 2/3] mmc : Add SDIO driver for Marvell SoCs (Kirkwood) Gérald Kerma
2010-11-21 15:31           ` Prafulla Wadaskar
2010-11-21 11:08         ` [U-Boot] [PATCH v3 3/3] Sheevaplug: Add MMC/SDIO support Gérald Kerma
2010-11-19 16:11   ` [U-Boot] [PATCH v2 2/2] " Gérald Kerma
2010-11-19 16:55     ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Gérald Kerma
2010-11-19 16:56       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system Gérald Kerma
2010-11-20 21:32         ` Prafulla Wadaskar
2010-11-20 21:33       ` [U-Boot] [PATCH v2 1/1] Sheevaplug: Add mvsata support Prafulla Wadaskar
2010-11-20 15:17     ` [U-Boot] [PATCH v2 2/2] Sheevaplug: Add MMC/SDIO support Ludovic Courtès
2010-11-20 21:42       ` Prafulla Wadaskar
2010-11-20 21:33     ` Prafulla Wadaskar
  -- strict thread matches above, loose matches on Subject: below --
2010-11-20 21:46 [U-Boot] [PATCH v2 1/1] Sheevaplug: Fix environments for booting retail system Prafulla Wadaskar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox