For emmc, it may has upto 7 partitions: two boot partitions, one user partition, one RPMB partition and four general purpose partitions. (Refer to JESD84-A44.pdf/page 154)
As bootloader may need to read out or reflashing images on those different partitions, it is better to enable the partition switch with console command support. Signed-off-by: Lei Wen <lei...@marvell.com> --- common/cmd_mmc.c | 24 +++++++++++++++++++++++- drivers/mmc/mmc.c | 16 ++++++++++++++++ include/mmc.h | 5 +++++ 3 files changed, 44 insertions(+), 1 deletions(-) diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 4323f76..2181e04 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -177,7 +177,6 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) case 0: case 1: - case 4: return cmd_usage(cmdtp); case 2: @@ -233,6 +232,28 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; + } else if (strcmp(argv[1], "sw_part") == 0) { + int dev = simple_strtoul(argv[2], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + int num = simple_strtoul(argv[3], NULL, 10); + int ret; + + if (num > PART_ACCESS_MASK) { + printf("#part_num shouldn't be larger than %d\n", + PART_ACCESS_MASK); + return 1; + } + + mmc_init(mmc); + if (mmc->part_config == MMCPART_NOAVAILABLE) { + printf("Card doesn't support part_switch\n"); + return 1; + } + + ret = mmc_switch_part(dev, num); + printf("switch to partions #%d, %s\n", + num, (!ret) ? "OK" : "ERROR"); + return (!ret) ? 0 : 1; } else rc = cmd_usage(cmdtp); @@ -247,5 +268,6 @@ U_BOOT_CMD( "mmc write <device num> addr blk# cnt\n" "mmc rescan <device num>\n" "mmc part <device num> - lists available partition on mmc\n" + "mmc sw_part <device num> <part_num> - switch part support for emmc\n" "mmc list - lists available devices"); #endif diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6805b33..f42b3fb 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -428,6 +428,18 @@ int mmc_change_freq(struct mmc *mmc) return 0; } +int mmc_switch_part(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 & ~PART_ACCESS_MASK) + | (part_num & PART_ACCESS_MASK)); +} + int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) { struct mmc_cmd cmd; @@ -725,6 +737,7 @@ int mmc_startup(struct mmc *mmc) if (err) return err; + mmc->part_config = MMCPART_NOAVAILABLE; if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { /* check ext_csd version and capacity */ err = mmc_send_ext_csd(mmc, ext_csd); @@ -733,6 +746,9 @@ int mmc_startup(struct mmc *mmc) ext_csd[214] << 16 | ext_csd[215] << 24; mmc->capacity *= 512; } + /* store the partition info of emmc */ + if (ext_csd[160] & 0x1) + mmc->part_config = ext_csd[179]; } if (IS_SD(mmc)) diff --git a/include/mmc.h b/include/mmc.h index 74c0b1d..10dfafd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -128,6 +128,7 @@ * EXT_CSD fields */ +#define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_CARD_TYPE 196 /* RO */ @@ -169,6 +170,8 @@ #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) +#define MMCPART_NOAVAILABLE (0xff) +#define PART_ACCESS_MASK (0x7) struct mmc_cid { unsigned long psn; @@ -265,6 +268,7 @@ struct mmc { uint csd[4]; uint cid[4]; ushort rca; + char part_config; uint tran_speed; uint read_bl_len; uint write_bl_len; @@ -285,6 +289,7 @@ struct mmc *find_mmc_device(int dev_num); int mmc_set_dev(int dev_num); void print_mmc_devices(char separator); int board_mmc_getcd(u8 *cd, struct mmc *mmc); +int mmc_switch_part(int dev_num, unsigned int part_num); #ifdef CONFIG_GENERIC_MMC int atmel_mci_init(void *regs); -- 1.7.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot