Merge branch 'master' of git://git.denx.de/u-boot-mmc

This commit is contained in:
Wolfgang Denk 2009-06-04 10:56:09 +02:00
commit 3bc8556f9b
4 changed files with 52 additions and 41 deletions

View file

@ -135,8 +135,9 @@ int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0; return 0;
} }
U_BOOT_CMD(mmcinfo, 2, 0, do_mmcinfo, "mmcinfo <dev num>-- display MMC info\n", U_BOOT_CMD(mmcinfo, 2, 0, do_mmcinfo,
NULL); "print MMC information",
"<dev num>\n");
int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{ {
@ -148,6 +149,9 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int dev = simple_strtoul(argv[2], NULL, 10); int dev = simple_strtoul(argv[2], NULL, 10);
struct mmc *mmc = find_mmc_device(dev); struct mmc *mmc = find_mmc_device(dev);
if (!mmc)
return 1;
mmc_init(mmc); mmc_init(mmc);
return 0; return 0;
@ -174,6 +178,9 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
u32 blk = simple_strtoul(argv[4], NULL, 16); u32 blk = simple_strtoul(argv[4], NULL, 16);
struct mmc *mmc = find_mmc_device(dev); struct mmc *mmc = find_mmc_device(dev);
if (!mmc)
return 1;
printf("\nMMC read: dev # %d, block # %d, count %d ... ", printf("\nMMC read: dev # %d, block # %d, count %d ... ",
dev, blk, cnt); dev, blk, cnt);
@ -196,6 +203,9 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int blk = simple_strtoul(argv[4], NULL, 16); int blk = simple_strtoul(argv[4], NULL, 16);
if (!mmc)
return 1;
printf("\nMMC write: dev # %d, block # %d, count %d ... ", printf("\nMMC write: dev # %d, block # %d, count %d ... ",
dev, blk, cnt); dev, blk, cnt);
@ -218,8 +228,8 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
U_BOOT_CMD( U_BOOT_CMD(
mmc, 6, 1, do_mmcops, mmc, 6, 1, do_mmcops,
"MMC sub system", "MMC sub system",
"mmc read <device num> addr blk# cnt\n" "read <device num> addr blk# cnt\n"
"mmc write <device num> addr blk# cnt\n" "mmc write <device num> addr blk# cnt\n"
"mmc rescan <device num>\n" "mmc rescan <device num>\n"
"mmc list - lists available devices\n"); "mmc list - list available devices\n");
#endif #endif

View file

@ -206,12 +206,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
cmdrsp2 = in_be32(&regs->cmdrsp2); cmdrsp2 = in_be32(&regs->cmdrsp2);
cmdrsp1 = in_be32(&regs->cmdrsp1); cmdrsp1 = in_be32(&regs->cmdrsp1);
cmdrsp0 = in_be32(&regs->cmdrsp0); cmdrsp0 = in_be32(&regs->cmdrsp0);
((uint *)(cmd->response))[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24); cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
((uint *)(cmd->response))[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24); cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
((uint *)(cmd->response))[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24); cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
((uint *)(cmd->response))[3] = (cmdrsp0 << 8); cmd->response[3] = (cmdrsp0 << 8);
} else } else
((uint *)(cmd->response))[0] = in_be32(&regs->cmdrsp0); cmd->response[0] = in_be32(&regs->cmdrsp0);
/* Wait until all of the blocks are transferred */ /* Wait until all of the blocks are transferred */
if (data) { if (data) {

View file

@ -31,6 +31,7 @@
#include <malloc.h> #include <malloc.h>
#include <linux/list.h> #include <linux/list.h>
#include <mmc.h> #include <mmc.h>
#include <div64.h>
static struct list_head mmc_devices; static struct list_head mmc_devices;
static int cur_dev_num = -1; static int cur_dev_num = -1;
@ -155,8 +156,8 @@ int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size)
char *buffer; char *buffer;
int i; int i;
int blklen = mmc->read_bl_len; int blklen = mmc->read_bl_len;
int startblock = src / blklen; int startblock = lldiv(src, mmc->read_bl_len);
int endblock = (src + size - 1) / blklen; int endblock = lldiv(src + size - 1, mmc->read_bl_len);
int err = 0; int err = 0;
/* Make a buffer big enough to hold all the blocks we might read */ /* Make a buffer big enough to hold all the blocks we might read */
@ -291,7 +292,7 @@ sd_send_op_cond(struct mmc *mmc)
if (mmc->version != SD_VERSION_2) if (mmc->version != SD_VERSION_2)
mmc->version = SD_VERSION_1_0; mmc->version = SD_VERSION_1_0;
mmc->ocr = ((uint *)(cmd.response))[0]; mmc->ocr = cmd.response[0];
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
mmc->rca = 0; mmc->rca = 0;
@ -326,7 +327,7 @@ int mmc_send_op_cond(struct mmc *mmc)
return UNUSABLE_ERR; return UNUSABLE_ERR;
mmc->version = MMC_VERSION_UNKNOWN; mmc->version = MMC_VERSION_UNKNOWN;
mmc->ocr = ((uint *)(cmd.response))[0]; mmc->ocr = cmd.response[0];
mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS); mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
mmc->rca = 0; mmc->rca = 0;
@ -486,8 +487,8 @@ retry_scr:
return err; return err;
} }
mmc->scr[0] = scr[0]; mmc->scr[0] = __be32_to_cpu(scr[0]);
mmc->scr[1] = scr[1]; mmc->scr[1] = __be32_to_cpu(scr[1]);
switch ((mmc->scr[0] >> 24) & 0xf) { switch ((mmc->scr[0] >> 24) & 0xf) {
case 0: case 0:
@ -517,7 +518,7 @@ retry_scr:
return err; return err;
/* The high-speed function is busy. Try again */ /* The high-speed function is busy. Try again */
if (!switch_status[7] & SD_HIGHSPEED_BUSY) if (!(__be32_to_cpu(switch_status[7]) & SD_HIGHSPEED_BUSY))
break; break;
} }
@ -525,7 +526,7 @@ retry_scr:
mmc->card_caps |= MMC_MODE_4BIT; mmc->card_caps |= MMC_MODE_4BIT;
/* If high-speed isn't supported, we return */ /* If high-speed isn't supported, we return */
if (!(switch_status[3] & SD_HIGHSPEED_SUPPORTED)) if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
return 0; return 0;
err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status); err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)&switch_status);
@ -533,7 +534,7 @@ retry_scr:
if (err) if (err)
return err; return err;
if ((switch_status[4] & 0x0f000000) == 0x01000000) if ((__be32_to_cpu(switch_status[4]) & 0x0f000000) == 0x01000000)
mmc->card_caps |= MMC_MODE_HS; mmc->card_caps |= MMC_MODE_HS;
return 0; return 0;
@ -631,7 +632,7 @@ int mmc_startup(struct mmc *mmc)
return err; return err;
if (IS_SD(mmc)) if (IS_SD(mmc))
mmc->rca = (((uint *)(cmd.response))[0] >> 16) & 0xffff; mmc->rca = (cmd.response[0] >> 16) & 0xffff;
/* Get the Card-Specific Data */ /* Get the Card-Specific Data */
cmd.cmdidx = MMC_CMD_SEND_CSD; cmd.cmdidx = MMC_CMD_SEND_CSD;
@ -644,13 +645,13 @@ int mmc_startup(struct mmc *mmc)
if (err) if (err)
return err; return err;
mmc->csd[0] = ((uint *)(cmd.response))[0]; mmc->csd[0] = cmd.response[0];
mmc->csd[1] = ((uint *)(cmd.response))[1]; mmc->csd[1] = cmd.response[1];
mmc->csd[2] = ((uint *)(cmd.response))[2]; mmc->csd[2] = cmd.response[2];
mmc->csd[3] = ((uint *)(cmd.response))[3]; mmc->csd[3] = cmd.response[3];
if (mmc->version == MMC_VERSION_UNKNOWN) { if (mmc->version == MMC_VERSION_UNKNOWN) {
int version = (cmd.response[0] >> 2) & 0xf; int version = (cmd.response[0] >> 26) & 0xf;
switch (version) { switch (version) {
case 0: case 0:
@ -675,17 +676,17 @@ int mmc_startup(struct mmc *mmc)
} }
/* divide frequency by 10, since the mults are 10x bigger */ /* divide frequency by 10, since the mults are 10x bigger */
freq = fbase[(cmd.response[3] & 0x7)]; freq = fbase[(cmd.response[0] & 0x7)];
mult = multipliers[((cmd.response[3] >> 3) & 0xf)]; mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
mmc->tran_speed = freq * mult; mmc->tran_speed = freq * mult;
mmc->read_bl_len = 1 << ((((uint *)(cmd.response))[1] >> 16) & 0xf); mmc->read_bl_len = 1 << ((cmd.response[1] >> 16) & 0xf);
if (IS_SD(mmc)) if (IS_SD(mmc))
mmc->write_bl_len = mmc->read_bl_len; mmc->write_bl_len = mmc->read_bl_len;
else else
mmc->write_bl_len = 1 << ((((uint *)(cmd.response))[3] >> 22) & 0xf); mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
if (mmc->high_capacity) { if (mmc->high_capacity) {
csize = (mmc->csd[1] & 0x3f) << 16 csize = (mmc->csd[1] & 0x3f) << 16
@ -789,14 +790,14 @@ int mmc_startup(struct mmc *mmc)
mmc->block_dev.lun = 0; mmc->block_dev.lun = 0;
mmc->block_dev.type = 0; mmc->block_dev.type = 0;
mmc->block_dev.blksz = mmc->read_bl_len; mmc->block_dev.blksz = mmc->read_bl_len;
mmc->block_dev.lba = mmc->capacity/mmc->read_bl_len; mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
sprintf(mmc->block_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x%02x", sprintf(mmc->block_dev.vendor, "Man %06x Snr %08x", mmc->cid[0] >> 8,
mmc->cid[0], mmc->cid[1], mmc->cid[2], (mmc->cid[2] << 8) | (mmc->cid[3] >> 24));
mmc->cid[9], mmc->cid[10], mmc->cid[11], mmc->cid[12]); sprintf(mmc->block_dev.product, "%c%c%c%c%c", mmc->cid[0] & 0xff,
sprintf(mmc->block_dev.product,"%c%c%c%c%c", mmc->cid[3], (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
mmc->cid[4], mmc->cid[5], mmc->cid[6], mmc->cid[7]); (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
sprintf(mmc->block_dev.revision,"%d.%d", mmc->cid[8] >> 4, sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28,
mmc->cid[8] & 0xf); (mmc->cid[2] >> 24) & 0xf);
init_part(&mmc->block_dev); init_part(&mmc->block_dev);
return 0; return 0;
@ -818,7 +819,7 @@ int mmc_send_if_cond(struct mmc *mmc)
if (err) if (err)
return err; return err;
if ((((uint *)(cmd.response))[0] & 0xff) != 0xaa) if ((cmd.response[0] & 0xff) != 0xaa)
return UNUSABLE_ERR; return UNUSABLE_ERR;
else else
mmc->version = SD_VERSION_2; mmc->version = SD_VERSION_2;
@ -846,7 +847,7 @@ block_dev_desc_t *mmc_get_dev(int dev)
{ {
struct mmc *mmc = find_mmc_device(dev); struct mmc *mmc = find_mmc_device(dev);
return &mmc->block_dev; return mmc ? &mmc->block_dev : NULL;
} }
int mmc_init(struct mmc *mmc) int mmc_init(struct mmc *mmc)

View file

@ -91,7 +91,7 @@
#define MMC_HS_TIMING 0x00000100 #define MMC_HS_TIMING 0x00000100
#define MMC_HS_52MHZ 0x2 #define MMC_HS_52MHZ 0x2
#define OCR_BUSY 0x80 #define OCR_BUSY 0x80000000
#define OCR_HCS 0x40000000 #define OCR_HCS 0x40000000
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
@ -223,7 +223,7 @@ struct mmc_cmd {
ushort cmdidx; ushort cmdidx;
uint resp_type; uint resp_type;
uint cmdarg; uint cmdarg;
char response[18]; uint response[4];
uint flags; uint flags;
}; };
@ -253,7 +253,7 @@ struct mmc {
uint ocr; uint ocr;
uint scr[2]; uint scr[2];
uint csd[4]; uint csd[4];
char cid[16]; uint cid[4];
ushort rca; ushort rca;
uint tran_speed; uint tran_speed;
uint read_bl_len; uint read_bl_len;