*/
-#include <common.h>
#include <blk.h>
#include <command.h>
#include <console.h>
#include <display_options.h>
+#include <mapmem.h>
#include <memalign.h>
#include <mmc.h>
#include <part.h>
#include <sparse_format.h>
#include <image-sparse.h>
+#include <vsprintf.h>
+#include <linux/ctype.h>
static int curr_device = -1;
curr_device = 0;
else {
puts("No MMC device available\n");
- return 1;
+ return CMD_RET_FAILURE;
}
}
if (argc == 5)
key_addr = (void *)hextoul(argv[4], NULL);
- printf("\nMMC RPMB read: dev # %d, block # %d, count %d ... ",
+ printf("MMC RPMB read: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
n = mmc_rpmb_read(mmc, addr, blk, cnt, key_addr);
cnt = hextoul(argv[3], NULL);
key_addr = (void *)hextoul(argv[4], NULL);
- printf("\nMMC RPMB write: dev # %d, block # %d, count %d ... ",
+ printf("MMC RPMB write: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
n = mmc_rpmb_write(mmc, addr, blk, cnt, key_addr);
{
struct mmc *mmc;
u32 blk, cnt, n;
- void *addr;
+ void *ptr;
if (argc != 4)
return CMD_RET_USAGE;
- addr = (void *)hextoul(argv[1], NULL);
+ ptr = map_sysmem(hextoul(argv[1], NULL), 0);
blk = hextoul(argv[2], NULL);
cnt = hextoul(argv[3], NULL);
if (!mmc)
return CMD_RET_FAILURE;
- printf("\nMMC read: dev # %d, block # %d, count %d ... ",
+ printf("MMC read: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
- n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
+ n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, ptr);
printf("%d blocks read: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+ unmap_sysmem(ptr);
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
}
if (!mmc)
return CMD_RET_FAILURE;
- printf("\nMMC Sparse write: dev # %d, block # %d ... ",
+ printf("MMC Sparse write: dev # %d, block # %d ... ",
curr_device, blk);
if (mmc_getwp(mmc) == 1) {
{
struct mmc *mmc;
u32 blk, cnt, n;
- void *addr;
+ void *ptr;
if (argc != 4)
return CMD_RET_USAGE;
- addr = (void *)hextoul(argv[1], NULL);
+ ptr = map_sysmem(hextoul(argv[1], NULL), 0);
blk = hextoul(argv[2], NULL);
cnt = hextoul(argv[3], NULL);
if (!mmc)
return CMD_RET_FAILURE;
- printf("\nMMC write: dev # %d, block # %d, count %d ... ",
+ printf("MMC write: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
if (mmc_getwp(mmc) == 1) {
printf("Error: card is write protected!\n");
return CMD_RET_FAILURE;
}
- n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
+ n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, ptr);
printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR");
+ unmap_sysmem(ptr);
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
}
int argc, char *const argv[])
{
struct mmc *mmc;
+ struct disk_partition info;
u32 blk, cnt, n;
- if (argc != 3)
+ if (argc < 2 || argc > 3)
return CMD_RET_USAGE;
- blk = hextoul(argv[1], NULL);
- cnt = hextoul(argv[2], NULL);
-
mmc = init_mmc_device(curr_device, false);
if (!mmc)
return CMD_RET_FAILURE;
- printf("\nMMC erase: dev # %d, block # %d, count %d ... ",
+ if (argc == 3) {
+ blk = hextoul(argv[1], NULL);
+ cnt = hextoul(argv[2], NULL);
+ } else if (part_get_info_by_name(mmc_get_blk_desc(mmc), argv[1], &info) >= 0) {
+ blk = info.start;
+ cnt = info.size;
+ } else {
+ return CMD_RET_FAILURE;
+ }
+
+ printf("MMC erase: dev # %d, block # %d, count %d ... ",
curr_device, blk, cnt);
if (mmc_getwp(mmc) == 1) {
printf("EXT_CSD[179], PARTITION_CONFIG:\n"
"BOOT_ACK: 0x%x\n"
- "BOOT_PARTITION_ENABLE: 0x%x\n"
- "PARTITION_ACCESS: 0x%x\n", ack, part, access);
+ "BOOT_PARTITION_ENABLE: 0x%x (%s)\n"
+ "PARTITION_ACCESS: 0x%x (%s)\n", ack, part, emmc_boot_part_names[part],
+ access, emmc_hwpart_names[access]);
return CMD_RET_SUCCESS;
}
static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- int dev;
+ int ret, dev;
struct mmc *mmc;
u8 ack, part_num, access;
}
if (argc == 2 || argc == 3)
- return mmc_partconf_print(mmc, argc == 3 ? argv[2] : NULL);
+ return mmc_partconf_print(mmc, cmd_arg2(argc, argv));
+ /* BOOT_ACK */
ack = dectoul(argv[2], NULL);
- part_num = dectoul(argv[3], NULL);
- access = dectoul(argv[4], NULL);
+ /* BOOT_PARTITION_ENABLE */
+ if (!isdigit(*argv[3])) {
+ for (part_num = ARRAY_SIZE(emmc_boot_part_names) - 1; part_num > 0; part_num--) {
+ if (!strcmp(argv[3], emmc_boot_part_names[part_num]))
+ break;
+ }
+ } else {
+ part_num = dectoul(argv[3], NULL);
+ }
+ /* PARTITION_ACCESS */
+ if (!isdigit(*argv[4])) {
+ for (access = ARRAY_SIZE(emmc_hwpart_names) - 1; access > 0; access--) {
+ if (!strcmp(argv[4], emmc_hwpart_names[access]))
+ break;
+ }
+ } else {
+ access = dectoul(argv[4], NULL);
+ }
/* acknowledge to be sent during boot operation */
- return mmc_set_part_conf(mmc, ack, part_num, access);
+ ret = mmc_set_part_conf(mmc, ack, part_num, access);
+ if (ret != 0)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
}
static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- int dev;
+ int ret, dev;
struct mmc *mmc;
u8 enable;
return CMD_RET_FAILURE;
}
- return mmc_set_rst_n_function(mmc, enable);
+ ret = mmc_set_rst_n_function(mmc, enable);
+ if (ret != 0)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
}
#endif
static int do_mmc_setdsr(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_SUCCESS;
}
+#if CONFIG_IS_ENABLED(CMD_MMC_REG)
+static int do_mmc_reg(struct cmd_tbl *cmdtp, int flag,
+ int argc, char *const argv[])
+{
+ ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+ struct mmc *mmc;
+ int i, ret;
+ u32 off;
+
+ if (argc < 3 || argc > 5)
+ return CMD_RET_USAGE;
+
+ mmc = find_mmc_device(curr_device);
+ if (!mmc) {
+ printf("no mmc device at slot %x\n", curr_device);
+ return CMD_RET_FAILURE;
+ }
+
+ if (IS_SD(mmc)) {
+ printf("SD registers are not supported\n");
+ return CMD_RET_FAILURE;
+ }
+
+ off = simple_strtoul(argv[3], NULL, 10);
+ if (!strcmp(argv[2], "cid")) {
+ if (off > 3)
+ return CMD_RET_USAGE;
+ printf("CID[%i]: 0x%08x\n", off, mmc->cid[off]);
+ if (argv[4])
+ env_set_hex(argv[4], mmc->cid[off]);
+ return CMD_RET_SUCCESS;
+ }
+ if (!strcmp(argv[2], "csd")) {
+ if (off > 3)
+ return CMD_RET_USAGE;
+ printf("CSD[%i]: 0x%08x\n", off, mmc->csd[off]);
+ if (argv[4])
+ env_set_hex(argv[4], mmc->csd[off]);
+ return CMD_RET_SUCCESS;
+ }
+ if (!strcmp(argv[2], "dsr")) {
+ printf("DSR: 0x%08x\n", mmc->dsr);
+ if (argv[4])
+ env_set_hex(argv[4], mmc->dsr);
+ return CMD_RET_SUCCESS;
+ }
+ if (!strcmp(argv[2], "ocr")) {
+ printf("OCR: 0x%08x\n", mmc->ocr);
+ if (argv[4])
+ env_set_hex(argv[4], mmc->ocr);
+ return CMD_RET_SUCCESS;
+ }
+ if (!strcmp(argv[2], "rca")) {
+ printf("RCA: 0x%08x\n", mmc->rca);
+ if (argv[4])
+ env_set_hex(argv[4], mmc->rca);
+ return CMD_RET_SUCCESS;
+ }
+ if (!strcmp(argv[2], "extcsd") &&
+ mmc->version >= MMC_VERSION_4_41) {
+ ret = mmc_send_ext_csd(mmc, ext_csd);
+ if (ret)
+ return CMD_RET_FAILURE;
+ if (!strcmp(argv[3], "all")) {
+ /* Dump the entire register */
+ printf("EXT_CSD:");
+ for (i = 0; i < MMC_MAX_BLOCK_LEN; i++) {
+ if (!(i % 10))
+ printf("\n%03i: ", i);
+ printf(" %02x", ext_csd[i]);
+ }
+ printf("\n");
+ return CMD_RET_SUCCESS;
+ }
+ off = simple_strtoul(argv[3], NULL, 10);
+ if (off > 512)
+ return CMD_RET_USAGE;
+ printf("EXT_CSD[%i]: 0x%02x\n", off, ext_csd[off]);
+ if (argv[4])
+ env_set_hex(argv[4], ext_csd[off]);
+ return CMD_RET_SUCCESS;
+ }
+
+ return CMD_RET_FAILURE;
+}
+#endif
+
static struct cmd_tbl cmd_mmc[] = {
U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
U_BOOT_CMD_MKENT(bkops-enable, 2, 0, do_mmc_bkops_enable, "", ""),
U_BOOT_CMD_MKENT(bkops, 4, 0, do_mmc_bkops, "", ""),
#endif
+#if CONFIG_IS_ENABLED(CMD_MMC_REG)
+ U_BOOT_CMD_MKENT(reg, 5, 0, do_mmc_reg, "", ""),
+#endif
};
static int do_mmcops(struct cmd_tbl *cmdtp, int flag, int argc,
"mmc swrite addr blk#\n"
#endif
"mmc erase blk# cnt\n"
+ "mmc erase partname\n"
"mmc rescan [mode]\n"
"mmc part - lists available partition on current mmc device\n"
"mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode\n"
" WARNING: This is a write-once setting.\n"
"mmc bkops <dev> [auto|manual] [enable|disable]\n"
" - configure background operations handshake on device\n"
+#endif
+#if CONFIG_IS_ENABLED(CMD_MMC_REG)
+ "mmc reg read <reg> <offset> [env] - read card register <reg> offset <offset>\n"
+ " (optionally into [env] variable)\n"
+ " - reg: cid/csd/dsr/ocr/rca/extcsd\n"
+ " - offset: for cid/csd [0..3], for extcsd [0..511,all]\n"
#endif
);