This patch parses mmc host caps and caps2 exported via debugfs. Signed-off-by: Harish Jenny K N <harish_kandiga@xxxxxxxxxx> --- Changes in v3: - Renamed "hostcaps2 read" to "caps2 read" to remove ambiguity Changes in v2: - Added support for parsing caps2 mmc.c | 10 +++ mmc_cmds.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mmc_cmds.h | 2 + 3 files changed, 234 insertions(+) diff --git a/mmc.c b/mmc.c index 50c9c9e..dab81bd 100644 --- a/mmc.c +++ b/mmc.c @@ -53,6 +53,16 @@ static struct Command commands[] = { /* * avoid short commands different for the case only */ + { do_read_hostcaps, -1, + "hostcaps read", "<path to debugfs host caps file>\n" + "Prints parsed data from host caps file>.", + NULL + }, + { do_read_hostcaps2, -1, + "caps2 read", "<path to debugfs host caps2 file>\n" + "Prints parsed data from host caps2 file>.", + NULL + }, { do_read_extcsd, -1, "extcsd read", "<device>\n" "Print extcsd data from <device>.", diff --git a/mmc_cmds.c b/mmc_cmds.c index 038dbd4..55a27f1 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -54,6 +54,61 @@ #define WPTYPE_PWRON 2 #define WPTYPE_PERM 3 +#define BIT(x) (1ul << x) + +#define MMCUTIL_4_BIT_DATA BIT(0) /*Can the host do 4 bit transfers*/ +#define MMCUTIL_MMC_HIGHSPEED BIT(1) /* Can do MMC high-speed timing */ +#define MMCUTIL_SD_HIGHSPEED BIT(2) /* Can do SD high-speed timing */ +#define MMCUTIL_SDIO_IRQ BIT(3) /* Can signal pending SDIO IRQs */ +#define MMCUTIL_SPI BIT(4) /* Talks only SPI protocols */ +#define MMCUTIL_NEEDS_POLL BIT(5) /* Needs polling for card-detection */ +#define MMCUTIL_8_BIT_DATA BIT(6) /* Can the host do 8 bit transfers */ +#define MMCUTIL_AGGRESSIVE_PM BIT(7) /* Suspend (e)MMC/SD at idle */ +#define MMCUTIL_NONREMOVABLE BIT(8) /* Nonremovable e.g. eMMC */ +#define MMCUTIL_WAIT_WHILE_BUSY BIT(9) /* Waits while card is busy */ +#define MMCUTIL_ERASE BIT(10) /* Allow erase/trim commands */ +#define MMCUTIL_3_3V_DDR BIT(11) /* Host supports eMMC DDR 3.3V */ +#define MMCUTIL_1_8V_DDR BIT(12) /* Host supports eMMC DDR 1.8V */ +#define MMCUTIL_1_2V_DDR BIT(13) /* Host supports eMMC DDR 1.2V */ +#define MMCUTIL_POWER_OFF_CARD BIT(14) /* Can power off after boot */ +#define MMCUTIL_BUS_WIDTH_TEST BIT(15) /* CMD14/CMD19 bus width ok */ +#define MMCUTIL_UHS_SDR12 BIT(16) /* Host supports UHS SDR12 mode */ +#define MMCUTIL_UHS_SDR25 BIT(17) /* Host supports UHS SDR25 mode */ +#define MMCUTIL_UHS_SDR50 BIT(18) /* Host supports UHS SDR50 mode */ +#define MMCUTIL_UHS_SDR104 BIT(19) /* Host supports UHS SDR104 mode */ +#define MMCUTIL_UHS_DDR50 BIT(20) /* Host supports UHS DDR50 mode */ +/* BIT(21) is free for reuse */ +#define MMCUTIL_DRIVER_TYPE_A BIT(23) /* Host supports Driver Type A */ +#define MMCUTIL_DRIVER_TYPE_C BIT(24) /* Host supports Driver Type C */ +#define MMCUTIL_DRIVER_TYPE_D BIT(25) /* Host supports Driver Type D */ +#define MMCUTIL_DONE_COMPLETE BIT(27) /* RW reqs can be completed */ +/* within mmc_request_done() */ +#define MMCUTIL_CD_WAKE BIT(28) /* Enable card detect wake */ +#define MMCUTIL_CMD_DURING_TFR BIT(29) /* Commands during data transfer*/ +#define MMCUTIL_CMD23 BIT(30) /* CMD23 supported. */ +#define MMCUTIL_HW_RESET BIT(31) /* Hardware reset */ + +#define MMCUTIL2_BOOTPART_NOACC BIT(0) /* Boot partition no access */ +#define MMCUTIL2_FULL_PWR_CYCLE BIT(2) /* Can do full power cycle */ +#define MMCUTIL2_HS200_1_8V_SDR BIT(5) /* can support */ +#define MMCUTIL2_HS200_1_2V_SDR BIT(6) /* can support */ +#define MMCUTIL2_CD_ACTIVE_HIGH BIT(10) /* Card-detect signal active high */ +#define MMCUTIL2_RO_ACTIVE_HIGH BIT(11) /* Write-protect signal active high */ +#define MMCUTIL2_NO_PRESCAN_POWERUP BIT(14) /* Don't power up before scan */ +#define MMCUTIL2_HS400_1_8V BIT(15) /* Can support HS400 1.8V */ +#define MMCUTIL2_HS400_1_2V BIT(16) /* Can support HS400 1.2V */ +#define MMCUTIL2_SDIO_IRQ_NOTHREAD BIT(17) +#define MMCUTIL2_NO_WRITE_PROTECT BIT(18) /* No physical write protect pin,*/ +/* assume that card is always read-write */ +#define MMCUTIL2_NO_SDIO BIT(19) /* Don't send SDIO commands */ +/* during initialization*/ +#define MMCUTIL2_HS400_ES BIT(20) /* Host supports enhanced strobe */ +#define MMCUTIL2_NO_SD BIT(21) /* Do not send SD commands */ +/* during initialization*/ +#define MMCUTIL2_NO_MMC BIT(22) /* Don't send (e)MMC commands*/ +/* during initialization */ +#define MMCUTIL2_CQE BIT(23) /* Has eMMC command queue engine */ +#define MMCUTIL2_CQE_DCMD BIT(24) /* CQE can issue a direct command */ int read_extcsd(int fd, __u8 *ext_csd) { @@ -1311,6 +1366,173 @@ int do_write_reliability_set(int nargs, char **argv) return 0; } +int do_read_hostcaps(int nargs, char **argv) +{ + __u32 caps = 0; + char caps_str[11]; + int fd, ret; + char *filepath; + + if (nargs != 2) { + fprintf(stderr, + "Usage: mmc hostcaps read </path/to/caps>\n"); + exit(1); + } + + filepath = argv[1]; + + fd = open(filepath, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + memset(caps_str, 0, sizeof(caps_str)); + ret = read(fd, caps_str, sizeof(caps_str)); + if (ret < 0) { + fprintf(stderr, "Could not read host capabilities from %s\n", + filepath); + exit(1); + } + caps = strtol(&caps_str[2], NULL, 16); + + printf("=============================================\n"); + printf(" Host capabilities of %s are\n", filepath); + printf("=============================================\n"); + printf("Can the host do 4 bit transfers :%s\n", + ((caps & MMCUTIL_4_BIT_DATA) ? "ENABLED" : "DISABLED")); + printf("Can do MMC high-speed timing :%s\n", + ((caps & MMCUTIL_MMC_HIGHSPEED) ? "ENABLED" : "DISABLED")); + printf("Can do SD high-speed timing :%s\n", + ((caps & MMCUTIL_SD_HIGHSPEED) ? "ENABLED" : "DISABLED")); + printf("Can signal pending SDIO IRQs :%s\n", + ((caps & MMCUTIL_SDIO_IRQ) ? "ENABLED" : "DISABLED")); + printf("Talks only SPI protocols :%s\n", + ((caps & MMCUTIL_SPI) ? "ENABLED" : "DISABLED")); + printf("Needs polling for card-detection :%s\n", + ((caps & MMCUTIL_NEEDS_POLL) ? "ENABLED" : "DISABLED")); + printf("Can the host do 8 bit transfers :%s\n", + ((caps & MMCUTIL_8_BIT_DATA) ? "ENABLED" : "DISABLED")); + printf("Suspend (e)MMC/SD at idle :%s\n", + ((caps & MMCUTIL_AGGRESSIVE_PM) ? "ENABLED" : "DISABLED")); + printf("Nonremovable e.g. eMMC :%s\n", + ((caps & MMCUTIL_NONREMOVABLE) ? "ENABLED" : "DISABLED")); + printf("Waits while card is busy :%s\n", + ((caps & MMCUTIL_WAIT_WHILE_BUSY) ? "ENABLED" : "DISABLED")); + printf("Allow erase/trim commands :%s\n", + ((caps & MMCUTIL_ERASE) ? "ENABLED" : "DISABLED")); + printf("Can support DDR mode at 3.3V :%s\n", + ((caps & MMCUTIL_3_3V_DDR) ? "ENABLED" : "DISABLED")); + printf("Can support DDR mode at 1.8V :%s\n", + ((caps & MMCUTIL_1_8V_DDR) ? "ENABLED" : "DISABLED")); + printf("Can support DDR mode at 1.2V :%s\n", + ((caps & MMCUTIL_1_2V_DDR) ? "ENABLED" : "DISABLED")); + printf("Can power off after boot :%s\n", + ((caps & MMCUTIL_POWER_OFF_CARD) ? "ENABLED" : "DISABLED")); + printf("CMD14/CMD19 bus width ok :%s\n", + ((caps & MMCUTIL_BUS_WIDTH_TEST) ? "ENABLED" : "DISABLED")); + printf("Host supports UHS SDR12 mode :%s\n", + ((caps & MMCUTIL_UHS_SDR12) ? "ENABLED" : "DISABLED")); + printf("Host supports UHS SDR25 mode :%s\n", + ((caps & MMCUTIL_UHS_SDR25) ? "ENABLED" : "DISABLED")); + printf("Host supports UHS SDR50 mode :%s\n", + ((caps & MMCUTIL_UHS_SDR50) ? "ENABLED" : "DISABLED")); + printf("Host supports UHS SDR104 mode :%s\n", + ((caps & MMCUTIL_UHS_SDR104) ? "ENABLED" : "DISABLED")); + printf("Host supports UHS DDR50 mode :%s\n", + ((caps & MMCUTIL_UHS_DDR50) ? "ENABLED" : "DISABLED")); + printf("Host supports Driver Type A :%s\n", + ((caps & MMCUTIL_DRIVER_TYPE_A) ? "ENABLED" : "DISABLED")); + printf("Host supports Driver Type C :%s\n", + ((caps & MMCUTIL_DRIVER_TYPE_C) ? "ENABLED" : "DISABLED")); + printf("Host supports Driver Type D :%s\n", + ((caps & MMCUTIL_DRIVER_TYPE_D) ? "ENABLED" : "DISABLED")); + printf("RW reqs can be completed within mmc_request_done() :%s\n", + ((caps & MMCUTIL_DONE_COMPLETE) ? "ENABLED" : "DISABLED")); + printf("Enable card detect wake :%s\n", + ((caps & MMCUTIL_CD_WAKE) ? "ENABLED" : "DISABLED")); + printf("Commands during data transfer :%s\n", + ((caps & MMCUTIL_CMD_DURING_TFR) ? "ENABLED" : "DISABLED")); + printf("CMD23 supported. :%s\n", + ((caps & MMCUTIL_CMD23) ? "ENABLED" : "DISABLED")); + printf("Hardware reset :%s\n", + ((caps & MMCUTIL_HW_RESET) ? "ENABLED" : "DISABLED")); + printf("=============================================\n"); + return 0; +} + +int do_read_hostcaps2(int nargs, char **argv) +{ + __u32 caps2 = 0; + char caps_str[11]; + int fd, ret; + char *filepath; + + if (nargs != 2) { + fprintf(stderr, + "Usage: mmc hostcaps2 read </path/to/caps2>\n"); + exit(1); + } + + filepath = argv[1]; + + fd = open(filepath, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + memset(caps_str, 0, sizeof(caps_str)); + ret = read(fd, caps_str, sizeof(caps_str)); + if (ret < 0) { + fprintf(stderr, "Could not read host capabilities from %s\n", + filepath); + exit(1); + } + caps2 = strtol(&caps_str[2], NULL, 16); + + printf("=============================================\n"); + printf(" Host additional capabilities of %s are\n", filepath); + printf("=============================================\n"); + printf("Boot partition no access :%s\n", + ((caps2 & MMCUTIL2_BOOTPART_NOACC) ? "ENABLED" : "DISABLED")); + printf("Can do full power cycle :%s\n", + ((caps2 & MMCUTIL2_FULL_PWR_CYCLE) ? "ENABLED" : "DISABLED")); + printf("Can support HS200 1.8V SDR :%s\n", + ((caps2 & MMCUTIL2_HS200_1_8V_SDR) ? "ENABLED" : "DISABLED")); + printf("Can support HS200 1.2V SDR :%s\n", + ((caps2 & MMCUTIL2_HS200_1_2V_SDR) ? "ENABLED" : "DISABLED")); + printf("Card-detect signal active high :%s\n", + ((caps2 & MMCUTIL2_CD_ACTIVE_HIGH) ? "ENABLED" : "DISABLED")); + printf("Write-protect signal active high :%s\n", + ((caps2 & MMCUTIL2_RO_ACTIVE_HIGH) ? "ENABLED" : "DISABLED")); + printf("Don't power up before scan :%s\n", + ((caps2 & MMCUTIL2_NO_PRESCAN_POWERUP) ? + "ENABLED" : "DISABLED")); + printf("Can support HS400 1.8V :%s\n", + ((caps2 & MMCUTIL2_HS400_1_8V) ? "ENABLED" : "DISABLED")); + printf("Can support HS400 1.2V :%s\n", + ((caps2 & MMCUTIL2_HS400_1_2V) ? "ENABLED" : "DISABLED")); + printf("SDIO IRQ Nothread :%s\n", + ((caps2 & MMCUTIL2_SDIO_IRQ_NOTHREAD) ? "ENABLED" : "DISABLED")); + printf("No physical write protect pin, assume always read-write :%s\n", + ((caps2 & MMCUTIL2_NO_WRITE_PROTECT) ? "ENABLED" : "DISABLED")); + printf("Do not send SDIO commands during initialization :%s\n", + ((caps2 & MMCUTIL2_NO_SDIO) ? "ENABLED" : "DISABLED")); + printf("Host supports enhanced strobe :%s\n", + ((caps2 & MMCUTIL2_HS400_ES) ? "ENABLED" : "DISABLED")); + printf("Do not send SD commands during initialization :%s\n", + ((caps2 & MMCUTIL2_NO_SD) ? "ENABLED" : "DISABLED")); + printf("Do not send (e)MMC commands during initialization :%s\n", + ((caps2 & MMCUTIL2_NO_MMC) ? "ENABLED" : "DISABLED")); + printf("Has eMMC command queue engine :%s\n", + ((caps2 & MMCUTIL2_CQE) ? "ENABLED" : "DISABLED")); + printf("CQE can issue a direct command :%s\n", + ((caps2 & MMCUTIL2_CQE_DCMD) ? "ENABLED" : "DISABLED")); + printf("=============================================\n"); + return 0; +} + int do_read_extcsd(int nargs, char **argv) { __u8 ext_csd[512], ext_csd_rev, reg; diff --git a/mmc_cmds.h b/mmc_cmds.h index 9d3246c..fce98ed 100644 --- a/mmc_cmds.h +++ b/mmc_cmds.h @@ -18,6 +18,8 @@ */ /* mmc_cmds.c */ +int do_read_hostcaps(int nargs, char **argv); +int do_read_hostcaps2(int nargs, char **argv); int do_read_extcsd(int nargs, char **argv); int do_write_extcsd(int nargs, char **argv); int do_writeprotect_boot_get(int nargs, char **argv); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html