diff options
author | Al Cooper <acooperx@gmail.com> | 2015-05-01 08:24:37 -0400 |
---|---|---|
committer | Chris Ball <chris@printf.net> | 2015-05-01 08:38:17 -0400 |
commit | 64c2de8b1476c42ef9e9729b7ca0e436b5d90170 (patch) | |
tree | 0f9fa7b7c07d71a2fc5a2368497b3473b3049f9a | |
parent | 7891236d62ccd201054324b5298dd9529c6a764f (diff) | |
download | mmc-utils-64c2de8b1476c42ef9e9729b7ca0e436b5d90170.tar.gz |
mmc-utils: Add command to set the boot bus conditions
This was added because some eMMC devices had the boot bus conditions
set incorrectly causing them to hang on boot.
Signed-off-by: Al Cooper <acooperx@gmail.com>
Signed-off-by: Chris Ball <chris@printf.net>
-rw-r--r-- | mmc.c | 8 | ||||
-rw-r--r-- | mmc.h | 3 | ||||
-rw-r--r-- | mmc_cmds.c | 72 | ||||
-rw-r--r-- | mmc_cmds.h | 1 |
4 files changed, 83 insertions, 1 deletions
@@ -95,6 +95,14 @@ static struct Command commands[] = { "Enable the boot partition for the <device>.\nTo receive acknowledgment of boot from the card set <send_ack>\nto 1, else set it to 0.", NULL }, + { do_boot_bus_conditions_set, -4, + "bootbus set", "<boot_mode> " "<reset_boot_bus_conditions> " "<boot_bus_width> " "<device>\n" + "Set Boot Bus Conditions.\n" + "<boot_mode> must be \"single_backward|single_hs|dual\"\n" + "<reset_boot_bus_conditions> must be \"x1|retain\"\n" + "<boot_bus_width> must be \"x1|x4|x8\"", + NULL + }, { do_write_bkops_en, -1, "bkops enable", "<device>\n" "Enable the eMMC BKOPS feature on <device>.\nNOTE! This is a one-time programmable (unreversible) change.", @@ -50,9 +50,10 @@ #define EXT_CSD_PART_SWITCH_TIME 199 #define EXT_CSD_BOOT_CFG 179 #define EXT_CSD_PART_CONFIG 179 +#define EXT_CSD_BOOT_BUS_CONDITIONS 177 #define EXT_CSD_ERASE_GROUP_DEF 175 #define EXT_CSD_BOOT_WP 173 -#define EXT_CSD_WR_REL_SET 167 +#define EXT_CSD_WR_REL_SET 167 #define EXT_CSD_WR_REL_PARAM 166 #define EXT_CSD_SANITIZE_START 165 #define EXT_CSD_BKOPS_EN 163 /* R/W */ @@ -303,6 +303,75 @@ int do_write_boot_en(int nargs, char **argv) return ret; } +int do_boot_bus_conditions_set(int nargs, char **argv) +{ + __u8 ext_csd[512]; + __u8 value = 0; + int fd, ret; + char *device; + + CHECK(nargs != 5, "Usage: mmc: bootbus set <boot_mode> " + "<reset_boot_bus_conditions> <boot_bus_width> <device>\n", + exit(1)); + + if (strcmp(argv[1], "single_backward") == 0) + value |= 0; + else if (strcmp(argv[1], "single_hs") == 0) + value |= 0x8; + else if (strcmp(argv[1], "dual") == 0) + value |= 0x10; + else { + fprintf(stderr, "illegal <boot_mode> specified\n"); + exit(1); + } + + if (strcmp(argv[2], "x1") == 0) + value |= 0; + else if (strcmp(argv[2], "retain") == 0) + value |= 0x4; + else { + fprintf(stderr, + "illegal <reset_boot_bus_conditions> specified\n"); + exit(1); + } + + if (strcmp(argv[3], "x1") == 0) + value |= 0; + else if (strcmp(argv[3], "x4") == 0) + value |= 0x1; + else if (strcmp(argv[3], "x8") == 0) + value |= 0x2; + else { + fprintf(stderr, "illegal <boot_bus_width> specified\n"); + exit(1); + } + + device = argv[4]; + fd = open(device, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + ret = read_extcsd(fd, ext_csd); + if (ret) { + fprintf(stderr, "Could not read EXT_CSD from %s\n", device); + exit(1); + } + printf("Changing ext_csd[BOOT_BUS_CONDITIONS] from 0x%02x to 0x%02x\n", + ext_csd[EXT_CSD_BOOT_BUS_CONDITIONS], value); + + ret = write_extcsd_value(fd, EXT_CSD_BOOT_BUS_CONDITIONS, value); + if (ret) { + fprintf(stderr, "Could not write 0x%02x to " + "EXT_CSD[%d] in %s\n", + value, EXT_CSD_BOOT_BUS_CONDITIONS, device); + exit(1); + } + close(fd); + return ret; +} + int do_hwreset(int value, int nargs, char **argv) { __u8 ext_csd[512]; @@ -948,6 +1017,9 @@ int do_read_extcsd(int nargs, char **argv) ext_csd_rev = ext_csd[192]; switch (ext_csd_rev) { + case 7: + str = "5.0"; + break; case 6: str = "4.5"; break; @@ -21,6 +21,7 @@ int do_writeprotect_get(int nargs, char **argv); int do_writeprotect_set(int nargs, char **argv); int do_disable_512B_emulation(int nargs, char **argv); int do_write_boot_en(int nargs, char **argv); +int do_boot_bus_conditions_set(int nargs, char **argv); int do_write_bkops_en(int nargs, char **argv); int do_hwreset_en(int nargs, char **argv); int do_hwreset_dis(int nargs, char **argv); |