Modified patch originates from Andy Green <andy@openmoko.com>
[u-boot-openmoko/mini2440.git] / common / cmd_nand.c
blobb78ec04fa5b2f17d7c7acdd38d2da613457a0a9d
1 /*
2 * Driver for NAND support, Rick Bronson
3 * borrowed heavily from:
4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
7 * Added 16-bit nand support
8 * (C) 2004 Texas Instruments
9 */
11 #include <common.h>
14 #ifndef CFG_NAND_LEGACY
17 * New NAND support
20 #include <common.h>
22 #if defined(CONFIG_CMD_NAND)
24 #include <command.h>
25 #include <watchdog.h>
26 #include <malloc.h>
27 #include <asm/byteorder.h>
28 #include <jffs2/jffs2.h>
29 #include <nand.h>
31 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
33 /* parition handling routines */
34 int mtdparts_init(void);
35 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
36 int find_dev_and_part(const char *id, struct mtd_device **dev,
37 u8 *part_num, struct part_info **part);
38 #endif
40 extern nand_info_t nand_info[]; /* info for NAND chips */
42 static int nand_dump_oob(nand_info_t *nand, ulong off)
44 return 0;
47 static int nand_dump(nand_info_t *nand, ulong off)
49 int i;
50 u_char *buf, *p;
52 buf = malloc(nand->oobblock + nand->oobsize);
53 if (!buf) {
54 puts("No memory for page buffer\n");
55 return 1;
57 off &= ~(nand->oobblock - 1);
58 i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize);
59 if (i < 0) {
60 printf("Error (%d) reading page %08x\n", i, off);
61 free(buf);
62 return 1;
64 printf("Page %08x dump:\n", off);
65 i = nand->oobblock >> 4; p = buf;
66 while (i--) {
67 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x"
68 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
69 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
70 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
71 p += 16;
73 puts("OOB:\n");
74 i = nand->oobsize >> 3;
75 while (i--) {
76 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
77 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
78 p += 8;
80 free(buf);
82 return 0;
85 /* ------------------------------------------------------------------------- */
87 static inline int str2long(char *p, ulong *num)
89 char *endptr;
91 *num = simple_strtoul(p, &endptr, 16);
92 return (*p != '\0' && *endptr == '\0') ? 1 : 0;
95 int
96 arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size, int net)
98 int idx = nand_curr_device;
99 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
100 struct mtd_device *dev;
101 struct part_info *part;
102 u8 pnum;
104 if (argc >= 1 && !(str2long(argv[0], off))) {
105 if ((mtdparts_init() == 0) &&
106 (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) {
107 if (dev->id->type != MTD_DEV_TYPE_NAND) {
108 puts("not a NAND device\n");
109 return -1;
111 *off = part->offset;
112 if (argc >= 2) {
113 if (!(str2long(argv[1], size))) {
114 printf("'%s' is not a number\n", argv[1]);
115 return -1;
117 if (*size > part->size) {
118 if (net)
119 *size = nand_net_part_size(part);
120 else
121 *size = part->size;
123 } else {
124 if (net)
125 *size = nand_net_part_size(part);
126 else
127 *size = part->size;
129 idx = dev->id->num;
130 *nand = nand_info[idx];
131 goto out;
134 #endif
136 if (argc >= 1) {
137 if (!(str2long(argv[0], off))) {
138 printf("'%s' is not a number\n", argv[0]);
139 return -1;
141 } else {
142 *off = 0;
145 if (argc >= 2) {
146 if (!(str2long(argv[1], size))) {
147 printf("'%s' is not a number\n", argv[1]);
148 return -1;
150 } else {
151 *size = nand->size - *off;
154 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
155 out:
156 #endif
157 printf("device %d ", idx);
158 if (*size == nand->size)
159 puts("whole chip\n");
160 else
161 printf("offset 0x%x, size 0x%x\n", *off, *size);
162 return 0;
165 static int yes(void)
167 char *s;
168 char c;
170 s = getenv("dontask");
171 if (s && (s[0] =='y' || s[0] == 'Y') && !s[1])
172 return 1;
173 c = getc();
174 if (c != 'y' && c != 'Y')
175 return 0;
176 c = getc();
177 return c == '\r' || c == '\n';
180 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
182 int i, dev, ret;
183 ulong addr, off, size;
184 char *cmd, *s;
185 nand_info_t *nand;
186 #ifdef CFG_NAND_QUIET
187 int quiet = CFG_NAND_QUIET;
188 #else
189 int quiet = 0;
190 #endif
191 const char *quiet_str = getenv("quiet");
193 /* at least two arguments please */
194 if (argc < 2)
195 goto usage;
197 if (quiet_str)
198 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
200 cmd = argv[1];
202 if (strcmp(cmd, "info") == 0) {
204 putc('\n');
205 for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
206 if (nand_info[i].name)
207 printf("Device %d: %s, page size %lu, "
208 "sector size %lu KiB\n",
209 i, nand_info[i].name,
210 nand_info[i].oobblock,
211 nand_info[i].erasesize >> 10);
213 return 0;
216 if (strcmp(cmd, "device") == 0) {
218 if (argc < 3) {
219 if ((nand_curr_device < 0) ||
220 (nand_curr_device >= CFG_MAX_NAND_DEVICE))
221 puts("\nno devices available\n");
222 else
223 printf("\nDevice %d: %s\n", nand_curr_device,
224 nand_info[nand_curr_device].name);
225 return 0;
227 dev = (int)simple_strtoul(argv[2], NULL, 10);
228 if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
229 puts("No such device\n");
230 return 1;
232 printf("Device %d: %s", dev, nand_info[dev].name);
233 puts("... is now current device\n");
234 nand_curr_device = dev;
236 #ifdef CFG_NAND_SELECT_DEVICE
238 * Select the chip in the board/cpu specific driver
240 board_nand_select_device(nand_info[dev].priv, dev);
241 #endif
243 return 0;
246 if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 &&
247 strncmp(cmd, "dump", 4) != 0 &&
248 strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
249 strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
250 strcmp(cmd, "biterr") != 0 &&
251 strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 &&
252 strcmp(cmd, "createbbt") != 0 )
253 goto usage;
255 /* the following commands operate on the current device */
256 if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE ||
257 !nand_info[nand_curr_device].name) {
258 puts("\nno devices available\n");
259 return 1;
261 nand = &nand_info[nand_curr_device];
263 if (strcmp(cmd, "bad") == 0) {
264 printf("\nDevice %d bad blocks:\n", nand_curr_device);
265 for (off = 0; off < nand->size; off += nand->erasesize)
266 if (nand_block_isbad(nand, off))
267 printf(" %08x\n", off);
268 return 0;
272 * Syntax is:
273 * 0 1 2 3 4
274 * nand erase [clean] [off size]
276 if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
277 nand_erase_options_t opts;
278 /* "clean" at index 2 means request to write cleanmarker */
279 int clean = argc > 2 && !strcmp("clean", argv[2]);
280 int o = clean ? 3 : 2;
281 int scrub = !strcmp(cmd, "scrub");
283 printf("\nNAND %s: ", scrub ? "scrub" : "erase");
284 /* skip first two or three arguments, look for offset and size */
285 if (arg_off_size(argc - o, argv + o, nand, &off, &size, 0) != 0)
286 return 1;
288 memset(&opts, 0, sizeof(opts));
289 opts.offset = off;
290 opts.length = size;
291 opts.jffs2 = clean;
292 opts.quiet = quiet;
294 if (scrub) {
295 puts("Warning: "
296 "scrub option will erase all factory set "
297 "bad blocks!\n"
299 "There is no reliable way to recover them.\n"
301 "Use this command only for testing purposes "
302 "if you\n"
304 "are sure of what you are doing!\n"
305 "\nReally scrub this NAND flash? <y/N>\n");
307 if (yes()) {
308 opts.scrub = 1;
309 } else {
310 puts("scrub aborted\n");
311 return -1;
314 else {
315 if (opts.length == nand->size) {
316 puts("Really erase everything ? <y/N>\n");
317 if (!yes()) {
318 puts("erase aborted\n");
319 return -1;
324 ret = nand_erase_opts(nand, &opts);
325 printf("%s\n", ret ? "ERROR" : "OK");
327 return ret == 0 ? 0 : 1;
330 if (strncmp(cmd, "dump", 4) == 0) {
331 if (argc < 3)
332 goto usage;
334 s = strchr(cmd, '.');
335 off = (int)simple_strtoul(argv[2], NULL, 16);
337 if (s != NULL && strcmp(s, ".oob") == 0)
338 ret = nand_dump_oob(nand, off);
339 else
340 ret = nand_dump(nand, off);
342 return ret == 0 ? 1 : 0;
346 /* read write */
347 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
348 int read;
350 if (argc < 4)
351 goto usage;
353 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
355 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
356 printf("\nNAND %s: ", read ? "read" : "write");
357 if (arg_off_size(argc - 3, argv + 3, nand, &off, &size, 1) != 0)
358 return 1;
360 s = strchr(cmd, '.');
361 if (s != NULL &&
362 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) {
363 if (read) {
364 /* read */
365 nand_read_options_t opts;
366 memset(&opts, 0, sizeof(opts));
367 opts.buffer = (u_char*) addr;
368 opts.length = size;
369 opts.offset = off;
370 opts.quiet = quiet;
371 ret = nand_read_opts(nand, &opts);
372 } else {
373 /* write */
374 nand_write_options_t opts;
375 memset(&opts, 0, sizeof(opts));
376 opts.buffer = (u_char*) addr;
377 opts.length = size;
378 opts.offset = off;
379 /* opts.forcejffs2 = 1; */
380 opts.pad = 1;
381 opts.blockalign = 1;
382 opts.quiet = quiet;
383 ret = nand_write_opts(nand, &opts);
385 } else if (!read && s != NULL &&
386 (!strcmp(s, ".yaffs") || !strcmp(s, ".yaffs1"))) {
387 nand_write_options_t opts;
388 memset(&opts, 0, sizeof(opts));
389 opts.buffer = (u_char*) addr;
390 opts.length = size;
391 opts.offset = off;
392 opts.pad = 0;
393 opts.blockalign = 1;
394 opts.quiet = quiet;
395 opts.writeoob = 1;
396 opts.autoplace = 1;
397 if (s[6] == '1')
398 opts.forceyaffs = 1;
399 ret = nand_write_opts(nand, &opts);
400 } else if (s != NULL && !strcmp(s, ".oob")) {
401 /* read out-of-band data */
402 if (read)
403 ret = nand->read_oob(nand, off, size, (size_t *) &size,
404 (u_char *) addr);
405 else
406 ret = nand->write_oob(nand, off, size, (size_t *) &size,
407 (u_char *) addr);
408 } else {
409 if (read)
410 ret = nand_read(nand, off, &size, (u_char *)addr);
411 else
412 ret = nand_write(nand, off, &size, (u_char *)addr);
415 printf(" %d bytes %s: %s\n", size,
416 read ? "read" : "written", ret ? "ERROR" : "OK");
418 return ret == 0 ? 0 : 1;
421 if (strcmp(cmd, "markbad") == 0) {
422 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
424 int ret = nand->block_markbad(nand, addr);
425 if (ret == 0) {
426 printf("block 0x%08lx successfully marked as bad\n",
427 (ulong) addr);
428 return 0;
429 } else {
430 printf("block 0x%08lx NOT marked as bad! ERROR %d\n",
431 (ulong) addr, ret);
433 return 1;
435 if (strcmp(cmd, "biterr") == 0) {
436 /* todo */
437 return 1;
440 if (strcmp(cmd, "lock") == 0) {
441 int tight = 0;
442 int status = 0;
443 if (argc == 3) {
444 if (!strcmp("tight", argv[2]))
445 tight = 1;
446 if (!strcmp("status", argv[2]))
447 status = 1;
450 if (status) {
451 ulong block_start = 0;
452 ulong off;
453 int last_status = -1;
455 struct nand_chip *nand_chip = nand->priv;
456 /* check the WP bit */
457 nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1);
458 printf("device is %swrite protected\n",
459 (nand_chip->read_byte(nand) & 0x80 ?
460 "NOT " : "" ) );
462 for (off = 0; off < nand->size; off += nand->oobblock) {
463 int s = nand_get_lock_status(nand, off);
465 /* print message only if status has changed
466 * or at end of chip
468 if (off == nand->size - nand->oobblock
469 || (s != last_status && off != 0)) {
471 printf("%08x - %08x: %8d pages %s%s%s\n",
472 block_start,
473 off-1,
474 (off-block_start)/nand->oobblock,
475 ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
476 ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
477 ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
480 last_status = s;
482 } else {
483 if (!nand_lock(nand, tight)) {
484 puts("NAND flash successfully locked\n");
485 } else {
486 puts("Error locking NAND flash\n");
487 return 1;
490 return 0;
493 if (strcmp(cmd, "unlock") == 0) {
494 if (arg_off_size(argc - 2, argv + 2, nand, &off, &size, 0) < 0)
495 return 1;
497 if (!nand_unlock(nand, off, size)) {
498 puts("NAND flash successfully unlocked\n");
499 } else {
500 puts("Error unlocking NAND flash, "
501 "write and erase will probably fail\n");
502 return 1;
504 return 0;
507 if (strcmp(cmd, "createbbt") == 0) {
508 struct nand_chip *nand_chip = nand->priv;
509 nand_erase_options_t opts;
511 puts("Create BBT and erase everything ? <y/N>\n");
512 if (!yes()) {
513 puts("createbbt aborted\n");
514 return -1;
516 memset(&opts, 0, sizeof(opts));
517 opts.length = nand->size;
518 if (nand_erase_opts(nand, &opts)) {
519 puts("Erase failed\n");
520 return 1;
522 nand_chip->options &= ~NAND_DONT_CREATE_BBT;
523 puts("Creating BBT. Please wait ...");
524 if (nand_default_bbt(nand)) {
525 puts("\nFailed\n");
526 return 1;
528 else {
529 puts("\n");
530 return 0;
534 usage:
535 printf("Usage:\n%s\n", cmdtp->usage);
536 return 1;
539 U_BOOT_CMD(nand, 5, 1, do_nand,
540 "nand - NAND sub-system\n",
541 "info - show available NAND devices\n"
542 "nand device [dev] - show or set current device\n"
543 "nand read[.jffs2] - addr off|partition size\n"
544 "nand write[.jffs2] - addr off|partition size - read/write `size' bytes starting\n"
545 " at offset `off' to/from memory address `addr'\n"
546 "nand write[.yaffs[1]] - addr off|partiton size - read/write `size' byte yaffs image\n"
547 " starting at offset `off' to/from memory address `addr' (.yaffs1 for 512+16 NAND)\n"
548 "nand erase [clean] [off size] - erase `size' bytes from\n"
549 " offset `off' (entire device if not specified)\n"
550 "nand bad - show bad blocks\n"
551 "nand dump[.oob] off - dump page\n"
552 "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
553 "nand markbad off - mark bad block at offset (UNSAFE)\n"
554 "nand biterr off - make a bit error at offset (UNSAFE)\n"
555 "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
556 "nand unlock [offset] [size] - unlock section\n"
557 "nand createbbt - create bad block table\n");
559 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
560 ulong offset, ulong addr, char *cmd)
562 int r;
563 char *ep, *s;
564 ulong cnt;
565 image_header_t *hdr;
566 int jffs2 = 0;
567 #if defined(CONFIG_FIT)
568 const void *fit_hdr;
569 #endif
571 s = strchr(cmd, '.');
572 if (s != NULL &&
573 (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")))
574 jffs2 = 1;
576 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
578 cnt = nand->oobblock;
579 if (jffs2) {
580 nand_read_options_t opts;
581 memset(&opts, 0, sizeof(opts));
582 opts.buffer = (u_char*) addr;
583 opts.length = cnt;
584 opts.offset = offset;
585 opts.quiet = 1;
586 r = nand_read_opts(nand, &opts);
587 } else {
588 r = nand_read(nand, offset, &cnt, (u_char *) addr);
591 if (r) {
592 puts("** Read error\n");
593 show_boot_progress (-56);
594 return 1;
596 show_boot_progress (56);
598 switch (genimg_get_format ((void *)addr)) {
599 case IMAGE_FORMAT_LEGACY:
600 hdr = (image_header_t *)addr;
602 show_boot_progress (57);
603 image_print_contents (hdr);
605 cnt = image_get_image_size (hdr);
606 break;
607 #if defined(CONFIG_FIT)
608 case IMAGE_FORMAT_FIT:
609 fit_hdr = (const void *)addr;
610 if (!fit_check_format (fit_hdr)) {
611 show_boot_progress (-150);
612 puts ("** Bad FIT image format\n");
613 return 1;
615 show_boot_progress (151);
616 puts ("Fit image detected...\n");
618 cnt = fit_get_size (fit_hdr);
619 break;
620 #endif
621 default:
622 show_boot_progress (-57);
623 puts ("** Unknown image type\n");
624 return 1;
627 if (jffs2) {
628 nand_read_options_t opts;
629 memset(&opts, 0, sizeof(opts));
630 opts.buffer = (u_char*) addr;
631 opts.length = cnt;
632 opts.offset = offset;
633 opts.quiet = 1;
634 r = nand_read_opts(nand, &opts);
635 } else {
636 r = nand_read(nand, offset, &cnt, (u_char *) addr);
639 if (r) {
640 puts("** Read error\n");
641 show_boot_progress (-58);
642 return 1;
644 show_boot_progress (58);
646 #if defined(CONFIG_FIT)
647 /* This cannot be done earlier, we need complete FIT image in RAM first */
648 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
649 fit_print_contents ((const void *)addr);
650 #endif
652 /* Loading ok, update default load address */
654 load_addr = addr;
656 /* Check if we should attempt an auto-start */
657 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
658 char *local_args[2];
659 extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
661 local_args[0] = cmd;
662 local_args[1] = NULL;
664 printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
666 do_bootm(cmdtp, 0, 1, local_args);
667 return 1;
669 return 0;
672 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
674 char *boot_device = NULL;
675 int idx;
676 ulong addr, offset = 0;
677 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
678 struct mtd_device *dev;
679 struct part_info *part;
680 u8 pnum;
682 if (argc >= 2) {
683 char *p = (argc == 2) ? argv[1] : argv[2];
684 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
685 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
686 if (dev->id->type != MTD_DEV_TYPE_NAND) {
687 puts("Not a NAND device\n");
688 return 1;
690 if (argc > 3)
691 goto usage;
692 if (argc == 3)
693 addr = simple_strtoul(argv[1], NULL, 16);
694 else
695 addr = CFG_LOAD_ADDR;
696 return nand_load_image(cmdtp, &nand_info[dev->id->num],
697 part->offset, addr, argv[0]);
700 #endif
702 show_boot_progress(52);
703 switch (argc) {
704 case 1:
705 addr = CFG_LOAD_ADDR;
706 boot_device = getenv("bootdevice");
707 break;
708 case 2:
709 addr = simple_strtoul(argv[1], NULL, 16);
710 boot_device = getenv("bootdevice");
711 break;
712 case 3:
713 addr = simple_strtoul(argv[1], NULL, 16);
714 boot_device = argv[2];
715 break;
716 case 4:
717 addr = simple_strtoul(argv[1], NULL, 16);
718 boot_device = argv[2];
719 offset = simple_strtoul(argv[3], NULL, 16);
720 break;
721 default:
722 #if defined(CONFIG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
723 usage:
724 #endif
725 printf("Usage:\n%s\n", cmdtp->usage);
726 show_boot_progress(-53);
727 return 1;
730 show_boot_progress(53);
731 if (!boot_device) {
732 puts("\n** No boot device **\n");
733 show_boot_progress(-54);
734 return 1;
736 show_boot_progress(54);
738 idx = simple_strtoul(boot_device, NULL, 16);
740 if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) {
741 printf("\n** Device %d not available\n", idx);
742 show_boot_progress(-55);
743 return 1;
745 show_boot_progress(55);
747 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
750 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
751 "nboot - boot from NAND device\n",
752 "[.jffs2] [partition] | [[[loadAddr] dev] offset]\n");
754 #endif
756 #else /* CFG_NAND_LEGACY */
759 * Legacy NAND support - to be phased out
762 #include <command.h>
763 #include <malloc.h>
764 #include <asm/io.h>
765 #include <watchdog.h>
767 #ifdef CONFIG_show_boot_progress
768 # include <status_led.h>
769 # define show_boot_progress(arg) show_boot_progress(arg)
770 #else
771 # define show_boot_progress(arg)
772 #endif
774 #if defined(CONFIG_CMD_NAND)
775 #include <linux/mtd/nand_legacy.h>
776 #if 0
777 #include <linux/mtd/nand_ids.h>
778 #include <jffs2/jffs2.h>
779 #endif
781 #ifdef CONFIG_OMAP1510
782 void archflashwp(void *archdata, int wp);
783 #endif
785 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
787 #undef NAND_DEBUG
788 #undef PSYCHO_DEBUG
790 /* ****************** WARNING *********************
791 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
792 * erase (or at least attempt to erase) blocks that are marked
793 * bad. This can be very handy if you are _sure_ that the block
794 * is OK, say because you marked a good block bad to test bad
795 * block handling and you are done testing, or if you have
796 * accidentally marked blocks bad.
798 * Erasing factory marked bad blocks is a _bad_ idea. If the
799 * erase succeeds there is no reliable way to find them again,
800 * and attempting to program or erase bad blocks can affect
801 * the data in _other_ (good) blocks.
803 #define ALLOW_ERASE_BAD_DEBUG 0
805 #define CONFIG_MTD_NAND_ECC /* enable ECC */
806 #define CONFIG_MTD_NAND_ECC_JFFS2
808 /* bits for nand_legacy_rw() `cmd'; or together as needed */
809 #define NANDRW_READ 0x01
810 #define NANDRW_WRITE 0x00
811 #define NANDRW_JFFS2 0x02
812 #define NANDRW_JFFS2_SKIP 0x04
815 * Imports from nand_legacy.c
817 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
818 extern int curr_device;
819 extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs,
820 size_t len, int clean);
821 extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start,
822 size_t len, size_t *retlen, u_char *buf);
823 extern void nand_print(struct nand_chip *nand);
824 extern void nand_print_bad(struct nand_chip *nand);
825 extern int nand_read_oob(struct nand_chip *nand, size_t ofs,
826 size_t len, size_t *retlen, u_char *buf);
827 extern int nand_write_oob(struct nand_chip *nand, size_t ofs,
828 size_t len, size_t *retlen, const u_char *buf);
831 int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
833 int rcode = 0;
835 switch (argc) {
836 case 0:
837 case 1:
838 printf ("Usage:\n%s\n", cmdtp->usage);
839 return 1;
840 case 2:
841 if (strcmp (argv[1], "info") == 0) {
842 int i;
844 putc ('\n');
846 for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) {
847 if (nand_dev_desc[i].ChipID ==
848 NAND_ChipID_UNKNOWN)
849 continue; /* list only known devices */
850 printf ("Device %d: ", i);
851 nand_print (&nand_dev_desc[i]);
853 return 0;
855 } else if (strcmp (argv[1], "device") == 0) {
856 if ((curr_device < 0)
857 || (curr_device >= CFG_MAX_NAND_DEVICE)) {
858 puts ("\nno devices available\n");
859 return 1;
861 printf ("\nDevice %d: ", curr_device);
862 nand_print (&nand_dev_desc[curr_device]);
863 return 0;
865 } else if (strcmp (argv[1], "bad") == 0) {
866 if ((curr_device < 0)
867 || (curr_device >= CFG_MAX_NAND_DEVICE)) {
868 puts ("\nno devices available\n");
869 return 1;
871 printf ("\nDevice %d bad blocks:\n", curr_device);
872 nand_print_bad (&nand_dev_desc[curr_device]);
873 return 0;
876 printf ("Usage:\n%s\n", cmdtp->usage);
877 return 1;
878 case 3:
879 if (strcmp (argv[1], "device") == 0) {
880 int dev = (int) simple_strtoul (argv[2], NULL, 10);
882 printf ("\nDevice %d: ", dev);
883 if (dev >= CFG_MAX_NAND_DEVICE) {
884 puts ("unknown device\n");
885 return 1;
887 nand_print (&nand_dev_desc[dev]);
888 /*nand_print (dev); */
890 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
891 return 1;
894 curr_device = dev;
896 puts ("... is now current device\n");
898 return 0;
899 } else if (strcmp (argv[1], "erase") == 0
900 && strcmp (argv[2], "clean") == 0) {
901 struct nand_chip *nand = &nand_dev_desc[curr_device];
902 ulong off = 0;
903 ulong size = nand->totlen;
904 int ret;
906 printf ("\nNAND erase: device %d offset %ld, size %ld ... ", curr_device, off, size);
908 ret = nand_legacy_erase (nand, off, size, 1);
910 printf ("%s\n", ret ? "ERROR" : "OK");
912 return ret;
915 printf ("Usage:\n%s\n", cmdtp->usage);
916 return 1;
917 default:
918 /* at least 4 args */
920 if (strncmp (argv[1], "read", 4) == 0 ||
921 strncmp (argv[1], "write", 5) == 0) {
922 ulong addr = simple_strtoul (argv[2], NULL, 16);
923 ulong off = simple_strtoul (argv[3], NULL, 16);
924 ulong size = simple_strtoul (argv[4], NULL, 16);
925 int cmd = (strncmp (argv[1], "read", 4) == 0) ?
926 NANDRW_READ : NANDRW_WRITE;
927 int ret, total;
928 char *cmdtail = strchr (argv[1], '.');
930 if (cmdtail && !strncmp (cmdtail, ".oob", 2)) {
931 /* read out-of-band data */
932 if (cmd & NANDRW_READ) {
933 ret = nand_read_oob (nand_dev_desc + curr_device,
934 off, size, (size_t *) & total,
935 (u_char *) addr);
936 } else {
937 ret = nand_write_oob (nand_dev_desc + curr_device,
938 off, size, (size_t *) & total,
939 (u_char *) addr);
941 return ret;
942 } else if (cmdtail && !strncmp (cmdtail, ".jffs2", 2))
943 cmd |= NANDRW_JFFS2; /* skip bad blocks */
944 else if (cmdtail && !strncmp (cmdtail, ".jffs2s", 2)) {
945 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
946 if (cmd & NANDRW_READ)
947 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
949 #ifdef SXNI855T
950 /* need ".e" same as ".j" for compatibility with older units */
951 else if (cmdtail && !strcmp (cmdtail, ".e"))
952 cmd |= NANDRW_JFFS2; /* skip bad blocks */
953 #endif
954 #ifdef CFG_NAND_SKIP_BAD_DOT_I
955 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */
956 /* ".i" for image -> read skips bad block (no 0xff) */
957 else if (cmdtail && !strcmp (cmdtail, ".i")) {
958 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
959 if (cmd & NANDRW_READ)
960 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
962 #endif /* CFG_NAND_SKIP_BAD_DOT_I */
963 else if (cmdtail) {
964 printf ("Usage:\n%s\n", cmdtp->usage);
965 return 1;
968 printf ("\nNAND %s: device %d offset %ld, size %ld ...\n",
969 (cmd & NANDRW_READ) ? "read" : "write",
970 curr_device, off, size);
972 ret = nand_legacy_rw (nand_dev_desc + curr_device,
973 cmd, off, size,
974 (size_t *) & total,
975 (u_char *) addr);
977 printf (" %d bytes %s: %s\n", total,
978 (cmd & NANDRW_READ) ? "read" : "written",
979 ret ? "ERROR" : "OK");
981 return ret;
982 } else if (strcmp (argv[1], "erase") == 0 &&
983 (argc == 4 || strcmp ("clean", argv[2]) == 0)) {
984 int clean = argc == 5;
985 ulong off =
986 simple_strtoul (argv[2 + clean], NULL, 16);
987 ulong size =
988 simple_strtoul (argv[3 + clean], NULL, 16);
989 int ret;
991 printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",
992 curr_device, off, size);
994 ret = nand_legacy_erase (nand_dev_desc + curr_device,
995 off, size, clean);
997 printf ("%s\n", ret ? "ERROR" : "OK");
999 return ret;
1000 } else {
1001 printf ("Usage:\n%s\n", cmdtp->usage);
1002 rcode = 1;
1005 return rcode;
1009 U_BOOT_CMD(
1010 nand, 5, 1, do_nand,
1011 "nand - legacy NAND sub-system\n",
1012 "info - show available NAND devices\n"
1013 "nand device [dev] - show or set current device\n"
1014 "nand read[.jffs2[s]] addr off size\n"
1015 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
1016 " at offset `off' to/from memory address `addr'\n"
1017 "nand erase [clean] [off size] - erase `size' bytes from\n"
1018 " offset `off' (entire device if not specified)\n"
1019 "nand bad - show bad blocks\n"
1020 "nand read.oob addr off size - read out-of-band data\n"
1021 "nand write.oob addr off size - read out-of-band data\n"
1024 int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
1026 char *boot_device = NULL;
1027 char *ep;
1028 int dev;
1029 ulong cnt;
1030 ulong addr;
1031 ulong offset = 0;
1032 image_header_t *hdr;
1033 int rcode = 0;
1034 #if defined(CONFIG_FIT)
1035 const void *fit_hdr;
1036 #endif
1038 show_boot_progress (52);
1039 switch (argc) {
1040 case 1:
1041 addr = CFG_LOAD_ADDR;
1042 boot_device = getenv ("bootdevice");
1043 break;
1044 case 2:
1045 addr = simple_strtoul(argv[1], NULL, 16);
1046 boot_device = getenv ("bootdevice");
1047 break;
1048 case 3:
1049 addr = simple_strtoul(argv[1], NULL, 16);
1050 boot_device = argv[2];
1051 break;
1052 case 4:
1053 addr = simple_strtoul(argv[1], NULL, 16);
1054 boot_device = argv[2];
1055 offset = simple_strtoul(argv[3], NULL, 16);
1056 break;
1057 default:
1058 printf ("Usage:\n%s\n", cmdtp->usage);
1059 show_boot_progress (-53);
1060 return 1;
1063 show_boot_progress (53);
1064 if (!boot_device) {
1065 puts ("\n** No boot device **\n");
1066 show_boot_progress (-54);
1067 return 1;
1069 show_boot_progress (54);
1071 dev = simple_strtoul(boot_device, &ep, 16);
1073 if ((dev >= CFG_MAX_NAND_DEVICE) ||
1074 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
1075 printf ("\n** Device %d not available\n", dev);
1076 show_boot_progress (-55);
1077 return 1;
1079 show_boot_progress (55);
1081 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
1082 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
1083 offset);
1085 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
1086 SECTORSIZE, NULL, (u_char *)addr)) {
1087 printf ("** Read error on %d\n", dev);
1088 show_boot_progress (-56);
1089 return 1;
1091 show_boot_progress (56);
1093 switch (genimg_get_format ((void *)addr)) {
1094 case IMAGE_FORMAT_LEGACY:
1095 hdr = (image_header_t *)addr;
1096 image_print_contents (hdr);
1098 cnt = image_get_image_size (hdr);
1099 cnt -= SECTORSIZE;
1100 break;
1101 #if defined(CONFIG_FIT)
1102 case IMAGE_FORMAT_FIT:
1103 fit_hdr = (const void *)addr;
1104 if (!fit_check_format (fit_hdr)) {
1105 show_boot_progress (-150);
1106 puts ("** Bad FIT image format\n");
1107 return 1;
1109 show_boot_progress (151);
1110 puts ("Fit image detected...\n");
1112 cnt = fit_get_size (fit_hdr);
1113 break;
1114 #endif
1115 default:
1116 show_boot_progress (-57);
1117 puts ("** Unknown image type\n");
1118 return 1;
1120 show_boot_progress (57);
1122 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
1123 offset + SECTORSIZE, cnt, NULL,
1124 (u_char *)(addr+SECTORSIZE))) {
1125 printf ("** Read error on %d\n", dev);
1126 show_boot_progress (-58);
1127 return 1;
1129 show_boot_progress (58);
1131 #if defined(CONFIG_FIT)
1132 /* This cannot be done earlier, we need complete FIT image in RAM first */
1133 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
1134 fit_print_contents ((const void *)addr);
1135 #endif
1137 /* Loading ok, update default load address */
1139 load_addr = addr;
1141 /* Check if we should attempt an auto-start */
1142 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
1143 char *local_args[2];
1144 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
1146 local_args[0] = argv[0];
1147 local_args[1] = NULL;
1149 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
1151 do_bootm (cmdtp, 0, 1, local_args);
1152 rcode = 1;
1154 return rcode;
1157 U_BOOT_CMD(
1158 nboot, 4, 1, do_nandboot,
1159 "nboot - boot from NAND device\n",
1160 "loadAddr dev\n"
1163 #endif
1165 #endif /* CFG_NAND_LEGACY */