[PATCH] MMC Module

Miles Hsieh miles_hsieh at openmoko.com
Thu Sep 6 11:39:41 CEST 2007


Hello,

I list mmc command sets on uboot as follows,

mmc test (old/new commands)
(1) old command
GTA01Bv4 # mmcinit
(2) new command
GTA01Bv4 # mmc clean
GTA01Bv4 # mmc write
GTA01Bv4 # mmc read

I add mmc "clean", "write", and "read" command , and modify mmc parts in 
uboot.

This patch can test MMC module.

Best regards,
-Miles

------------------------------------------------------------------------


Index: git/common/cmd_mmc.c
===================================================================
--- git.orig/common/cmd_mmc.c	2007-09-06 17:07:08.000000000 +0800
+++ git/common/cmd_mmc.c	2007-09-06 17:07:56.000000000 +0800
@@ -28,7 +28,13 @@
 
 #include <mmc.h>
 
-int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+#define cmd_mmc_write 1
+#define cmd_mmc_read 0
+
+int * tbuf;
+int * rbuf;
+
+int do_mmc_init (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	if (mmc_init (1) != 0) {
 		printf ("No MMC card found\n");
@@ -37,10 +43,107 @@
 	return 0;
 }
 
+int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	if(argc < 2)
+		goto out_help;
+
+	if (mmc_init (0) != 0) {
+		printf ("No MMC card found\n");
+		return 1;
+	}
+
+	if (!strcmp(argv[1], "write")) {
+		mmc_wrblk(cmd_mmc_write, 1);
+	} else if (!strcmp(argv[1], "clean")) {
+		mmc_wrblk(cmd_mmc_write, 0);
+	} else if (!strcmp(argv[1], "read")) {
+		mmc_wrblk(cmd_mmc_read, -1);
+	} else {
+		goto out_help;
+	}
+
+	return 0;
+
+out_help:
+	printf ("Usage:\n%s\n", cmdtp->usage);
+	return 1;
+}
+
+void mmc_wrblk(int cmd, int div)
+{
+	int i,j;
+
+	if(cmd>=1) {
+		printf("[Block write test]\n");
+		mmc_wblk(1,1,div);
+	}
+
+	if(cmd!=1) {
+		rbuf=(int *)0x31800000;
+		printf("[Block read test]\n");
+		mmc_rblk(1,1, rbuf);
+	}
+}
+
+void mmc_rblk(ulong blknr, ulong blkcnt, void *dst)
+{
+	int mmc_block_size = MMC_BLOCK_SIZE;
+	ulong src = blknr * mmc_block_size + CFG_MMC_BASE;
+	int i,j;
+
+	for(i=0;i<blkcnt*mmc_block_size/4;i++)     *(rbuf+i)=0;
+
+	mmc_read(src, dst, blkcnt*mmc_block_size);
+
+	for(i = 0; i < 2; i++)
+	{
+		for( j = 0; j < 16; j++ )
+			printf("%04x ", rbuf[i*16+j]);
+		printf("\n");
+	}
+}
+
+void mmc_wblk(ulong blknr, ulong blkcnt, int div)
+{
+	int i,j;
+	int size= blkcnt * MMC_BLOCK_SIZE;
+	ulong dst =  blknr * MMC_BLOCK_SIZE + CFG_MMC_BASE;
+
+	tbuf=(int *)0x31000000;
+	j=div;
+	for(i=0;i<size/4;i++) {
+		if(div == 0) *(tbuf+i)=0;
+		else *(tbuf+i)=i+j;
+	}
+
+	mmc_write(tbuf, dst, size);
+
+	for(i = 0; i < 2; i++)
+	{
+		for( j = 0; j < 16; j++ )
+			printf("%04x ", tbuf[i*16+j]);
+		printf("\n");
+	}
+
+}
+
+
+
 U_BOOT_CMD(
-	mmcinit,	1,	0,	do_mmc,
+	mmcinit,        1,      0,      do_mmc_init,
 	"mmcinit - init mmc card\n",
-	NULL
+	NULL 
 );
 
+U_BOOT_CMD(
+	mmc,    CFG_MAXARGS,    1,      do_mmc,
+	"mmc  -  write and read mmc card\n",
+	" [write/clean/read] \n"
+	"  clean  - clean block value\n"
+	"  write  - write data to block\n"
+	"  read   - read mmc block\n"
+);
+
+
 #endif	/* CFG_CMD_MMC */
Index: git/cpu/arm920t/s3c24x0/mmc.c
===================================================================
--- git.orig/cpu/arm920t/s3c24x0/mmc.c	2007-09-06 17:08:37.000000000 +0800
+++ git/cpu/arm920t/s3c24x0/mmc.c	2007-09-06 17:09:24.000000000 +0800
@@ -169,20 +169,73 @@
 	}
 
 	debug("waiting for SDIDSTA  (currently 0x%08x\n", sdi->SDIDSTA);
-	while (!(sdi->SDIDSTA & (1 << 4))) {}
+	while (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH)) {
+		/* Wait */
+	}
 	debug("done waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA);
 
 	sdi->SDIDCON = 0;
 
 	if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
-		debug("mmc_block_read; transfer not finished!\n");
+		debug("mmc_block_read: transfer not finished!\n");
 
 	return 0;
 }
 
 static int mmc_block_write(ulong dst, uchar *src, int len)
 {
-	printf("MMC block write not yet supported on S3C2410!\n");
+	u_int32_t dcon, fifo;
+	u_int32_t *src_u32 = (u_int32_t *)src;
+	u_int32_t *resp;
+
+	/* set block len */
+	resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP);
+	sdi->SDIBSIZE = len;
+
+	/* setup data */
+	dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM;
+	dcon |= S3C2410_SDIDCON_BLOCKMODE;
+	dcon |= S3C2410_SDIDCON_TXAFTERRESP|S3C2410_SDIDCON_XFER_TXSTART;
+	if (wide)
+		dcon |= S3C2410_SDIDCON_WIDEBUS;
+#if defined(CONFIG_S3C2440)
+	dcon |= S3C2440_SDIDCON_DS_WORD | S3C2440_SDIDCON_DATSTART;
+#endif
+	sdi->SDIDCON = dcon;
+	sdi->SDICARG = 0x0;
+
+	/* send write command */
+	resp = mmc_cmd(MMC_CMD_WRITE_BLOCK, dst, CMD_F_RESP);
+
+	if (len > 0) {
+		u_int32_t sdidsta = sdi->SDIDSTA;
+		if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL|
+					S3C2410_SDIDSTA_CRCFAIL|
+					S3C2410_SDIDSTA_DATATIMEOUT)) {
+			printf("mmc_block_write: err SDIDSTA=0x%08x\n", sdidsta);
+			return -EIO;
+		}
+
+		while (len > 0) {
+			if((sdi->SDIFSTA & S3C2410_SDIFSTA_TFDET)==S3C2410_SDIFSTA_TFDET) {
+				sdi->SDIDAT = *src_u32++;
+				if (len >= 2)
+					len -= 4;
+				else {
+					len = 0;
+					break;
+				}
+			}
+		}
+	}
+
+	while (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH)) {
+		/* Wait */
+	}
+
+	if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
+		printf("mmc_block_write: transfer not finished!\n");
+
 	return -1;
 }
 
@@ -292,7 +345,6 @@
 		src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
 		if ((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",
 	src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);

-------------- next part --------------
A non-text attachment was scrubbed...
Name: uboot-mmc-modify.patch
Type: text/x-patch
Size: 5064 bytes
Desc: not available
Url : http://lists.openmoko.org/pipermail/openmoko-uboot/attachments/20070906/974e54d6/uboot-mmc-modify.bin


More information about the openmoko-uboot mailing list