---
 cpu/arm920t/s3c24x0/mmc.c      |   67 +++++++++++++++++++++++++++++++++++++++--
 include/asm/arch-s3c24x0/mmc.h |    1 
 include/part.h                 |    1 
 3 files changed, 66 insertions(+), 3 deletions(-)

Index: uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/cpu/arm920t/s3c24x0/mmc.c
===================================================================
--- uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512.orig/cpu/arm920t/s3c24x0/mmc.c	2008-12-01 22:45:55.000000000 +0800
+++ uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/cpu/arm920t/s3c24x0/mmc.c	2008-12-15 07:13:41.000000000 +0800
@@ -33,6 +33,12 @@
 
 #if defined(CONFIG_MMC) && defined(CONFIG_MMC_S3C)
 
+#ifdef DEBUG
+#define pr_debug(fmt, args...) printf(fmt, ##args)
+#else
+#define pr_debug(...) do { } while(0)
+#endif
+
 #define CONFIG_MMC_WIDE
 
 static S3C2410_SDI *sdi;
@@ -57,6 +63,8 @@
 #define CMD_F_RESP	0x01
 #define CMD_F_RESP_LONG	0x02
 
+#define CMD_F_RESP_R7 CMD_F_RESP
+
 static u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags)
 {
 	static u_int32_t resp[5];
@@ -143,7 +151,7 @@
 	sdi->SDIDCON = dcon;
 
 	/* send read command */
-	resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP);
+	resp = mmc_cmd(MMC_CMD_READ_BLOCK, (mmc_dev.if_type == IF_TYPE_SDHC) ? (src >> 9) : src, CMD_F_RESP);
 
 	while (len > 0) {
 		u_int32_t sdidsta = sdi->SDIDSTA;
@@ -390,6 +398,7 @@
 	int is_sd = 0;
 	u_int32_t *resp;
 	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+	block_dev_desc_t *mmc_blkdev_p = &mmc_dev;
 
 	sdi = S3C2410_GetBase_SDI();
 
@@ -417,11 +426,49 @@
 	retries = 10;
 	resp = mmc_cmd(MMC_CMD_RESET, 0, 0);
 
+	mmc_dev.if_type = IF_TYPE_UNKNOWN;
+	if(verbose)
+		puts("mmc: Probing for SDHC ...\n");
+
+	/* Send supported voltage range */
+	/* SD cards 1.x do not answer to CMD8 */
+        resp = mmc_cmd(MMC_CMD_IF_COND, ((1 << 8) | 0xAA), CMD_F_RESP_R7);
+        if (!resp[0]) {
+             /*
+              * ARC: No answer let's try SD 1.x
+              */
+             if(verbose)
+                     puts("mmc: No answer to CMD8 trying SD\n");
+             mmc_blkdev_p->if_type = IF_TYPE_SD;
+        } else {
+             /*
+              * ARC: probably an SDHC card
+              */
+             mmc_blkdev_p->if_type = IF_TYPE_SDHC;
+             if(verbose)
+                     puts("mmc: SD 2.0 or later card found\n");
+
+             /* Check if the card supports this voltage */
+             if (resp[0] != ((1 << 8) | 0xAA)) {
+                     pr_debug("mmc: Invalid voltage range\n");
+                     return -ENODEV;
+             }
+        }
+
+	/*
+	 * ARC: HC (30) bit set according to response to
+	 * CMD8 command
+	 */
+
+	pr_debug("mmc: Sending ACMD41 %s HC set\n",
+		         ((mmc_blkdev_p->if_type ==
+		           IF_TYPE_SDHC) ? "with" : "without"));
+
 	printf("trying to detect SD Card...\n");
 	while (retries--) {
 		udelay(100000);
 		resp = mmc_cmd(55, 0x00000000, CMD_F_RESP);
-		resp = mmc_cmd(41, 0x00300000, CMD_F_RESP);
+		resp = mmc_cmd(41, (mmc_blkdev_p->if_type == IF_TYPE_SDHC)? (0x00300000 | (1<<30)) : 0x00300000, CMD_F_RESP);
 
 		if (resp[0] & (1 << 31)) {
 			is_sd = 1;
@@ -429,9 +476,18 @@
 		}
 	}
 
+	/*
+	* ARC: check for HC bit, if its not set
+	* sd card is SD
+	*/
+	if (is_sd && (resp[0] & 0xc0000000) == 0x80000000) {
+	       mmc_dev.if_type = IF_TYPE_SD;
+	}
+
 	if (retries == 0 && !is_sd) {
 		retries = 10;
 		printf("failed to detect SD Card, trying MMC\n");
+		mmc_blkdev_p->if_type = IF_TYPE_MMC;
 		resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ffc000, CMD_F_RESP);
 		while (retries-- && resp && !(resp[4] & 0x80)) {
 			debug("resp %x %x\n", resp[0], resp[1]);
@@ -476,7 +532,8 @@
 		}
 
 		/* fill in device description */
-		mmc_dev.if_type = IF_TYPE_MMC;
+		if (mmc_dev.if_type == IF_TYPE_UNKNOWN)
+			mmc_dev.if_type = IF_TYPE_MMC;
 		mmc_dev.part_type = PART_TYPE_DOS;
 		mmc_dev.dev = 0;
 		mmc_dev.lun = 0;
@@ -507,6 +564,10 @@
 
 	resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca<<16, CMD_F_RESP);
 
+	if (verbose)
+	       printf("SD Card detected RCA: 0x%x type: %s\n",
+	              rca, ((mmc_dev.if_type == IF_TYPE_SDHC) ? "SDHC" : ((mmc_dev.if_type == IF_TYPE_SD) ? "SD" : "MMC")));
+
 #ifdef CONFIG_MMC_WIDE
 	if (is_sd) {
 		resp = mmc_cmd(55, rca<<16, CMD_F_RESP);
Index: uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/include/asm/arch-s3c24x0/mmc.h
===================================================================
--- uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512.orig/include/asm/arch-s3c24x0/mmc.h	2008-12-01 22:45:55.000000000 +0800
+++ uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/include/asm/arch-s3c24x0/mmc.h	2008-12-01 22:46:15.000000000 +0800
@@ -23,6 +23,7 @@
 #define MMC_CMD_ALL_SEND_CID 		2
 #define MMC_CMD_SET_RCA			3
 #define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_IF_COND                 8
 #define MMC_CMD_SEND_CSD 		9
 #define MMC_CMD_SEND_CID 		10
 #define MMC_CMD_SEND_STATUS		13
Index: uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/include/part.h
===================================================================
--- uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512.orig/include/part.h	2008-12-01 22:49:05.000000000 +0800
+++ uboot-git-650149a53dbdd48bf6dfef90930c8ab182adb512/include/part.h	2008-12-01 22:49:31.000000000 +0800
@@ -62,6 +62,7 @@
 #define IF_TYPE_MMC		6
 #define IF_TYPE_SD		7
 #define IF_TYPE_SATA		8
+#define IF_TYPE_SDHC		9
 
 /* Part types */
 #define PART_TYPE_UNKNOWN	0x00
