
From: WingMan Kwok w-kwok2@ti.com
This commit adds a nand ecclayout command that allows the ecclayout of the current nand device to be changed during run time. This feature is useful when using u-boot to write something to nand flash that will be read by other applications, such as ROM bootloader, that expects a different ECC layout. In that case, change the current nand device ecclayout using the "nand ecclayout set" command before writing the data to nand flash.
Signed-off-by: WingMan Kwok w-kwok2@ti.com Signed-off-by: Ivan Khoronzhuk ivan.khoronzhuk@ti.com --- common/cmd_nand.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/README.nand | 12 ++++++++ include/nand.h | 7 +++++ 3 files changed, 110 insertions(+)
diff --git a/common/cmd_nand.c b/common/cmd_nand.c index a84f7dc..61d3fcc 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -462,6 +462,51 @@ static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev) } }
+#ifdef CONFIG_CMD_NAND_ECCLAYOUT +static void nand_print_ecclayout_info(struct nand_ecclayout *layout) +{ + int i; + struct nand_oobfree *oobfree; + + if (!layout) + return; + + printf(" num ecc bytes: %d\n", layout->eccbytes); + puts(" ecc pos:\n "); + for (i = 0; i < layout->eccbytes; i++) { + if (i && !(i % 8)) + printf("\n "); + + printf("%4d ", layout->eccpos[i]); + } + + puts("\n oobfree:\n"); + puts(" offset length\n"); + oobfree = layout->oobfree; + for (i = 0; oobfree->length && i < MTD_MAX_OOBFREE_ENTRIES_LARGE; i++) { + printf(" %3d %3d\n", oobfree->offset, oobfree->length); + oobfree++; + } +} + +static void nand_print_device_ecclayout(int dev) +{ + int idx; + nand_info_t *nand = &nand_info[dev]; + struct nand_chip *chip = nand->priv; + + idx = board_nand_get_ecclayout_idx(chip, chip->ecc.layout); + + if (idx < 0) { + puts("no ecc layout\n"); + return; + } + + printf("\necc layout %d:\n", idx); + nand_print_ecclayout_info(chip->ecc.layout); +} +#endif + static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int i, ret = 0; @@ -830,6 +875,45 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } #endif
+#ifdef CONFIG_CMD_NAND_ECCLAYOUT + if (strcmp(cmd, "ecclayout") == 0) { + int i; + struct nand_ecclayout *lt; + nand_info_t *nand = &nand_info[dev]; + + if (argc < 3) { + puts("Current device ecclayout:\n"); + nand_print_device_ecclayout(dev); + return 0; + } + + if (!strcmp(argv[2], "set")) { + if (argc < 4) + return 1; + + i = (int)simple_strtoul(argv[3], NULL, 10); + if (board_nand_set_ecclayout(nand, i)) + printf("Setting current device to ecc layout %d FAILED!\n", i); + + return 0; + } + + if (strcmp(argv[2], "all") != 0) + return 1; + + /* show all available ecc layouts */ + puts("Available ecc layouts:\n"); + + for (i = 0; (lt = board_nand_get_ecclayout(i)); i++) { + + printf("\n ecc laytout %d:\n", i); + nand_print_ecclayout_info(lt); + } + + return 0; + } +#endif + usage: return CMD_RET_USAGE; } @@ -884,6 +968,13 @@ static char nand_help_text[] = "nand env.oob set off|partition - set enviromnent offset\n" "nand env.oob get - get environment offset" #endif +#ifdef CONFIG_CMD_NAND_ECCLAYOUT + "\n" + "nand ecclayout [all] - show ecclayout, 'all' shows all \n" + " available ecc layouts for setting to current device\n" + "nand ecclayout set idx - sets current device ecc layout \n" + " to layout indexed by idx\n" +#endif ""; #endif
diff --git a/doc/README.nand b/doc/README.nand index 70cf768..6fdce26 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -87,6 +87,15 @@ Commands: a packed sequence of "data, oob, data, oob, ..." -- no alignment of individual pages is maintained.
+ nand ecclayout [all] + Enabled by the CONFIG_CMD_NAND_ECCLAYOUT macro. This command show current + ecclayout, "all" shows all available ecc layouts for setting to current + device. + + nand ecclayout set idx + Enabled by the CONFIG_CMD_NAND_ECCLAYOUT macro. This command set current + device ecc layout to layout indexed by idx. + Configuration Options:
CONFIG_CMD_NAND @@ -208,6 +217,9 @@ Configuration Options: drivers/mtd/nand/ndfc.c drivers/mtd/nand/omap_gpmc.c
+ CONFIG_CMD_NAND_ECCLAYOUT + Enables support of nand ecclayout commands. +
Platform specific options ========================= diff --git a/include/nand.h b/include/nand.h index fc735d1..a810626 100644 --- a/include/nand.h +++ b/include/nand.h @@ -155,6 +155,13 @@ void nand_deselect(void); void board_nand_select_device(struct nand_chip *nand, int chip); #endif
+int board_nand_get_ecclayout_idx(struct nand_chip *nand, + struct nand_ecclayout *layout); + +struct nand_ecclayout *board_nand_get_ecclayout(int idx); + +int board_nand_set_ecclayout(struct mtd_info *mtd, int idx); + __attribute__((noreturn)) void nand_boot(void);
#endif