diff --git a/board/ti/dra7xx/README b/board/ti/dra7xx/README index 2fdaeac..533da01 100644 --- a/board/ti/dra7xx/README +++ b/board/ti/dra7xx/README @@ -23,3 +23,4 @@ U-Boot # tftp ${loadaddr} dra7xx/u-boot.img U-Boot # mmc write ${loadaddr} 300 400 U-Boot # mmc bootbus 1 2 0 2 U-Boot # mmc partconf 1 1 1 0 +U-Boot # mmc rst-function 1 1 diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index bd1edc8..c1916c9 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -330,6 +330,40 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("EMMC boot partition Size change Failed.\n"); return 1; } + } else if (strcmp(argv[1], "rst-function") == 0) { + /* + * Set the RST_n_ENABLE bit of RST_n_FUNCTION + * The only valid values are 0x0, 0x1 and 0x2 and writing + * a value of 0x1 or 0x2 sets the value permanently. + */ + int dev; + struct mmc *mmc; + u8 enable; + + if (argc == 4) { + dev = simple_strtoul(argv[2], NULL, 10); + enable = simple_strtoul(argv[3], NULL, 10); + } else { + return CMD_RET_USAGE; + } + + if (enable > 2 || enable < 0) { + puts("Invalid RST_n_ENABLE value\n"); + return CMD_RET_USAGE; + } + + mmc = find_mmc_device(dev); + if (!mmc) { + printf("no mmc device at slot %x\n", dev); + return 1; + } + + if (IS_SD(mmc)) { + puts("RST_n_FUNCTION only exists on eMMC\n"); + return 1; + } + + return mmc_set_rst_n_function(mmc, enable); #endif /* CONFIG_SUPPORT_EMMC_BOOT */ } @@ -436,6 +470,9 @@ U_BOOT_CMD( " - Change sizes of boot and RPMB partitions of specified device\n" "mmc partconf dev boot_ack boot_partition partition_access\n" " - Change the bits of the PARTITION_CONFIG field of the specified device\n" + "mmc rst-function dev value\n" + " - Change the RST_n_FUNCTION field of the specified device\n" + " WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.\n" #endif "mmc setdsr - set DSR register value\n" ); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index eccdbc4..16051e5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1513,4 +1513,16 @@ int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access) return err; return 0; } + +/* + * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value + * for enable. Note that this is a write-once field for non-zero values. + * + * Returns 0 on success. + */ +int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) +{ + return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION, + enable); +} #endif diff --git a/include/mmc.h b/include/mmc.h index 8a82974..c0a1d9e 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -150,6 +150,7 @@ #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ #define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ +#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ #define EXT_CSD_RPMB_MULT 168 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_BOOT_BUS_WIDTH 177 @@ -332,6 +333,8 @@ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize, int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access); /* Function to modify the BOOT_BUS_WIDTH field of EXT_CSD */ int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode); +/* Function to modify the RST_n_FUNCTION field of EXT_CSD */ +int mmc_set_rst_n_function(struct mmc *mmc, u8 enable); /** * Start device initialization and return immediately; it does not block on