3 * Kyle Harris, kharris@nexus-tech.net
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #ifndef CONFIG_GENERIC_MMC
29 static int curr_device = -1;
31 int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
40 if (strcmp(argv[1], "init") == 0) {
46 } else if (argc == 3) {
47 dev = (int)simple_strtoul(argv[2], NULL, 10);
53 if (mmc_legacy_init(dev) != 0) {
54 puts("No MMC card found\n");
59 printf("mmc%d is available\n", curr_device);
60 } else if (strcmp(argv[1], "device") == 0) {
62 if (curr_device < 0) {
63 puts("No MMC device available\n");
66 } else if (argc == 3) {
67 dev = (int)simple_strtoul(argv[2], NULL, 10);
69 #ifdef CONFIG_SYS_MMC_SET_DEV
70 if (mmc_set_dev(dev) != 0)
79 printf("mmc%d is current device\n", curr_device);
91 "init [dev] - init MMC sub system\n"
92 "mmc device [dev] - show or set current device"
94 #else /* !CONFIG_GENERIC_MMC */
96 #ifdef CONFIG_BOOT_PARTITION_ACCESS
97 #define MMC_PARTITION_SWITCH(mmc, part, enable_boot) \
102 "\nError: SD partition can only be 0 or 1\n");\
105 if (sd_switch_partition(mmc, part) < 0) { \
107 printf("\nError: Unable to switch SD "\
113 if (mmc_switch_partition(mmc, part, enable_boot) \
115 printf("Error: Fail to switch " \
116 "partition to %d\n", part); \
123 static void print_mmcinfo(struct mmc *mmc)
125 printf("Device: %s\n", mmc->name);
126 printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
127 printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
128 printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff,
129 (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
130 (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
132 printf("Tran Speed: %d\n", mmc->tran_speed);
133 printf("Rd Block Len: %d\n", mmc->read_bl_len);
135 printf("%s version %d.%d\n", IS_SD(mmc) ? "SD" : "MMC",
136 (mmc->version >> 4) & 0xf, mmc->version & 0xf);
138 printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
139 printf("Capacity: %lld\n", mmc->capacity);
141 #ifdef CONFIG_EMMC_DDR_MODE
142 if (mmc->bus_width == EMMC_MODE_4BIT_DDR ||
143 mmc->bus_width == EMMC_MODE_8BIT_DDR)
144 printf("Bus Width: %d-bit DDR\n", (mmc->bus_width >> 8));
147 printf("Bus Width: %d-bit\n", mmc->bus_width);
148 #ifdef CONFIG_BOOT_PARTITION_ACCESS
149 if (mmc->boot_size_mult == 0) {
150 printf("Boot Partition Size: %s\n", "No boot partition available");
152 printf("Boot Partition Size: %5dKB\n", mmc->boot_size_mult * 128);
154 printf("Current Partition for boot: ");
155 switch (mmc->boot_config & EXT_CSD_BOOT_PARTITION_ENABLE_MASK) {
156 case EXT_CSD_BOOT_PARTITION_DISABLE:
157 printf("Not bootable\n");
159 case EXT_CSD_BOOT_PARTITION_PART1:
160 printf("Boot partition 1\n");
162 case EXT_CSD_BOOT_PARTITION_PART2:
163 printf("Boot partition 2\n");
165 case EXT_CSD_BOOT_PARTITION_USER:
166 printf("User area\n");
176 int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
184 dev_num = simple_strtoul(argv[1], NULL, 0);
186 mmc = find_mmc_device(dev_num);
190 puts("MMC card init failed!\n");
198 U_BOOT_CMD(mmcinfo, 2, 0, do_mmcinfo,
199 "mmcinfo <dev num>-- display MMC info",
203 int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
206 #ifdef CONFIG_BOOT_PARTITION_ACCESS
212 if (strcmp(argv[1], "rescan") == 0) {
213 int dev = simple_strtoul(argv[2], NULL, 10);
214 struct mmc *mmc = find_mmc_device(dev);
227 printf("Usage:\n%s\n", cmdtp->usage);
231 if (!strcmp(argv[1], "list")) {
232 print_mmc_devices('\n');
236 #ifdef CONFIG_BOOT_PARTITION_ACCESS
237 case 7: /* Fall through */
238 part = simple_strtoul(argv[6], NULL, 10);
240 default: /* at least 5 args */
241 if (strcmp(argv[1], "read") == 0) {
242 int dev = simple_strtoul(argv[2], NULL, 10);
243 void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
244 u32 cnt = simple_strtoul(argv[5], NULL, 16);
246 u32 blk = simple_strtoul(argv[4], NULL, 16);
248 struct mmc *mmc = find_mmc_device(dev);
253 #ifdef CONFIG_BOOT_PARTITION_ACCESS
254 printf("\nMMC read: dev # %d, block # %d, "
255 "count %d partition # %d ... \n",
256 dev, blk, cnt, part);
258 printf("\nMMC read: dev # %d, block # %d,"
259 "count %d ... \n", dev, blk, cnt);
264 #ifdef CONFIG_BOOT_PARTITION_ACCESS
265 if (((mmc->boot_config &
266 EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
269 * After mmc_init, we now know whether
270 * this is a eSD/eMMC which support boot
273 MMC_PARTITION_SWITCH(mmc, part, 0);
277 n = mmc->block_dev.block_read(dev, blk, cnt, addr);
279 /* flush cache after read */
280 flush_cache((ulong)addr, cnt * 512); /* FIXME */
282 printf("%d blocks read: %s\n",
283 n, (n==cnt) ? "OK" : "ERROR");
284 return (n == cnt) ? 0 : 1;
285 } else if (strcmp(argv[1], "write") == 0) {
286 int dev = simple_strtoul(argv[2], NULL, 10);
287 void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
288 u32 cnt = simple_strtoul(argv[5], NULL, 16);
291 struct mmc *mmc = find_mmc_device(dev);
293 int blk = simple_strtoul(argv[4], NULL, 16);
298 #ifdef CONFIG_BOOT_PARTITION_ACCESS
299 printf("\nMMC write: dev # %d, block # %d, "
300 "count %d, partition # %d ... \n",
301 dev, blk, cnt, part);
303 printf("\nMMC write: dev # %d, block # %d, "
310 #ifdef CONFIG_BOOT_PARTITION_ACCESS
311 if (((mmc->boot_config &
312 EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
315 * After mmc_init, we now know whether this is a
316 * eSD/eMMC which support boot partition
318 MMC_PARTITION_SWITCH(mmc, part, 1);
322 n = mmc->block_dev.block_write(dev, blk, cnt, addr);
324 printf("%d blocks written: %s\n",
325 n, (n == cnt) ? "OK" : "ERROR");
326 return (n == cnt) ? 0 : 1;
328 printf("Usage:\n%s\n", cmdtp->usage);
336 #ifndef CONFIG_BOOT_PARTITION_ACCESS
338 mmc, 6, 1, do_mmcops,
340 "mmc read <device num> addr blk# cnt\n"
341 "mmc write <device num> addr blk# cnt\n"
342 "mmc rescan <device num>\n"
343 "mmc list - lists available devices");
346 mmc, 7, 1, do_mmcops,
348 "mmc read <device num> addr blk# cnt [partition]\n"
349 "mmc write <device num> addr blk# cnt [partition]\n"
350 "mmc rescan <device num>\n"
351 "mmc list - lists available devices");