--- 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