]> git.sur5r.net Git - u-boot/blobdiff - cmd/mmc.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / cmd / mmc.c
index 5def4ea1a29ad0b6c72bd60b3c4132c749a1d6ca..3920a1836a594903116841f809676f34ff022061 100644 (file)
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -1,14 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2003
  * Kyle Harris, kharris@nexus-tech.net
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <command.h>
 #include <console.h>
 #include <mmc.h>
+#include <sparse_format.h>
+#include <image-sparse.h>
 
 static int curr_device = -1;
 
@@ -23,7 +24,12 @@ static void print_mmcinfo(struct mmc *mmc)
                        (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
                        (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
 
-       printf("Tran Speed: %d\n", mmc->tran_speed);
+       printf("Bus Speed: %d\n", mmc->clock);
+#if CONFIG_IS_ENABLED(MMC_VERBOSE)
+       printf("Mode : %s\n", mmc_mode_name(mmc->selected_mode));
+       mmc_dump_capabilities("card capabilities", mmc->card_caps);
+       mmc_dump_capabilities("host capabilities", mmc->host_caps);
+#endif
        printf("Rd Block Len: %d\n", mmc->read_bl_len);
 
        printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
@@ -40,15 +46,19 @@ static void print_mmcinfo(struct mmc *mmc)
        printf("Bus Width: %d-bit%s\n", mmc->bus_width,
                        mmc->ddr_mode ? " DDR" : "");
 
+#if CONFIG_IS_ENABLED(MMC_WRITE)
        puts("Erase Group Size: ");
        print_size(((u64)mmc->erase_grp_size) << 9, "\n");
+#endif
 
        if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
                bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
                bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
 
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
                puts("HC WP Group Size: ");
                print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
+#endif
 
                puts("User Capacity: ");
                print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
@@ -118,7 +128,7 @@ static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        return CMD_RET_SUCCESS;
 }
 
-#ifdef CONFIG_SUPPORT_EMMC_RPMB
+#if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
 static int confirm_key_prog(void)
 {
        puts("Warning: Programming authentication key can be done only once !\n"
@@ -297,6 +307,73 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
+
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
+static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk,
+                                lbaint_t blkcnt, const void *buffer)
+{
+       struct blk_desc *dev_desc = info->priv;
+
+       return blk_dwrite(dev_desc, blk, blkcnt, buffer);
+}
+
+static lbaint_t mmc_sparse_reserve(struct sparse_storage *info,
+                                  lbaint_t blk, lbaint_t blkcnt)
+{
+       return blkcnt;
+}
+
+static int do_mmc_sparse_write(cmd_tbl_t *cmdtp, int flag,
+                              int argc, char * const argv[])
+{
+       struct sparse_storage sparse;
+       struct blk_desc *dev_desc;
+       struct mmc *mmc;
+       char dest[11];
+       void *addr;
+       u32 blk;
+
+       if (argc != 3)
+               return CMD_RET_USAGE;
+
+       addr = (void *)simple_strtoul(argv[1], NULL, 16);
+       blk = simple_strtoul(argv[2], NULL, 16);
+
+       if (!is_sparse_image(addr)) {
+               printf("Not a sparse image\n");
+               return CMD_RET_FAILURE;
+       }
+
+       mmc = init_mmc_device(curr_device, false);
+       if (!mmc)
+               return CMD_RET_FAILURE;
+
+       printf("\nMMC Sparse write: dev # %d, block # %d ... ",
+              curr_device, blk);
+
+       if (mmc_getwp(mmc) == 1) {
+               printf("Error: card is write protected!\n");
+               return CMD_RET_FAILURE;
+       }
+
+       dev_desc = mmc_get_blk_desc(mmc);
+       sparse.priv = dev_desc;
+       sparse.blksz = 512;
+       sparse.start = blk;
+       sparse.size = dev_desc->lba - blk;
+       sparse.write = mmc_sparse_write;
+       sparse.reserve = mmc_sparse_reserve;
+       sparse.mssg = NULL;
+       sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz);
+
+       if (write_sparse_image(&sparse, dest, addr, NULL))
+               return CMD_RET_FAILURE;
+       else
+               return CMD_RET_SUCCESS;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(MMC_WRITE)
 static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
                        int argc, char * const argv[])
 {
@@ -355,6 +432,8 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
 
        return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
 }
+#endif
+
 static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
                         int argc, char * const argv[])
 {
@@ -433,6 +512,7 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
        return CMD_RET_SUCCESS;
 }
 
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
 static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
                             int argc, char * const argv[])
 {
@@ -582,6 +662,7 @@ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
                return CMD_RET_FAILURE;
        }
 }
+#endif
 
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
 static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
@@ -785,20 +866,27 @@ static int do_mmc_bkops_enable(cmd_tbl_t *cmdtp, int flag,
 static cmd_tbl_t cmd_mmc[] = {
        U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
        U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
+#if CONFIG_IS_ENABLED(MMC_WRITE)
        U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
        U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
+#endif
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
+       U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
+#endif
        U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
        U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
        U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
        U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
        U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
+#endif
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
        U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
        U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
        U_BOOT_CMD_MKENT(partconf, 5, 0, do_mmc_partconf, "", ""),
        U_BOOT_CMD_MKENT(rst-function, 3, 0, do_mmc_rst_func, "", ""),
 #endif
-#ifdef CONFIG_SUPPORT_EMMC_RPMB
+#if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
        U_BOOT_CMD_MKENT(rpmb, CONFIG_SYS_MAXARGS, 1, do_mmcrpmb, "", ""),
 #endif
        U_BOOT_CMD_MKENT(setdsr, 2, 0, do_mmc_setdsr, "", ""),
@@ -839,11 +927,15 @@ U_BOOT_CMD(
        "info - display info of the current MMC device\n"
        "mmc read addr blk# cnt\n"
        "mmc write addr blk# cnt\n"
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
+       "mmc swrite addr blk#\n"
+#endif
        "mmc erase blk# cnt\n"
        "mmc rescan\n"
        "mmc part - lists available partition on current mmc device\n"
        "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
        "mmc list - lists available devices\n"
+#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
        "mmc hwpartition [args...] - does hardware partitioning\n"
        "  arguments (sizes in 512-byte blocks):\n"
        "    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n"
@@ -851,6 +943,7 @@ U_BOOT_CMD(
        "    [check|set|complete] - mode, complete set partitioning completed\n"
        "  WARNING: Partitioning is a write-once setting once it is set to complete.\n"
        "  Power cycling is required to initialize partitions after set to complete.\n"
+#endif
 #ifdef CONFIG_SUPPORT_EMMC_BOOT
        "mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
        " - Set the BOOT_BUS_WIDTH field of the specified device\n"
@@ -862,7 +955,7 @@ U_BOOT_CMD(
        " - 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
-#ifdef CONFIG_SUPPORT_EMMC_RPMB
+#if CONFIG_IS_ENABLED(CMD_MMC_RPMB)
        "mmc rpmb read addr blk# cnt [address of auth-key] - block size is 256 bytes\n"
        "mmc rpmb write addr blk# cnt <address of auth-key> - block size is 256 bytes\n"
        "mmc rpmb key <address of auth-key> - program the RPMB authentication key.\n"