From: LI Qingwu <Qing-wu.Li@xxxxxxxxxxxxxxxxxxxxxxx> Add new sub-command to enable the write reliability. Signed-off-by: LI Qingwu <Qing-wu.Li@xxxxxxxxxxxxxxxxxxxxxxx> [m.felsch@xxxxxxxxxxxxxx: minor cleanups] Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx> --- commands/mmc.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- include/mci.h | 4 +++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/commands/mmc.c b/commands/mmc.c index 1e62b71850e0..1009b16bfdf7 100644 --- a/commands/mmc.c +++ b/commands/mmc.c @@ -147,6 +147,67 @@ static int do_mmc_enh_area(int argc, char *argv[]) return COMMAND_ERROR; } +static int do_mmc_write_reliability(int argc, char *argv[]) +{ + const char *devpath; + struct mci *mci; + u8 *ext_csd; + + if (argc - optind != 1) { + printf("Usage: mmc write_reliability /dev/mmcX\n"); + return COMMAND_ERROR_USAGE; + } + + devpath = argv[optind]; + + mci = mci_get_device_by_devpath(devpath); + if (!mci) { + printf("Failure to open %s as mci device\n", devpath); + return COMMAND_ERROR; + } + + ext_csd = mci_get_ext_csd(mci); + if (IS_ERR(ext_csd)) + return COMMAND_ERROR; + + if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED]) { + printf("Partitioning already finalized\n"); + goto error; + } + + if (!(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_EN_REL_WR)) { + printf("Device doesn't support the enhanced definition of reliable write\n"); + goto error; + } + + if (!(ext_csd[EXT_CSD_WR_REL_PARAM] & EXT_CSD_HS_CTRL_REL)) { + printf("Device doesn't support WR_REL_SET writes\n"); + goto error; + } + + /* + * Host has one opportunity to write all of the bits. Separate writes to + * individual bits are not permitted so set all bits for now. + */ + if ((ext_csd[EXT_CSD_WR_REL_SET] & 0x1f) != 0x1f) { + int ret; + + ret = mci_switch(mci, EXT_CSD_WR_REL_SET, 0x1f); + if (ret) { + printf("Failure to write to EXT_CSD_WR_REL_SET\n"); + goto error; + } + } + + free(ext_csd); + + return COMMAND_SUCCESS; + +error: + free(ext_csd); + return COMMAND_ERROR; +} + static struct { const char *cmd; int (*func)(int argc, char *argv[]); @@ -154,6 +215,9 @@ static struct { { .cmd = "enh_area", .func = do_mmc_enh_area, + }, { + .cmd = "write_reliability", + .func = do_mmc_write_reliability, } }; @@ -189,11 +253,13 @@ BAREBOX_CMD_HELP_TEXT("The subcommand enh_area creates an enhanced area of") BAREBOX_CMD_HELP_TEXT("maximal size.") BAREBOX_CMD_HELP_TEXT("Note, with -c this is an irreversible action.") BAREBOX_CMD_HELP_OPT("-c", "complete partitioning") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("The subcommand write_reliability enable write reliability") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(mmc) .cmd = do_mmc, - BAREBOX_CMD_OPTS("enh_area [-c] /dev/mmcX") + BAREBOX_CMD_OPTS("write_reliability|enh_area [-c] /dev/mmcX") BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP) BAREBOX_CMD_HELP(cmd_mmc_help) BAREBOX_CMD_END diff --git a/include/mci.h b/include/mci.h index f38384613728..4fed8d739284 100644 --- a/include/mci.h +++ b/include/mci.h @@ -307,6 +307,10 @@ /* register PARTITIONING_SUPPORT [160] */ #define EXT_CSD_ENH_ATTRIBUTE_EN_MASK (1 << 1) +/* register EXT_CSD_WR_REL_PARAM [166] */ +#define EXT_CSD_HS_CTRL_REL (1 << 0) +#define EXT_CSD_EN_REL_WR (1 << 2) + /* register BUS_WIDTH [183], field Bus Mode Selection [4:0] */ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ -- 2.39.2