summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnish Trivedi <anish@freescale.com>2010-06-15 18:01:10 -0500
committerAnish Trivedi <anish@freescale.com>2010-06-24 09:47:41 -0500
commit3bd50a46e4453ca2492169e7add9cde0752442e2 (patch)
treea33e0bfa7f917396a43c8b951f31f0ef64927863
parent90bfe6af18c84a7e3ba424cba0c2602d883bd286 (diff)
downloadu-boot-imx-3bd50a46e4453ca2492169e7add9cde0752442e2.zip
u-boot-imx-3bd50a46e4453ca2492169e7add9cde0752442e2.tar.gz
u-boot-imx-3bd50a46e4453ca2492169e7add9cde0752442e2.tar.bz2
ENGR00123782 Fix boot partition problem for emmc
Enable boot partition in BOOT_CONFIG byte of EXT_CSD Signed-off-by: Anish Trivedi <anish@freescale.com>
-rw-r--r--common/cmd_mmc.c136
-rw-r--r--drivers/mmc/mmc.c118
-rw-r--r--include/configs/mx53_arm2.h2
-rw-r--r--include/configs/mx53_evk.h2
-rw-r--r--include/mmc.h5
5 files changed, 129 insertions, 134 deletions
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index cd7d16f..29cae1b 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -93,6 +93,29 @@ U_BOOT_CMD(
);
#else /* !CONFIG_GENERIC_MMC */
+#ifdef CONFIG_BOOT_PARTITION_ACCESS
+#define MMC_PARTITION_SWITCH(mmc, part, enable_boot) \
+ do { \
+ if (IS_SD(mmc)) { \
+ if (part > 1) {\
+ printf( \
+ "\nError: SD partition can only be 0 or 1\n");\
+ return 1; \
+ } \
+ if (sd_switch_partition(mmc, part) < 0) { \
+ return 1; \
+ } \
+ } else { \
+ if (mmc_switch_partition(mmc, part, enable_boot) \
+ < 0) { \
+ printf("Error: Fail to switch " \
+ "partition to %d\n", part); \
+ return 1; \
+ } \
+ } \
+ } while (0)
+#endif
+
static void print_mmcinfo(struct mmc *mmc)
{
printf("Device: %s\n", mmc->name);
@@ -136,22 +159,6 @@ static void print_mmcinfo(struct mmc *mmc)
printf("Unknown\n");
break;
}
-
- printf("Current Partition for read/write: ");
- switch (mmc->boot_config & EXT_CSD_BOOT_PARTITION_ACCESS_MASK) {
- case EXT_CSD_BOOT_PARTITION_ACCESS_DISABLE:
- printf("User Area\n");
- break;
- case EXT_CSD_BOOT_PARTITION_ACCESS_PART1:
- printf("Boot partition 1\n");
- break;
- case EXT_CSD_BOOT_PARTITION_ACCESS_PART2:
- printf("Boot partition 2\n");
- break;
- default:
- printf("Unknown\n");
- break;
- }
}
#endif
}
@@ -217,7 +224,7 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
}
return 1;
#ifdef CONFIG_BOOT_PARTITION_ACCESS
- case 6: /* Fall through */
+ case 7: /* Fall through */
part = simple_strtoul(argv[6], NULL, 10);
#endif
default: /* at least 5 args */
@@ -233,25 +240,27 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (!mmc)
return 1;
- printf("\nMMC read: dev # %d, block # %d, count %d ... ",
- dev, blk, cnt);
+#ifdef CONFIG_BOOT_PARTITION_ACCESS
+ printf("\nMMC read: dev # %d, block # %d, "
+ "count %d partition # %d ... \n",
+ dev, blk, cnt, part);
+#else
+ printf("\nMMC read: dev # %d, block # %d,"
+ "count %d ... \n", dev, blk, cnt);
+#endif
mmc_init(mmc);
#ifdef CONFIG_BOOT_PARTITION_ACCESS
- /* After mmc_init, we now know whether this is a eSD/eMMC which support boot partition */
- if (part > 0) {
- if (IS_SD(mmc)) {
- if (sd_switch_partition(mmc, 1) < 0) {
- printf("\nError: Fail to switch partition to %d before reading\n", 1);
- return 1;
- }
- } else {
- if (mmc_switch_partition(mmc, part) < 0) {
- printf("\nError: Fail to switch partition to %d before reading\n", part);
- return 1;
- }
- }
+ if (((mmc->boot_config &
+ EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
+ || IS_SD(mmc)) {
+ /*
+ * After mmc_init, we now know whether
+ * this is a eSD/eMMC which support boot
+ * partition
+ */
+ MMC_PARTITION_SWITCH(mmc, part, 0);
}
#endif
@@ -260,22 +269,6 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
/* flush cache after read */
flush_cache((ulong)addr, cnt * 512); /* FIXME */
-#ifdef CONFIG_BOOT_PARTITION_ACCESS
- /* Switch back */
- if (part > 0) {
- if (IS_SD(mmc)) {
- if (sd_switch_partition(mmc, 0) < 0) {
- printf("\nError: Fail to switch partition back!\n");
- return 1;
- }
- } else {
- if (mmc_switch_partition(mmc, 0) < 0) {
- printf("\nError: Fail to switch partition back!\n");
- return 1;
- }
- }
- }
-#endif
printf("%d blocks read: %s\n",
n, (n==cnt) ? "OK" : "ERROR");
return (n == cnt) ? 0 : 1;
@@ -292,47 +285,32 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
if (!mmc)
return 1;
- printf("\nMMC write: dev # %d, block # %d, count %d ... ",
+#ifdef CONFIG_BOOT_PARTITION_ACCESS
+ printf("\nMMC write: dev # %d, block # %d, "
+ "count %d, partition # %d ... \n",
+ dev, blk, cnt, part);
+#else
+ printf("\nMMC write: dev # %d, block # %d, "
+ "count %d ... \n",
dev, blk, cnt);
+#endif
mmc_init(mmc);
#ifdef CONFIG_BOOT_PARTITION_ACCESS
- /* After mmc_init, we now know whether this is a eSD/eMMC which support boot partition */
- if (part > 0) {
- if (IS_SD(mmc)) {
- if (sd_switch_partition(mmc, 1) < 0) {
- printf("\nError: Fail to switch partition to %d before writing\n", 1);
- return 1;
- }
- } else {
- if (mmc_switch_partition(mmc, part) < 0) {
- printf("\nError: Fail to switch partition to %d before writing\n", part);
- return 1;
- }
- }
+ if (((mmc->boot_config &
+ EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
+ || IS_SD(mmc)) {
+ /*
+ * After mmc_init, we now know whether this is a
+ * eSD/eMMC which support boot partition
+ */
+ MMC_PARTITION_SWITCH(mmc, part, 1);
}
#endif
n = mmc->block_dev.block_write(dev, blk, cnt, addr);
-#ifdef CONFIG_BOOT_PARTITION_ACCESS
- /* Switch back */
- if (part > 0) {
- if (IS_SD(mmc)) {
- if (sd_switch_partition(mmc, 0) < 0) {
- printf("\nError: Fail to switch partition back!\n");
- return 1;
- }
- } else {
- if (mmc_switch_partition(mmc, 0) < 0) {
- printf("\nError: Fail to switch partition back!\n");
- return 1;
- }
- }
- }
-#endif
-
printf("%d blocks written: %s\n",
n, (n == cnt) ? "OK" : "ERROR");
return (n == cnt) ? 0 : 1;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 2f774ee..072ef46 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -40,12 +40,13 @@
static struct list_head mmc_devices;
static int cur_dev_num = -1;
-int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+static int mmc_send_cmd(struct mmc *mmc,
+ struct mmc_cmd *cmd, struct mmc_data *data)
{
return mmc->send_cmd(mmc, cmd, data);
}
-int mmc_set_blocklen(struct mmc *mmc, int len)
+static int mmc_set_blocklen(struct mmc *mmc, int len)
{
struct mmc_cmd cmd;
@@ -140,7 +141,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
return blkcnt;
}
-int mmc_read_block(struct mmc *mmc, void *dst, uint blocknum)
+static int mmc_read_block(struct mmc *mmc, void *dst, uint blocknum)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -279,7 +280,9 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
return blkcnt;
}
-int mmc_go_idle(struct mmc* mmc)
+#define CARD_STATE(r) ((u32)((r) & 0x1e00) >> 9)
+
+static int mmc_go_idle(struct mmc *mmc)
{
struct mmc_cmd cmd;
int err;
@@ -301,7 +304,7 @@ int mmc_go_idle(struct mmc* mmc)
return 0;
}
-int
+static int
sd_send_op_cond(struct mmc *mmc)
{
int timeout = 1000;
@@ -356,7 +359,7 @@ sd_send_op_cond(struct mmc *mmc)
return 0;
}
-int mmc_send_op_cond(struct mmc *mmc)
+static int mmc_send_op_cond(struct mmc *mmc)
{
int timeout = 1000;
struct mmc_cmd cmd;
@@ -392,7 +395,7 @@ int mmc_send_op_cond(struct mmc *mmc)
}
-int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
+static int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -415,7 +418,7 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
}
-int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
{
struct mmc_cmd cmd;
@@ -429,7 +432,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
return mmc_send_cmd(mmc, &cmd, NULL);
}
-int mmc_change_freq(struct mmc *mmc)
+static int mmc_change_freq(struct mmc *mmc)
{
char *ext_csd;
char cardtype;
@@ -455,13 +458,13 @@ int mmc_change_freq(struct mmc *mmc)
if (err)
goto err_rtn;
-/*
- if (ext_csd[EXT_CSD_SEC_CNT] ||
- ext_csd[EXT_CSD_SEC_CNT + 1] ||
- ext_csd[EXT_CSD_SEC_CNT + 2] ||
- ext_csd[EXT_CSD_SEC_CNT + 3])
- mmc->high_capacity = 1;
-*/
+ if (mmc->high_capacity) {
+ mmc->capacity = ext_csd[EXT_CSD_SEC_CNT + 3] << 24 |
+ ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
+ ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
+ ext_csd[EXT_CSD_SEC_CNT];
+ mmc->capacity *= 512;
+ }
cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
@@ -495,7 +498,7 @@ err_rtn:
return err;
}
-int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
+static int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -517,7 +520,7 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp)
}
-int sd_change_freq(struct mmc *mmc)
+static int sd_change_freq(struct mmc *mmc)
{
int err;
struct mmc_cmd cmd;
@@ -616,7 +619,7 @@ retry_scr:
/* frequency bases */
/* divided by 10 to be nice to platforms without floating point */
-int fbase[] = {
+static int fbase[] = {
10000,
100000,
1000000,
@@ -626,7 +629,7 @@ int fbase[] = {
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
* to platforms without floating point.
*/
-int multipliers[] = {
+static int multipliers[] = {
0, /* reserved */
10,
12,
@@ -645,12 +648,12 @@ int multipliers[] = {
80,
};
-void mmc_set_ios(struct mmc *mmc)
+static void mmc_set_ios(struct mmc *mmc)
{
mmc->set_ios(mmc);
}
-void mmc_set_clock(struct mmc *mmc, uint clock)
+static void mmc_set_clock(struct mmc *mmc, uint clock)
{
if (clock > mmc->f_max)
clock = mmc->f_max;
@@ -663,7 +666,7 @@ void mmc_set_clock(struct mmc *mmc, uint clock)
mmc_set_ios(mmc);
}
-void mmc_set_bus_width(struct mmc *mmc, uint width)
+static void mmc_set_bus_width(struct mmc *mmc, uint width)
{
mmc->bus_width = width;
@@ -672,7 +675,7 @@ void mmc_set_bus_width(struct mmc *mmc, uint width)
#ifdef CONFIG_BOOT_PARTITION_ACCESS
/* Return 0/1/2 for partition id before switch; Return -1 if fail to switch */
-int mmc_switch_partition(struct mmc *mmc, uint part)
+int mmc_switch_partition(struct mmc *mmc, uint part, uint enable_boot)
{
char *ext_csd;
int err;
@@ -685,66 +688,79 @@ int mmc_switch_partition(struct mmc *mmc, uint part)
2 - boot partition 2
*/
if (part > 2) {
- printf("\nWrong partition id - 0 (user area), 1 (boot1), 2 (boot2)\n");
+ printf("\nWrong partition id - "
+ "0 (user area), 1 (boot1), 2 (boot2)\n");
return 1;
}
/* Before calling this func, "mmc" struct must have been initialized */
if (mmc->version < MMC_VERSION_4) {
- puts("Error: invalid mmc version! mmc version is below version 4!");
+ puts("\nError: invalid mmc version! "
+ "mmc version is below version 4!");
return -1;
}
if (mmc->boot_size_mult <= 0) {
/* it's a normal SD/MMC but user request to boot partition */
- printf("\nError: This is a normal SD/MMC card but you request to access boot partition\n");
+ printf("\nError: This is a normal SD/MMC card but you"
+ "request to access boot partition\n");
return -1;
}
- /* part must be 0 (user area), 1 (boot partition1) or 2 (boot partition2) */
+ /*
+ * Part must be 0 (user area), 1 (boot partition1)
+ * or 2 (boot partition2)
+ */
if (part > 2) {
- puts("Error: partition id must be 0(user area), 1(boot partition1) or 2(boot partition2)\n");
- return -1;
- }
-
- if (IS_SD(mmc)) {
- /* eSD card hadn't been supported. Return directly without warning */
+ puts("\nError: partition id must be 0(user area), "
+ "1(boot partition1) or 2(boot partition2)\n");
return -1;
}
ext_csd = (char *)malloc(512);
if (!ext_csd) {
- puts("Error: Could not allocate buffer for MMC ext csd!\n");
+ puts("\nError: Could not allocate buffer for MMC ext csd!\n");
return -1;
}
err = mmc_send_ext_csd(mmc, ext_csd);
if (err) {
- puts("Warning: fail to get ext csd for MMC!\n");
+ puts("\nWarning: fail to get ext csd for MMC!\n");
goto err_rtn;
- }
+ }
- old_part = ext_csd[EXT_CSD_BOOT_CONFIG] & EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
+ old_part = ext_csd[EXT_CSD_BOOT_CONFIG] &
+ EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
/* Send SWITCH command to change partition for access */
- boot_config = (ext_csd[EXT_CSD_BOOT_CONFIG] & ~EXT_CSD_BOOT_PARTITION_ACCESS_MASK) | (char)part;
+ boot_config = (ext_csd[EXT_CSD_BOOT_CONFIG] &
+ ~EXT_CSD_BOOT_PARTITION_ACCESS_MASK) |
+ (char)part;
+
+ /* enable access plus boot from that partition and boot_ack bit */
+ if (enable_boot != 0)
+ boot_config = (char)(part) | (char)(part << 3) | (char)(1 << 6);
- err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_CONFIG, boot_config);
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BOOT_CONFIG, boot_config);
if (err) {
- puts("Error: fail to send SWITCH command to card to swich partition for access!\n");
+ puts("\nError: fail to send SWITCH command to card "
+ "to swich partition for access!\n");
goto err_rtn;
}
/* Now check whether it works */
err = mmc_send_ext_csd(mmc, ext_csd);
if (err) {
- puts("Warning: fail to get ext csd for MMC!\n");
+ puts("\nWarning: fail to get ext csd for MMC!\n");
goto err_rtn;
}
- new_part = ext_csd[EXT_CSD_BOOT_CONFIG] & EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
+ new_part = ext_csd[EXT_CSD_BOOT_CONFIG] &
+ EXT_CSD_BOOT_PARTITION_ACCESS_MASK;
if ((char)part != new_part) {
- printf("Warning: after SWITCH, current part id %d is not same as requested partition %d!\n",
+ printf("\nWarning: after SWITCH, current part id %d is "
+ "not same as requested partition %d!\n",
new_part, part);
goto err_rtn;
}
@@ -775,15 +791,13 @@ int sd_switch_partition(struct mmc *mmc, uint part)
err = mmc_send_cmd(mmc, &cmd, NULL);
- if (err) {
- printf("Failed to switch to partition %d\nPartition not exists or command execute fail!\n");
+ if (err)
return -1;
- }
return 0;
}
-int mmc_get_cur_boot_partition(struct mmc *mmc)
+static int mmc_get_cur_boot_partition(struct mmc *mmc)
{
char *ext_csd;
int err;
@@ -791,7 +805,7 @@ int mmc_get_cur_boot_partition(struct mmc *mmc)
ext_csd = (char *)malloc(512);
if (!ext_csd) {
- puts("Error! Could not allocate buffer for MMC ext csd!\n");
+ puts("\nError! Could not allocate buffer for MMC ext csd!\n");
return -1;
}
@@ -803,7 +817,7 @@ int mmc_get_cur_boot_partition(struct mmc *mmc)
/* continue since it's not a fatal error */
} else {
mmc->boot_config = ext_csd[EXT_CSD_BOOT_CONFIG];
- mmc->boot_size_mult = ext_csd[EXT_CSD_BOOT_INFO];
+ mmc->boot_size_mult = ext_csd[EXT_CSD_BOOT_SIZE_MULT];
}
free(ext_csd);
@@ -813,7 +827,7 @@ int mmc_get_cur_boot_partition(struct mmc *mmc)
#endif
-int mmc_startup(struct mmc *mmc)
+static int mmc_startup(struct mmc *mmc)
{
int err;
uint mult, freq;
@@ -1039,7 +1053,7 @@ int mmc_startup(struct mmc *mmc)
return 0;
}
-int mmc_send_if_cond(struct mmc *mmc)
+static int mmc_send_if_cond(struct mmc *mmc)
{
struct mmc_cmd cmd;
int err;
diff --git a/include/configs/mx53_arm2.h b/include/configs/mx53_arm2.h
index c28f6d3..0af93c9 100644
--- a/include/configs/mx53_arm2.h
+++ b/include/configs/mx53_arm2.h
@@ -199,6 +199,8 @@
#define CONFIG_DOS_PARTITION 1
#define CONFIG_CMD_FAT 1
#define CONFIG_CMD_EXT2 1
+
+ #define CONFIG_BOOT_PARTITION_ACCESS
#endif
/*
diff --git a/include/configs/mx53_evk.h b/include/configs/mx53_evk.h
index 4fa66f2..e139840 100644
--- a/include/configs/mx53_evk.h
+++ b/include/configs/mx53_evk.h
@@ -198,6 +198,8 @@
#define CONFIG_DOS_PARTITION 1
#define CONFIG_CMD_FAT 1
#define CONFIG_CMD_EXT2 1
+
+ #define CONFIG_BOOT_PARTITION_ACCESS
#endif
/*
diff --git a/include/mmc.h b/include/mmc.h
index fe63ed7..b8d6871 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -137,7 +137,7 @@
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
-#define EXT_CSD_BOOT_INFO 228 /* RO */
+#define EXT_CSD_BOOT_SIZE_MULT 226 /* RO */
/*
* EXT_CSD field definitions
@@ -185,7 +185,6 @@
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
-
struct mmc_cid {
unsigned long psn;
unsigned short oid;
@@ -293,7 +292,7 @@ int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
struct mmc *find_mmc_device(int dev_num);
void print_mmc_devices(char separator);
#ifdef CONFIG_BOOT_PARTITION_ACCESS
-int mmc_switch_partition(struct mmc *mmc, uint part);
+int mmc_switch_partition(struct mmc *mmc, uint part, uint enable_boot);
int sd_switch_partition(struct mmc *mmc, uint part);
#endif