diff options
author | Pekon Gupta <pekon@ti.com> | 2014-02-26 05:23:13 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2014-03-20 05:30:27 -0400 |
commit | 2c9f2365d1e1d0e318b068f683f18c99515b80f8 (patch) | |
tree | aeb5c94431ee4749a532ace999524487348e0788 | |
parent | f5dc06fb71ae10c4f205a08f5ef26fd90fc122fc (diff) |
mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in omap_calculate_ecc_bch
merges omap3_calculate_ecc_bch4() into omap_calculate_ecc_bch() so that
common callback can be used for both OMAP_ECC_BCH4_CODE_HW and
OMAP_ECC_BCH4_CODE_HW_DETECTION_SW ecc-schemes
+---------------------+-------------------------------------------------------+
|ecc-scheme | nand_chip->calculate() after this patch |
+---------------------+-------------------------------------------------------+
|HAM1_ECC | omap_calculate_ecc() |
+---------------------+-------------------------------------------------------+
|BCH4_HW_DETECTION_SW | omap3_calculate_ecc_bch4() -> omap_calculate_ecc_bch()|
|BCH4_HW | omap_calculate_ecc_bch() |
|BCH8_HW_DETECTION_SW | omap3_calculate_ecc_bch8() |
|BCH8_HW | omap_calculate_ecc_bch() |
+---------------------+-------------------------------------------------------+
Tested-by: Stefan Roese <sr@denx.de>
Signed-off-by: Pekon Gupta <pekon@ti.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r-- | drivers/mtd/nand/omap2.c | 51 |
1 files changed, 10 insertions, 41 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 2ccd557bf77d..e536267231e2 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1121,48 +1121,10 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode) | |||
1121 | writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); | 1121 | writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); |
1122 | } | 1122 | } |
1123 | #endif | 1123 | #endif |
1124 | static u8 bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f}; | ||
1124 | 1125 | ||
1125 | #ifdef CONFIG_MTD_NAND_ECC_BCH | 1126 | #ifdef CONFIG_MTD_NAND_ECC_BCH |
1126 | /** | 1127 | /** |
1127 | * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes | ||
1128 | * @mtd: MTD device structure | ||
1129 | * @dat: The pointer to data on which ecc is computed | ||
1130 | * @ecc_code: The ecc_code buffer | ||
1131 | */ | ||
1132 | static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat, | ||
1133 | u_char *ecc_code) | ||
1134 | { | ||
1135 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | ||
1136 | mtd); | ||
1137 | unsigned long nsectors, val1, val2; | ||
1138 | int i; | ||
1139 | |||
1140 | nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; | ||
1141 | |||
1142 | for (i = 0; i < nsectors; i++) { | ||
1143 | |||
1144 | /* Read hw-computed remainder */ | ||
1145 | val1 = readl(info->reg.gpmc_bch_result0[i]); | ||
1146 | val2 = readl(info->reg.gpmc_bch_result1[i]); | ||
1147 | |||
1148 | /* | ||
1149 | * Add constant polynomial to remainder, in order to get an ecc | ||
1150 | * sequence of 0xFFs for a buffer filled with 0xFFs; and | ||
1151 | * left-justify the resulting polynomial. | ||
1152 | */ | ||
1153 | *ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF); | ||
1154 | *ecc_code++ = 0x13 ^ ((val2 >> 4) & 0xFF); | ||
1155 | *ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF)); | ||
1156 | *ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF); | ||
1157 | *ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF); | ||
1158 | *ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF); | ||
1159 | *ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4); | ||
1160 | } | ||
1161 | |||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | /** | ||
1166 | * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes | 1128 | * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes |
1167 | * @mtd: MTD device structure | 1129 | * @mtd: MTD device structure |
1168 | * @dat: The pointer to data on which ecc is computed | 1130 | * @dat: The pointer to data on which ecc is computed |
@@ -1209,7 +1171,6 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat, | |||
1209 | } | 1171 | } |
1210 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | 1172 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ |
1211 | 1173 | ||
1212 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
1213 | /** | 1174 | /** |
1214 | * omap_calculate_ecc_bch - Generate bytes of ECC bytes | 1175 | * omap_calculate_ecc_bch - Generate bytes of ECC bytes |
1215 | * @mtd: MTD device structure | 1176 | * @mtd: MTD device structure |
@@ -1252,6 +1213,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, | |||
1252 | *ecc_code++ = ((bch_val1 >> 8) & 0xFF); | 1213 | *ecc_code++ = ((bch_val1 >> 8) & 0xFF); |
1253 | *ecc_code++ = (bch_val1 & 0xFF); | 1214 | *ecc_code++ = (bch_val1 & 0xFF); |
1254 | break; | 1215 | break; |
1216 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | ||
1255 | case OMAP_ECC_BCH4_CODE_HW: | 1217 | case OMAP_ECC_BCH4_CODE_HW: |
1256 | bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); | 1218 | bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]); |
1257 | bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); | 1219 | bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]); |
@@ -1270,6 +1232,12 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, | |||
1270 | 1232 | ||
1271 | /* ECC scheme specific syndrome customizations */ | 1233 | /* ECC scheme specific syndrome customizations */ |
1272 | switch (info->ecc_opt) { | 1234 | switch (info->ecc_opt) { |
1235 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | ||
1236 | /* Add constant polynomial to remainder, so that | ||
1237 | * ECC of blank pages results in 0x0 on reading back */ | ||
1238 | for (i = 0; i < eccbytes; i++) | ||
1239 | ecc_calc[i] ^= bch4_polynomial[i]; | ||
1240 | break; | ||
1273 | case OMAP_ECC_BCH4_CODE_HW: | 1241 | case OMAP_ECC_BCH4_CODE_HW: |
1274 | /* Set 8th ECC byte as 0x0 for ROM compatibility */ | 1242 | /* Set 8th ECC byte as 0x0 for ROM compatibility */ |
1275 | ecc_calc[eccbytes - 1] = 0x0; | 1243 | ecc_calc[eccbytes - 1] = 0x0; |
@@ -1327,6 +1295,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob, | |||
1327 | return flip_bits; | 1295 | return flip_bits; |
1328 | } | 1296 | } |
1329 | 1297 | ||
1298 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | ||
1330 | /** | 1299 | /** |
1331 | * omap_elm_correct_data - corrects page data area in case error reported | 1300 | * omap_elm_correct_data - corrects page data area in case error reported |
1332 | * @mtd: MTD device structure | 1301 | * @mtd: MTD device structure |
@@ -1835,7 +1804,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1835 | nand_chip->ecc.strength = 4; | 1804 | nand_chip->ecc.strength = 4; |
1836 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; | 1805 | nand_chip->ecc.hwctl = omap3_enable_hwecc_bch; |
1837 | nand_chip->ecc.correct = nand_bch_correct_data; | 1806 | nand_chip->ecc.correct = nand_bch_correct_data; |
1838 | nand_chip->ecc.calculate = omap3_calculate_ecc_bch4; | 1807 | nand_chip->ecc.calculate = omap_calculate_ecc_bch; |
1839 | /* define ECC layout */ | 1808 | /* define ECC layout */ |
1840 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1809 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1841 | (mtd->writesize / | 1810 | (mtd->writesize / |