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
14 #ifndef CFG_NAND_LEGACY
22 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
24 #define CFG_NAND_WRITE_YAFFS
29 #include <asm/byteorder.h>
31 #ifdef CONFIG_SHOW_BOOT_PROGRESS
32 # include <status_led.h>
33 # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
35 # define SHOW_BOOT_PROGRESS(arg)
38 #include <jffs2/jffs2.h>
41 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
43 /* parition handling routines */
44 int mtdparts_init(void);
45 int id_parse(const char *id
, const char **ret_id
, u8
*dev_type
, u8
*dev_num
);
46 int find_dev_and_part(const char *id
, struct mtd_device
**dev
,
47 u8
*part_num
, struct part_info
**part
);
50 extern nand_info_t nand_info
[]; /* info for NAND chips */
52 static int nand_dump_oob(nand_info_t
*nand
, ulong off
)
57 static int nand_dump(nand_info_t
*nand
, ulong off
)
62 buf
= malloc(nand
->oobblock
+ nand
->oobsize
);
64 puts("No memory for page buffer\n");
67 off
&= ~(nand
->oobblock
- 1);
68 i
= nand_read_raw(nand
, buf
, off
, nand
->oobblock
, nand
->oobsize
);
70 printf("Error (%d) reading page %08x\n", i
, off
);
74 printf("Page %08x dump:\n", off
);
75 i
= nand
->oobblock
>> 4; p
= buf
;
77 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x"
78 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
79 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7],
80 p
[8], p
[9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15]);
84 i
= nand
->oobsize
>> 3;
86 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
87 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7]);
95 /* ------------------------------------------------------------------------- */
97 static inline int str2long(char *p
, ulong
*num
)
101 *num
= simple_strtoul(p
, &endptr
, 16);
102 return (*p
!= '\0' && *endptr
== '\0') ? 1 : 0;
106 arg_off_size(int argc
, char *argv
[], nand_info_t
*nand
, ulong
*off
, ulong
*size
)
108 int idx
= nand_curr_device
;
109 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
110 struct mtd_device
*dev
;
111 struct part_info
*part
;
114 if (argc
>= 1 && !(str2long(argv
[0], off
))) {
115 if ((mtdparts_init() == 0) &&
116 (find_dev_and_part(argv
[0], &dev
, &pnum
, &part
) == 0)) {
117 if (dev
->id
->type
!= MTD_DEV_TYPE_NAND
) {
118 puts("not a NAND device\n");
123 if (!(str2long(argv
[1], size
))) {
124 printf("'%s' is not a number\n", argv
[1]);
127 if (*size
> part
->size
)
133 *nand
= nand_info
[idx
];
140 if (!(str2long(argv
[0], off
))) {
141 printf("'%s' is not a number\n", argv
[0]);
149 if (!(str2long(argv
[1], size
))) {
150 printf("'%s' is not a number\n", argv
[1]);
154 *size
= nand
->size
- *off
;
157 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
160 printf("device %d ", idx
);
161 if (*size
== nand
->size
)
162 puts("whole chip\n");
164 printf("offset 0x%x, size 0x%x\n", *off
, *size
);
168 #ifdef CFG_NAND_WRITE_YAFFS
171 * Write a yaffs filesystem image to NAND.
173 * If yaffs flag is 1, then the image is assumed to have been
174 * generated by yaffs2/utils/mkyaffsimage.c, and only
175 * 512B block + 16B OOB NAND is supported using the YAFFS1 OOB layout.
177 * Otherwise, the image is assumed to have been generated by
178 * yaffs2/utils/mkyaffs2image.c with Sergey Kubushyn's patch applied
179 * (see http://aleph1.co.uk/lurker/message/20060211.004601.77b55bf3.en.html)
180 * and supports larger 2KB block + 64B OOB NAND.
182 * Only MTD generated ECC is supported.
184 * Loosely based on mtd/util/nandwrite.c.
187 static struct nand_oobinfo yaffs1_oobinfo
= {
188 .useecc
= MTD_NANDECC_PLACE
,
190 .eccpos
= { 8, 9, 10, 13, 14, 15 }
193 static struct nand_oobinfo yaffs2_oobinfo
= {
194 .useecc
= MTD_NANDECC_AUTOPLACE
,
197 40, 41, 42, 43, 44, 45, 46, 47,
198 48, 49, 50, 51, 52, 53, 54, 55,
199 56, 57, 58, 59, 60, 61, 62, 63},
200 .oobfree
= { {2, 38} }
203 static int nand_write_yaffs(nand_info_t
*nand
, ulong off
, ulong
*size
, u_char
*image
, int yaffs
)
206 u_char
*imgptr
, *oobptr
;
210 struct nand_oobinfo old_oobinfo
;
216 /* Make sure device page sizes are valid */
217 if ((yaffs
== 1 && !(nand
->oobsize
== 16 && nand
->oobblock
== 512)) ||
218 (yaffs
== 2 && !(nand
->oobsize
== 64 && nand
->oobblock
== 2048))) {
219 printf("Unsupported flash layout\n");
223 /* update oobinfo for yaffs */
224 old_oobinfo
= nand
->oobinfo
;
225 nand
->oobinfo
= yaffs
== 1 ? yaffs1_oobinfo
: yaffs2_oobinfo
;
227 /* Check, if image is pagealigned */
228 pagelen
= nand
->oobblock
+ nand
->oobsize
;
229 if ((off
% nand
->erasesize
) != 0 || (imglen
% pagelen
) != 0) {
230 printf ("Input image is not page aligned\n");
234 /* Check, if length fits into device */
235 if ( ((imglen
/ pagelen
) * nand
->oobblock
) > (nand
->size
- off
)) {
236 printf ("Input image does not fit into device");
240 /* Get data from input and write to the device */
241 while (imglen
> 0 && (off
< nand
->size
)) {
243 /* if start of eraseblock, check for bad block */
244 if (off
% nand
->erasesize
== 0 && (nand
->block_isbad
)(nand
, off
)) {
245 printf ("Bad block at 0x%08lx, will be skipped\n", off
);
247 off
+= nand
->erasesize
;
251 oobptr
= imgptr
+ nand
->oobblock
;
253 /* set the ECC bytes to 0xff so MTD will calculate it */
254 for (i
= 0; i
< nand
->oobinfo
.eccbytes
; i
++)
255 oobptr
[nand
->oobinfo
.eccpos
[i
]] = 0xff;
257 /* Write OOB data first, as ecc will be placed in there */
258 ret
= (nand
->write_oob
)(nand
, off
, nand
->oobsize
, &retlen
, oobptr
);
260 printf("\nNAND OOB write error %d at block 0x%08lx\n", ret
, off
);
264 /* Write out the Page data */
265 ret
= (nand
->write
)(nand
, off
, nand
->oobblock
, &retlen
, imgptr
);
267 printf("\nNAND write error %d at block 0x%08lx\n", ret
, off
);
273 off
+= nand
->oobblock
;
277 nand
->oobinfo
= old_oobinfo
;
279 *size
= imgptr
- image
;
282 printf("Data did not fit into device, due to bad blocks\n");
289 #endif /* CFG_NAND_WRITE_YAFFS */
292 int do_nand(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *argv
[])
295 ulong addr
, off
, size
;
300 const char *quiet_str
= getenv("quiet");
302 #ifdef CFG_NAND_WRITE_YAFFS
303 int yaffs
= 0; /* 1 = 512+64 NAND, 2 = 2048+64 NAND */
306 /* at least two arguments please */
311 quiet
= simple_strtoul(quiet_str
, NULL
, 0) != 0;
315 if (strcmp(cmd
, "info") == 0) {
318 for (i
= 0; i
< CFG_MAX_NAND_DEVICE
; i
++) {
319 if (nand_info
[i
].name
)
320 printf("Device %d: %s, sector size %lu KiB\n",
321 i
, nand_info
[i
].name
,
322 nand_info
[i
].erasesize
>> 10);
327 if (strcmp(cmd
, "device") == 0) {
330 if ((nand_curr_device
< 0) ||
331 (nand_curr_device
>= CFG_MAX_NAND_DEVICE
))
332 puts("\nno devices available\n");
334 printf("\nDevice %d: %s\n", nand_curr_device
,
335 nand_info
[nand_curr_device
].name
);
338 dev
= (int)simple_strtoul(argv
[2], NULL
, 10);
339 if (dev
< 0 || dev
>= CFG_MAX_NAND_DEVICE
|| !nand_info
[dev
].name
) {
340 puts("No such device\n");
343 printf("Device %d: %s", dev
, nand_info
[dev
].name
);
344 puts("... is now current device\n");
345 nand_curr_device
= dev
;
347 #ifdef CFG_NAND_SELECT_DEVICE
349 * Select the chip in the board/cpu specific driver
351 board_nand_select_device(nand_info
[dev
].priv
, dev
);
357 if (strcmp(cmd
, "bad") != 0 && strcmp(cmd
, "erase") != 0 &&
358 strncmp(cmd
, "dump", 4) != 0 &&
359 strncmp(cmd
, "read", 4) != 0 && strncmp(cmd
, "write", 5) != 0 &&
360 strcmp(cmd
, "scrub") != 0 && strcmp(cmd
, "markbad") != 0 &&
361 strcmp(cmd
, "biterr") != 0 &&
362 strcmp(cmd
, "lock") != 0 && strcmp(cmd
, "unlock") != 0 )
365 /* the following commands operate on the current device */
366 if (nand_curr_device
< 0 || nand_curr_device
>= CFG_MAX_NAND_DEVICE
||
367 !nand_info
[nand_curr_device
].name
) {
368 puts("\nno devices available\n");
371 nand
= &nand_info
[nand_curr_device
];
373 if (strcmp(cmd
, "bad") == 0) {
374 printf("\nDevice %d bad blocks:\n", nand_curr_device
);
375 for (off
= 0; off
< nand
->size
; off
+= nand
->erasesize
)
376 if (nand_block_isbad(nand
, off
))
377 printf(" %08x\n", off
);
384 * nand erase [clean] [off size]
386 if (strcmp(cmd
, "erase") == 0 || strcmp(cmd
, "scrub") == 0) {
387 nand_erase_options_t opts
;
388 /* "clean" at index 2 means request to write cleanmarker */
389 int clean
= argc
> 2 && !strcmp("clean", argv
[2]);
390 int o
= clean
? 3 : 2;
391 int scrub
= !strcmp(cmd
, "scrub");
393 printf("\nNAND %s: ", scrub
? "scrub" : "erase");
394 /* skip first two or three arguments, look for offset and size */
395 if (arg_off_size(argc
- o
, argv
+ o
, nand
, &off
, &size
) != 0)
398 memset(&opts
, 0, sizeof(opts
));
406 "scrub option will erase all factory set "
409 "There is no reliable way to recover them.\n"
411 "Use this command only for testing purposes "
414 "are sure of what you are doing!\n"
415 "\nReally scrub this NAND flash? <y/N>\n");
417 if (getc() == 'y' && getc() == '\r') {
420 puts("scrub aborted\n");
424 ret
= nand_erase_opts(nand
, &opts
);
425 printf("%s\n", ret
? "ERROR" : "OK");
427 return ret
== 0 ? 0 : 1;
430 if (strncmp(cmd
, "dump", 4) == 0) {
434 s
= strchr(cmd
, '.');
435 off
= (int)simple_strtoul(argv
[2], NULL
, 16);
437 if (s
!= NULL
&& strcmp(s
, ".oob") == 0)
438 ret
= nand_dump_oob(nand
, off
);
440 ret
= nand_dump(nand
, off
);
442 return ret
== 0 ? 1 : 0;
447 if (strncmp(cmd
, "read", 4) == 0 || strncmp(cmd
, "write", 5) == 0) {
453 addr
= (ulong
)simple_strtoul(argv
[2], NULL
, 16);
455 read
= strncmp(cmd
, "read", 4) == 0; /* 1 = read, 0 = write */
456 printf("\nNAND %s: ", read
? "read" : "write");
457 if (arg_off_size(argc
- 3, argv
+ 3, nand
, &off
, &size
) != 0)
460 s
= strchr(cmd
, '.');
462 #ifdef CFG_NAND_WRITE_YAFFS
463 if (s
!= NULL
&& strncmp(s
, ".yaffs", 6) == 0) {
466 else if (s
[6] == '2' || s
[6] == '\0')
473 (!strcmp(s
, ".jffs2") || !strcmp(s
, ".yaffs1")|| !strcmp(s
, ".yaffs2")|| !strcmp(s
, ".e") || !strcmp(s
, ".i"))) {
476 nand_read_options_t opts
;
477 memset(&opts
, 0, sizeof(opts
));
478 opts
.buffer
= (u_char
*) addr
;
482 ret
= nand_read_opts(nand
, &opts
);
485 nand_write_options_t opts
;
486 memset(&opts
, 0, sizeof(opts
));
487 opts
.buffer
= (u_char
*) addr
;
490 /* opts.forcejffs2 = 1; */
494 #ifdef CFG_NAND_WRITE_YAFFS
496 ret
= nand_write_yaffs(nand
, off
, &size
, (u_char
*)addr
, yaffs
);
498 ret
= nand_write_opts(nand
, &opts
);
500 #ifndef CFG_NAND_WRITE_YAFFS
501 ret
= nand_write_opts(nand
, &opts
);
506 ret
= nand_read(nand
, off
, &size
, (u_char
*)addr
);
508 ret
= nand_write(nand
, off
, &size
, (u_char
*)addr
);
511 printf(" %d bytes %s: %s\n", size
,
512 read
? "read" : "written", ret
? "ERROR" : "OK");
514 return ret
== 0 ? 0 : 1;
517 if (strcmp(cmd
, "markbad") == 0) {
518 addr
= (ulong
)simple_strtoul(argv
[2], NULL
, 16);
520 int ret
= nand
->block_markbad(nand
, addr
);
522 printf("block 0x%08lx successfully marked as bad\n",
526 printf("block 0x%08lx NOT marked as bad! ERROR %d\n",
531 if (strcmp(cmd
, "biterr") == 0) {
536 if (strcmp(cmd
, "lock") == 0) {
540 if (!strcmp("tight", argv
[2]))
542 if (!strcmp("status", argv
[2]))
547 ulong block_start
= 0;
549 int last_status
= -1;
551 struct nand_chip
*nand_chip
= nand
->priv
;
552 /* check the WP bit */
553 nand_chip
->cmdfunc (nand
, NAND_CMD_STATUS
, -1, -1);
554 printf("device is %swrite protected\n",
555 (nand_chip
->read_byte(nand
) & 0x80 ?
558 for (off
= 0; off
< nand
->size
; off
+= nand
->oobblock
) {
559 int s
= nand_get_lock_status(nand
, off
);
561 /* print message only if status has changed
564 if (off
== nand
->size
- nand
->oobblock
565 || (s
!= last_status
&& off
!= 0)) {
567 printf("%08x - %08x: %8d pages %s%s%s\n",
570 (off
-block_start
)/nand
->oobblock
,
571 ((last_status
& NAND_LOCK_STATUS_TIGHT
) ? "TIGHT " : ""),
572 ((last_status
& NAND_LOCK_STATUS_LOCK
) ? "LOCK " : ""),
573 ((last_status
& NAND_LOCK_STATUS_UNLOCK
) ? "UNLOCK " : ""));
579 if (!nand_lock(nand
, tight
)) {
580 puts("NAND flash successfully locked\n");
582 puts("Error locking NAND flash\n");
589 if (strcmp(cmd
, "unlock") == 0) {
590 if (arg_off_size(argc
- 2, argv
+ 2, nand
, &off
, &size
) < 0)
593 if (!nand_unlock(nand
, off
, size
)) {
594 puts("NAND flash successfully unlocked\n");
596 puts("Error unlocking NAND flash, "
597 "write and erase will probably fail\n");
604 printf("Usage:\n%s\n", cmdtp
->usage
);
608 U_BOOT_CMD(nand
, 5, 1, do_nand
,
609 "nand - NAND sub-system\n",
610 "info - show available NAND devices\n"
611 "nand device [dev] - show or set current device\n"
612 "nand read[.jffs2] - addr off|partition size\n"
613 "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
614 " at offset `off' to/from memory address `addr'\n"
615 #ifdef CFG_NAND_WRITE_YAFFS
616 "nand write[.yaffs[1]] addr off size - read/write `size' bytes starting\n"
617 " at offset `off' to memory address `addr' [yaffs1 or yaffs2 format]\n"
619 "nand erase [clean] [off size] - erase `size' bytes from\n"
620 " offset `off' (entire device if not specified)\n"
621 "nand bad - show bad blocks\n"
622 "nand dump[.oob] off - dump page\n"
623 "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
624 "nand markbad off - mark bad block at offset (UNSAFE)\n"
625 "nand biterr off - make a bit error at offset (UNSAFE)\n"
626 "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
627 "nand unlock [offset] [size] - unlock section\n");
629 static int nand_load_image(cmd_tbl_t
*cmdtp
, nand_info_t
*nand
,
630 ulong offset
, ulong addr
, char *cmd
)
637 printf("\nLoading from %s, offset 0x%lx\n", nand
->name
, offset
);
639 cnt
= nand
->oobblock
;
640 r
= nand_read(nand
, offset
, &cnt
, (u_char
*) addr
);
642 puts("** Read error\n");
643 SHOW_BOOT_PROGRESS(-1);
647 hdr
= (image_header_t
*) addr
;
649 if (ntohl(hdr
->ih_magic
) != IH_MAGIC
) {
650 printf("\n** Bad Magic Number 0x%x **\n", hdr
->ih_magic
);
651 SHOW_BOOT_PROGRESS(-1);
655 print_image_hdr(hdr
);
657 cnt
= (ntohl(hdr
->ih_size
) + sizeof (image_header_t
));
659 r
= nand_read(nand
, offset
, &cnt
, (u_char
*) addr
);
661 puts("** Read error\n");
662 SHOW_BOOT_PROGRESS(-1);
666 /* Loading ok, update default load address */
670 /* Check if we should attempt an auto-start */
671 if (((ep
= getenv("autostart")) != NULL
) && (strcmp(ep
, "yes") == 0)) {
673 extern int do_bootm(cmd_tbl_t
*, int, int, char *[]);
676 local_args
[1] = NULL
;
678 printf("Automatic boot of image at addr 0x%08lx ...\n", addr
);
680 do_bootm(cmdtp
, 0, 1, local_args
);
686 int do_nandboot(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *argv
[])
688 char *boot_device
= NULL
;
690 ulong addr
, offset
= 0;
691 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
692 struct mtd_device
*dev
;
693 struct part_info
*part
;
697 char *p
= (argc
== 2) ? argv
[1] : argv
[2];
698 if (!(str2long(p
, &addr
)) && (mtdparts_init() == 0) &&
699 (find_dev_and_part(p
, &dev
, &pnum
, &part
) == 0)) {
700 if (dev
->id
->type
!= MTD_DEV_TYPE_NAND
) {
701 puts("Not a NAND device\n");
707 addr
= simple_strtoul(argv
[2], NULL
, 16);
709 addr
= CFG_LOAD_ADDR
;
710 return nand_load_image(cmdtp
, &nand_info
[dev
->id
->num
],
711 part
->offset
, addr
, argv
[0]);
718 addr
= CFG_LOAD_ADDR
;
719 boot_device
= getenv("bootdevice");
722 addr
= simple_strtoul(argv
[1], NULL
, 16);
723 boot_device
= getenv("bootdevice");
726 addr
= simple_strtoul(argv
[1], NULL
, 16);
727 boot_device
= argv
[2];
730 addr
= simple_strtoul(argv
[1], NULL
, 16);
731 boot_device
= argv
[2];
732 offset
= simple_strtoul(argv
[3], NULL
, 16);
735 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
738 printf("Usage:\n%s\n", cmdtp
->usage
);
739 SHOW_BOOT_PROGRESS(-1);
744 puts("\n** No boot device **\n");
745 SHOW_BOOT_PROGRESS(-1);
749 idx
= simple_strtoul(boot_device
, NULL
, 16);
751 if (idx
< 0 || idx
>= CFG_MAX_NAND_DEVICE
|| !nand_info
[idx
].name
) {
752 printf("\n** Device %d not available\n", idx
);
753 SHOW_BOOT_PROGRESS(-1);
757 return nand_load_image(cmdtp
, &nand_info
[idx
], offset
, addr
, argv
[0]);
760 U_BOOT_CMD(nboot
, 4, 1, do_nandboot
,
761 "nboot - boot from NAND device\n",
762 "[partition] | [[[loadAddr] dev] offset]\n");
764 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
766 #else /* CFG_NAND_LEGACY */
769 * Legacy NAND support - to be phased out
775 #include <watchdog.h>
777 #ifdef CONFIG_SHOW_BOOT_PROGRESS
778 # include <status_led.h>
779 # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
781 # define SHOW_BOOT_PROGRESS(arg)
784 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
785 #include <linux/mtd/nand_legacy.h>
787 #include <linux/mtd/nand_ids.h>
788 #include <jffs2/jffs2.h>
791 #ifdef CONFIG_OMAP1510
792 void archflashwp(void *archdata
, int wp
);
795 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
800 /* ****************** WARNING *********************
801 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
802 * erase (or at least attempt to erase) blocks that are marked
803 * bad. This can be very handy if you are _sure_ that the block
804 * is OK, say because you marked a good block bad to test bad
805 * block handling and you are done testing, or if you have
806 * accidentally marked blocks bad.
808 * Erasing factory marked bad blocks is a _bad_ idea. If the
809 * erase succeeds there is no reliable way to find them again,
810 * and attempting to program or erase bad blocks can affect
811 * the data in _other_ (good) blocks.
813 #define ALLOW_ERASE_BAD_DEBUG 0
815 #define CONFIG_MTD_NAND_ECC /* enable ECC */
816 #define CONFIG_MTD_NAND_ECC_JFFS2
818 /* bits for nand_legacy_rw() `cmd'; or together as needed */
819 #define NANDRW_READ 0x01
820 #define NANDRW_WRITE 0x00
821 #define NANDRW_JFFS2 0x02
822 #define NANDRW_JFFS2_SKIP 0x04
825 * Imports from nand_legacy.c
827 extern struct nand_chip nand_dev_desc
[CFG_MAX_NAND_DEVICE
];
828 extern int curr_device
;
829 extern int nand_legacy_erase(struct nand_chip
*nand
, size_t ofs
,
830 size_t len
, int clean
);
831 extern int nand_legacy_rw(struct nand_chip
*nand
, int cmd
, size_t start
,
832 size_t len
, size_t *retlen
, u_char
*buf
);
833 extern void nand_print(struct nand_chip
*nand
);
834 extern void nand_print_bad(struct nand_chip
*nand
);
835 extern int nand_read_oob(struct nand_chip
*nand
, size_t ofs
,
836 size_t len
, size_t *retlen
, u_char
*buf
);
837 extern int nand_write_oob(struct nand_chip
*nand
, size_t ofs
,
838 size_t len
, size_t *retlen
, const u_char
*buf
);
841 int do_nand (cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
848 printf ("Usage:\n%s\n", cmdtp
->usage
);
851 if (strcmp(argv
[1],"info") == 0) {
856 for (i
=0; i
<CFG_MAX_NAND_DEVICE
; ++i
) {
857 if(nand_dev_desc
[i
].ChipID
== NAND_ChipID_UNKNOWN
)
858 continue; /* list only known devices */
859 printf ("Device %d: ", i
);
860 nand_print(&nand_dev_desc
[i
]);
864 } else if (strcmp(argv
[1],"device") == 0) {
865 if ((curr_device
< 0) || (curr_device
>= CFG_MAX_NAND_DEVICE
)) {
866 puts ("\nno devices available\n");
869 printf ("\nDevice %d: ", curr_device
);
870 nand_print(&nand_dev_desc
[curr_device
]);
873 } else if (strcmp(argv
[1],"bad") == 0) {
874 if ((curr_device
< 0) || (curr_device
>= CFG_MAX_NAND_DEVICE
)) {
875 puts ("\nno devices available\n");
878 printf ("\nDevice %d bad blocks:\n", curr_device
);
879 nand_print_bad(&nand_dev_desc
[curr_device
]);
883 printf ("Usage:\n%s\n", cmdtp
->usage
);
886 if (strcmp(argv
[1],"device") == 0) {
887 int dev
= (int)simple_strtoul(argv
[2], NULL
, 10);
889 printf ("\nDevice %d: ", dev
);
890 if (dev
>= CFG_MAX_NAND_DEVICE
) {
891 puts ("unknown device\n");
894 nand_print(&nand_dev_desc
[dev
]);
895 /*nand_print (dev);*/
897 if (nand_dev_desc
[dev
].ChipID
== NAND_ChipID_UNKNOWN
) {
903 puts ("... is now current device\n");
907 else if (strcmp(argv
[1],"erase") == 0 && strcmp(argv
[2], "clean") == 0) {
908 struct nand_chip
* nand
= &nand_dev_desc
[curr_device
];
910 ulong size
= nand
->totlen
;
913 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
914 curr_device
, off
, size
);
916 ret
= nand_legacy_erase (nand
, off
, size
, 1);
918 printf("%s\n", ret
? "ERROR" : "OK");
923 printf ("Usage:\n%s\n", cmdtp
->usage
);
926 /* at least 4 args */
928 if (strncmp(argv
[1], "read", 4) == 0 ||
929 strncmp(argv
[1], "write", 5) == 0) {
930 ulong addr
= simple_strtoul(argv
[2], NULL
, 16);
931 ulong off
= simple_strtoul(argv
[3], NULL
, 16);
932 ulong size
= simple_strtoul(argv
[4], NULL
, 16);
933 int cmd
= (strncmp(argv
[1], "read", 4) == 0) ?
934 NANDRW_READ
: NANDRW_WRITE
;
936 char* cmdtail
= strchr(argv
[1], '.');
938 if (cmdtail
&& !strncmp(cmdtail
, ".oob", 2)) {
939 /* read out-of-band data */
940 if (cmd
& NANDRW_READ
) {
941 ret
= nand_read_oob(nand_dev_desc
+ curr_device
,
942 off
, size
, (size_t *)&total
,
946 ret
= nand_write_oob(nand_dev_desc
+ curr_device
,
947 off
, size
, (size_t *)&total
,
952 else if (cmdtail
&& !strncmp(cmdtail
, ".jffs2", 2))
953 cmd
|= NANDRW_JFFS2
; /* skip bad blocks */
954 else if (cmdtail
&& !strncmp(cmdtail
, ".jffs2s", 2)) {
955 cmd
|= NANDRW_JFFS2
; /* skip bad blocks (on read too) */
956 if (cmd
& NANDRW_READ
)
957 cmd
|= NANDRW_JFFS2_SKIP
; /* skip bad blocks (on read too) */
960 /* need ".e" same as ".j" for compatibility with older units */
961 else if (cmdtail
&& !strcmp(cmdtail
, ".e"))
962 cmd
|= NANDRW_JFFS2
; /* skip bad blocks */
964 #ifdef CFG_NAND_SKIP_BAD_DOT_I
965 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */
966 /* ".i" for image -> read skips bad block (no 0xff) */
967 else if (cmdtail
&& !strcmp(cmdtail
, ".i")) {
968 cmd
|= NANDRW_JFFS2
; /* skip bad blocks (on read too) */
969 if (cmd
& NANDRW_READ
)
970 cmd
|= NANDRW_JFFS2_SKIP
; /* skip bad blocks (on read too) */
972 #endif /* CFG_NAND_SKIP_BAD_DOT_I */
974 printf ("Usage:\n%s\n", cmdtp
->usage
);
978 printf ("\nNAND %s: device %d offset %ld, size %ld ...\n",
979 (cmd
& NANDRW_READ
) ? "read" : "write",
980 curr_device
, off
, size
);
982 ret
= nand_legacy_rw(nand_dev_desc
+ curr_device
, cmd
, off
, size
,
983 (size_t *)&total
, (u_char
*)addr
);
985 printf (" %d bytes %s: %s\n", total
,
986 (cmd
& NANDRW_READ
) ? "read" : "written",
987 ret
? "ERROR" : "OK");
990 } else if (strcmp(argv
[1],"erase") == 0 &&
991 (argc
== 4 || strcmp("clean", argv
[2]) == 0)) {
992 int clean
= argc
== 5;
993 ulong off
= simple_strtoul(argv
[2 + clean
], NULL
, 16);
994 ulong size
= simple_strtoul(argv
[3 + clean
], NULL
, 16);
997 printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",
998 curr_device
, off
, size
);
1000 ret
= nand_legacy_erase (nand_dev_desc
+ curr_device
,
1003 printf("%s\n", ret
? "ERROR" : "OK");
1007 printf ("Usage:\n%s\n", cmdtp
->usage
);
1016 nand
, 5, 1, do_nand
,
1017 "nand - legacy NAND sub-system\n",
1018 "info - show available NAND devices\n"
1019 "nand device [dev] - show or set current device\n"
1020 "nand read[.jffs2[s]] addr off size\n"
1021 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
1022 " at offset `off' to/from memory address `addr'\n"
1023 "nand erase [clean] [off size] - erase `size' bytes from\n"
1024 " offset `off' (entire device if not specified)\n"
1025 "nand bad - show bad blocks\n"
1026 "nand read.oob addr off size - read out-of-band data\n"
1027 "nand write.oob addr off size - read out-of-band data\n"
1030 int do_nandboot (cmd_tbl_t
*cmdtp
, int flag
, int argc
, char *argv
[])
1032 char *boot_device
= NULL
;
1038 image_header_t
*hdr
;
1042 addr
= CFG_LOAD_ADDR
;
1043 boot_device
= getenv ("bootdevice");
1046 addr
= simple_strtoul(argv
[1], NULL
, 16);
1047 boot_device
= getenv ("bootdevice");
1050 addr
= simple_strtoul(argv
[1], NULL
, 16);
1051 boot_device
= argv
[2];
1054 addr
= simple_strtoul(argv
[1], NULL
, 16);
1055 boot_device
= argv
[2];
1056 offset
= simple_strtoul(argv
[3], NULL
, 16);
1059 printf ("Usage:\n%s\n", cmdtp
->usage
);
1060 SHOW_BOOT_PROGRESS (-1);
1065 puts ("\n** No boot device **\n");
1066 SHOW_BOOT_PROGRESS (-1);
1070 dev
= simple_strtoul(boot_device
, &ep
, 16);
1072 if ((dev
>= CFG_MAX_NAND_DEVICE
) ||
1073 (nand_dev_desc
[dev
].ChipID
== NAND_ChipID_UNKNOWN
)) {
1074 printf ("\n** Device %d not available\n", dev
);
1075 SHOW_BOOT_PROGRESS (-1);
1079 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
1080 dev
, nand_dev_desc
[dev
].name
, nand_dev_desc
[dev
].IO_ADDR
,
1083 if (nand_legacy_rw (nand_dev_desc
+ dev
, NANDRW_READ
, offset
,
1084 SECTORSIZE
, NULL
, (u_char
*)addr
)) {
1085 printf ("** Read error on %d\n", dev
);
1086 SHOW_BOOT_PROGRESS (-1);
1090 hdr
= (image_header_t
*)addr
;
1092 if (ntohl(hdr
->ih_magic
) == IH_MAGIC
) {
1094 print_image_hdr (hdr
);
1096 cnt
= (ntohl(hdr
->ih_size
) + sizeof(image_header_t
));
1099 printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr
->ih_magic
));
1100 SHOW_BOOT_PROGRESS (-1);
1104 if (nand_legacy_rw (nand_dev_desc
+ dev
, NANDRW_READ
,
1105 offset
+ SECTORSIZE
, cnt
, NULL
,
1106 (u_char
*)(addr
+SECTORSIZE
))) {
1107 printf ("** Read error on %d\n", dev
);
1108 SHOW_BOOT_PROGRESS (-1);
1112 /* Loading ok, update default load address */
1116 /* Check if we should attempt an auto-start */
1117 if (((ep
= getenv("autostart")) != NULL
) && (strcmp(ep
,"yes") == 0)) {
1118 char *local_args
[2];
1119 extern int do_bootm (cmd_tbl_t
*, int, int, char *[]);
1121 local_args
[0] = argv
[0];
1122 local_args
[1] = NULL
;
1124 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr
);
1126 do_bootm (cmdtp
, 0, 1, local_args
);
1133 nboot
, 4, 1, do_nandboot
,
1134 "nboot - boot from NAND device\n",
1138 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
1140 #endif /* CFG_NAND_LEGACY */