mmc-utils: add ability to enable/disable optional eMMC cache

The MMC4.5 specification added an optional cache for eMMC devices.
This change will add the ability to enable/disable the cache.

Signed-off-by: Al Cooper <acooperx@gmail.com>
Signed-off-by: Chris Ball <chris@printf.net>
This commit is contained in:
Al Cooper 2015-04-29 18:12:35 -04:00 committed by Chris Ball
parent 64c2de8b14
commit d0b46442b5
4 changed files with 93 additions and 3 deletions

12
mmc.c
View File

@ -163,6 +163,18 @@ static struct Command commands[] = {
" mmc rpmb write-block /dev/mmcblk0rpmb 0x02 - -",
NULL
},
{ do_cache_en, -1,
"cache enable", "<device>\n"
"Enable the eMMC cache feature on <device>.\n"
"NOTE! The cache is an optional feature on devices >= eMMC4.5.",
NULL
},
{ do_cache_dis, -1,
"cache disable", "<device>\n"
"Disable the eMMC cache feature on <device>.\n"
"NOTE! The cache is an optional feature on devices >= eMMC4.5.",
NULL
},
{ 0, 0, 0, 0 }
};

15
mmc.h
View File

@ -42,12 +42,17 @@
#define EXT_CSD_S_CMD_SET 504
#define EXT_CSD_HPI_FEATURE 503
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_CACHE_SIZE_3 252
#define EXT_CSD_CACHE_SIZE_2 251
#define EXT_CSD_CACHE_SIZE_1 250
#define EXT_CSD_CACHE_SIZE_0 249
#define EXT_CSD_BOOT_INFO 228 /* R/W */
#define EXT_CSD_SEC_COUNT_3 215
#define EXT_CSD_SEC_COUNT_2 214
#define EXT_CSD_SEC_COUNT_1 213
#define EXT_CSD_SEC_COUNT_0 212
#define EXT_CSD_PART_SWITCH_TIME 199
#define EXT_CSD_REV 192
#define EXT_CSD_BOOT_CFG 179
#define EXT_CSD_PART_CONFIG 179
#define EXT_CSD_BOOT_BUS_CONDITIONS 177
@ -88,6 +93,7 @@
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_1 53
#define EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_0 52
#define EXT_CSD_CACHE_CTRL 33
/*
* WR_REL_PARAM field definitions
@ -131,6 +137,15 @@
#define EXT_CSD_ENH_2 (1<<2)
#define EXT_CSD_ENH_1 (1<<1)
#define EXT_CSD_ENH_USR (1<<0)
#define EXT_CSD_REV_V5_1 8
#define EXT_CSD_REV_V5_0 7
#define EXT_CSD_REV_V4_5 6
#define EXT_CSD_REV_V4_4_1 5
#define EXT_CSD_REV_V4_3 3
#define EXT_CSD_REV_V4_2 2
#define EXT_CSD_REV_V4_1 1
#define EXT_CSD_REV_V4_0 0
/* From kernel linux/mmc/core.h */
#define MMC_RSP_PRESENT (1 << 0)

View File

@ -98,7 +98,7 @@ int send_status(int fd, __u32 *response)
void print_writeprotect_status(__u8 *ext_csd)
{
__u8 reg;
__u8 ext_csd_rev = ext_csd[192];
__u8 ext_csd_rev = ext_csd[EXT_CSD_REV];
/* A43: reserved [174:0] */
if (ext_csd_rev >= 5) {
@ -1014,7 +1014,7 @@ int do_read_extcsd(int nargs, char **argv)
exit(1);
}
ext_csd_rev = ext_csd[192];
ext_csd_rev = ext_csd[EXT_CSD_REV];
switch (ext_csd_rev) {
case 7:
@ -1218,7 +1218,7 @@ int do_read_extcsd(int nargs, char **argv)
if (reg & 0x01) printf(" HS eMMC @26MHz - at rated device voltage(s)\n");
printf("CSD structure version [CSD_STRUCTURE: 0x%02x]\n", ext_csd[194]);
/* ext_csd_rev = ext_csd[192] (already done!!!) */
/* ext_csd_rev = ext_csd[EXT_CSD_REV] (already done!!!) */
printf("Command set [CMD_SET: 0x%02x]\n", ext_csd[191]);
printf("Command set revision [CMD_SET_REV: 0x%02x]\n", ext_csd[189]);
printf("Power class [POWER_CLASS: 0x%02x]\n", ext_csd[187]);
@ -1971,3 +1971,64 @@ int do_rpmb_write_block(int nargs, char **argv)
return ret;
}
int do_cache_ctrl(int value, int nargs, char **argv)
{
__u8 ext_csd[512];
int fd, ret;
char *device;
CHECK(nargs != 2, "Usage: mmc cache enable </path/to/mmcblkX>\n",
exit(1));
device = argv[1];
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);
}
if (ext_csd[EXT_CSD_REV] < EXT_CSD_REV_V4_5) {
fprintf(stderr,
"The CACHE option is only availabe on devices >= "
"MMC 4.5 %s\n", device);
exit(1);
}
/* If the cache size is zero, this device does not have a cache */
if (!(ext_csd[EXT_CSD_CACHE_SIZE_3] ||
ext_csd[EXT_CSD_CACHE_SIZE_2] ||
ext_csd[EXT_CSD_CACHE_SIZE_1] ||
ext_csd[EXT_CSD_CACHE_SIZE_0])) {
fprintf(stderr,
"The CACHE option is not available on %s\n",
device);
exit(1);
}
ret = write_extcsd_value(fd, EXT_CSD_CACHE_CTRL, value);
if (ret) {
fprintf(stderr,
"Could not write 0x%02x to EXT_CSD[%d] in %s\n",
value, EXT_CSD_CACHE_CTRL, device);
exit(1);
}
return ret;
}
int do_cache_en(int nargs, char **argv)
{
return do_cache_ctrl(1, nargs, argv);
}
int do_cache_dis(int nargs, char **argv)
{
return do_cache_ctrl(0, nargs, argv);
}

View File

@ -34,3 +34,5 @@ int do_rpmb_write_key(int nargs, char **argv);
int do_rpmb_read_counter(int nargs, char **argv);
int do_rpmb_read_block(int nargs, char **argv);
int do_rpmb_write_block(int nargs, char **argv);
int do_cache_en(int nargs, char **argv);
int do_cache_dis(int nargs, char **argv);