Merge branch 'master' of git://git.denx.de/u-boot-mmc
This commit is contained in:
		
						commit
						3bc8556f9b
					
				| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,12 +206,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 | 
				
			||||||
		cmdrsp2 = in_be32(®s->cmdrsp2);
 | 
							cmdrsp2 = in_be32(®s->cmdrsp2);
 | 
				
			||||||
		cmdrsp1 = in_be32(®s->cmdrsp1);
 | 
							cmdrsp1 = in_be32(®s->cmdrsp1);
 | 
				
			||||||
		cmdrsp0 = in_be32(®s->cmdrsp0);
 | 
							cmdrsp0 = in_be32(®s->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(®s->cmdrsp0);
 | 
							cmd->response[0] = in_be32(®s->cmdrsp0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wait until all of the blocks are transferred */
 | 
						/* Wait until all of the blocks are transferred */
 | 
				
			||||||
	if (data) {
 | 
						if (data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue