[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