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

login
register
mail settings
Submitter pekon gupta
Date Aug. 6, 2013, 9:55 a.m.
Message ID <1375782920-25935-4-git-send-email-pekon@ti.com>
Download mbox | patch
Permalink /patch/264965/
State Superseded
Headers show

Comments

pekon gupta - Aug. 6, 2013, 9:55 a.m.
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@ti.com>
---
 drivers/mtd/nand/omap_gpmc.c | 82 ++++++++++----------------------------------
 1 file changed, 18 insertions(+), 64 deletions(-)

Patch

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index f3b86e5..40b71a7 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -281,34 +281,26 @@  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);
-}
 
 #if defined(CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW)
 /*
- * BCH8 support (needs ELM and thus AM33xx-only)
- */
-/*
- * omap_read_bch8_result - Read BCH result for BCH8 level
+ *  omap_calculate_ecc_bch - Read BCH ECC result
  *
- * @mtd:	MTD device structure
- * @big_endian:	When set read register 3 first
- * @ecc_code:	Read syndrome from BCH result registers
+ *  @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--;
@@ -319,18 +311,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;
 }
 
 /*
@@ -369,35 +356,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
@@ -594,12 +552,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;
 }