aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorInderpal Singh <inderpal.singh@linaro.org>2012-12-07 10:34:42 +0530
committerTushar Behera <tushar.behera@linaro.org>2013-02-05 10:39:12 +0530
commit5b93b27bbcc74c5c13ec015206a5adb364f108dc (patch)
tree76f86f5acd85d51646563aef4d7ebb0f4e0b893f
parent9eb4a7766b57a7d26772787b40c2738c3d335dd4 (diff)
COMMAND: MMC: Extend mmc command to make emmc bootable
Signed-off-by: Inderpal Singh <inderpal.singh@linaro.org>
-rw-r--r--common/cmd_mmc.c26
-rw-r--r--drivers/mmc/mmc.c14
-rw-r--r--include/mmc.h2
3 files changed, 39 insertions, 3 deletions
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 62a1c224d..c50b6d31c 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -199,7 +199,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
print_mmc_devices('\n');
return 0;
} else if (strcmp(argv[1], "dev") == 0) {
- int dev, part = -1;
+ int dev, part = -1, bootable = 0;
struct mmc *mmc;
if (argc == 2)
@@ -214,6 +214,19 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
" than %d\n", PART_ACCESS_MASK);
return 1;
}
+ } else if (argc == 5) {
+ dev = (int)simple_strtoul(argv[2], NULL, 10);
+ part = (int)simple_strtoul(argv[3], NULL, 10);
+ if (part > PART_ACCESS_MASK) {
+ printf("#part_num shouldn't be larger"
+ " than %d\n", PART_ACCESS_MASK);
+ return 1;
+ }
+ bootable = (int)simple_strtoul(argv[4], NULL, 10);
+ if (bootable < 0 || bootable > 1) {
+ printf("bootable is boolean variable \n");
+ return 1;
+ }
} else
return CMD_RET_USAGE;
@@ -231,7 +244,14 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (part != mmc->part_num) {
+ if (bootable) {
+ ret = mmc_part_bootenable(dev, part);
+ if (!ret)
+ mmc->part_num = part;
+ printf("partions #%d, made bootable %s\n",
+ part, (!ret) ? "OK" : "ERROR");
+
+ } else if (part != mmc->part_num) {
ret = mmc_switch_part(dev, part);
if (!ret)
mmc->part_num = part;
@@ -317,6 +337,6 @@ U_BOOT_CMD(
"mmc erase blk# cnt\n"
"mmc rescan\n"
"mmc part - lists available partition on current mmc device\n"
- "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
+ "mmc dev [dev] [part] [bootable]- show or set current mmc device [partition] [bootable]\n"
"mmc list - lists available devices");
#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5ffd8c59e..1d2fa7319 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -669,6 +669,20 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
| (part_num & PART_ACCESS_MASK));
}
+int mmc_part_bootenable(int dev_num, unsigned int part_num)
+{
+ struct mmc *mmc = find_mmc_device(dev_num);
+
+ if (!mmc)
+ return -1;
+
+ return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
+ (mmc->part_config & ~(BOOT_PART_ENABLE_MASK | PART_ACCESS_MASK))
+ | (part_num & PART_ACCESS_MASK)
+ | ((part_num << 3) & BOOT_PART_ENABLE_MASK)
+ | BOOT_ACK);
+}
+
int mmc_getcd(struct mmc *mmc)
{
int cd;
diff --git a/include/mmc.h b/include/mmc.h
index a13e2bdcf..ed4c4e24d 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -199,6 +199,8 @@
#define MMCPART_NOAVAILABLE (0xff)
#define PART_ACCESS_MASK (0x7)
+#define BOOT_PART_ENABLE_MASK (0x7 << 3)
+#define BOOT_ACK (0x1 << 6)
#define PART_SUPPORT (0x1)
struct mmc_cid {