Lines Matching +full:nand +full:- +full:oob +full:- +full:sector +full:- +full:size

2  * Driver for NAND support, Rick Bronson
7 * Ported 'dynenv' to 'nand env.oob' command
9 * 'dynenv' -- Dynamic environment offset in NAND OOB
10 * (C) Copyright 2006-2007 OpenMoko, Inc.
11 * Added 16-bit nand support
16 * are not considered a derived work of GPL v2-only code may be distributed
30 #include <nand.h>
50 off = last + mtd->writesize; in nand_dump()
54 datbuf = memalign(ARCH_DMA_MINALIGN, mtd->writesize); in nand_dump()
60 oobbuf = memalign(ARCH_DMA_MINALIGN, mtd->oobsize); in nand_dump()
66 off &= ~(mtd->writesize - 1); in nand_dump()
72 ops.len = mtd->writesize; in nand_dump()
73 ops.ooblen = mtd->oobsize; in nand_dump()
84 i = mtd->writesize >> 4; in nand_dump()
87 while (i--) { in nand_dump()
97 puts("OOB:\n"); in nand_dump()
98 i = mtd->oobsize >> 3; in nand_dump()
100 while (i--) { in nand_dump()
114 /* ------------------------------------------------------------------------- */
121 return -ENODEV; in set_dev()
126 printf("Device %d: %s", dev, mtd->name); in set_dev()
141 * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is in print_status()
146 printf("%08lx - %08lx: %08lx blocks %s%s%s\n", in print_status()
148 end - 1, in print_status()
149 (end - start) / erasesize, in print_status()
159 int last_status = -1; in do_nand_status()
163 nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); in do_nand_status()
165 (nand_chip->read_byte(mtd) & 0x80 ? in do_nand_status()
168 for (off = 0; off < mtd->size; off += mtd->erasesize) { in do_nand_status()
173 print_status(block_start, off, mtd->erasesize, in do_nand_status()
180 print_status(block_start, off, mtd->erasesize, last_status); in do_nand_status()
217 /* We don't care about size, or maxsize. */ in do_nand_env_oob()
219 MTD_DEV_TYPE_NAND, mtd->size)) { in do_nand_env_oob()
229 puts("Partition not on first NAND device\n"); in do_nand_env_oob()
233 if (mtd->oobavail < ENV_OFFSET_SIZE) { in do_nand_env_oob()
234 printf("Insufficient available OOB bytes:\n" in do_nand_env_oob()
235 "%d OOB bytes available but %d required for " in do_nand_env_oob()
236 "env.oob support\n", in do_nand_env_oob()
237 mtd->oobavail, ENV_OFFSET_SIZE); in do_nand_env_oob()
241 if ((addr & (mtd->erasesize - 1)) != 0) { in do_nand_env_oob()
242 printf("Environment offset must be block-aligned\n"); in do_nand_env_oob()
253 oob_buf[1] = addr / mtd->erasesize; in do_nand_env_oob()
255 ret = mtd->write_oob(mtd, ENV_OFFSET_SIZE, &ops); in do_nand_env_oob()
257 printf("Error writing OOB block 0\n"); in do_nand_env_oob()
263 printf("Error reading env offset in OOB\n"); in do_nand_env_oob()
268 printf("Verification of env offset in OOB failed: " in do_nand_env_oob()
296 if (chip->numchips > 1) in nand_print_and_set_info()
297 printf("%dx ", chip->numchips); in nand_print_and_set_info()
298 printf("%s, sector size %u KiB\n", in nand_print_and_set_info()
299 mtd->name, mtd->erasesize >> 10); in nand_print_and_set_info()
300 printf(" Page size %8d b\n", mtd->writesize); in nand_print_and_set_info()
301 printf(" OOB size %8d b\n", mtd->oobsize); in nand_print_and_set_info()
302 printf(" Erase size %8d b\n", mtd->erasesize); in nand_print_and_set_info()
303 printf(" subpagesize %8d b\n", chip->subpagesize); in nand_print_and_set_info()
304 printf(" options 0x%08x\n", chip->options); in nand_print_and_set_info()
305 printf(" bbt options 0x%08x\n", chip->bbt_options); in nand_print_and_set_info()
308 env_set_hex("nand_writesize", mtd->writesize); in nand_print_and_set_info()
309 env_set_hex("nand_oobsize", mtd->oobsize); in nand_print_and_set_info()
310 env_set_hex("nand_erasesize", mtd->erasesize); in nand_print_and_set_info()
318 while (count--) { in raw_access()
322 .oobbuf = ((u8 *)addr) + mtd->writesize, in raw_access()
323 .len = mtd->writesize, in raw_access()
324 .ooblen = mtd->oobsize, in raw_access()
342 addr += mtd->writesize + mtd->oobsize; in raw_access()
343 off += mtd->writesize; in raw_access()
349 /* Adjust a chip/partition size down for bad blocks so we don't
352 static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev) in adjust_size_for_badblocks() argument
354 /* We grab the nand info object here fresh because this is usually in adjust_size_for_badblocks()
358 loff_t maxoffset = offset + *size; in adjust_size_for_badblocks()
361 /* count badblocks in NAND from offset to offset + size */ in adjust_size_for_badblocks()
362 for (; offset < maxoffset; offset += mtd->erasesize) { in adjust_size_for_badblocks()
366 /* adjust size if any bad blocks found */ in adjust_size_for_badblocks()
368 *size -= badblocks * mtd->erasesize; in adjust_size_for_badblocks()
369 printf("size adjusted to 0x%llx (%d bad blocks)\n", in adjust_size_for_badblocks()
370 (unsigned long long)*size, badblocks); in adjust_size_for_badblocks()
378 loff_t off, size, maxsize; in do_nand() local
428 /* this command operates only on the first nand device */ in do_nand()
429 if (strcmp(cmd, "env.oob") == 0) in do_nand()
430 return do_nand_env_oob(cmdtp, argc - 1, argv + 1); in do_nand()
447 for (off = 0; off < mtd->size; off += mtd->erasesize) in do_nand()
456 * nand erase [clean] [off size] in do_nand()
462 int scrub_yes = argc > 2 && !strcmp("-y", argv[2]); in do_nand()
476 "\nReally scrub this NAND flash? <y/N>\n"; in do_nand()
492 * erases -- easy to do accidentally, e.g. with a misspelled in do_nand()
499 /* skip first two or three arguments, look for offset and size */ in do_nand()
500 if (mtd_arg_off_size(argc - o, argv + o, &dev, &off, &size, in do_nand()
502 mtd->size) != 0) in do_nand()
512 opts.length = size; in do_nand()
541 ret = nand_dump(mtd, off, !strcmp(&cmd[4], ".oob"), repeat); in do_nand()
569 if (mtd_arg_off(argv[3], &dev, &off, &size, &maxsize, in do_nand()
571 mtd->size)) in do_nand()
584 if (pagecount * mtd->writesize > size) { in do_nand()
585 puts("Size exceeds partition or device limit\n"); in do_nand()
586 return -1; in do_nand()
589 rwsize = pagecount * (mtd->writesize + mtd->oobsize); in do_nand()
591 if (mtd_arg_off_size(argc - 3, argv + 3, &dev, &off, in do_nand()
592 &size, &maxsize, in do_nand()
594 mtd->size) != 0) in do_nand()
600 /* size is unspecified */ in do_nand()
602 adjust_size_for_badblocks(&size, off, dev); in do_nand()
603 rwsize = size; in do_nand()
622 printf("Unknown nand command suffix '%s'\n", s); in do_nand()
629 } else if (!strcmp(s, ".oob")) { in do_nand()
630 /* out-of-band data */ in do_nand()
645 printf("Unknown nand command suffix '%s'.\n", s); in do_nand()
668 size = mtd->erasesize; in do_nand()
670 if (!str2off(argv[3], &size)) { in do_nand()
671 puts("Size is not a valid number\n"); in do_nand()
676 endoff = off + size; in do_nand()
677 if (endoff > mtd->size) { in do_nand()
678 puts("Arguments beyond end of NAND\n"); in do_nand()
682 off = round_down(off, mtd->erasesize); in do_nand()
683 endoff = round_up(endoff, mtd->erasesize); in do_nand()
684 size = endoff - off; in do_nand()
685 printf("\nNAND torture: device %d offset 0x%llx size 0x%llx (block size 0x%x)\n", in do_nand()
686 dev, off, size, mtd->erasesize); in do_nand()
695 off += mtd->erasesize; in do_nand()
703 argc -= 2; in do_nand()
722 --argc; in do_nand()
747 puts("NAND flash successfully locked\n"); in do_nand()
749 puts("Error locking NAND flash\n"); in do_nand()
764 if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size, in do_nand()
766 mtd->size) < 0) in do_nand()
774 if (!nand_unlock(mtd, off, size, allexcept)) { in do_nand()
775 puts("NAND flash successfully unlocked\n"); in do_nand()
777 puts("Error unlocking NAND flash, " in do_nand()
791 "info - show available NAND devices\n"
792 "nand device [dev] - show or set current device\n"
793 "nand read - addr off|partition size\n"
794 "nand write - addr off|partition size\n"
795 " read/write 'size' bytes starting at offset 'off'\n"
797 "nand read.raw - addr off|partition [count]\n"
798 "nand write.raw[.noverify] - addr off|partition [count]\n"
799 " Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
801 "nand write.trimffs - addr off|partition size\n"
802 " write 'size' bytes starting at offset 'off' from memory address\n"
806 "nand erase[.spread] [clean] off size - erase 'size' bytes "
808 " With '.spread', erase enough for given file size, otherwise,\n"
809 " 'size' includes skipped bad blocks.\n"
810 "nand erase.part [clean] partition - erase entire mtd partition'\n"
811 "nand erase.chip [clean] - erase entire chip'\n"
812 "nand bad - show bad blocks\n"
813 "nand dump[.oob] off - dump page\n"
815 "nand torture off - torture one block at offset\n"
816 "nand torture off [size] - torture blocks from off to off+size\n"
818 "nand scrub [-y] off size | scrub.part partition | scrub.chip\n"
819 " really clean NAND erasing bad blocks (UNSAFE)\n"
820 "nand markbad off [...] - mark bad block(s) at offset (UNSAFE)\n"
821 "nand biterr off - make a bit error at offset (UNSAFE)"
824 "nand lock [tight] [status]\n"
825 " bring nand to lock state or display locked pages\n"
826 "nand unlock[.allexcept] [offset] [size] - unlock section"
830 "nand env.oob - environment offset in OOB of block 0 of"
832 "nand env.oob set off|partition - set enviromnent offset\n"
833 "nand env.oob get - get environment offset"
839 nand, CONFIG_SYS_MAXARGS, 1, do_nand,
840 "NAND sub-system", nand_help_text
859 printf("Unknown nand load suffix '%s'\n", s); in nand_load_image()
864 printf("\nLoading from %s, offset 0x%lx\n", mtd->name, offset); in nand_load_image()
866 cnt = mtd->writesize; in nand_load_image()
867 r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, in nand_load_image()
902 r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, in nand_load_image()
947 if (dev->id->type != MTD_DEV_TYPE_NAND) { in do_nandboot()
948 puts("Not a NAND device\n"); in do_nandboot()
958 mtd = get_nand_dev_by_index(dev->id->num); in do_nandboot()
959 return nand_load_image(cmdtp, mtd, part->offset, in do_nandboot()
1014 "boot from NAND device",