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 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 = malloc(nand->writesize + nand->oobsize);
52 oobbuf = malloc(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));
62 ops.oobbuf = oobbuf; /* must exist, but oob data will be appended to ops.datbuf */
63 ops.len = nand->writesize;
64 ops.ooblen = nand->oobsize;
65 ops.mode = MTD_OOB_RAW;
66 i = nand->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;
89 printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
90 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
99 /* ------------------------------------------------------------------------- */
101 static int set_dev(int dev)
103 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
104 !nand_info[dev].name) {
105 puts("No such device\n");
109 if (nand_curr_device == dev)
112 printf("Device %d: %s", dev, nand_info[dev].name);
113 puts("... is now current device\n");
114 nand_curr_device = dev;
116 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
117 board_nand_select_device(nand_info[dev].priv, dev);
123 static inline int str2off(const char *p, loff_t *num)
127 *num = simple_strtoull(p, &endptr, 16);
128 return *p != '\0' && *endptr == '\0';
131 static inline int str2long(const char *p, ulong *num)
135 *num = simple_strtoul(p, &endptr, 16);
136 return *p != '\0' && *endptr == '\0';
139 static int get_part(const char *partname, int *idx, loff_t *off, loff_t *size)
141 #ifdef CONFIG_CMD_MTDPARTS
142 struct mtd_device *dev;
143 struct part_info *part;
147 ret = mtdparts_init();
151 ret = find_dev_and_part(partname, &dev, &pnum, &part);
155 if (dev->id->type != MTD_DEV_TYPE_NAND) {
156 puts("not a NAND device\n");
170 puts("offset is not a number\n");
175 static int arg_off(const char *arg, int *idx, loff_t *off, loff_t *maxsize)
177 if (!str2off(arg, off))
178 return get_part(arg, idx, off, maxsize);
180 if (*off >= nand_info[*idx].size) {
181 puts("Offset exceeds device limit\n");
185 *maxsize = nand_info[*idx].size - *off;
189 static int arg_off_size(int argc, char *const argv[], int *idx,
190 loff_t *off, loff_t *size)
197 *size = nand_info[*idx].size;
201 ret = arg_off(argv[0], idx, off, &maxsize);
210 if (!str2off(argv[1], size)) {
211 printf("'%s' is not a number\n", argv[1]);
215 if (*size > maxsize) {
216 puts("Size exceeds partition or device limit\n");
221 printf("device %d ", *idx);
222 if (*size == nand_info[*idx].size)
223 puts("whole chip\n");
225 printf("offset 0x%llx, size 0x%llx\n",
226 (unsigned long long)*off, (unsigned long long)*size);
230 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
231 static void print_status(ulong start, ulong end, ulong erasesize, int status)
233 printf("%08lx - %08lx: %08lx blocks %s%s%s\n",
236 (end - start) / erasesize,
237 ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
238 ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
239 ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
242 static void do_nand_status(nand_info_t *nand)
244 ulong block_start = 0;
246 int last_status = -1;
248 struct nand_chip *nand_chip = nand->priv;
249 /* check the WP bit */
250 nand_chip->cmdfunc(nand, NAND_CMD_STATUS, -1, -1);
251 printf("device is %swrite protected\n",
252 (nand_chip->read_byte(nand) & 0x80 ?
255 for (off = 0; off < nand->size; off += nand->erasesize) {
256 int s = nand_get_lock_status(nand, off);
258 /* print message only if status has changed */
259 if (s != last_status && off != 0) {
260 print_status(block_start, off, nand->erasesize,
266 /* Print the last block info */
267 print_status(block_start, off, nand->erasesize, last_status);
271 #ifdef CONFIG_ENV_OFFSET_OOB
272 unsigned long nand_env_oob_offset;
274 int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[])
277 uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)];
278 nand_info_t *nand = &nand_info[0];
281 if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !nand->name) {
282 puts("no devices available\n");
288 if (!strcmp(cmd, "get")) {
289 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
293 printf("0x%08lx\n", nand_env_oob_offset);
294 } else if (!strcmp(cmd, "set")) {
297 struct mtd_oob_ops ops;
303 if (arg_off(argv[2], &idx, &addr, &maxsize)) {
304 puts("Offset or partition name expected\n");
309 puts("Partition not on first NAND device\n");
313 if (nand->oobavail < ENV_OFFSET_SIZE) {
314 printf("Insufficient available OOB bytes:\n"
315 "%d OOB bytes available but %d required for "
317 nand->oobavail, ENV_OFFSET_SIZE);
321 if ((addr & (nand->erasesize - 1)) != 0) {
322 printf("Environment offset must be block-aligned\n");
327 ops.mode = MTD_OOB_AUTO;
329 ops.ooblen = ENV_OFFSET_SIZE;
330 ops.oobbuf = (void *) oob_buf;
332 oob_buf[0] = ENV_OOB_MARKER;
333 oob_buf[1] = addr / nand->erasesize;
335 ret = nand->write_oob(nand, ENV_OFFSET_SIZE, &ops);
337 printf("Error writing OOB block 0\n");
341 ret = get_nand_env_oob(nand, &nand_env_oob_offset);
343 printf("Error reading env offset in OOB\n");
347 if (addr != nand_env_oob_offset) {
348 printf("Verification of env offset in OOB failed: "
349 "0x%08llx expected but got 0x%08lx\n",
350 (unsigned long long)addr, nand_env_oob_offset);
360 return cmd_usage(cmdtp);
365 static void nand_print_info(int idx)
367 nand_info_t *nand = &nand_info[idx];
368 struct nand_chip *chip = nand->priv;
369 printf("Device %d: ", idx);
370 if (chip->numchips > 1)
371 printf("%dx ", chip->numchips);
372 printf("%s, sector size %u KiB\n",
373 nand->name, nand->erasesize >> 10);
376 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
383 #ifdef CONFIG_SYS_NAND_QUIET
384 int quiet = CONFIG_SYS_NAND_QUIET;
388 const char *quiet_str = getenv("quiet");
389 int dev = nand_curr_device;
390 int repeat = flag & CMD_FLAG_REPEAT;
392 /* at least two arguments please */
397 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
401 /* Only "dump" is repeatable. */
402 if (repeat && strcmp(cmd, "dump"))
405 if (strcmp(cmd, "info") == 0) {
408 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
409 if (nand_info[i].name)
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_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 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
444 !nand_info[dev].name) {
445 puts("\nno devices available\n");
448 nand = &nand_info[dev];
450 if (strcmp(cmd, "bad") == 0) {
451 printf("\nDevice %d bad blocks:\n", dev);
452 for (off = 0; off < nand->size; off += nand->erasesize)
453 if (nand_block_isbad(nand, off))
454 printf(" %08llx\n", (unsigned long long)off);
461 * nand erase [clean] [off size]
463 if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
464 nand_erase_options_t opts;
465 /* "clean" at index 2 means request to write cleanmarker */
466 int clean = argc > 2 && !strcmp("clean", argv[2]);
467 int scrub_yes = argc > 2 && !strcmp("-y", argv[2]);
468 int o = (clean || scrub_yes) ? 3 : 2;
469 int scrub = !strncmp(cmd, "scrub", 5);
472 const char *scrub_warn =
474 "scrub option will erase all factory set bad blocks!\n"
476 "There is no reliable way to recover them.\n"
478 "Use this command only for testing purposes if you\n"
480 "are sure of what you are doing!\n"
481 "\nReally scrub this NAND flash? <y/N>\n";
484 if (!strcmp(&cmd[5], ".spread")) {
486 } else if (!strcmp(&cmd[5], ".part")) {
488 } else if (!strcmp(&cmd[5], ".chip")) {
496 * Don't allow missing arguments to cause full chip/partition
497 * erases -- easy to do accidentally, e.g. with a misspelled
500 if (argc != o + args)
503 printf("\nNAND %s: ", cmd);
504 /* skip first two or three arguments, look for offset and size */
505 if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
508 nand = &nand_info[dev];
510 memset(&opts, 0, sizeof(opts));
515 opts.spread = spread;
523 else if (getc() == 'y') {
528 puts("scrub aborted\n");
532 puts("scrub aborted\n");
536 ret = nand_erase_opts(nand, &opts);
537 printf("%s\n", ret ? "ERROR" : "OK");
539 return ret == 0 ? 0 : 1;
542 if (strncmp(cmd, "dump", 4) == 0) {
546 off = (int)simple_strtoul(argv[2], NULL, 16);
547 ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
549 return ret == 0 ? 1 : 0;
552 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
559 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
561 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
562 printf("\nNAND %s: ", read ? "read" : "write");
563 if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0)
566 nand = &nand_info[dev];
569 s = strchr(cmd, '.');
570 if (!s || !strcmp(s, ".jffs2") ||
571 !strcmp(s, ".e") || !strcmp(s, ".i")) {
573 ret = nand_read_skip_bad(nand, off, &rwsize,
576 ret = nand_write_skip_bad(nand, off, &rwsize,
578 #ifdef CONFIG_CMD_NAND_TRIMFFS
579 } else if (!strcmp(s, ".trimffs")) {
581 printf("Unknown nand command suffix '%s'\n", s);
584 ret = nand_write_skip_bad(nand, off, &rwsize,
588 #ifdef CONFIG_CMD_NAND_YAFFS
589 } else if (!strcmp(s, ".yaffs")) {
591 printf("Unknown nand command suffix '%s'.\n", s);
594 ret = nand_write_skip_bad(nand, off, &rwsize,
595 (u_char *)addr, WITH_YAFFS_OOB);
597 } else if (!strcmp(s, ".oob")) {
598 /* out-of-band data */
599 mtd_oob_ops_t ops = {
600 .oobbuf = (u8 *)addr,
606 ret = nand->read_oob(nand, off, &ops);
608 ret = nand->write_oob(nand, off, &ops);
609 } else if (!strcmp(s, ".raw")) {
611 mtd_oob_ops_t ops = {
612 .datbuf = (u8 *)addr,
613 .oobbuf = ((u8 *)addr) + nand->writesize,
614 .len = nand->writesize,
615 .ooblen = nand->oobsize,
619 rwsize = nand->writesize + nand->oobsize;
622 ret = nand->read_oob(nand, off, &ops);
624 ret = nand->write_oob(nand, off, &ops);
626 printf("Unknown nand command suffix '%s'.\n", s);
630 printf(" %zu bytes %s: %s\n", rwsize,
631 read ? "read" : "written", ret ? "ERROR" : "OK");
633 return ret == 0 ? 0 : 1;
636 if (strcmp(cmd, "markbad") == 0) {
644 addr = simple_strtoul(*argv, NULL, 16);
646 if (nand->block_markbad(nand, addr)) {
647 printf("block 0x%08lx NOT marked "
648 "as bad! ERROR %d\n",
652 printf("block 0x%08lx successfully "
662 if (strcmp(cmd, "biterr") == 0) {
667 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
668 if (strcmp(cmd, "lock") == 0) {
672 if (!strcmp("tight", argv[2]))
674 if (!strcmp("status", argv[2]))
678 do_nand_status(nand);
680 if (!nand_lock(nand, tight)) {
681 puts("NAND flash successfully locked\n");
683 puts("Error locking NAND flash\n");
690 if (strcmp(cmd, "unlock") == 0) {
691 if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0)
694 if (!nand_unlock(&nand_info[dev], off, size)) {
695 puts("NAND flash successfully unlocked\n");
697 puts("Error unlocking NAND flash, "
698 "write and erase will probably fail\n");
706 return cmd_usage(cmdtp);
710 nand, CONFIG_SYS_MAXARGS, 1, do_nand,
712 "info - show available NAND devices\n"
713 "nand device [dev] - show or set current device\n"
714 "nand read - addr off|partition size\n"
715 "nand write - addr off|partition size\n"
716 " read/write 'size' bytes starting at offset 'off'\n"
717 " to/from memory address 'addr', skipping bad blocks.\n"
718 "nand read.raw - addr off|partition\n"
719 "nand write.raw - addr off|partition\n"
720 " Use read.raw/write.raw to avoid ECC and access the page as-is.\n"
721 #ifdef CONFIG_CMD_NAND_TRIMFFS
722 "nand write.trimffs - addr off|partition size\n"
723 " write 'size' bytes starting at offset 'off' from memory address\n"
724 " 'addr', skipping bad blocks and dropping any pages at the end\n"
725 " of eraseblocks that contain only 0xFF\n"
727 #ifdef CONFIG_CMD_NAND_YAFFS
728 "nand write.yaffs - addr off|partition size\n"
729 " write 'size' bytes starting at offset 'off' with yaffs format\n"
730 " from memory address 'addr', skipping bad blocks.\n"
732 "nand erase[.spread] [clean] off size - erase 'size' bytes "
733 "from offset 'off'\n"
734 " With '.spread', erase enough for given file size, otherwise,\n"
735 " 'size' includes skipped bad blocks.\n"
736 "nand erase.part [clean] partition - erase entire mtd partition'\n"
737 "nand erase.chip [clean] - erase entire chip'\n"
738 "nand bad - show bad blocks\n"
739 "nand dump[.oob] off - dump page\n"
740 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
741 " really clean NAND erasing bad blocks (UNSAFE)\n"
742 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
743 "nand biterr off - make a bit error at offset (UNSAFE)"
744 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
746 "nand lock [tight] [status]\n"
747 " bring nand to lock state or display locked pages\n"
748 "nand unlock [offset] [size] - unlock section"
750 #ifdef CONFIG_ENV_OFFSET_OOB
752 "nand env.oob - environment offset in OOB of block 0 of"
754 "nand env.oob set off|partition - set enviromnent offset\n"
755 "nand env.oob get - get environment offset"
759 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
760 ulong offset, ulong addr, char *cmd)
766 #if defined(CONFIG_FIT)
767 const void *fit_hdr = NULL;
770 s = strchr(cmd, '.');
772 (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
773 printf("Unknown nand load suffix '%s'\n", s);
774 show_boot_progress(-53);
778 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
780 cnt = nand->writesize;
781 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
783 puts("** Read error\n");
784 show_boot_progress (-56);
787 show_boot_progress (56);
789 switch (genimg_get_format ((void *)addr)) {
790 case IMAGE_FORMAT_LEGACY:
791 hdr = (image_header_t *)addr;
793 show_boot_progress (57);
794 image_print_contents (hdr);
796 cnt = image_get_image_size (hdr);
798 #if defined(CONFIG_FIT)
799 case IMAGE_FORMAT_FIT:
800 fit_hdr = (const void *)addr;
801 puts ("Fit image detected...\n");
803 cnt = fit_get_size (fit_hdr);
807 show_boot_progress (-57);
808 puts ("** Unknown image type\n");
811 show_boot_progress (57);
813 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
815 puts("** Read error\n");
816 show_boot_progress (-58);
819 show_boot_progress (58);
821 #if defined(CONFIG_FIT)
822 /* This cannot be done earlier, we need complete FIT image in RAM first */
823 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
824 if (!fit_check_format (fit_hdr)) {
825 show_boot_progress (-150);
826 puts ("** Bad FIT image format\n");
829 show_boot_progress (151);
830 fit_print_contents (fit_hdr);
834 /* Loading ok, update default load address */
838 return bootm_maybe_autostart(cmdtp, cmd);
841 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
843 char *boot_device = NULL;
845 ulong addr, offset = 0;
846 #if defined(CONFIG_CMD_MTDPARTS)
847 struct mtd_device *dev;
848 struct part_info *part;
852 char *p = (argc == 2) ? argv[1] : argv[2];
853 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
854 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
855 if (dev->id->type != MTD_DEV_TYPE_NAND) {
856 puts("Not a NAND device\n");
862 addr = simple_strtoul(argv[1], NULL, 16);
864 addr = CONFIG_SYS_LOAD_ADDR;
865 return nand_load_image(cmdtp, &nand_info[dev->id->num],
866 part->offset, addr, argv[0]);
871 show_boot_progress(52);
874 addr = CONFIG_SYS_LOAD_ADDR;
875 boot_device = getenv("bootdevice");
878 addr = simple_strtoul(argv[1], NULL, 16);
879 boot_device = getenv("bootdevice");
882 addr = simple_strtoul(argv[1], NULL, 16);
883 boot_device = argv[2];
886 addr = simple_strtoul(argv[1], NULL, 16);
887 boot_device = argv[2];
888 offset = simple_strtoul(argv[3], NULL, 16);
891 #if defined(CONFIG_CMD_MTDPARTS)
894 show_boot_progress(-53);
895 return cmd_usage(cmdtp);
898 show_boot_progress(53);
900 puts("\n** No boot device **\n");
901 show_boot_progress(-54);
904 show_boot_progress(54);
906 idx = simple_strtoul(boot_device, NULL, 16);
908 if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) {
909 printf("\n** Device %d not available\n", idx);
910 show_boot_progress(-55);
913 show_boot_progress(55);
915 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
918 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
919 "boot from NAND device",
920 "[partition] | [[[loadAddr] dev] offset]"