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.
24 #include <asm/cache.h>
25 #include <linux/mtd/mtd.h>
31 #include <asm/byteorder.h>
32 #include <jffs2/jffs2.h>
35 #include "legacy-mtd-utils.h"
37 #if defined(CONFIG_CMD_MTDPARTS)
39 /* partition handling routines */
40 int mtdparts_init(void);
41 int find_dev_and_part(const char *id
, struct mtd_device
**dev
,
42 u8
*part_num
, struct part_info
**part
);
45 static int nand_dump(struct mtd_info
*mtd
, ulong off
, int only_oob
,
49 u_char
*datbuf
, *oobbuf
, *p
;
54 off
= last
+ mtd
->writesize
;
58 datbuf
= memalign(ARCH_DMA_MINALIGN
, mtd
->writesize
);
60 puts("No memory for page buffer\n");
64 oobbuf
= memalign(ARCH_DMA_MINALIGN
, mtd
->oobsize
);
66 puts("No memory for page buffer\n");
70 off
&= ~(mtd
->writesize
- 1);
71 loff_t addr
= (loff_t
) off
;
72 struct mtd_oob_ops ops
;
73 memset(&ops
, 0, sizeof(ops
));
76 ops
.len
= mtd
->writesize
;
77 ops
.ooblen
= mtd
->oobsize
;
78 ops
.mode
= MTD_OPS_RAW
;
79 i
= mtd_read_oob(mtd
, addr
, &ops
);
81 printf("Error (%d) reading page %08lx\n", i
, off
);
85 printf("Page %08lx dump:\n", off
);
88 i
= mtd
->writesize
>> 4;
92 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
93 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
94 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7],
95 p
[8], p
[9], p
[10], p
[11], p
[12], p
[13], p
[14],
102 i
= mtd
->oobsize
>> 3;
105 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
106 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7]);
118 /* ------------------------------------------------------------------------- */
120 static int set_dev(int dev
)
122 struct mtd_info
*mtd
= get_nand_dev_by_index(dev
);
127 if (nand_curr_device
== dev
)
130 printf("Device %d: %s", dev
, mtd
->name
);
131 puts("... is now current device\n");
132 nand_curr_device
= dev
;
134 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
135 board_nand_select_device(mtd_to_nand(mtd
), dev
);
141 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
142 static void print_status(ulong start
, ulong end
, ulong erasesize
, int status
)
145 * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is
146 * not the same as others. Instead of bit 1 being lock, it is
147 * #lock_tight. To make the driver support either format, ignore bit 1
148 * and use only bit 0 and bit 2.
150 printf("%08lx - %08lx: %08lx blocks %s%s%s\n",
153 (end
- start
) / erasesize
,
154 ((status
& NAND_LOCK_STATUS_TIGHT
) ? "TIGHT " : ""),
155 (!(status
& NAND_LOCK_STATUS_UNLOCK
) ? "LOCK " : ""),
156 ((status
& NAND_LOCK_STATUS_UNLOCK
) ? "UNLOCK " : ""));
159 static void do_nand_status(struct mtd_info
*mtd
)
161 ulong block_start
= 0;
163 int last_status
= -1;
165 struct nand_chip
*nand_chip
= mtd_to_nand(mtd
);
166 /* check the WP bit */
167 nand_chip
->cmdfunc(mtd
, NAND_CMD_STATUS
, -1, -1);
168 printf("device is %swrite protected\n",
169 (nand_chip
->read_byte(mtd
) & 0x80 ?
172 for (off
= 0; off
< mtd
->size
; off
+= mtd
->erasesize
) {
173 int s
= nand_get_lock_status(mtd
, off
);
175 /* print message only if status has changed */
176 if (s
!= last_status
&& off
!= 0) {
177 print_status(block_start
, off
, mtd
->erasesize
,
183 /* Print the last block info */
184 print_status(block_start
, off
, mtd
->erasesize
, last_status
);
188 #ifdef CONFIG_ENV_OFFSET_OOB
189 unsigned long nand_env_oob_offset
;
191 int do_nand_env_oob(cmd_tbl_t
*cmdtp
, int argc
, char *const argv
[])
194 uint32_t oob_buf
[ENV_OFFSET_SIZE
/sizeof(uint32_t)];
195 struct mtd_info
*mtd
= get_nand_dev_by_index(0);
198 if (CONFIG_SYS_MAX_NAND_DEVICE
== 0 || !mtd
) {
199 puts("no devices available\n");
205 if (!strcmp(cmd
, "get")) {
206 ret
= get_nand_env_oob(mtd
, &nand_env_oob_offset
);
210 printf("0x%08lx\n", nand_env_oob_offset
);
211 } else if (!strcmp(cmd
, "set")) {
214 struct mtd_oob_ops ops
;
220 mtd
= get_nand_dev_by_index(idx
);
221 /* We don't care about size, or maxsize. */
222 if (mtd_arg_off(argv
[2], &idx
, &addr
, &maxsize
, &maxsize
,
223 MTD_DEV_TYPE_NAND
, mtd
->size
)) {
224 puts("Offset or partition name expected\n");
228 puts("Offset or partition name expected\n");
233 puts("Partition not on first NAND device\n");
237 if (mtd
->oobavail
< ENV_OFFSET_SIZE
) {
238 printf("Insufficient available OOB bytes:\n"
239 "%d OOB bytes available but %d required for "
241 mtd
->oobavail
, ENV_OFFSET_SIZE
);
245 if ((addr
& (mtd
->erasesize
- 1)) != 0) {
246 printf("Environment offset must be block-aligned\n");
251 ops
.mode
= MTD_OOB_AUTO
;
253 ops
.ooblen
= ENV_OFFSET_SIZE
;
254 ops
.oobbuf
= (void *) oob_buf
;
256 oob_buf
[0] = ENV_OOB_MARKER
;
257 oob_buf
[1] = addr
/ mtd
->erasesize
;
259 ret
= mtd
->write_oob(mtd
, ENV_OFFSET_SIZE
, &ops
);
261 printf("Error writing OOB block 0\n");
265 ret
= get_nand_env_oob(mtd
, &nand_env_oob_offset
);
267 printf("Error reading env offset in OOB\n");
271 if (addr
!= nand_env_oob_offset
) {
272 printf("Verification of env offset in OOB failed: "
273 "0x%08llx expected but got 0x%08lx\n",
274 (unsigned long long)addr
, nand_env_oob_offset
);
284 return CMD_RET_USAGE
;
289 static void nand_print_and_set_info(int idx
)
291 struct mtd_info
*mtd
;
292 struct nand_chip
*chip
;
294 mtd
= get_nand_dev_by_index(idx
);
298 chip
= mtd_to_nand(mtd
);
299 printf("Device %d: ", idx
);
300 if (chip
->numchips
> 1)
301 printf("%dx ", chip
->numchips
);
302 printf("%s, sector size %u KiB\n",
303 mtd
->name
, mtd
->erasesize
>> 10);
304 printf(" Page size %8d b\n", mtd
->writesize
);
305 printf(" OOB size %8d b\n", mtd
->oobsize
);
306 printf(" Erase size %8d b\n", mtd
->erasesize
);
307 printf(" subpagesize %8d b\n", chip
->subpagesize
);
308 printf(" options 0x%08x\n", chip
->options
);
309 printf(" bbt options 0x%08x\n", chip
->bbt_options
);
311 /* Set geometry info */
312 env_set_hex("nand_writesize", mtd
->writesize
);
313 env_set_hex("nand_oobsize", mtd
->oobsize
);
314 env_set_hex("nand_erasesize", mtd
->erasesize
);
317 static int raw_access(struct mtd_info
*mtd
, ulong addr
, loff_t off
,
318 ulong count
, int read
, int no_verify
)
324 mtd_oob_ops_t ops
= {
325 .datbuf
= (u8
*)addr
,
326 .oobbuf
= ((u8
*)addr
) + mtd
->writesize
,
327 .len
= mtd
->writesize
,
328 .ooblen
= mtd
->oobsize
,
333 ret
= mtd_read_oob(mtd
, off
, &ops
);
335 ret
= mtd_write_oob(mtd
, off
, &ops
);
336 if (!ret
&& !no_verify
)
337 ret
= nand_verify_page_oob(mtd
, &ops
, off
);
341 printf("%s: error at offset %llx, ret %d\n",
342 __func__
, (long long)off
, ret
);
346 addr
+= mtd
->writesize
+ mtd
->oobsize
;
347 off
+= mtd
->writesize
;
353 /* Adjust a chip/partition size down for bad blocks so we don't
354 * read/write past the end of a chip/partition by accident.
356 static void adjust_size_for_badblocks(loff_t
*size
, loff_t offset
, int dev
)
358 /* We grab the nand info object here fresh because this is usually
359 * called after arg_off_size() which can change the value of dev.
361 struct mtd_info
*mtd
= get_nand_dev_by_index(dev
);
362 loff_t maxoffset
= offset
+ *size
;
365 /* count badblocks in NAND from offset to offset + size */
366 for (; offset
< maxoffset
; offset
+= mtd
->erasesize
) {
367 if (nand_block_isbad(mtd
, offset
))
370 /* adjust size if any bad blocks found */
372 *size
-= badblocks
* mtd
->erasesize
;
373 printf("size adjusted to 0x%llx (%d bad blocks)\n",
374 (unsigned long long)*size
, badblocks
);
378 static int do_nand(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
382 loff_t off
, size
, maxsize
;
384 struct mtd_info
*mtd
;
385 #ifdef CONFIG_SYS_NAND_QUIET
386 int quiet
= CONFIG_SYS_NAND_QUIET
;
390 const char *quiet_str
= env_get("quiet");
391 int dev
= nand_curr_device
;
392 int repeat
= flag
& CMD_FLAG_REPEAT
;
394 /* at least two arguments please */
399 quiet
= simple_strtoul(quiet_str
, NULL
, 0) != 0;
403 /* Only "dump" is repeatable. */
404 if (repeat
&& strcmp(cmd
, "dump"))
407 if (strcmp(cmd
, "info") == 0) {
410 for (i
= 0; i
< CONFIG_SYS_MAX_NAND_DEVICE
; i
++)
411 nand_print_and_set_info(i
);
415 if (strcmp(cmd
, "device") == 0) {
418 if (dev
< 0 || dev
>= CONFIG_SYS_MAX_NAND_DEVICE
)
419 puts("no devices available\n");
421 nand_print_and_set_info(dev
);
425 dev
= (int)simple_strtoul(argv
[2], NULL
, 10);
431 #ifdef CONFIG_ENV_OFFSET_OOB
432 /* this command operates only on the first nand device */
433 if (strcmp(cmd
, "env.oob") == 0)
434 return do_nand_env_oob(cmdtp
, argc
- 1, argv
+ 1);
437 /* The following commands operate on the current device, unless
438 * overridden by a partition specifier. Note that if somehow the
439 * current device is invalid, it will have to be changed to a valid
440 * one before these commands can run, even if a partition specifier
441 * for another device is to be used.
443 mtd
= get_nand_dev_by_index(dev
);
445 puts("\nno devices available\n");
449 if (strcmp(cmd
, "bad") == 0) {
450 printf("\nDevice %d bad blocks:\n", dev
);
451 for (off
= 0; off
< mtd
->size
; off
+= mtd
->erasesize
)
452 if (nand_block_isbad(mtd
, off
))
453 printf(" %08llx\n", (unsigned long long)off
);
460 * nand erase [clean] [off size]
462 if (strncmp(cmd
, "erase", 5) == 0 || strncmp(cmd
, "scrub", 5) == 0) {
463 nand_erase_options_t opts
;
464 /* "clean" at index 2 means request to write cleanmarker */
465 int clean
= argc
> 2 && !strcmp("clean", argv
[2]);
466 int scrub_yes
= argc
> 2 && !strcmp("-y", argv
[2]);
467 int o
= (clean
|| scrub_yes
) ? 3 : 2;
468 int scrub
= !strncmp(cmd
, "scrub", 5);
471 const char *scrub_warn
=
473 "scrub option will erase all factory set bad blocks!\n"
475 "There is no reliable way to recover them.\n"
477 "Use this command only for testing purposes if you\n"
479 "are sure of what you are doing!\n"
480 "\nReally scrub this NAND flash? <y/N>\n";
483 if (!strcmp(&cmd
[5], ".spread")) {
485 } else if (!strcmp(&cmd
[5], ".part")) {
487 } else if (!strcmp(&cmd
[5], ".chip")) {
495 * Don't allow missing arguments to cause full chip/partition
496 * erases -- easy to do accidentally, e.g. with a misspelled
499 if (argc
!= o
+ args
)
502 printf("\nNAND %s: ", cmd
);
503 /* skip first two or three arguments, look for offset and size */
504 if (mtd_arg_off_size(argc
- o
, argv
+ o
, &dev
, &off
, &size
,
505 &maxsize
, MTD_DEV_TYPE_NAND
,
512 mtd
= get_nand_dev_by_index(dev
);
514 memset(&opts
, 0, sizeof(opts
));
519 opts
.spread
= spread
;
526 if (confirm_yesno()) {
529 puts("scrub aborted\n");
534 ret
= nand_erase_opts(mtd
, &opts
);
535 printf("%s\n", ret
? "ERROR" : "OK");
537 return ret
== 0 ? 0 : 1;
540 if (strncmp(cmd
, "dump", 4) == 0) {
544 off
= (int)simple_strtoul(argv
[2], NULL
, 16);
545 ret
= nand_dump(mtd
, off
, !strcmp(&cmd
[4], ".oob"), repeat
);
547 return ret
== 0 ? 1 : 0;
550 if (strncmp(cmd
, "read", 4) == 0 || strncmp(cmd
, "write", 5) == 0) {
560 addr
= (ulong
)simple_strtoul(argv
[2], NULL
, 16);
562 read
= strncmp(cmd
, "read", 4) == 0; /* 1 = read, 0 = write */
563 printf("\nNAND %s: ", read
? "read" : "write");
565 s
= strchr(cmd
, '.');
567 if (s
&& !strncmp(s
, ".raw", 4)) {
570 if (!strcmp(s
, ".raw.noverify"))
573 if (mtd_arg_off(argv
[3], &dev
, &off
, &size
, &maxsize
,
581 mtd
= get_nand_dev_by_index(dev
);
583 if (argc
> 4 && !str2long(argv
[4], &pagecount
)) {
584 printf("'%s' is not a number\n", argv
[4]);
588 if (pagecount
* mtd
->writesize
> size
) {
589 puts("Size exceeds partition or device limit\n");
593 rwsize
= pagecount
* (mtd
->writesize
+ mtd
->oobsize
);
595 if (mtd_arg_off_size(argc
- 3, argv
+ 3, &dev
, &off
,
604 /* size is unspecified */
606 adjust_size_for_badblocks(&size
, off
, dev
);
610 mtd
= get_nand_dev_by_index(dev
);
612 if (!s
|| !strcmp(s
, ".jffs2") ||
613 !strcmp(s
, ".e") || !strcmp(s
, ".i")) {
615 ret
= nand_read_skip_bad(mtd
, off
, &rwsize
,
619 ret
= nand_write_skip_bad(mtd
, off
, &rwsize
,
623 #ifdef CONFIG_CMD_NAND_TRIMFFS
624 } else if (!strcmp(s
, ".trimffs")) {
626 printf("Unknown nand command suffix '%s'\n", s
);
629 ret
= nand_write_skip_bad(mtd
, off
, &rwsize
, NULL
,
630 maxsize
, (u_char
*)addr
,
631 WITH_DROP_FFS
| WITH_WR_VERIFY
);
633 } else if (!strcmp(s
, ".oob")) {
634 /* out-of-band data */
635 mtd_oob_ops_t ops
= {
636 .oobbuf
= (u8
*)addr
,
642 ret
= mtd_read_oob(mtd
, off
, &ops
);
644 ret
= mtd_write_oob(mtd
, off
, &ops
);
646 ret
= raw_access(mtd
, addr
, off
, pagecount
, read
,
649 printf("Unknown nand command suffix '%s'.\n", s
);
653 printf(" %zu bytes %s: %s\n", rwsize
,
654 read
? "read" : "written", ret
? "ERROR" : "OK");
656 return ret
== 0 ? 0 : 1;
659 #ifdef CONFIG_CMD_NAND_TORTURE
660 if (strcmp(cmd
, "torture") == 0) {
662 unsigned int failed
= 0, passed
= 0;
667 if (!str2off(argv
[2], &off
)) {
668 puts("Offset is not a valid number\n");
672 size
= mtd
->erasesize
;
674 if (!str2off(argv
[3], &size
)) {
675 puts("Size is not a valid number\n");
681 if (endoff
> mtd
->size
) {
682 puts("Arguments beyond end of NAND\n");
686 off
= round_down(off
, mtd
->erasesize
);
687 endoff
= round_up(endoff
, mtd
->erasesize
);
689 printf("\nNAND torture: device %d offset 0x%llx size 0x%llx (block size 0x%x)\n",
690 dev
, off
, size
, mtd
->erasesize
);
691 while (off
< endoff
) {
692 ret
= nand_torture(mtd
, off
);
695 printf(" block at 0x%llx failed\n", off
);
699 off
+= mtd
->erasesize
;
701 printf(" Passed: %u, failed: %u\n", passed
, failed
);
706 if (strcmp(cmd
, "markbad") == 0) {
714 addr
= simple_strtoul(*argv
, NULL
, 16);
716 if (mtd_block_markbad(mtd
, addr
)) {
717 printf("block 0x%08lx NOT marked "
718 "as bad! ERROR %d\n",
722 printf("block 0x%08lx successfully "
732 if (strcmp(cmd
, "biterr") == 0) {
737 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
738 if (strcmp(cmd
, "lock") == 0) {
742 if (!strcmp("tight", argv
[2]))
744 if (!strcmp("status", argv
[2]))
750 if (!nand_lock(mtd
, tight
)) {
751 puts("NAND flash successfully locked\n");
753 puts("Error locking NAND flash\n");
760 if (strncmp(cmd
, "unlock", 5) == 0) {
763 s
= strchr(cmd
, '.');
765 if (s
&& !strcmp(s
, ".allexcept"))
768 if (mtd_arg_off_size(argc
- 2, argv
+ 2, &dev
, &off
, &size
,
769 &maxsize
, MTD_DEV_TYPE_NAND
,
776 mtd
= get_nand_dev_by_index(dev
);
778 if (!nand_unlock(mtd
, off
, size
, allexcept
)) {
779 puts("NAND flash successfully unlocked\n");
781 puts("Error unlocking NAND flash, "
782 "write and erase will probably fail\n");
790 return CMD_RET_USAGE
;
793 #ifdef CONFIG_SYS_LONGHELP
794 static char nand_help_text
[] =
795 "info - show available NAND devices\n"
796 "nand device [dev] - show or set current device\n"
797 "nand read - addr off|partition size\n"
798 "nand write - addr off|partition size\n"
799 " read/write 'size' bytes starting at offset 'off'\n"
800 " to/from memory address 'addr', skipping bad blocks.\n"
801 "nand read.raw - addr off|partition [count]\n"
802 "nand write.raw[.noverify] - addr off|partition [count]\n"
803 " Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
804 #ifdef CONFIG_CMD_NAND_TRIMFFS
805 "nand write.trimffs - addr off|partition size\n"
806 " write 'size' bytes starting at offset 'off' from memory address\n"
807 " 'addr', skipping bad blocks and dropping any pages at the end\n"
808 " of eraseblocks that contain only 0xFF\n"
810 "nand erase[.spread] [clean] off size - erase 'size' bytes "
811 "from offset 'off'\n"
812 " With '.spread', erase enough for given file size, otherwise,\n"
813 " 'size' includes skipped bad blocks.\n"
814 "nand erase.part [clean] partition - erase entire mtd partition'\n"
815 "nand erase.chip [clean] - erase entire chip'\n"
816 "nand bad - show bad blocks\n"
817 "nand dump[.oob] off - dump page\n"
818 #ifdef CONFIG_CMD_NAND_TORTURE
819 "nand torture off - torture one block at offset\n"
820 "nand torture off [size] - torture blocks from off to off+size\n"
822 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
823 " really clean NAND erasing bad blocks (UNSAFE)\n"
824 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
825 "nand biterr off - make a bit error at offset (UNSAFE)"
826 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
828 "nand lock [tight] [status]\n"
829 " bring nand to lock state or display locked pages\n"
830 "nand unlock[.allexcept] [offset] [size] - unlock section"
832 #ifdef CONFIG_ENV_OFFSET_OOB
834 "nand env.oob - environment offset in OOB of block 0 of"
836 "nand env.oob set off|partition - set enviromnent offset\n"
837 "nand env.oob get - get environment offset"
843 nand
, CONFIG_SYS_MAXARGS
, 1, do_nand
,
844 "NAND sub-system", nand_help_text
847 static int nand_load_image(cmd_tbl_t
*cmdtp
, struct mtd_info
*mtd
,
848 ulong offset
, ulong addr
, char *cmd
)
853 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
856 #if defined(CONFIG_FIT)
857 const void *fit_hdr
= NULL
;
860 s
= strchr(cmd
, '.');
862 (strcmp(s
, ".jffs2") && strcmp(s
, ".e") && strcmp(s
, ".i"))) {
863 printf("Unknown nand load suffix '%s'\n", s
);
864 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX
);
868 printf("\nLoading from %s, offset 0x%lx\n", mtd
->name
, offset
);
870 cnt
= mtd
->writesize
;
871 r
= nand_read_skip_bad(mtd
, offset
, &cnt
, NULL
, mtd
->size
,
874 puts("** Read error\n");
875 bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ
);
878 bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ
);
880 switch (genimg_get_format ((void *)addr
)) {
881 #if defined(CONFIG_LEGACY_IMAGE_FORMAT)
882 case IMAGE_FORMAT_LEGACY
:
883 hdr
= (image_header_t
*)addr
;
885 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE
);
886 image_print_contents (hdr
);
888 cnt
= image_get_image_size (hdr
);
891 #if defined(CONFIG_FIT)
892 case IMAGE_FORMAT_FIT
:
893 fit_hdr
= (const void *)addr
;
894 puts ("Fit image detected...\n");
896 cnt
= fit_get_size (fit_hdr
);
900 bootstage_error(BOOTSTAGE_ID_NAND_TYPE
);
901 puts ("** Unknown image type\n");
904 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE
);
906 r
= nand_read_skip_bad(mtd
, offset
, &cnt
, NULL
, mtd
->size
,
909 puts("** Read error\n");
910 bootstage_error(BOOTSTAGE_ID_NAND_READ
);
913 bootstage_mark(BOOTSTAGE_ID_NAND_READ
);
915 #if defined(CONFIG_FIT)
916 /* This cannot be done earlier, we need complete FIT image in RAM first */
917 if (genimg_get_format ((void *)addr
) == IMAGE_FORMAT_FIT
) {
918 if (!fit_check_format (fit_hdr
)) {
919 bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ
);
920 puts ("** Bad FIT image format\n");
923 bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK
);
924 fit_print_contents (fit_hdr
);
928 /* Loading ok, update default load address */
930 image_load_addr
= addr
;
932 return bootm_maybe_autostart(cmdtp
, cmd
);
935 static int do_nandboot(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
938 char *boot_device
= NULL
;
940 ulong addr
, offset
= 0;
941 struct mtd_info
*mtd
;
942 #if defined(CONFIG_CMD_MTDPARTS)
943 struct mtd_device
*dev
;
944 struct part_info
*part
;
948 char *p
= (argc
== 2) ? argv
[1] : argv
[2];
949 if (!(str2long(p
, &addr
)) && (mtdparts_init() == 0) &&
950 (find_dev_and_part(p
, &dev
, &pnum
, &part
) == 0)) {
951 if (dev
->id
->type
!= MTD_DEV_TYPE_NAND
) {
952 puts("Not a NAND device\n");
958 addr
= simple_strtoul(argv
[1], NULL
, 16);
960 addr
= CONFIG_SYS_LOAD_ADDR
;
962 mtd
= get_nand_dev_by_index(dev
->id
->num
);
963 return nand_load_image(cmdtp
, mtd
, part
->offset
,
969 bootstage_mark(BOOTSTAGE_ID_NAND_PART
);
972 addr
= CONFIG_SYS_LOAD_ADDR
;
973 boot_device
= env_get("bootdevice");
976 addr
= simple_strtoul(argv
[1], NULL
, 16);
977 boot_device
= env_get("bootdevice");
980 addr
= simple_strtoul(argv
[1], NULL
, 16);
981 boot_device
= argv
[2];
984 addr
= simple_strtoul(argv
[1], NULL
, 16);
985 boot_device
= argv
[2];
986 offset
= simple_strtoul(argv
[3], NULL
, 16);
989 #if defined(CONFIG_CMD_MTDPARTS)
992 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX
);
993 return CMD_RET_USAGE
;
995 bootstage_mark(BOOTSTAGE_ID_NAND_SUFFIX
);
998 puts("\n** No boot device **\n");
999 bootstage_error(BOOTSTAGE_ID_NAND_BOOT_DEVICE
);
1002 bootstage_mark(BOOTSTAGE_ID_NAND_BOOT_DEVICE
);
1004 idx
= simple_strtoul(boot_device
, NULL
, 16);
1006 mtd
= get_nand_dev_by_index(idx
);
1008 printf("\n** Device %d not available\n", idx
);
1009 bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE
);
1012 bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE
);
1014 return nand_load_image(cmdtp
, mtd
, offset
, addr
, argv
[0]);
1017 U_BOOT_CMD(nboot
, 4, 1, do_nandboot
,
1018 "boot from NAND device",
1019 "[partition] | [[[loadAddr] dev] offset]"