Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

omap3: nand: making ecc layout as compatible with romcode ecc

This patch overrides nand ecc layout and bad block descriptor (for 8-bit
device) to support hw ecc in romcode layout. So as to have in sync with ecc
layout throughout; i.e. x-loader, u-boot and kernel.

This enables to flash x-loader, u-boot, kernel, FS images from kernel itself
and compatiable with other tools.

This patch does not enables this feature by default and need to pass from
board file to enable for any board.

Signed-off-by: Vimal Singh <vimalsingh@ti.com>
Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by

Sukumar Ghorai and committed by
Tony Lindgren
f040d332 f3d73f36

+38 -1
+2
arch/arm/plat-omap/include/plat/gpmc.h
··· 90 90 /* 1-bit ecc: stored at end of spare area */ 91 91 OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ 92 92 OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ 93 + /* 1-bit ecc: stored at begining of spare area as romcode */ 94 + OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ 93 95 }; 94 96 95 97 /*
+36 -1
drivers/mtd/nand/omap2.c
··· 98 98 static const char *part_probes[] = { "cmdlinepart", NULL }; 99 99 #endif 100 100 101 + /* oob info generated runtime depending on ecc algorithm and layout selected */ 102 + static struct nand_ecclayout omap_oobinfo; 103 + /* Define some generic bad / good block scan pattern which are used 104 + * while scanning a device for factory marked good / bad blocks 105 + */ 106 + static uint8_t scan_ff_pattern[] = { 0xff }; 107 + static struct nand_bbt_descr bb_descrip_flashbased = { 108 + .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, 109 + .offs = 0, 110 + .len = 1, 111 + .pattern = scan_ff_pattern, 112 + }; 113 + 114 + 101 115 struct omap_nand_info { 102 116 struct nand_hw_control controller; 103 117 struct omap_nand_platform_data *pdata; ··· 928 914 struct omap_nand_info *info; 929 915 struct omap_nand_platform_data *pdata; 930 916 int err; 917 + int i, offset; 931 918 932 919 pdata = pdev->dev.platform_data; 933 920 if (pdata == NULL) { ··· 1052 1037 /* selsect the ecc type */ 1053 1038 if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) 1054 1039 info->nand.ecc.mode = NAND_ECC_SOFT; 1055 - else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { 1040 + else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || 1041 + (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { 1056 1042 info->nand.ecc.bytes = 3; 1057 1043 info->nand.ecc.size = 512; 1058 1044 info->nand.ecc.calculate = omap_calculate_ecc; ··· 1073 1057 } 1074 1058 } 1075 1059 1060 + /* rom code layout */ 1061 + if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { 1062 + 1063 + if (info->nand.options & NAND_BUSWIDTH_16) 1064 + offset = 2; 1065 + else { 1066 + offset = 1; 1067 + info->nand.badblock_pattern = &bb_descrip_flashbased; 1068 + } 1069 + omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); 1070 + for (i = 0; i < omap_oobinfo.eccbytes; i++) 1071 + omap_oobinfo.eccpos[i] = i+offset; 1072 + 1073 + omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; 1074 + omap_oobinfo.oobfree->length = info->mtd.oobsize - 1075 + (offset + omap_oobinfo.eccbytes); 1076 + 1077 + info->nand.ecc.layout = &omap_oobinfo; 1078 + } 1076 1079 1077 1080 #ifdef CONFIG_MTD_PARTITIONS 1078 1081 err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);