linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes
@ 2014-01-07 13:45 Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 1/4] mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to omap_calculate_ecc_bch Pekon Gupta
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Pekon Gupta @ 2014-01-07 13:45 UTC (permalink / raw)
  To: Brian Norris; +Cc: Stefan Roese, linux-mtd, Pekon Gupta, Felipe Balbi

This patch series is split version of earlier patch:
http://lists.infradead.org/pipermail/linux-mtd/2013-November/050240.html

chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
processing the data passed during Read/Write accesses.
Though all H/W ECC schemes in OMAP NAND use GPMC controller for ECC calculation
But each of them implements its own callback to process and fetch ECC syndrome.

This patch tries to merge common code for different BCHx_ECC schemes into single
omap_calculate_ecc_bch(). This imporves scalability for future ecc-schemes.
 +----------------------+----------------------------+
 | ecc-scheme           | nand_chip->ecc.calculate   |
 +----------------------+----------------------------+
 | HAM1_ECC             | omap_calculate_ecc()       |
 | BCH4_HW_DETECTION_SW | omap3_calculate_ecc_bch4() |
 | BCH4_HW              | omap3_calculate_ecc_bch()  |
 | BCH8_HW_DETECTION_SW | omap3_calculate_ecc_bch8() |
 | BCH8_HW              | omap3_calculate_ecc_bch()  |
 +----------------------+----------------------------+


Pekon Gupta (4):
  mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to
    omap_calculate_ecc_bch
  mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for
    BCHx_HW ecc-scheme
  mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in
    omap_calculate_ecc_bch
  mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 in
    omap_calculate_ecc_bch

 drivers/mtd/nand/omap2.c | 187 +++++++++++++++--------------------------------
 1 file changed, 60 insertions(+), 127 deletions(-)

-- 
1.8.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v5 1/4] mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to omap_calculate_ecc_bch
  2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
@ 2014-01-07 13:45 ` Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 2/4] mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for BCHx_HW ecc-scheme Pekon Gupta
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2014-01-07 13:45 UTC (permalink / raw)
  To: Brian Norris; +Cc: Stefan Roese, linux-mtd, Pekon Gupta, Felipe Balbi

This patch renames omap3_calculate_ecc_bch -> omap_calculate_ecc_bch to
keep nomenclature independent of any device family.

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/omap2.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c690721..bf9bf7e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1211,15 +1211,15 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
- * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
+ * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
  * @dat:	The pointer to data on which ecc is computed
  * @ecc_code:	The ecc_code buffer
  *
  * Support calculating of BCH4/8 ecc vectors for the page
  */
-static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
-				    u_char *ecc_code)
+static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
+					const u_char *dat, u_char *ecc_code)
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
@@ -1858,7 +1858,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* define ECC layout */
@@ -1929,7 +1929,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* This ECC scheme requires ELM H/W block */
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 2/4] mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for BCHx_HW ecc-scheme
  2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 1/4] mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to omap_calculate_ecc_bch Pekon Gupta
@ 2014-01-07 13:45 ` Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 3/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in omap_calculate_ecc_bch Pekon Gupta
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2014-01-07 13:45 UTC (permalink / raw)
  To: Brian Norris; +Cc: Stefan Roese, linux-mtd, Pekon Gupta, Felipe Balbi

OMAP NAND driver supports multiple flavours of BCH4 and BCH8 ECC algorithms.
+------+------------------------------------+---------------+---------------+
| Algo | ECC scheme                         |ECC calculation|Error detection|
+------+------------------------------------+---------------+---------------+
|      |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW  |H/W (GPMC)     |S/W            |
| BCH4 |OMAP_ECC_BCH4_CODE_HW               |H/W (GPMC)     |H/W (ELM)      |
+------+------------------------------------+---------------+---------------+
|      |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW  |H/W (GPMC)     |S/W            |
| BCH8 |OMAP_ECC_BCH8_CODE_HW               |H/W (GPMC)     |H/W (ELM)      |
+------+------------------------------------+---------------+---------------+

As all implementations of H/W ecc-scheme use GPMC engine for ECC calculation,
Thus this patch:
(1) Replaces if..then..else with switch..case statements, so that code is
    scalable for adding new ecc-schemes in future.

(2) Separates out ecc-scheme specific customizations into separate switch..case,
    so that common code can be re-used between different flavours of ecc-scheme.

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/omap2.c | 69 +++++++++++++++++++++++++-----------------------
 1 file changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index bf9bf7e..dabea92 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1219,33 +1219,26 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
  * Support calculating of BCH4/8 ecc vectors for the page
  */
 static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
-					const u_char *dat, u_char *ecc_code)
+					const u_char *dat, u_char *ecc_calc)
 {
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
+	int eccbytes	= info->nand.ecc.bytes;
+	enum omap_ecc ecc_opt = info->ecc_opt;
+	struct gpmc_nand_regs	*gpmc_regs = &info->reg;
+	u8 *ecc_code;
 	unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4;
-	int i, eccbchtsel;
+	int i;
 
 	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-	/*
-	 * find BCH scheme used
-	 * 0 -> BCH4
-	 * 1 -> BCH8
-	 */
-	eccbchtsel = ((readl(info->reg.gpmc_ecc_config) >> 12) & 0x3);
-
 	for (i = 0; i < nsectors; i++) {
-
-		/* Read hw-computed remainder */
-		bch_val1 = readl(info->reg.gpmc_bch_result0[i]);
-		bch_val2 = readl(info->reg.gpmc_bch_result1[i]);
-		if (eccbchtsel) {
-			bch_val3 = readl(info->reg.gpmc_bch_result2[i]);
-			bch_val4 = readl(info->reg.gpmc_bch_result3[i]);
-		}
-
-		if (eccbchtsel) {
-			/* BCH8 ecc scheme */
+		ecc_code = ecc_calc;
+		switch (ecc_opt) {
+		case OMAP_ECC_BCH8_CODE_HW:
+			bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+			bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
+			bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
+			bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
 			*ecc_code++ = (bch_val4 & 0xFF);
 			*ecc_code++ = ((bch_val3 >> 24) & 0xFF);
 			*ecc_code++ = ((bch_val3 >> 16) & 0xFF);
@@ -1259,14 +1252,10 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 			*ecc_code++ = ((bch_val1 >> 16) & 0xFF);
 			*ecc_code++ = ((bch_val1 >> 8) & 0xFF);
 			*ecc_code++ = (bch_val1 & 0xFF);
-			/*
-			 * Setting 14th byte to zero to handle
-			 * erased page & maintain compatibility
-			 * with RBL
-			 */
-			*ecc_code++ = 0x0;
-		} else {
-			/* BCH4 ecc scheme */
+			break;
+		case OMAP_ECC_BCH4_CODE_HW:
+			bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+			bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
 			*ecc_code++ = ((bch_val2 >> 12) & 0xFF);
 			*ecc_code++ = ((bch_val2 >> 4) & 0xFF);
 			*ecc_code++ = ((bch_val2 & 0xF) << 4) |
@@ -1275,12 +1264,26 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 			*ecc_code++ = ((bch_val1 >> 12) & 0xFF);
 			*ecc_code++ = ((bch_val1 >> 4) & 0xFF);
 			*ecc_code++ = ((bch_val1 & 0xF) << 4);
-			/*
-			 * Setting 8th byte to zero to handle
-			 * erased page
-			 */
-			*ecc_code++ = 0x0;
+			break;
+		default:
+			return -EINVAL;
 		}
+
+		/* ECC scheme specific syndrome customizations */
+		switch (ecc_opt) {
+		case OMAP_ECC_BCH4_CODE_HW:
+			/* Set  8th ECC byte as 0x0 for ROM compatibility */
+			ecc_calc[eccbytes - 1] = 0x0;
+			break;
+		case OMAP_ECC_BCH8_CODE_HW:
+			/* Set 14th ECC byte as 0x0 for ROM compatibility */
+			ecc_calc[eccbytes - 1] = 0x0;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+	ecc_calc += eccbytes;
 	}
 
 	return 0;
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 3/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in omap_calculate_ecc_bch
  2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 1/4] mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to omap_calculate_ecc_bch Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 2/4] mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for BCHx_HW ecc-scheme Pekon Gupta
@ 2014-01-07 13:45 ` Pekon Gupta
  2014-01-07 13:45 ` [PATCH v5 4/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 " Pekon Gupta
  2014-01-08  8:08 ` [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Stefan Roese
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2014-01-07 13:45 UTC (permalink / raw)
  To: Brian Norris; +Cc: Stefan Roese, linux-mtd, Pekon Gupta, Felipe Balbi

chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
processing the data passed during Read/Write accesses.
All H/W ECC schemes use GPMC controller for ECC syndrome calculation,but each
ecc-scheme implements its own calback to config, process and fetch ECC syndrome.

This patch merges omap3_calculate_ecc_bch4() into omap_calculate_ecc_bch()
to re-use common code between BCH4_HW and BCH4_HW_DETECTION_SW

+---------------------+-------------------------------------------------------+
|ecc-scheme           | implementations for nand_chip->calculate()            |
+---------------------+-------------------------------------------------------+
|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()                              |
+---------------------+-------------------------------------------------------+

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/omap2.c | 51 ++++++++++--------------------------------------
 1 file changed, 10 insertions(+), 41 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index dabea92..26db491 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -141,6 +141,7 @@ static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
 static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
 #endif
+static u8  bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f};
 
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
@@ -1124,45 +1125,6 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch4(struct mtd_info *mtd, const u_char *dat,
-				    u_char *ecc_code)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	unsigned long nsectors, val1, val2;
-	int i;
-
-	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		/* Read hw-computed remainder */
-		val1 = readl(info->reg.gpmc_bch_result0[i]);
-		val2 = readl(info->reg.gpmc_bch_result1[i]);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs; and
-		 * left-justify the resulting polynomial.
-		 */
-		*ecc_code++ = 0x28 ^ ((val2 >> 12) & 0xFF);
-		*ecc_code++ = 0x13 ^ ((val2 >>  4) & 0xFF);
-		*ecc_code++ = 0xcc ^ (((val2 & 0xF) << 4)|((val1 >> 28) & 0xF));
-		*ecc_code++ = 0x39 ^ ((val1 >> 20) & 0xFF);
-		*ecc_code++ = 0x96 ^ ((val1 >> 12) & 0xFF);
-		*ecc_code++ = 0xac ^ ((val1 >> 4) & 0xFF);
-		*ecc_code++ = 0x7f ^ ((val1 & 0xF) << 4);
-	}
-
-	return 0;
-}
-
-/**
  * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes
  * @mtd: MTD device structure
  * @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,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1253,6 +1214,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 			*ecc_code++ = ((bch_val1 >> 8) & 0xFF);
 			*ecc_code++ = (bch_val1 & 0xFF);
 			break;
+		case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
 		case OMAP_ECC_BCH4_CODE_HW:
 			bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
 			bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
@@ -1271,6 +1233,12 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 
 		/* ECC scheme specific syndrome customizations */
 		switch (ecc_opt) {
+		case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+			/* Add constant polynomial to remainder, so that
+			 * ECC of blank pages results in 0x0 on reading back */
+			for (i = 0; i < eccbytes; i++)
+				ecc_calc[i] ^= bch4_polynomial[i];
+			break;
 		case OMAP_ECC_BCH4_CODE_HW:
 			/* Set  8th ECC byte as 0x0 for ROM compatibility */
 			ecc_calc[eccbytes - 1] = 0x0;
@@ -1289,6 +1257,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 	return 0;
 }
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_elm_correct_data - corrects page data area in case error reported
  * @mtd:	MTD device structure
@@ -1823,7 +1792,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
 							(mtd->writesize /
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 4/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 in omap_calculate_ecc_bch
  2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
                   ` (2 preceding siblings ...)
  2014-01-07 13:45 ` [PATCH v5 3/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in omap_calculate_ecc_bch Pekon Gupta
@ 2014-01-07 13:45 ` Pekon Gupta
  2014-01-08  8:08 ` [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Stefan Roese
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2014-01-07 13:45 UTC (permalink / raw)
  To: Brian Norris; +Cc: Stefan Roese, linux-mtd, Pekon Gupta, Felipe Balbi

chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
processing the data passed during Read/Write accesses.
All H/W ECC schemes use GPMC controller for ECC syndrome calculation,but each
ecc-scheme implements its own calback to config, process and fetch ECC syndrome.

This patch merges omap3_calculate_ecc_bch8() into omap_calculate_ecc_bch()
to re-use common code between BCH8_HW and BCH8_HW_DETECTION_SW

+---------------------+-------------------------------------------------------+
|ecc-scheme           | implementations for nand_chip->calculate()            |
+---------------------+-------------------------------------------------------+
|HAM1_ECC             | omap_calculate_ecc()                                  |
+---------------------+-------------------------------------------------------+
|BCH4_HW_DETECTION_SW | omap_calculate_ecc_bch()                              |
|BCH4_HW              | omap_calculate_ecc_bch()                              |
|BCH8_HW_DETECTION_SW | omap3_calculate_ecc_bch8() -> omap_calculate_ecc_bch()|
|BCH8_HW              | omap_calculate_ecc_bch()                              |
+---------------------+-------------------------------------------------------+

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/nand/omap2.c | 59 ++++++++----------------------------------------
 1 file changed, 10 insertions(+), 49 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 26db491..72d5f23 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -142,6 +142,8 @@ static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
 #endif
 static u8  bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f};
+static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
+				0x97, 0x79, 0xe5, 0x24, 0xb5};
 
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
@@ -1123,54 +1125,6 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 }
 #endif
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
-				    u_char *ecc_code)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	unsigned long nsectors, val1, val2, val3, val4;
-	int i;
-
-	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-
-		/* Read hw-computed remainder */
-		val1 = readl(info->reg.gpmc_bch_result0[i]);
-		val2 = readl(info->reg.gpmc_bch_result1[i]);
-		val3 = readl(info->reg.gpmc_bch_result2[i]);
-		val4 = readl(info->reg.gpmc_bch_result3[i]);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs.
-		 */
-		*ecc_code++ = 0xef ^ (val4 & 0xFF);
-		*ecc_code++ = 0x51 ^ ((val3 >> 24) & 0xFF);
-		*ecc_code++ = 0x2e ^ ((val3 >> 16) & 0xFF);
-		*ecc_code++ = 0x09 ^ ((val3 >> 8) & 0xFF);
-		*ecc_code++ = 0xed ^ (val3 & 0xFF);
-		*ecc_code++ = 0x93 ^ ((val2 >> 24) & 0xFF);
-		*ecc_code++ = 0x9a ^ ((val2 >> 16) & 0xFF);
-		*ecc_code++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
-		*ecc_code++ = 0x97 ^ (val2 & 0xFF);
-		*ecc_code++ = 0x79 ^ ((val1 >> 24) & 0xFF);
-		*ecc_code++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
-		*ecc_code++ = 0x24 ^ ((val1 >> 8) & 0xFF);
-		*ecc_code++ = 0xb5 ^ (val1 & 0xFF);
-	}
-
-	return 0;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 /**
  * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1195,6 +1149,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 	for (i = 0; i < nsectors; i++) {
 		ecc_code = ecc_calc;
 		switch (ecc_opt) {
+		case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 		case OMAP_ECC_BCH8_CODE_HW:
 			bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
 			bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
@@ -1243,6 +1198,12 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
 			/* Set  8th ECC byte as 0x0 for ROM compatibility */
 			ecc_calc[eccbytes - 1] = 0x0;
 			break;
+		case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+			/* Add constant polynomial to remainder, so that
+			 * ECC of blank pages results in 0x0 on reading back */
+			for (i = 0; i < eccbytes; i++)
+				ecc_calc[i] ^= bch8_polynomial[i];
+			break;
 		case OMAP_ECC_BCH8_CODE_HW:
 			/* Set 14th ECC byte as 0x0 for ROM compatibility */
 			ecc_calc[eccbytes - 1] = 0x0;
@@ -1862,7 +1823,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
 							(mtd->writesize /
-- 
1.8.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes
  2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
                   ` (3 preceding siblings ...)
  2014-01-07 13:45 ` [PATCH v5 4/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 " Pekon Gupta
@ 2014-01-08  8:08 ` Stefan Roese
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Roese @ 2014-01-08  8:08 UTC (permalink / raw)
  To: Pekon Gupta, Brian Norris; +Cc: linux-mtd, Felipe Balbi

On 07.01.2014 14:45, Pekon Gupta wrote:
> This patch series is split version of earlier patch:
> http://lists.infradead.org/pipermail/linux-mtd/2013-November/050240.html
> 
> chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
> processing the data passed during Read/Write accesses.
> Though all H/W ECC schemes in OMAP NAND use GPMC controller for ECC calculation
> But each of them implements its own callback to process and fetch ECC syndrome.
> 
> This patch tries to merge common code for different BCHx_ECC schemes into single
> omap_calculate_ecc_bch(). This imporves scalability for future ecc-schemes.
>  +----------------------+----------------------------+
>  | ecc-scheme           | nand_chip->ecc.calculate   |
>  +----------------------+----------------------------+
>  | HAM1_ECC             | omap_calculate_ecc()       |
>  | BCH4_HW_DETECTION_SW | omap3_calculate_ecc_bch4() |
>  | BCH4_HW              | omap3_calculate_ecc_bch()  |
>  | BCH8_HW_DETECTION_SW | omap3_calculate_ecc_bch8() |
>  | BCH8_HW              | omap3_calculate_ecc_bch()  |
>  +----------------------+----------------------------+
> 
> 
> Pekon Gupta (4):
>   mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to
>     omap_calculate_ecc_bch
>   mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for
>     BCHx_HW ecc-scheme
>   mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in
>     omap_calculate_ecc_bch
>   mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 in
>     omap_calculate_ecc_bch
> 
>  drivers/mtd/nand/omap2.c | 187 +++++++++++++++--------------------------------
>  1 file changed, 60 insertions(+), 127 deletions(-)

Thanks Pekon. This works just fine on our AM335x based board. So, for
the complete patch series:

Tested-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-01-08  8:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-07 13:45 [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Pekon Gupta
2014-01-07 13:45 ` [PATCH v5 1/4] mtd: nand: omap: ecc.calculate: rename omap3_calculate_ecc_bch to omap_calculate_ecc_bch Pekon Gupta
2014-01-07 13:45 ` [PATCH v5 2/4] mtd: nand: omap: ecc.calculate: refactor omap_calculate_ecc_bch for BCHx_HW ecc-scheme Pekon Gupta
2014-01-07 13:45 ` [PATCH v5 3/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch4 in omap_calculate_ecc_bch Pekon Gupta
2014-01-07 13:45 ` [PATCH v5 4/4] mtd: nand: omap: ecc.calculate: merge omap3_calculate_ecc_bch8 " Pekon Gupta
2014-01-08  8:08 ` [PATCH v5 0/4] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes Stefan Roese

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).