mirror of
https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git
synced 2024-11-27 11:53:24 +08:00
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:
parent
64c2de8b14
commit
d0b46442b5
12
mmc.c
12
mmc.c
@ -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
15
mmc.h
@ -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)
|
||||
|
67
mmc_cmds.c
67
mmc_cmds.c
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user