mmc: Add 'mmc rst-function' sub-command
authorTom Rini <trini@ti.com>
Fri, 7 Feb 2014 19:15:20 +0000 (14:15 -0500)
committerPantelis Antoniou <panto@antoniou-consulting.com>
Wed, 2 Apr 2014 10:02:58 +0000 (13:02 +0300)
Some eMMC chips may need the RST_n_FUNCTION bit set to a non-zero value
in order for warm reset of the system to work.  Details on this being
required will be part of the eMMC datasheet.  Also add using this
command to the dra7xx README.

* Whitespace fix by panto

Signed-off-by: Tom Rini <trini@ti.com>
Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>
board/ti/dra7xx/README
common/cmd_mmc.c
drivers/mmc/mmc.c
include/mmc.h

index 2fdaeac31eec1c936a5e17ca890f80beea302430..533da01a347e6391ee3eaf3e6eb396e86354a280 100644 (file)
@@ -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
index bd1edc8c844871e85be5b3e812436e082d66f40e..c1916c9b56a6456bebb115367308d8e03c5f268a 100644 (file)
@@ -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"
        );
index eccdbc4b617716fea2dad4916fa5e0b3e376a79a..16051e52ff1659d24f5a07f46e82d47e21503182 100644 (file)
@@ -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
index 8a8297437bbb51261fe641ebfc7c58f9df4ae206..c0a1d9e0221fad2d19b430bc0ac5f4acf1096516 100644 (file)
 #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