diff options
-rw-r--r-- | arch/arm/plat-omap/include/plat/gpmc.h | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/omap2.c | 37 |
2 files changed, 38 insertions, 1 deletions
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 773351bc25a2..12b316165037 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h | |||
@@ -90,6 +90,8 @@ enum omap_ecc { | |||
90 | /* 1-bit ecc: stored at end of spare area */ | 90 | /* 1-bit ecc: stored at end of spare area */ |
91 | OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ | 91 | OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ |
92 | OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ | 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 | /* |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 6d4a42e39380..4e33972ad17a 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -98,6 +98,20 @@ | |||
98 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 98 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
99 | #endif | 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 | struct omap_nand_info { | 115 | struct omap_nand_info { |
102 | struct nand_hw_control controller; | 116 | struct nand_hw_control controller; |
103 | struct omap_nand_platform_data *pdata; | 117 | struct omap_nand_platform_data *pdata; |
@@ -914,6 +928,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
914 | struct omap_nand_info *info; | 928 | struct omap_nand_info *info; |
915 | struct omap_nand_platform_data *pdata; | 929 | struct omap_nand_platform_data *pdata; |
916 | int err; | 930 | int err; |
931 | int i, offset; | ||
917 | 932 | ||
918 | pdata = pdev->dev.platform_data; | 933 | pdata = pdev->dev.platform_data; |
919 | if (pdata == NULL) { | 934 | if (pdata == NULL) { |
@@ -1037,7 +1052,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1037 | /* selsect the ecc type */ | 1052 | /* selsect the ecc type */ |
1038 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) | 1053 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) |
1039 | info->nand.ecc.mode = NAND_ECC_SOFT; | 1054 | info->nand.ecc.mode = NAND_ECC_SOFT; |
1040 | else if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) { | 1055 | else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || |
1056 | (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { | ||
1041 | info->nand.ecc.bytes = 3; | 1057 | info->nand.ecc.bytes = 3; |
1042 | info->nand.ecc.size = 512; | 1058 | info->nand.ecc.size = 512; |
1043 | info->nand.ecc.calculate = omap_calculate_ecc; | 1059 | info->nand.ecc.calculate = omap_calculate_ecc; |
@@ -1057,6 +1073,25 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1057 | } | 1073 | } |
1058 | } | 1074 | } |
1059 | 1075 | ||
1076 | /* rom code layout */ | ||
1077 | if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { | ||
1078 | |||
1079 | if (info->nand.options & NAND_BUSWIDTH_16) | ||
1080 | offset = 2; | ||
1081 | else { | ||
1082 | offset = 1; | ||
1083 | info->nand.badblock_pattern = &bb_descrip_flashbased; | ||
1084 | } | ||
1085 | omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); | ||
1086 | for (i = 0; i < omap_oobinfo.eccbytes; i++) | ||
1087 | omap_oobinfo.eccpos[i] = i+offset; | ||
1088 | |||
1089 | omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; | ||
1090 | omap_oobinfo.oobfree->length = info->mtd.oobsize - | ||
1091 | (offset + omap_oobinfo.eccbytes); | ||
1092 | |||
1093 | info->nand.ecc.layout = &omap_oobinfo; | ||
1094 | } | ||
1060 | 1095 | ||
1061 | #ifdef CONFIG_MTD_PARTITIONS | 1096 | #ifdef CONFIG_MTD_PARTITIONS |
1062 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); | 1097 | err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); |