summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/ti/dra7xx/README1
-rw-r--r--common/cmd_mmc.c37
-rw-r--r--drivers/mmc/mmc.c12
-rw-r--r--include/mmc.h3
4 files changed, 53 insertions, 0 deletions
diff --git a/board/ti/dra7xx/README b/board/ti/dra7xx/README
index 2fdaeac31e..533da01a34 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 bd1edc8c84..c1916c9b56 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 eccdbc4b61..16051e52ff 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 8a8297437b..c0a1d9e022 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