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_and_set_info(int idx)
367 nand_info_t *nand = &nand_info[idx];
368 struct nand_chip *chip = nand->priv;
369 const int bufsz = 32;
372 printf("Device %d: ", idx);
373 if (chip->numchips > 1)
374 printf("%dx ", chip->numchips);
375 printf("%s, sector size %u KiB\n",
376 nand->name, nand->erasesize >> 10);
377 printf(" Page size %8d b\n", nand->writesize);
378 printf(" OOB size %8d b\n", nand->oobsize);
379 printf(" Erase size %8d b\n", nand->erasesize);
381 /* Set geometry info */
382 sprintf(buf, "%x", nand->writesize);
383 setenv("nand_writesize", buf);
385 sprintf(buf, "%x", nand->oobsize);
386 setenv("nand_oobsize", buf);
388 sprintf(buf, "%x", nand->erasesize);
389 setenv("nand_erasesize", buf);
392 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
399 #ifdef CONFIG_SYS_NAND_QUIET
400 int quiet = CONFIG_SYS_NAND_QUIET;
404 const char *quiet_str = getenv("quiet");
405 int dev = nand_curr_device;
406 int repeat = flag & CMD_FLAG_REPEAT;
408 /* at least two arguments please */
413 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
417 /* Only "dump" is repeatable. */
418 if (repeat && strcmp(cmd, "dump"))
421 if (strcmp(cmd, "info") == 0) {
424 for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {
425 if (nand_info[i].name)
426 nand_print_and_set_info(i);
431 if (strcmp(cmd, "device") == 0) {
434 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE)
435 puts("no devices available\n");
437 nand_print_and_set_info(dev);
441 dev = (int)simple_strtoul(argv[2], NULL, 10);
447 #ifdef CONFIG_ENV_OFFSET_OOB
448 /* this command operates only on the first nand device */
449 if (strcmp(cmd, "env.oob") == 0)
450 return do_nand_env_oob(cmdtp, argc - 1, argv + 1);
453 /* The following commands operate on the current device, unless
454 * overridden by a partition specifier. Note that if somehow the
455 * current device is invalid, it will have to be changed to a valid
456 * one before these commands can run, even if a partition specifier
457 * for another device is to be used.
459 if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
460 !nand_info[dev].name) {
461 puts("\nno devices available\n");
464 nand = &nand_info[dev];
466 if (strcmp(cmd, "bad") == 0) {
467 printf("\nDevice %d bad blocks:\n", dev);
468 for (off = 0; off < nand->size; off += nand->erasesize)
469 if (nand_block_isbad(nand, off))
470 printf(" %08llx\n", (unsigned long long)off);
477 * nand erase [clean] [off size]
479 if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) {
480 nand_erase_options_t opts;
481 /* "clean" at index 2 means request to write cleanmarker */
482 int clean = argc > 2 && !strcmp("clean", argv[2]);
483 int scrub_yes = argc > 2 && !strcmp("-y", argv[2]);
484 int o = (clean || scrub_yes) ? 3 : 2;
485 int scrub = !strncmp(cmd, "scrub", 5);
488 const char *scrub_warn =
490 "scrub option will erase all factory set bad blocks!\n"
492 "There is no reliable way to recover them.\n"
494 "Use this command only for testing purposes if you\n"
496 "are sure of what you are doing!\n"
497 "\nReally scrub this NAND flash? <y/N>\n";
500 if (!strcmp(&cmd[5], ".spread")) {
502 } else if (!strcmp(&cmd[5], ".part")) {
504 } else if (!strcmp(&cmd[5], ".chip")) {
512 * Don't allow missing arguments to cause full chip/partition
513 * erases -- easy to do accidentally, e.g. with a misspelled
516 if (argc != o + args)
519 printf("\nNAND %s: ", cmd);
520 /* skip first two or three arguments, look for offset and size */
521 if (arg_off_size(argc - o, argv + o, &dev, &off, &size) != 0)
524 nand = &nand_info[dev];
526 memset(&opts, 0, sizeof(opts));
531 opts.spread = spread;
539 else if (getc() == 'y') {
544 puts("scrub aborted\n");
548 puts("scrub aborted\n");
552 ret = nand_erase_opts(nand, &opts);
553 printf("%s\n", ret ? "ERROR" : "OK");
555 return ret == 0 ? 0 : 1;
558 if (strncmp(cmd, "dump", 4) == 0) {
562 off = (int)simple_strtoul(argv[2], NULL, 16);
563 ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
565 return ret == 0 ? 1 : 0;
568 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
575 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
577 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
578 printf("\nNAND %s: ", read ? "read" : "write");
579 if (arg_off_size(argc - 3, argv + 3, &dev, &off, &size) != 0)
582 nand = &nand_info[dev];
585 s = strchr(cmd, '.');
586 if (!s || !strcmp(s, ".jffs2") ||
587 !strcmp(s, ".e") || !strcmp(s, ".i")) {
589 ret = nand_read_skip_bad(nand, off, &rwsize,
592 ret = nand_write_skip_bad(nand, off, &rwsize,
594 #ifdef CONFIG_CMD_NAND_TRIMFFS
595 } else if (!strcmp(s, ".trimffs")) {
597 printf("Unknown nand command suffix '%s'\n", s);
600 ret = nand_write_skip_bad(nand, off, &rwsize,
604 #ifdef CONFIG_CMD_NAND_YAFFS
605 } else if (!strcmp(s, ".yaffs")) {
607 printf("Unknown nand command suffix '%s'.\n", s);
610 ret = nand_write_skip_bad(nand, off, &rwsize,
611 (u_char *)addr, WITH_YAFFS_OOB);
613 } else if (!strcmp(s, ".oob")) {
614 /* out-of-band data */
615 mtd_oob_ops_t ops = {
616 .oobbuf = (u8 *)addr,
622 ret = nand->read_oob(nand, off, &ops);
624 ret = nand->write_oob(nand, off, &ops);
625 } else if (!strcmp(s, ".raw")) {
627 mtd_oob_ops_t ops = {
628 .datbuf = (u8 *)addr,
629 .oobbuf = ((u8 *)addr) + nand->writesize,
630 .len = nand->writesize,
631 .ooblen = nand->oobsize,
635 rwsize = nand->writesize + nand->oobsize;
638 ret = nand->read_oob(nand, off, &ops);
640 ret = nand->write_oob(nand, off, &ops);
642 printf("Unknown nand command suffix '%s'.\n", s);
646 printf(" %zu bytes %s: %s\n", rwsize,
647 read ? "read" : "written", ret ? "ERROR" : "OK");
649 return ret == 0 ? 0 : 1;
652 if (strcmp(cmd, "markbad") == 0) {
660 addr = simple_strtoul(*argv, NULL, 16);
662 if (nand->block_markbad(nand, addr)) {
663 printf("block 0x%08lx NOT marked "
664 "as bad! ERROR %d\n",
668 printf("block 0x%08lx successfully "
678 if (strcmp(cmd, "biterr") == 0) {
683 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
684 if (strcmp(cmd, "lock") == 0) {
688 if (!strcmp("tight", argv[2]))
690 if (!strcmp("status", argv[2]))
694 do_nand_status(nand);
696 if (!nand_lock(nand, tight)) {
697 puts("NAND flash successfully locked\n");
699 puts("Error locking NAND flash\n");
706 if (strcmp(cmd, "unlock") == 0) {
707 if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0)
710 if (!nand_unlock(&nand_info[dev], off, size)) {
711 puts("NAND flash successfully unlocked\n");
713 puts("Error unlocking NAND flash, "
714 "write and erase will probably fail\n");
722 return cmd_usage(cmdtp);
726 nand, CONFIG_SYS_MAXARGS, 1, do_nand,
728 "info - show available NAND devices\n"
729 "nand device [dev] - show or set current device\n"
730 "nand read - addr off|partition size\n"
731 "nand write - addr off|partition size\n"
732 " read/write 'size' bytes starting at offset 'off'\n"
733 " to/from memory address 'addr', skipping bad blocks.\n"
734 "nand read.raw - addr off|partition\n"
735 "nand write.raw - addr off|partition\n"
736 " Use read.raw/write.raw to avoid ECC and access the page as-is.\n"
737 #ifdef CONFIG_CMD_NAND_TRIMFFS
738 "nand write.trimffs - addr off|partition size\n"
739 " write 'size' bytes starting at offset 'off' from memory address\n"
740 " 'addr', skipping bad blocks and dropping any pages at the end\n"
741 " of eraseblocks that contain only 0xFF\n"
743 #ifdef CONFIG_CMD_NAND_YAFFS
744 "nand write.yaffs - addr off|partition size\n"
745 " write 'size' bytes starting at offset 'off' with yaffs format\n"
746 " from memory address 'addr', skipping bad blocks.\n"
748 "nand erase[.spread] [clean] off size - erase 'size' bytes "
749 "from offset 'off'\n"
750 " With '.spread', erase enough for given file size, otherwise,\n"
751 " 'size' includes skipped bad blocks.\n"
752 "nand erase.part [clean] partition - erase entire mtd partition'\n"
753 "nand erase.chip [clean] - erase entire chip'\n"
754 "nand bad - show bad blocks\n"
755 "nand dump[.oob] off - dump page\n"
756 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
757 " really clean NAND erasing bad blocks (UNSAFE)\n"
758 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
759 "nand biterr off - make a bit error at offset (UNSAFE)"
760 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
762 "nand lock [tight] [status]\n"
763 " bring nand to lock state or display locked pages\n"
764 "nand unlock [offset] [size] - unlock section"
766 #ifdef CONFIG_ENV_OFFSET_OOB
768 "nand env.oob - environment offset in OOB of block 0 of"
770 "nand env.oob set off|partition - set enviromnent offset\n"
771 "nand env.oob get - get environment offset"
775 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
776 ulong offset, ulong addr, char *cmd)
782 #if defined(CONFIG_FIT)
783 const void *fit_hdr = NULL;
786 s = strchr(cmd, '.');
788 (strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) {
789 printf("Unknown nand load suffix '%s'\n", s);
790 show_boot_progress(-53);
794 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
796 cnt = nand->writesize;
797 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
799 puts("** Read error\n");
800 show_boot_progress (-56);
803 show_boot_progress (56);
805 switch (genimg_get_format ((void *)addr)) {
806 case IMAGE_FORMAT_LEGACY:
807 hdr = (image_header_t *)addr;
809 show_boot_progress (57);
810 image_print_contents (hdr);
812 cnt = image_get_image_size (hdr);
814 #if defined(CONFIG_FIT)
815 case IMAGE_FORMAT_FIT:
816 fit_hdr = (const void *)addr;
817 puts ("Fit image detected...\n");
819 cnt = fit_get_size (fit_hdr);
823 show_boot_progress (-57);
824 puts ("** Unknown image type\n");
827 show_boot_progress (57);
829 r = nand_read_skip_bad(nand, offset, &cnt, (u_char *) addr);
831 puts("** Read error\n");
832 show_boot_progress (-58);
835 show_boot_progress (58);
837 #if defined(CONFIG_FIT)
838 /* This cannot be done earlier, we need complete FIT image in RAM first */
839 if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
840 if (!fit_check_format (fit_hdr)) {
841 show_boot_progress (-150);
842 puts ("** Bad FIT image format\n");
845 show_boot_progress (151);
846 fit_print_contents (fit_hdr);
850 /* Loading ok, update default load address */
854 return bootm_maybe_autostart(cmdtp, cmd);
857 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
859 char *boot_device = NULL;
861 ulong addr, offset = 0;
862 #if defined(CONFIG_CMD_MTDPARTS)
863 struct mtd_device *dev;
864 struct part_info *part;
868 char *p = (argc == 2) ? argv[1] : argv[2];
869 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
870 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
871 if (dev->id->type != MTD_DEV_TYPE_NAND) {
872 puts("Not a NAND device\n");
878 addr = simple_strtoul(argv[1], NULL, 16);
880 addr = CONFIG_SYS_LOAD_ADDR;
881 return nand_load_image(cmdtp, &nand_info[dev->id->num],
882 part->offset, addr, argv[0]);
887 show_boot_progress(52);
890 addr = CONFIG_SYS_LOAD_ADDR;
891 boot_device = getenv("bootdevice");
894 addr = simple_strtoul(argv[1], NULL, 16);
895 boot_device = getenv("bootdevice");
898 addr = simple_strtoul(argv[1], NULL, 16);
899 boot_device = argv[2];
902 addr = simple_strtoul(argv[1], NULL, 16);
903 boot_device = argv[2];
904 offset = simple_strtoul(argv[3], NULL, 16);
907 #if defined(CONFIG_CMD_MTDPARTS)
910 show_boot_progress(-53);
911 return cmd_usage(cmdtp);
914 show_boot_progress(53);
916 puts("\n** No boot device **\n");
917 show_boot_progress(-54);
920 show_boot_progress(54);
922 idx = simple_strtoul(boot_device, NULL, 16);
924 if (idx < 0 || idx >= CONFIG_SYS_MAX_NAND_DEVICE || !nand_info[idx].name) {
925 printf("\n** Device %d not available\n", idx);
926 show_boot_progress(-55);
929 show_boot_progress(55);
931 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
934 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
935 "boot from NAND device",
936 "[partition] | [[[loadAddr] dev] offset]"