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
;
47 off
= last
+ nand
->writesize
;
51 datbuf
= memalign(ARCH_DMA_MINALIGN
, nand
->writesize
);
52 oobbuf
= memalign(ARCH_DMA_MINALIGN
, nand
->oobsize
);
53 if (!datbuf
|| !oobbuf
) {
54 puts("No memory for page buffer\n");
57 off
&= ~(nand
->writesize
- 1);
58 loff_t addr
= (loff_t
) off
;
59 struct mtd_oob_ops ops
;
60 memset(&ops
, 0, sizeof(ops
));
63 ops
.len
= nand
->writesize
;
64 ops
.ooblen
= nand
->oobsize
;
65 ops
.mode
= MTD_OPS_RAW
;
66 i
= mtd_read_oob(nand
, addr
, &ops
);
68 printf("Error (%d) reading page %08lx\n", i
, off
);
73 printf("Page %08lx dump:\n", off
);
74 i
= nand
->writesize
>> 4;
79 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x"
80 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
81 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7],
82 p
[8], p
[9], p
[10], p
[11], p
[12], p
[13], p
[14],
87 i
= nand
->oobsize
>> 3;
90 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
91 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7]);
100 /* ------------------------------------------------------------------------- */
102 static int set_dev(int dev
)
104 if (dev
< 0 || dev
>= CONFIG_SYS_MAX_NAND_DEVICE
||
105 !nand_info
[dev
].name
) {
106 puts("No such device\n");
110 if (nand_curr_device
== dev
)
113 printf("Device %d: %s", dev
, nand_info
[dev
].name
);
114 puts("... is now current device\n");
115 nand_curr_device
= dev
;
117 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
118 board_nand_select_device(nand_info
[dev
].priv
, dev
);
124 static inline int str2off(const char *p
, loff_t
*num
)
128 *num
= simple_strtoull(p
, &endptr
, 16);
129 return *p
!= '\0' && *endptr
== '\0';
132 static inline int str2long(const char *p
, ulong
*num
)
136 *num
= simple_strtoul(p
, &endptr
, 16);
137 return *p
!= '\0' && *endptr
== '\0';
140 static int get_part(const char *partname
, int *idx
, loff_t
*off
, loff_t
*size
,
143 #ifdef CONFIG_CMD_MTDPARTS
144 struct mtd_device
*dev
;
145 struct part_info
*part
;
149 ret
= mtdparts_init();
153 ret
= find_dev_and_part(partname
, &dev
, &pnum
, &part
);
157 if (dev
->id
->type
!= MTD_DEV_TYPE_NAND
) {
158 puts("not a NAND device\n");
164 *maxsize
= part
->size
;
173 puts("offset is not a number\n");
178 static int arg_off(const char *arg
, int *idx
, loff_t
*off
, loff_t
*size
,
181 if (!str2off(arg
, off
))
182 return get_part(arg
, idx
, off
, size
, maxsize
);
184 if (*off
>= nand_info
[*idx
].size
) {
185 puts("Offset exceeds device limit\n");
189 *maxsize
= nand_info
[*idx
].size
- *off
;
194 static int arg_off_size(int argc
, char *const argv
[], int *idx
,
195 loff_t
*off
, loff_t
*size
, loff_t
*maxsize
)
201 *size
= nand_info
[*idx
].size
;
206 ret
= arg_off(argv
[0], idx
, off
, size
, maxsize
);
213 if (!str2off(argv
[1], size
)) {
214 printf("'%s' is not a number\n", argv
[1]);
218 if (*size
> *maxsize
) {
219 puts("Size exceeds partition or device limit\n");
224 printf("device %d ", *idx
);
225 if (*size
== nand_info
[*idx
].size
)
226 puts("whole chip\n");
228 printf("offset 0x%llx, size 0x%llx\n",
229 (unsigned long long)*off
, (unsigned long long)*size
);
233 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
234 static void print_status(ulong start
, ulong end
, ulong erasesize
, int status
)
237 * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is
238 * not the same as others. Instead of bit 1 being lock, it is
239 * #lock_tight. To make the driver support either format, ignore bit 1
240 * and use only bit 0 and bit 2.
242 printf("%08lx - %08lx: %08lx blocks %s%s%s\n",
245 (end
- start
) / erasesize
,
246 ((status
& NAND_LOCK_STATUS_TIGHT
) ? "TIGHT " : ""),
247 (!(status
& NAND_LOCK_STATUS_UNLOCK
) ? "LOCK " : ""),
248 ((status
& NAND_LOCK_STATUS_UNLOCK
) ? "UNLOCK " : ""));
251 static void do_nand_status(nand_info_t
*nand
)
253 ulong block_start
= 0;
255 int last_status
= -1;
257 struct nand_chip
*nand_chip
= nand
->priv
;
258 /* check the WP bit */
259 nand_chip
->cmdfunc(nand
, NAND_CMD_STATUS
, -1, -1);
260 printf("device is %swrite protected\n",
261 (nand_chip
->read_byte(nand
) & 0x80 ?
264 for (off
= 0; off
< nand
->size
; off
+= nand
->erasesize
) {
265 int s
= nand_get_lock_status(nand
, off
);
267 /* print message only if status has changed */
268 if (s
!= last_status
&& off
!= 0) {
269 print_status(block_start
, off
, nand
->erasesize
,
275 /* Print the last block info */
276 print_status(block_start
, off
, nand
->erasesize
, last_status
);
280 #ifdef CONFIG_ENV_OFFSET_OOB
281 unsigned long nand_env_oob_offset
;
283 int do_nand_env_oob(cmd_tbl_t
*cmdtp
, int argc
, char *const argv
[])
286 uint32_t oob_buf
[ENV_OFFSET_SIZE
/sizeof(uint32_t)];
287 nand_info_t
*nand
= &nand_info
[0];
290 if (CONFIG_SYS_MAX_NAND_DEVICE
== 0 || !nand
->name
) {
291 puts("no devices available\n");
297 if (!strcmp(cmd
, "get")) {
298 ret
= get_nand_env_oob(nand
, &nand_env_oob_offset
);
302 printf("0x%08lx\n", nand_env_oob_offset
);
303 } else if (!strcmp(cmd
, "set")) {
306 struct mtd_oob_ops ops
;
312 /* We don't care about size, or maxsize. */
313 if (arg_off(argv
[2], &idx
, &addr
, &maxsize
, &maxsize
)) {
314 puts("Offset or partition name expected\n");
319 puts("Partition not on first NAND device\n");
323 if (nand
->oobavail
< ENV_OFFSET_SIZE
) {
324 printf("Insufficient available OOB bytes:\n"
325 "%d OOB bytes available but %d required for "
327 nand
->oobavail
, ENV_OFFSET_SIZE
);
331 if ((addr
& (nand
->erasesize
- 1)) != 0) {
332 printf("Environment offset must be block-aligned\n");
337 ops
.mode
= MTD_OOB_AUTO
;
339 ops
.ooblen
= ENV_OFFSET_SIZE
;
340 ops
.oobbuf
= (void *) oob_buf
;
342 oob_buf
[0] = ENV_OOB_MARKER
;
343 oob_buf
[1] = addr
/ nand
->erasesize
;
345 ret
= nand
->write_oob(nand
, ENV_OFFSET_SIZE
, &ops
);
347 printf("Error writing OOB block 0\n");
351 ret
= get_nand_env_oob(nand
, &nand_env_oob_offset
);
353 printf("Error reading env offset in OOB\n");
357 if (addr
!= nand_env_oob_offset
) {
358 printf("Verification of env offset in OOB failed: "
359 "0x%08llx expected but got 0x%08lx\n",
360 (unsigned long long)addr
, nand_env_oob_offset
);
370 return CMD_RET_USAGE
;
375 static void nand_print_and_set_info(int idx
)
377 nand_info_t
*nand
= &nand_info
[idx
];
378 struct nand_chip
*chip
= nand
->priv
;
380 printf("Device %d: ", idx
);
381 if (chip
->numchips
> 1)
382 printf("%dx ", chip
->numchips
);
383 printf("%s, sector size %u KiB\n",
384 nand
->name
, nand
->erasesize
>> 10);
385 printf(" Page size %8d b\n", nand
->writesize
);
386 printf(" OOB size %8d b\n", nand
->oobsize
);
387 printf(" Erase size %8d b\n", nand
->erasesize
);
389 /* Set geometry info */
390 setenv_hex("nand_writesize", nand
->writesize
);
391 setenv_hex("nand_oobsize", nand
->oobsize
);
392 setenv_hex("nand_erasesize", nand
->erasesize
);
395 static int raw_access(nand_info_t
*nand
, ulong addr
, loff_t off
, ulong count
,
402 mtd_oob_ops_t ops
= {
403 .datbuf
= (u8
*)addr
,
404 .oobbuf
= ((u8
*)addr
) + nand
->writesize
,
405 .len
= nand
->writesize
,
406 .ooblen
= nand
->oobsize
,
411 ret
= mtd_read_oob(nand
, off
, &ops
);
413 ret
= mtd_write_oob(nand
, off
, &ops
);
416 printf("%s: error at offset %llx, ret %d\n",
417 __func__
, (long long)off
, ret
);
421 addr
+= nand
->writesize
+ nand
->oobsize
;
422 off
+= nand
->writesize
;
428 /* Adjust a chip/partition size down for bad blocks so we don't
429 * read/write past the end of a chip/partition by accident.
431 static void adjust_size_for_badblocks(loff_t
*size
, loff_t offset
, int dev
)
433 /* We grab the nand info object here fresh because this is usually
434 * called after arg_off_size() which can change the value of dev.
436 nand_info_t
*nand
= &nand_info
[dev
];
437 loff_t maxoffset
= offset
+ *size
;
440 /* count badblocks in NAND from offset to offset + size */
441 for (; offset
< maxoffset
; offset
+= nand
->erasesize
) {
442 if (nand_block_isbad(nand
, offset
))
445 /* adjust size if any bad blocks found */
447 *size
-= badblocks
* nand
->erasesize
;
448 printf("size adjusted to 0x%llx (%d bad blocks)\n",
449 (unsigned long long)*size
, badblocks
);
453 static int do_nand(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
457 loff_t off
, size
, maxsize
;
460 #ifdef CONFIG_SYS_NAND_QUIET
461 int quiet
= CONFIG_SYS_NAND_QUIET
;
465 const char *quiet_str
= getenv("quiet");
466 int dev
= nand_curr_device
;
467 int repeat
= flag
& CMD_FLAG_REPEAT
;
469 /* at least two arguments please */
474 quiet
= simple_strtoul(quiet_str
, NULL
, 0) != 0;
478 /* Only "dump" is repeatable. */
479 if (repeat
&& strcmp(cmd
, "dump"))
482 if (strcmp(cmd
, "info") == 0) {
485 for (i
= 0; i
< CONFIG_SYS_MAX_NAND_DEVICE
; i
++) {
486 if (nand_info
[i
].name
)
487 nand_print_and_set_info(i
);
492 if (strcmp(cmd
, "device") == 0) {
495 if (dev
< 0 || dev
>= CONFIG_SYS_MAX_NAND_DEVICE
)
496 puts("no devices available\n");
498 nand_print_and_set_info(dev
);
502 dev
= (int)simple_strtoul(argv
[2], NULL
, 10);
508 #ifdef CONFIG_ENV_OFFSET_OOB
509 /* this command operates only on the first nand device */
510 if (strcmp(cmd
, "env.oob") == 0)
511 return do_nand_env_oob(cmdtp
, argc
- 1, argv
+ 1);
514 /* The following commands operate on the current device, unless
515 * overridden by a partition specifier. Note that if somehow the
516 * current device is invalid, it will have to be changed to a valid
517 * one before these commands can run, even if a partition specifier
518 * for another device is to be used.
520 if (dev
< 0 || dev
>= CONFIG_SYS_MAX_NAND_DEVICE
||
521 !nand_info
[dev
].name
) {
522 puts("\nno devices available\n");
525 nand
= &nand_info
[dev
];
527 if (strcmp(cmd
, "bad") == 0) {
528 printf("\nDevice %d bad blocks:\n", dev
);
529 for (off
= 0; off
< nand
->size
; off
+= nand
->erasesize
)
530 if (nand_block_isbad(nand
, off
))
531 printf(" %08llx\n", (unsigned long long)off
);
538 * nand erase [clean] [off size]
540 if (strncmp(cmd
, "erase", 5) == 0 || strncmp(cmd
, "scrub", 5) == 0) {
541 nand_erase_options_t opts
;
542 /* "clean" at index 2 means request to write cleanmarker */
543 int clean
= argc
> 2 && !strcmp("clean", argv
[2]);
544 int scrub_yes
= argc
> 2 && !strcmp("-y", argv
[2]);
545 int o
= (clean
|| scrub_yes
) ? 3 : 2;
546 int scrub
= !strncmp(cmd
, "scrub", 5);
549 const char *scrub_warn
=
551 "scrub option will erase all factory set bad blocks!\n"
553 "There is no reliable way to recover them.\n"
555 "Use this command only for testing purposes if you\n"
557 "are sure of what you are doing!\n"
558 "\nReally scrub this NAND flash? <y/N>\n";
561 if (!strcmp(&cmd
[5], ".spread")) {
563 } else if (!strcmp(&cmd
[5], ".part")) {
565 } else if (!strcmp(&cmd
[5], ".chip")) {
573 * Don't allow missing arguments to cause full chip/partition
574 * erases -- easy to do accidentally, e.g. with a misspelled
577 if (argc
!= o
+ args
)
580 printf("\nNAND %s: ", cmd
);
581 /* skip first two or three arguments, look for offset and size */
582 if (arg_off_size(argc
- o
, argv
+ o
, &dev
, &off
, &size
,
586 nand
= &nand_info
[dev
];
588 memset(&opts
, 0, sizeof(opts
));
593 opts
.spread
= spread
;
601 else if (getc() == 'y') {
606 puts("scrub aborted\n");
610 puts("scrub aborted\n");
614 ret
= nand_erase_opts(nand
, &opts
);
615 printf("%s\n", ret
? "ERROR" : "OK");
617 return ret
== 0 ? 0 : 1;
620 if (strncmp(cmd
, "dump", 4) == 0) {
624 off
= (int)simple_strtoul(argv
[2], NULL
, 16);
625 ret
= nand_dump(nand
, off
, !strcmp(&cmd
[4], ".oob"), repeat
);
627 return ret
== 0 ? 1 : 0;
630 if (strncmp(cmd
, "read", 4) == 0 || strncmp(cmd
, "write", 5) == 0) {
639 addr
= (ulong
)simple_strtoul(argv
[2], NULL
, 16);
641 read
= strncmp(cmd
, "read", 4) == 0; /* 1 = read, 0 = write */
642 printf("\nNAND %s: ", read
? "read" : "write");
644 nand
= &nand_info
[dev
];
646 s
= strchr(cmd
, '.');
648 if (s
&& !strcmp(s
, ".raw")) {
651 if (arg_off(argv
[3], &dev
, &off
, &size
, &maxsize
))
654 if (argc
> 4 && !str2long(argv
[4], &pagecount
)) {
655 printf("'%s' is not a number\n", argv
[4]);
659 if (pagecount
* nand
->writesize
> size
) {
660 puts("Size exceeds partition or device limit\n");
664 rwsize
= pagecount
* (nand
->writesize
+ nand
->oobsize
);
666 if (arg_off_size(argc
- 3, argv
+ 3, &dev
,
667 &off
, &size
, &maxsize
) != 0)
670 /* size is unspecified */
672 adjust_size_for_badblocks(&size
, off
, dev
);
676 if (!s
|| !strcmp(s
, ".jffs2") ||
677 !strcmp(s
, ".e") || !strcmp(s
, ".i")) {
679 ret
= nand_read_skip_bad(nand
, off
, &rwsize
,
683 ret
= nand_write_skip_bad(nand
, off
, &rwsize
,
686 #ifdef CONFIG_CMD_NAND_TRIMFFS
687 } else if (!strcmp(s
, ".trimffs")) {
689 printf("Unknown nand command suffix '%s'\n", s
);
692 ret
= nand_write_skip_bad(nand
, off
, &rwsize
, NULL
,
693 maxsize
, (u_char
*)addr
,
696 #ifdef CONFIG_CMD_NAND_YAFFS
697 } else if (!strcmp(s
, ".yaffs")) {
699 printf("Unknown nand command suffix '%s'.\n", s
);
702 ret
= nand_write_skip_bad(nand
, off
, &rwsize
, NULL
,
703 maxsize
, (u_char
*)addr
,
706 } else if (!strcmp(s
, ".oob")) {
707 /* out-of-band data */
708 mtd_oob_ops_t ops
= {
709 .oobbuf
= (u8
*)addr
,
715 ret
= mtd_read_oob(nand
, off
, &ops
);
717 ret
= mtd_write_oob(nand
, off
, &ops
);
719 ret
= raw_access(nand
, addr
, off
, pagecount
, read
);
721 printf("Unknown nand command suffix '%s'.\n", s
);
725 printf(" %zu bytes %s: %s\n", rwsize
,
726 read
? "read" : "written", ret
? "ERROR" : "OK");
728 return ret
== 0 ? 0 : 1;
731 #ifdef CONFIG_CMD_NAND_TORTURE
732 if (strcmp(cmd
, "torture") == 0) {
736 if (!str2off(argv
[2], &off
)) {
737 puts("Offset is not a valid number\n");
741 printf("\nNAND torture: device %d offset 0x%llx size 0x%x\n",
742 dev
, off
, nand
->erasesize
);
743 ret
= nand_torture(nand
, off
);
744 printf(" %s\n", ret
? "Failed" : "Passed");
746 return ret
== 0 ? 0 : 1;
750 if (strcmp(cmd
, "markbad") == 0) {
758 addr
= simple_strtoul(*argv
, NULL
, 16);
760 if (mtd_block_markbad(nand
, addr
)) {
761 printf("block 0x%08lx NOT marked "
762 "as bad! ERROR %d\n",
766 printf("block 0x%08lx successfully "
776 if (strcmp(cmd
, "biterr") == 0) {
781 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
782 if (strcmp(cmd
, "lock") == 0) {
786 if (!strcmp("tight", argv
[2]))
788 if (!strcmp("status", argv
[2]))
792 do_nand_status(nand
);
794 if (!nand_lock(nand
, tight
)) {
795 puts("NAND flash successfully locked\n");
797 puts("Error locking NAND flash\n");
804 if (strncmp(cmd
, "unlock", 5) == 0) {
807 s
= strchr(cmd
, '.');
809 if (s
&& !strcmp(s
, ".allexcept"))
812 if (arg_off_size(argc
- 2, argv
+ 2, &dev
, &off
, &size
,
816 if (!nand_unlock(&nand_info
[dev
], off
, size
, allexcept
)) {
817 puts("NAND flash successfully unlocked\n");
819 puts("Error unlocking NAND flash, "
820 "write and erase will probably fail\n");
828 return CMD_RET_USAGE
;
831 #ifdef CONFIG_SYS_LONGHELP
832 static char nand_help_text
[] =
833 "info - show available NAND devices\n"
834 "nand device [dev] - show or set current device\n"
835 "nand read - addr off|partition size\n"
836 "nand write - addr off|partition size\n"
837 " read/write 'size' bytes starting at offset 'off'\n"
838 " to/from memory address 'addr', skipping bad blocks.\n"
839 "nand read.raw - addr off|partition [count]\n"
840 "nand write.raw - addr off|partition [count]\n"
841 " Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
842 #ifdef CONFIG_CMD_NAND_TRIMFFS
843 "nand write.trimffs - addr off|partition size\n"
844 " write 'size' bytes starting at offset 'off' from memory address\n"
845 " 'addr', skipping bad blocks and dropping any pages at the end\n"
846 " of eraseblocks that contain only 0xFF\n"
848 #ifdef CONFIG_CMD_NAND_YAFFS
849 "nand write.yaffs - addr off|partition size\n"
850 " write 'size' bytes starting at offset 'off' with yaffs format\n"
851 " from memory address 'addr', skipping bad blocks.\n"
853 "nand erase[.spread] [clean] off size - erase 'size' bytes "
854 "from offset 'off'\n"
855 " With '.spread', erase enough for given file size, otherwise,\n"
856 " 'size' includes skipped bad blocks.\n"
857 "nand erase.part [clean] partition - erase entire mtd partition'\n"
858 "nand erase.chip [clean] - erase entire chip'\n"
859 "nand bad - show bad blocks\n"
860 "nand dump[.oob] off - dump page\n"
861 #ifdef CONFIG_CMD_NAND_TORTURE
862 "nand torture off - torture block at offset\n"
864 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
865 " really clean NAND erasing bad blocks (UNSAFE)\n"
866 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
867 "nand biterr off - make a bit error at offset (UNSAFE)"
868 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
870 "nand lock [tight] [status]\n"
871 " bring nand to lock state or display locked pages\n"
872 "nand unlock[.allexcept] [offset] [size] - unlock section"
874 #ifdef CONFIG_ENV_OFFSET_OOB
876 "nand env.oob - environment offset in OOB of block 0 of"
878 "nand env.oob set off|partition - set enviromnent offset\n"
879 "nand env.oob get - get environment offset"
885 nand
, CONFIG_SYS_MAXARGS
, 1, do_nand
,
886 "NAND sub-system", nand_help_text
889 static int nand_load_image(cmd_tbl_t
*cmdtp
, nand_info_t
*nand
,
890 ulong offset
, ulong addr
, char *cmd
)
896 #if defined(CONFIG_FIT)
897 const void *fit_hdr
= NULL
;
900 s
= strchr(cmd
, '.');
902 (strcmp(s
, ".jffs2") && strcmp(s
, ".e") && strcmp(s
, ".i"))) {
903 printf("Unknown nand load suffix '%s'\n", s
);
904 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX
);
908 printf("\nLoading from %s, offset 0x%lx\n", nand
->name
, offset
);
910 cnt
= nand
->writesize
;
911 r
= nand_read_skip_bad(nand
, offset
, &cnt
, NULL
, nand
->size
,
914 puts("** Read error\n");
915 bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ
);
918 bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ
);
920 switch (genimg_get_format ((void *)addr
)) {
921 case IMAGE_FORMAT_LEGACY
:
922 hdr
= (image_header_t
*)addr
;
924 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE
);
925 image_print_contents (hdr
);
927 cnt
= image_get_image_size (hdr
);
929 #if defined(CONFIG_FIT)
930 case IMAGE_FORMAT_FIT
:
931 fit_hdr
= (const void *)addr
;
932 puts ("Fit image detected...\n");
934 cnt
= fit_get_size (fit_hdr
);
938 bootstage_error(BOOTSTAGE_ID_NAND_TYPE
);
939 puts ("** Unknown image type\n");
942 bootstage_mark(BOOTSTAGE_ID_NAND_TYPE
);
944 r
= nand_read_skip_bad(nand
, offset
, &cnt
, NULL
, nand
->size
,
947 puts("** Read error\n");
948 bootstage_error(BOOTSTAGE_ID_NAND_READ
);
951 bootstage_mark(BOOTSTAGE_ID_NAND_READ
);
953 #if defined(CONFIG_FIT)
954 /* This cannot be done earlier, we need complete FIT image in RAM first */
955 if (genimg_get_format ((void *)addr
) == IMAGE_FORMAT_FIT
) {
956 if (!fit_check_format (fit_hdr
)) {
957 bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ
);
958 puts ("** Bad FIT image format\n");
961 bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK
);
962 fit_print_contents (fit_hdr
);
966 /* Loading ok, update default load address */
970 return bootm_maybe_autostart(cmdtp
, cmd
);
973 static int do_nandboot(cmd_tbl_t
*cmdtp
, int flag
, int argc
,
976 char *boot_device
= NULL
;
978 ulong addr
, offset
= 0;
979 #if defined(CONFIG_CMD_MTDPARTS)
980 struct mtd_device
*dev
;
981 struct part_info
*part
;
985 char *p
= (argc
== 2) ? argv
[1] : argv
[2];
986 if (!(str2long(p
, &addr
)) && (mtdparts_init() == 0) &&
987 (find_dev_and_part(p
, &dev
, &pnum
, &part
) == 0)) {
988 if (dev
->id
->type
!= MTD_DEV_TYPE_NAND
) {
989 puts("Not a NAND device\n");
995 addr
= simple_strtoul(argv
[1], NULL
, 16);
997 addr
= CONFIG_SYS_LOAD_ADDR
;
998 return nand_load_image(cmdtp
, &nand_info
[dev
->id
->num
],
999 part
->offset
, addr
, argv
[0]);
1004 bootstage_mark(BOOTSTAGE_ID_NAND_PART
);
1007 addr
= CONFIG_SYS_LOAD_ADDR
;
1008 boot_device
= getenv("bootdevice");
1011 addr
= simple_strtoul(argv
[1], NULL
, 16);
1012 boot_device
= getenv("bootdevice");
1015 addr
= simple_strtoul(argv
[1], NULL
, 16);
1016 boot_device
= argv
[2];
1019 addr
= simple_strtoul(argv
[1], NULL
, 16);
1020 boot_device
= argv
[2];
1021 offset
= simple_strtoul(argv
[3], NULL
, 16);
1024 #if defined(CONFIG_CMD_MTDPARTS)
1027 bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX
);
1028 return CMD_RET_USAGE
;
1030 bootstage_mark(BOOTSTAGE_ID_NAND_SUFFIX
);
1033 puts("\n** No boot device **\n");
1034 bootstage_error(BOOTSTAGE_ID_NAND_BOOT_DEVICE
);
1037 bootstage_mark(BOOTSTAGE_ID_NAND_BOOT_DEVICE
);
1039 idx
= simple_strtoul(boot_device
, NULL
, 16);
1041 if (idx
< 0 || idx
>= CONFIG_SYS_MAX_NAND_DEVICE
|| !nand_info
[idx
].name
) {
1042 printf("\n** Device %d not available\n", idx
);
1043 bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE
);
1046 bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE
);
1048 return nand_load_image(cmdtp
, &nand_info
[idx
], offset
, addr
, argv
[0]);
1051 U_BOOT_CMD(nboot
, 4, 1, do_nandboot
,
1052 "boot from NAND device",
1053 "[partition] | [[[loadAddr] dev] offset]"