]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_mmc.c
merged current version of git://git.denx.de/u-boot
[karo-tx-uboot.git] / common / cmd_mmc.c
1 /*
2  * (C) Copyright 2003
3  * Kyle Harris, kharris@nexus-tech.net
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
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.
12  *
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.
17  *
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,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <command.h>
26 #include <mmc.h>
27
28 static int curr_device = -1;
29 #ifndef CONFIG_GENERIC_MMC
30 int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
31 {
32         int dev;
33
34         if (argc < 2)
35                 return cmd_usage(cmdtp);
36
37         if (strcmp(argv[1], "init") == 0) {
38                 if (argc == 2) {
39                         if (curr_device < 0)
40                                 dev = 1;
41                         else
42                                 dev = curr_device;
43                 } else if (argc == 3) {
44                         dev = (int)simple_strtoul(argv[2], NULL, 10);
45                 } else {
46                         return cmd_usage(cmdtp);
47                 }
48
49                 if (mmc_legacy_init(dev) != 0) {
50                         puts("No MMC card found\n");
51                         return 1;
52                 }
53
54                 curr_device = dev;
55                 printf("mmc%d is available\n", curr_device);
56         } else if (strcmp(argv[1], "device") == 0) {
57                 if (argc == 2) {
58                         if (curr_device < 0) {
59                                 puts("No MMC device available\n");
60                                 return 1;
61                         }
62                 } else if (argc == 3) {
63                         dev = (int)simple_strtoul(argv[2], NULL, 10);
64
65 #ifdef CONFIG_SYS_MMC_SET_DEV
66                         if (mmc_set_dev(dev) != 0)
67                                 return 1;
68 #endif
69                         curr_device = dev;
70                 } else {
71                         return cmd_usage(cmdtp);
72                 }
73
74                 printf("mmc%d is current device\n", curr_device);
75         } else {
76                 return cmd_usage(cmdtp);
77         }
78
79         return 0;
80 }
81
82 U_BOOT_CMD(
83         mmc, 3, 1, do_mmc,
84         "MMC sub-system",
85         "init [dev] - init MMC sub system\n"
86         "mmc device [dev] - show or set current device"
87 );
88 #else /* !CONFIG_GENERIC_MMC */
89
90 <<<<<<< HEAD
91 #ifdef CONFIG_BOOT_PARTITION_ACCESS
92 #define MMC_PARTITION_SWITCH(mmc, part, enable_boot) \
93         do { \
94                 if (IS_SD(mmc)) {       \
95                         if (part > 1)   {\
96                                 printf( \
97                                 "\nError: SD partition can only be 0 or 1\n");\
98                                 return 1;       \
99                         }       \
100                         if (sd_switch_partition(mmc, part) < 0) {       \
101                                 if (part > 0) { \
102                                         printf("\nError: Unable to switch SD "\
103                                         "partition\n");\
104                                         return 1;       \
105                                 }       \
106                         }       \
107                 } else {        \
108                         if (mmc_switch_partition(mmc, part, enable_boot) \
109                                 < 0) {  \
110                                 printf("Error: Fail to switch " \
111                                         "partition to %d\n", part);     \
112                                 return 1;       \
113                         }       \
114                 } \
115         } while (0)
116 #endif
117
118 =======
119 enum mmc_state {
120         MMC_INVALID,
121         MMC_READ,
122         MMC_WRITE,
123         MMC_ERASE,
124 };
125 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
126 static void print_mmcinfo(struct mmc *mmc)
127 {
128         printf("Device: %s\n", mmc->name);
129         printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
130         printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
131         printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff,
132                         (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
133                         (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
134
135         printf("Tran Speed: %d\n", mmc->tran_speed);
136         printf("Rd Block Len: %d\n", mmc->read_bl_len);
137
138         printf("%s version %d.%d\n", IS_SD(mmc) ? "SD" : "MMC",
139                         (mmc->version >> 4) & 0xf, mmc->version & 0xf);
140
141         printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
142         puts("Capacity: ");
143         print_size(mmc->capacity, "\n");
144
145         printf("Bus Width: %d-bit\n", mmc->bus_width);
146 }
147
148 int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
149 {
150         struct mmc *mmc;
151
152         if (curr_device < 0) {
153                 if (get_mmc_num() > 0)
154                         curr_device = 0;
155                 else {
156                         puts("No MMC device available\n");
157                         return 1;
158                 }
159         }
160
161         mmc = find_mmc_device(curr_device);
162
163         if (mmc) {
164 <<<<<<< HEAD
165                 if (mmc_init(mmc))
166                         puts("MMC card init failed!\n");
167                 else
168                         print_mmcinfo(mmc);
169 =======
170                 mmc_init(mmc);
171
172                 print_mmcinfo(mmc);
173                 return 0;
174         } else {
175                 printf("no mmc device at slot %x\n", curr_device);
176                 return 1;
177 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
178         }
179 }
180
181 <<<<<<< HEAD
182 U_BOOT_CMD(mmcinfo, 2, 0, do_mmcinfo,
183         "mmcinfo <dev num>-- display MMC info",
184 =======
185 U_BOOT_CMD(
186         mmcinfo, 1, 0, do_mmcinfo,
187         "display MMC info",
188         "    - device number of the device to dislay info of\n"
189 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
190         ""
191 );
192
193 int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
194 {
195 <<<<<<< HEAD
196         int rc = 0;
197 #ifdef CONFIG_BOOT_PARTITION_ACCESS
198         u32 part = 0;
199 #endif
200 =======
201         enum mmc_state state;
202 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
203
204         if (argc < 2)
205                 return cmd_usage(cmdtp);
206
207         if (curr_device < 0) {
208                 if (get_mmc_num() > 0)
209                         curr_device = 0;
210                 else {
211                         puts("No MMC device available\n");
212                         return 1;
213                 }
214         }
215
216         if (strcmp(argv[1], "rescan") == 0) {
217                 struct mmc *mmc = find_mmc_device(curr_device);
218
219                 if (!mmc) {
220                         printf("no mmc device at slot %x\n", curr_device);
221                         return 1;
222                 }
223
224                 mmc->has_init = 0;
225
226                 if (mmc_init(mmc))
227                         return 1;
228                 else
229                         return 0;
230         } else if (strncmp(argv[1], "part", 4) == 0) {
231                 block_dev_desc_t *mmc_dev;
232                 struct mmc *mmc = find_mmc_device(curr_device);
233
234                 if (!mmc) {
235                         printf("no mmc device at slot %x\n", curr_device);
236                         return 1;
237                 }
238                 mmc_init(mmc);
239                 mmc_dev = mmc_get_dev(curr_device);
240                 if (mmc_dev != NULL &&
241                                 mmc_dev->type != DEV_TYPE_UNKNOWN) {
242                         print_part(mmc_dev);
243                         return 0;
244                 }
245
246                 puts("get mmc type error!\n");
247                 return 1;
248 <<<<<<< HEAD
249 #ifdef CONFIG_BOOT_PARTITION_ACCESS
250         case 7: /* Fall through */
251                 part = simple_strtoul(argv[6], NULL, 10);
252 #endif
253         default: /* at least 5 args */
254                 if (strcmp(argv[1], "read") == 0) {
255                         int dev = simple_strtoul(argv[2], NULL, 10);
256                         void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
257                         u32 cnt = simple_strtoul(argv[5], NULL, 16);
258                         u32 n;
259                         u32 blk = simple_strtoul(argv[4], NULL, 16);
260
261                         struct mmc *mmc = find_mmc_device(dev);
262
263                         if (!mmc)
264 =======
265         } else if (strcmp(argv[1], "list") == 0) {
266                 print_mmc_devices('\n');
267                 return 0;
268         } else if (strcmp(argv[1], "dev") == 0) {
269                 int dev, part = -1;
270                 struct mmc *mmc;
271
272                 if (argc == 2)
273                         dev = curr_device;
274                 else if (argc == 3)
275                         dev = simple_strtoul(argv[2], NULL, 10);
276                 else if (argc == 4) {
277                         dev = (int)simple_strtoul(argv[2], NULL, 10);
278                         part = (int)simple_strtoul(argv[3], NULL, 10);
279                         if (part > PART_ACCESS_MASK) {
280                                 printf("#part_num shouldn't be larger"
281                                         " than %d\n", PART_ACCESS_MASK);
282 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
283                                 return 1;
284                         }
285                 } else
286                         return cmd_usage(cmdtp);
287
288 <<<<<<< HEAD
289 #ifdef CONFIG_BOOT_PARTITION_ACCESS
290                         printf("\nMMC read: dev # %d, block # %d, "
291                                 "count %d partition # %d ... \n",
292                                 dev, blk, cnt, part);
293 #else
294                         printf("\nMMC read: dev # %d, block # %d,"
295                                 "count %d ... \n", dev, blk, cnt);
296 #endif
297
298                         mmc_init(mmc);
299
300 #ifdef CONFIG_BOOT_PARTITION_ACCESS
301                         if (((mmc->boot_config &
302                                 EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
303                                 || IS_SD(mmc)) {
304                                 /*
305                                  * After mmc_init, we now know whether
306                                  * this is a eSD/eMMC which support boot
307                                  * partition
308                                  */
309                                 MMC_PARTITION_SWITCH(mmc, part, 0);
310                         }
311 #endif
312
313                         n = mmc->block_dev.block_read(dev, blk, cnt, addr);
314 =======
315                 mmc = find_mmc_device(dev);
316                 if (!mmc) {
317                         printf("no mmc device at slot %x\n", dev);
318                         return 1;
319                 }
320 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
321
322                 mmc_init(mmc);
323                 if (part != -1) {
324                         int ret;
325                         if (mmc->part_config == MMCPART_NOAVAILABLE) {
326                                 printf("Card doesn't support part_switch\n");
327                                 return 1;
328                         }
329
330 <<<<<<< HEAD
331                         printf("%d blocks read: %s\n",
332                                 n, (n==cnt) ? "OK" : "ERROR");
333                         return (n == cnt) ? 0 : 1;
334                 } else if (strcmp(argv[1], "write") == 0) {
335                         int dev = simple_strtoul(argv[2], NULL, 10);
336                         void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
337                         u32 cnt = simple_strtoul(argv[5], NULL, 16);
338                         u32 n;
339
340                         struct mmc *mmc = find_mmc_device(dev);
341 =======
342                         if (part != mmc->part_num) {
343                                 ret = mmc_switch_part(dev, part);
344                                 if (!ret)
345                                         mmc->part_num = part;
346 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
347
348                                 printf("switch to partions #%d, %s\n",
349                                                 part, (!ret) ? "OK" : "ERROR");
350                         }
351                 }
352                 curr_device = dev;
353                 if (mmc->part_config == MMCPART_NOAVAILABLE)
354                         printf("mmc%d is current device\n", curr_device);
355                 else
356                         printf("mmc%d(part %d) is current device\n",
357                                 curr_device, mmc->part_num);
358
359                 return 0;
360         }
361
362 <<<<<<< HEAD
363 #ifdef CONFIG_BOOT_PARTITION_ACCESS
364                         printf("\nMMC write: dev # %d, block # %d, "
365                                 "count %d, partition # %d ... \n",
366                                 dev, blk, cnt, part);
367 #else
368                         printf("\nMMC write: dev # %d, block # %d, "
369                                 "count %d ... \n",
370                                 dev, blk, cnt);
371 #endif
372 =======
373         if (strcmp(argv[1], "read") == 0)
374                 state = MMC_READ;
375         else if (strcmp(argv[1], "write") == 0)
376                 state = MMC_WRITE;
377         else if (strcmp(argv[1], "erase") == 0)
378                 state = MMC_ERASE;
379         else
380                 state = MMC_INVALID;
381
382         if (state != MMC_INVALID) {
383                 struct mmc *mmc = find_mmc_device(curr_device);
384                 int idx = 2;
385                 u32 blk, cnt, n;
386                 void *addr;
387
388                 if (state != MMC_ERASE) {
389                         addr = (void *)simple_strtoul(argv[idx], NULL, 16);
390                         ++idx;
391                 } else
392                         addr = 0;
393                 blk = simple_strtoul(argv[idx], NULL, 16);
394                 cnt = simple_strtoul(argv[idx + 1], NULL, 16);
395
396                 if (!mmc) {
397                         printf("no mmc device at slot %x\n", curr_device);
398                         return 1;
399                 }
400 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
401
402                 printf("\nMMC %s: dev # %d, block # %d, count %d ... ",
403                                 argv[1], curr_device, blk, cnt);
404
405 <<<<<<< HEAD
406 #ifdef CONFIG_BOOT_PARTITION_ACCESS
407                         if (((mmc->boot_config &
408                                 EXT_CSD_BOOT_PARTITION_ACCESS_MASK) != part)
409                                 || IS_SD(mmc)) {
410                                 /*
411                                  * After mmc_init, we now know whether this is a
412                                  * eSD/eMMC which support boot partition
413                                  */
414                                 MMC_PARTITION_SWITCH(mmc, part, 1);
415                         }
416 #endif
417
418                         n = mmc->block_dev.block_write(dev, blk, cnt, addr);
419 =======
420                 mmc_init(mmc);
421 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
422
423                 switch (state) {
424                 case MMC_READ:
425                         n = mmc->block_dev.block_read(curr_device, blk,
426                                                       cnt, addr);
427                         /* flush cache after read */
428                         flush_cache((ulong)addr, cnt * 512); /* FIXME */
429                         break;
430                 case MMC_WRITE:
431                         n = mmc->block_dev.block_write(curr_device, blk,
432                                                       cnt, addr);
433                         break;
434                 case MMC_ERASE:
435                         n = mmc->block_dev.block_erase(curr_device, blk, cnt);
436                         break;
437                 default:
438                         BUG();
439                 }
440
441                 printf("%d blocks %s: %s\n",
442                                 n, argv[1], (n == cnt) ? "OK" : "ERROR");
443                 return (n == cnt) ? 0 : 1;
444         }
445
446         return cmd_usage(cmdtp);
447 }
448
449 U_BOOT_CMD(
450         mmc, 6, 1, do_mmcops,
451         "MMC sub system",
452 <<<<<<< HEAD
453         "mmc read <device num> addr blk# cnt\n"
454         "mmc write <device num> addr blk# cnt\n"
455         "mmc rescan <device num>\n"
456 =======
457         "read addr blk# cnt\n"
458         "mmc write addr blk# cnt\n"
459         "mmc erase blk# cnt\n"
460         "mmc rescan\n"
461         "mmc part - lists available partition on current mmc device\n"
462         "mmc dev [dev] [part] - show or set current mmc device [partition]\n"
463 >>>>>>> 9a3aae22edf1eda6326cc51c28631ca5c23b7706
464         "mmc list - lists available devices");
465 #else
466 U_BOOT_CMD(
467         mmc, 7, 1, do_mmcops,
468         "MMC sub system",
469         "mmc read <device num> addr blk# cnt [partition]\n"
470         "mmc write <device num> addr blk# cnt [partition]\n"
471         "mmc rescan <device num>\n"
472         "mmc list - lists available devices");
473 #endif