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 * Ported 'dynenv' to 'nand env.oob' command
8 * (C) 2010 Nanometrics, Inc.
9 * 'dynenv' -- Dynamic environment offset in NAND OOB
10 * (C) Copyright 2006-2007 OpenMoko, Inc.
11 * Added 16-bit nand support
12 * (C) 2004 Texas Instruments
14 * Copyright 2010, 2012 Freescale Semiconductor
15 * The portions of this file whose copyright is held by Freescale and which
16 * are not considered a derived work of GPL v2-only code may be distributed
17 * and/or modified under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of the
19 * License, or (at your option) any later version.
23 #include <linux/mtd/mtd.h>
27 #include <asm/byteorder.h>
28 #include <jffs2/jffs2.h>
31 #if defined(CONFIG_CMD_MTDPARTS)
33 /* partition 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);
40 static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)
43 u_char *datbuf, *oobbuf, *p;
48 off = last + nand->writesize;
52 datbuf = memalign(ARCH_DMA_MINALIGN, nand->writesize);
54 puts("No memory for page buffer\n");
58 oobbuf = memalign(ARCH_DMA_MINALIGN, nand->oobsize);
60 puts("No memory for page buffer\n");
64 off &= ~(nand->writesize - 1);
65 loff_t addr = (loff_t) off;
66 struct mtd_oob_ops ops;
67 memset(&ops, 0, sizeof(ops));
70 ops.len = nand->writesize;
71 ops.ooblen = nand->oobsize;
72 ops.mode = MTD_OPS_RAW;
73 i = mtd_read_oob(nand, addr, &ops);
75 printf("Error (%d) reading page %08lx\n", i, off);
79 printf("Page %08lx dump:\n", off);
82 i = nand->writesize >> 4;
86 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
87 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
88 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
89 p[8], p[9], p[10], p[11], p[12], p[13], p[14],
96 i = nand->oobsize >> 3;
99 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
100 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
112 /* ------------------------------------------------------------------------- */
114 static int set_dev(int dev)
116 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
117 !nand_info[dev].name) {
118 puts("No such device\n");
122 if (nand_curr_device == dev)
125 printf("Device %d: %s", dev, nand_info[dev].name);
126 puts("... is now current device\n");
127 nand_curr_device = dev;
129 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
130 board_nand_select_device(nand_info[dev].priv, dev);
136 static inline int str2off(const char *p, loff_t *num)
140 *num = simple_strtoull(p, &endptr, 16);
141 return *p != '\0' && *endptr == '\0';
144 static inline int str2long(const char *p, ulong *num)
148 *num = simple_strtoul(p, &endptr, 16);
149 return *p != '\0' && *endptr == '\0';
152 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size,
155 #ifdef CONFIG_CMD_MTDPARTS
156 struct mtd_device *dev;
157 struct part_info *part;
161 ret = mtdparts_init();
165 ret = find_dev_and_part(partname, &dev, &pnum, &part);
169 if (dev->id->type != MTD_DEV_TYPE_NAND) {
170 puts("not a NAND device\n");
176 *maxsize = part->size;
185 puts("offset is not a number\n");
190 static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *size,
193 if (!str2off(arg, off))
194 return get_part(arg, idx, off, size, maxsize);
196 if (*off >= nand_info[*idx].size) {
197 puts("Offset exceeds device limit\n");
201 *maxsize = nand_info[*idx].size - *off;
206 static int arg_off_size(int argc, char *const argv[], int *idx,
207 loff_t *off, loff_t *size, loff_t *maxsize)
213 *size = nand_info[*idx].size;
218 ret = arg_off(argv[0], idx, off, size, maxsize);
225 if (!str2off(argv[1], size)) {
226 printf("'%s' is not a number\n", argv[1]);
230 if (*size > *maxsize) {
231 puts("Size exceeds partition or device limit\n");
236 printf("device %d ", *idx);
237 if (*size == nand_info[*idx].size)
238 puts("whole chip\n");
240 printf("offset 0x%llx, size 0x%llx\n",
241 (unsigned long long)*off, (unsigned long long)*size);
245 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
246 static void print_status(ulong start, ulong end, ulong erasesize, int status)
249 * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is
250 * not the same as others. Instead of bit 1 being lock, it is
251 * #lock_tight. To make the driver support either format, ignore bit 1
252 * and use only bit 0 and bit 2.
254 printf("%08lx - %08lx: %08lx blocks %s%s%s\n",
257 (end - start) / erasesize,
258 ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
259 (!(status & NAND_LOCK_STATUS_UNLOCK) ? "LOCK " : ""),
260 ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
263 static void do_nand_status(nand_info_t *nand)
265 ulong block_start = 0;
267 int last_status = -1;
269 struct nand_chip *nand_chip = nand->priv;
270 /* check the WP bit */
271 nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1);
272 printf("device is %swrite protected\n",
273 (nand_chip->read_byte(nand) & 0x80 ?
276 for (off = 0; off < nand->size; off += nand->erasesize) {
277 int s = nand_get_lock_status(nand, off);
279 /* print message only if status has changed */
280 if (s != last_status && off != 0) {
281 print_status(block_start, off, nand->erasesize,
287 /* Print the last block info */
288 print_status(block_start, off, nand->erasesize, last_status);
292 #ifdef CONFIG_ENV_OFFSET_OOB
293 unsigned long nand_env_oob_offset;
295 int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[])
298 uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
299 nand_info_t *nand = &nand_info[0];
302 if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) {
303 puts("no devices available\n");
309 if (!strcmp(cmd, "get")) {
310 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
314 printf("0x%08lx\n", nand_env_oob_offset);
315 } else if (!strcmp(cmd, "set")) {
318 struct mtd_oob_ops ops;
324 /* We don't care about size, or maxsize. */
325 if (arg_off(argv[2], &idx, &addr, &maxsize, &maxsize)) {
326 puts("Offset or partition name expected\n");
331 puts("Partition not on first NAND device\n");
335 if (nand->oobavail < ENV_OFFSET_SIZE) {
336 printf("Insufficient available OOB bytes:\n"
337 "%d OOB bytes available but %d required for "
339 nand->oobavail, ENV_OFFSET_SIZE);
343 if ((addr & (nand->erasesize - 1)) != 0) {
344 printf("Environment offset must be block-aligned\n");
349 ops.mode = MTD_OOB_AUTO;
351 ops.ooblen = ENV_OFFSET_SIZE;
352 ops.oobbuf = (void *) oob_buf;
354 oob_buf[0] = ENV_OOB_MARKER;
355 oob_buf[1] = addr / nand->erasesize;
357 ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops);
359 printf("Error writing OOB block 0\n");
363 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
365 printf("Error reading env offset in OOB\n");
369 if (addr != nand_env_oob_offset) {
370 printf("Verification of env offset in OOB failed: "
371 "0x%08llx expected but got 0x%08lx\n",
372 (unsigned long long)addr, nand_env_oob_offset);
382 return CMD_RET_USAGE;
387 static void nand_print_and_set_info(int idx)
389 nand_info_t *nand = &nand_info[idx];
390 struct nand_chip *chip = nand->priv;
392 printf("Device %d: ", idx);
393 if (chip->numchips > 1)
394 printf("%dx ", chip->numchips);
395 printf("%s, sector size %u KiB\n",
396 nand->name, nand->erasesize >> 10);
397 printf(" Page size %8d b\n", nand->writesize);
398 printf(" OOB size %8d b\n", nand->oobsize);
399 printf(" Erase size %8d b\n", nand->erasesize);
401 /* Set geometry info */
402 setenv_hex("nand_writesize", nand->writesize);
403 setenv_hex("nand_oobsize", nand->oobsize);
404 setenv_hex("nand_erasesize", nand->erasesize);
407 static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,
414 mtd_oob_ops_t ops = {
415 .datbuf = (u8 *)addr,
416 .oobbuf = ((u8 *)addr) + nand->writesize,
417 .len = nand->writesize,
418 .ooblen = nand->oobsize,
423 ret = mtd_read_oob(nand, off, &ops);
425 ret = mtd_write_oob(nand, off, &ops);
427 ret = nand_verify_page_oob(nand, &ops, off);
431 printf("%s: error at offset %llx, ret %d\n",
432 __func__, (long long)off, ret);
436 addr += nand->writesize + nand->oobsize;
437 off += nand->writesize;
443 /* Adjust a chip/partition size down for bad blocks so we don't
444 * read/write past the end of a chip/partition by accident.
446 static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev)
448 /* We grab the nand info object here fresh because this is usually
449 * called after arg_off_size() which can change the value of dev.
451 nand_info_t *nand = &nand_info[dev];
452 loff_t maxoffset = offset + *size;
455 /* count badblocks in NAND from offset to offset + size */
456 for (; offset < maxoffset; offset += nand->erasesize) {
457 if (nand_block_isbad(nand, offset))
460 /* adjust size if any bad blocks found */
462 *size -= badblocks * nand->erasesize;
463 printf("size adjusted to 0x%llx (%d bad blocks)\n",
464 (unsigned long long)*size, badblocks);
468 static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
472 loff_t off, size, maxsize;
475 #ifdef CONFIG_SYS_NAND_QUIET
476 int quiet = CONFIG_SYS_NAND_QUIET;
480 const char *quiet_str = getenv("quiet");
481 int dev = nand_curr_device;
482 int repeat = flag & CMD_FLAG_REPEAT;
484 /* at least two arguments please */
489 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
493 /* Only "dump" is repeatable. */
494 if (repeat && strcmp(cmd, "dump"))
495 return CMD_RET_FAILURE;
497 if (strcmp(cmd, "info") == 0) {
500 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
501 if (nand_info[i].name)
502 nand_print_and_set_info(i);
504 return CMD_RET_SUCCESS;
507 if (strcmp(cmd, "device") == 0) {
510 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE)
511 puts("no devices available\n");
513 nand_print_and_set_info(dev);
514 return CMD_RET_SUCCESS;
517 dev = (int)simple_strtoul(argv[2], NULL, 10);
520 return CMD_RET_SUCCESS;
523 #ifdef CONFIG_ENV_OFFSET_OOB
524 /* this command operates only on the first nand device */
525 if (strcmp(cmd, "env.oob") == 0)
526 return do_nand_env_oob(cmdtp, argc - 1, argv + 1) ?
527 CMD_RET_FAILURE : CMD_RET_SUCCESS;;
530 /* The following commands operate on the current device, unless
531 * overridden by a partition specifier. Note that if somehow the
532 * current device is invalid, it will have to be changed to a valid
533 * one before these commands can run, even if a partition specifier
534 * for another device is to be used.
536 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
537 !nand_info[dev].name) {
538 puts("\nno devices available\n");
539 return CMD_RET_FAILURE;
541 nand = &nand_info[dev];
543 if (strcmp(cmd, "bad") == 0) {
544 printf("\nDevice %d bad blocks:\n", dev);
545 for (off = 0; off < nand->size; off += nand->erasesize)
546 if (nand_block_isbad(nand, off))
547 printf(" %08llx\n", (unsigned long long)off);
548 return CMD_RET_SUCCESS;
554 * nand erase [clean] [off size]
556 if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
557 nand_erase_options_t opts;
558 /* "clean" at index 2 means request to write cleanmarker */
559 int clean = argc > 2 && !strcmp("clean", argv[2]);
560 int scrub_yes = argc > 2 && !strcmp("-y", argv[2]);
561 int o = (clean || scrub_yes) ? 3 : 2;
562 int scrub = !strncmp(cmd, "scrub", 5);
565 const char *scrub_warn =
567 "scrub option will erase all factory set bad blocks!\n"
569 "There is no reliable way to recover them.\n"
571 "Use this command only for testing purposes if you\n"
573 "are sure of what you are doing!\n"
574 "\nReally scrub this NAND flash? <y/N>\n";
577 if (!strcmp(&cmd[5], ".spread")) {
579 } else if (!strcmp(&cmd[5], ".part")) {
581 } else if (!strcmp(&cmd[5], ".chip")) {
589 * Don't allow missing arguments to cause full chip/partition
590 * erases -- easy to do accidentally, e.g. with a misspelled
593 if (argc != o + args)
596 printf("\nNAND %s: ", cmd);
597 /* skip first two or three arguments, look for offset and size */
598 if (arg_off_size(argc - o, argv + o, &dev, &off, &size,
600 return CMD_RET_FAILURE;
602 nand = &nand_info[dev];
604 memset(&opts, 0, sizeof(opts));
609 opts.spread = spread;
616 if (confirm_yesno()) {
619 puts("scrub aborted\n");
620 return CMD_RET_FAILURE;
624 ret = nand_erase_opts(nand, &opts);
625 printf("%s\n", ret ? "ERROR" : "OK");
627 return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
630 if (strncmp(cmd, "dump", 4) == 0) {
634 off = (int)simple_strtoul(argv[2], NULL, 16);
635 ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
637 return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
640 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
649 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
651 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
652 printf("\nNAND %s: ", read ? "read" : "write");
654 s = strchr(cmd, '.');
656 if (s && !strcmp(s, ".raw")) {
659 if (arg_off(argv[3], &dev, &off, &size, &maxsize))
662 nand = &nand_info[dev];
664 if (argc > 4 && !str2long(argv[4], &pagecount)) {
665 printf("'%s' is not a number\n", argv[4]);
669 if (pagecount * nand->writesize > size) {
670 puts("Size exceeds partition or device limit\n");
674 rwsize = pagecount * (nand->writesize + nand->oobsize);
676 if (arg_off_size(argc - 3, argv + 3, &dev,
677 &off, &size, &maxsize) != 0)
680 /* size is unspecified */
682 adjust_size_for_badblocks(&size, off, dev);
686 nand = &nand_info[dev];
688 if (!s || !strcmp(s, ".jffs2") ||
689 !strcmp(s, ".e") || !strcmp(s, ".i")) {
691 ret = nand_read_skip_bad(nand, off, &rwsize,
695 ret = nand_write_skip_bad(nand, off, &rwsize,
699 #ifdef CONFIG_CMD_NAND_TRIMFFS
700 } else if (!strcmp(s, ".trimffs")) {
702 printf("Unknown nand command suffix '%s'\n", s);
703 return CMD_RET_FAILURE;
705 ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
706 maxsize, (u_char *)addr,
707 WITH_DROP_FFS | WITH_WR_VERIFY);
709 #ifdef CONFIG_CMD_NAND_YAFFS
710 } else if (!strcmp(s, ".yaffs")) {
712 printf("Unknown nand command suffix '%s'.\n", s);
713 return CMD_RET_FAILURE;
715 ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
716 maxsize, (u_char *)addr,
717 WITH_YAFFS_OOB | WITH_WR_VERIFY);
719 } else if (!strcmp(s, ".oob")) {
720 /* out-of-band data */
721 mtd_oob_ops_t ops = {
722 .oobbuf = (u8 *)addr,
728 ret = mtd_read_oob(nand, off, &ops);
730 ret = mtd_write_oob(nand, off, &ops);
732 ret = raw_access(nand, addr, off, pagecount, read);
734 printf("Unknown nand command suffix '%s'.\n", s);
735 return CMD_RET_FAILURE;
738 printf(" %zu bytes %s: %s\n", rwsize,
739 read ? "read" : "written", ret ? "ERROR" : "OK");
741 return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
744 #ifdef CONFIG_CMD_NAND_TORTURE
745 if (strcmp(cmd, "torture") == 0) {
749 if (!str2off(argv[2], &off)) {
750 puts("Offset is not a valid number\n");
754 printf("\nNAND torture: device %d offset 0x%llx size 0x%x\n",
755 dev, off, nand->erasesize);
756 ret = nand_torture(nand, off);
757 printf(" %s\n", ret ? "Failed" : "Passed");
759 return ret == 0 ? 0 : 1;
763 if (strcmp(cmd, "markbad") == 0) {
771 addr = simple_strtoul(*argv, NULL, 16);
773 if (mtd_block_markbad(nand, addr)) {
774 printf("block 0x%08lx NOT marked "
775 "as bad! ERROR %d\n",
779 printf("block 0x%08lx successfully "
786 return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
789 if (strcmp(cmd, "biterr") == 0) {
791 return CMD_RET_FAILURE;
794 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
795 if (strcmp(cmd, "lock") == 0) {
799 if (!strcmp("tight", argv[2]))
801 if (!strcmp("status", argv[2]))
805 do_nand_status(nand);
807 if (!nand_lock(nand, tight)) {
808 puts("NAND flash successfully locked\n");
810 puts("Error locking NAND flash\n");
811 return CMD_RET_FAILURE;
814 return CMD_RET_SUCCESS;
817 if (strncmp(cmd, "unlock", 5) == 0) {
820 s = strchr(cmd, '.');
822 if (s && !strcmp(s, ".allexcept"))
825 if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
827 return CMD_RET_FAILURE;
829 if (!nand_unlock(&nand_info[dev], off, size, allexcept)) {
830 puts("NAND flash successfully unlocked\n");
832 puts("Error unlocking NAND flash, "
833 "write and erase will probably fail\n");
834 return CMD_RET_FAILURE;
836 return CMD_RET_SUCCESS;
841 return CMD_RET_USAGE;
844 #ifdef CONFIG_SYS_LONGHELP
845 static char nand_help_text[] =
846 "info - show available NAND devices\n"
847 "nand device [dev] - show or set current device\n"
848 "nand read - addr off|partition size\n"
849 "nand write - addr off|partition size\n"
850 " read/write 'size' bytes starting at offset 'off'\n"
851 " to/from memory address 'addr', skipping bad blocks.\n"
852 "nand read.raw - addr off|partition [count]\n"
853 "nand write.raw - addr off|partition [count]\n"
854 " Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
855 #ifdef CONFIG_CMD_NAND_TRIMFFS
856 "nand write.trimffs - addr off|partition size\n"
857 " write 'size' bytes starting at offset 'off' from memory address\n"
858 " 'addr', skipping bad blocks and dropping any pages at the end\n"
859 " of eraseblocks that contain only 0xFF\n"
861 #ifdef CONFIG_CMD_NAND_YAFFS
862 "nand write.yaffs - addr off|partition size\n"
863 " write 'size' bytes starting at offset 'off' with yaffs format\n"
864 " from memory address 'addr', skipping bad blocks.\n"
866 "nand erase[.spread] [clean] off size - erase 'size' bytes "
867 "from offset 'off'\n"
868 " With '.spread', erase enough for given file size, otherwise,\n"
869 " 'size' includes skipped bad blocks.\n"
870 "nand erase.part [clean] partition - erase entire mtd partition'\n"
871 "nand erase.chip [clean] - erase entire chip'\n"
872 "nand bad - show bad blocks\n"
873 "nand dump[.oob] off - dump page\n"
874 #ifdef CONFIG_CMD_NAND_TORTURE
875 "nand torture off - torture block at offset\n"
877 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
878 " really clean NAND erasing bad blocks (UNSAFE)\n"
879 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
880 "nand biterr off - make a bit error at offset (UNSAFE)"
881 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
883 "nand lock [tight] [status]\n"
884 " bring nand to lock state or display locked pages\n"
885 "nand unlock[.allexcept] [offset] [size] - unlock section"
887 #ifdef CONFIG_ENV_OFFSET_OOB
889 "nand env.oob - environment offset in OOB of block 0 of"
891 "nand env.oob set off|partition - set enviromnent offset\n"
892 "nand env.oob get - get environment offset"
898 nand, CONFIG_SYS_MAXARGS, 1, do_nand,
899 "NAND sub-system", nand_help_text
902 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
903 ulong offset, ulong addr, char *cmd)
908 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
911 #if defined(CONFIG_FIT)
912 const void *fit_hdr = NULL;
915 s = strchr(cmd, '.');
917 (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
918 printf("Unknown nand load suffix '%s'\n", s);
919 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX);
923 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
925 cnt = nand->writesize;
926 r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size,
929 puts("** Read error\n");
930 bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ);
933 bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ);
935 switch (genimg_get_format ((void *)addr)) {
936 #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
937 case IMAGE_FORMAT_LEGACY:
938 hdr = (image_header_t *)addr;
940 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE);
941 image_print_contents (hdr);
943 cnt = image_get_image_size (hdr);
946 #if defined(CONFIG_FIT)
947 case IMAGE_FORMAT_FIT:
948 fit_hdr = (const void *)addr;
949 puts ("Fit image detected...\n");
951 cnt = fit_get_size (fit_hdr);
955 bootstage_error(BOOTSTAGE_ID_NAND_TYPE);
956 puts ("** Unknown image type\n");
959 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE);
961 r = nand_read_skip_bad(nand, offset, &cnt, NULL, nand->size,
964 puts("** Read error\n");
965 bootstage_error(BOOTSTAGE_ID_NAND_READ);
968 bootstage_mark(BOOTSTAGE_ID_NAND_READ);
970 #if defined(CONFIG_FIT)
971 /* This cannot be done earlier, we need complete FIT image in RAM first */
972 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
973 if (!fit_check_format (fit_hdr)) {
974 bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ);
975 puts ("** Bad FIT image format\n");
978 bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK);
979 fit_print_contents (fit_hdr);
983 /* Loading ok, update default load address */
987 return bootm_maybe_autostart(cmdtp, cmd);
990 static int do_nandboot(cmd_tbl_t *cmdtp, int flag, int argc,
993 char *boot_device = NULL;
995 ulong addr, offset = 0;
996 #if defined(CONFIG_CMD_MTDPARTS)
997 struct mtd_device *dev;
998 struct part_info *part;
1002 char *p = (argc == 2) ? argv[1] : argv[2];
1003 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
1004 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
1005 if (dev->id->type != MTD_DEV_TYPE_NAND) {
1006 puts("Not a NAND device\n");
1012 addr = simple_strtoul(argv[1], NULL, 16);
1014 addr = CONFIG_SYS_LOAD_ADDR;
1015 return nand_load_image(cmdtp, &nand_info[dev->id->num],
1016 part->offset, addr, argv[0]);
1021 bootstage_mark(BOOTSTAGE_ID_NAND_PART);
1024 addr = CONFIG_SYS_LOAD_ADDR;
1025 boot_device = getenv("bootdevice");
1028 addr = simple_strtoul(argv[1], NULL, 16);
1029 boot_device = getenv("bootdevice");
1032 addr = simple_strtoul(argv[1], NULL, 16);
1033 boot_device = argv[2];
1036 addr = simple_strtoul(argv[1], NULL, 16);
1037 boot_device = argv[2];
1038 offset = simple_strtoul(argv[3], NULL, 16);
1041 #if defined(CONFIG_CMD_MTDPARTS)
1044 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX);
1045 return CMD_RET_USAGE;
1047 bootstage_mark(BOOTSTAGE_ID_NAND_SUFFIX);
1050 puts("\n** No boot device **\n");
1051 bootstage_error(BOOTSTAGE_ID_NAND_BOOT_DEVICE);
1054 bootstage_mark(BOOTSTAGE_ID_NAND_BOOT_DEVICE);
1056 idx = simple_strtoul(boot_device, NULL, 16);
1058 if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) {
1059 printf("\n** Device %d not available\n", idx);
1060 bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE);
1063 bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE);
1065 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
1068 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
1069 "boot from NAND device",
1070 "[partition] | [[[loadAddr] dev] offset]"