[U-Boot] [PATCH v2 3/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes

Pekon Gupta pekon at ti.com
Wed Aug 14 08:16:54 CEST 2013


chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
processing the data passed during Read/Write accesses.

All H/W based ECC schemes use GPMC controller to calculate ECC syndrome.
But each BCHx_ECC scheme has its own implemetation of post-processing and
fetching ECC syndrome from GPMC controller.

This patch updates OMAP_ECC_BCH8_CODE_HW ECC scheme in following way:
- merges various sub-functions into single omap_calculate_ecc_bch().
- removes omap_ecc_disable() and instead uses it as inline.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap_gpmc.c | 81 ++++++++++----------------------------------
 1 file changed, 18 insertions(+), 63 deletions(-)

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index b8f0e86..fa3a82a 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -277,35 +277,28 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 	writel(ecc_config_val | 0x1, &gpmc_cfg->ecc_config);
 }
 
-/*
- * omap_ecc_disable - Disable H/W ECC calculation
- *
- * @mtd:	MTD device structure
- */
-static void __maybe_unused omap_ecc_disable(struct mtd_info *mtd)
-{
-	writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config);
-}
-
 
 /*
  * BCH support using ELM module
  */
 #if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW)
 /*
- * omap_read_bch8_result - Read BCH result for BCH8 level
- *
- * @mtd:	MTD device structure
- * @big_endian:	When set read register 3 first
- * @ecc_code:	Read syndrome from BCH result registers
+ *  omap_calculate_ecc_bch - Read BCH ECC result
+ *  @mtd:	MTD structure
+ *  @dat:	unused
+ *  @ecc_code:	ecc_code buffer
  */
-static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
+static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
 				uint8_t *ecc_code)
 {
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	int8_t ret = 0;
 	uint32_t *ptr;
 	int8_t i = 0, j;
 
-	if (big_endian) {
+	switch (bch->type) {
+	case ECC_BCH8:
 		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
 		ecc_code[i++] = readl(ptr) & 0xFF;
 		ptr--;
@@ -316,18 +309,13 @@ static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
 			ecc_code[i++] = readl(ptr) & 0xFF;
 			ptr--;
 		}
-	} else {
-		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
-		for (j = 0; j < 3; j++) {
-			ecc_code[i++] = readl(ptr) & 0xFF;
-			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
-			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
-			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
-			ptr++;
-		}
-		ecc_code[i++] = readl(ptr) & 0xFF;
-		ecc_code[i++] = 0;	/* 14th byte is always zero */
+		break;
+	default:
+		ret = -1;
 	}
+	/* clear result and disable engine */
+	writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config);
+	return ret;
 }
 
 /*
@@ -366,35 +354,6 @@ static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
 }
 
 /*
- *  omap_calculate_ecc_bch - Read BCH ECC result
- *
- *  @mtd:	MTD structure
- *  @dat:	unused
- *  @ecc_code:	ecc_code buffer
- */
-static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
-				uint8_t *ecc_code)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct nand_bch_priv *bch = chip->priv;
-	uint8_t big_endian = 1;
-	int8_t ret = 0;
-
-	if (bch->type == ECC_BCH8)
-		omap_read_bch8_result(mtd, big_endian, ecc_code);
-	else /* BCH4 and BCH16 currently not supported */
-		ret = -1;
-
-	/*
-	 * Stop reading anymore ECC vals and clear old results
-	 * enable will be called if more reads are required
-	 */
-	omap_ecc_disable(mtd);
-
-	return ret;
-}
-
-/*
  * omap_fix_errors_bch - Correct bch error in the data
  *
  * @mtd:	MTD device structure
@@ -592,12 +551,8 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
 		*ecc++ = 0x24 ^ ((val1 >> 8) & 0xFF);
 		*ecc++ = 0xb5 ^ (val1 & 0xFF);
 	}
-
-	/*
-	 * Stop reading anymore ECC vals and clear old results
-	 * enable will be called if more reads are required
-	 */
-	omap_ecc_disable(mtd);
+	/* Stop reading anymore ECC vals and clear old results */
+	writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config);
 
 	return ret;
 }
-- 
1.8.1



More information about the U-Boot mailing list