devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC
@ 2013-07-17 19:52 Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 1/4] mtd: nand: omap: add support for BCH16_ECC - DT updates Pekon Gupta
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Pekon Gupta @ 2013-07-17 19:52 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: dedekind1, tony, benoit.cousson, avinashphilipk, balbi,
	devicetree-discuss, Pekon Gupta

This patch series add support of BCH16_ECC scheme.
As BCH16_ECC scheme generates 26bytes of ECC syndrome per 512B data,
hence this scheme is usable only for NAND devices having 4K or above
page-size, as their OOB/spare area has enough space to accomodate ECC.

This patch series is applicable over an above following series:
[1] [Patch] mtd:nand:omap2: clean-up of supported ECC schemes 
 http://lists.infradead.org/pipermail/linux-mtd/2013-July/047530.html
[2] [Patch] optimize and clean-up of OMAP NAND and ELM driver
 http://lists.infradead.org/pipermail/linux-mtd/2013-July/047538.html

Also this BCH16_ECC patch series is sparsely tested, due to limited
availability of boards with 4K/224NAND, so request the users to test
the mentioned series, and provide Tested-by.


Pekon Gupta (4):
  mtd: nand: omap: add support for BCH16_ECC - DT updates
  mtd: nand: omap: add support for BCH16_ECC - ELM driver updates
  mtd: nand: omap: add support for BCH16_ECC - GPMC driver updates
  mtd: nand: omap: add support for BCH16_ECC - NAND driver updates

 .../devicetree/bindings/mtd/gpmc-nand.txt          |   7 ++
 arch/arm/mach-omap2/gpmc.c                         |  22 +++--
 drivers/mtd/devices/elm.c                          |  29 ++++++
 drivers/mtd/nand/omap2.c                           | 104 +++++++++++++++++++--
 include/linux/platform_data/elm.h                  |   8 +-
 include/linux/platform_data/mtd-nand-omap2.h       |   7 +-
 6 files changed, 155 insertions(+), 22 deletions(-)

-- 
1.8.1


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

* [PATCH v1 1/4] mtd: nand: omap: add support for BCH16_ECC - DT updates
  2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
@ 2013-07-17 19:52 ` Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 2/4] mtd: nand: omap: add support for BCH16_ECC - ELM driver updates Pekon Gupta
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2013-07-17 19:52 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: dedekind1, tony, benoit.cousson, avinashphilipk, balbi,
	devicetree-discuss, Pekon Gupta

With increase in NAND flash densities occurence of bit-flips has increased.
Thus stronger ECC schemes are required for detecting and correcting multiple
simultaneous bit-flips in same NAND page. But stronger ECC schemes have large
ECC syndrome which require more space in OOB/Spare.
This patch add support for BCH16_ECC:
(a) BCH16_ECC can correct 16 bit-flips per 512Bytes of data.
(b) BCH16_ECC generates 26-bytes of ECC syndrome / 512B.

Due to (b) this scheme can only be used with NAND devices which have enough
OOB to satisfy following equation:
OOBsize per page >= 26 * (page-size / 512)

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 7 +++++++
 include/linux/platform_data/mtd-nand-omap2.h        | 7 ++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index d307c67..017d818 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -66,6 +66,13 @@ Optional properties:
 					* depends on CONFIG_MTD_NAND_OMAP_BCH
 					* requires <elm_id> to be specified
 
+	"bch16_code_hw"             	16-bit BCH ECC
+					- ECC calculation in hardware
+					- Error detection in hardware
+					- ECC layout compatible with ROM code
+					* depends on CONFIG_MTD_NAND_OMAP_BCH
+					* requires <elm_id> to be specified
+
 
  - elm_id:			Specifies elm device node. This is required to
 				support some BCH ECC schemes mentioned above.
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 9fcee61..50a6413 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -37,7 +37,9 @@ enum omap_ecc {
 	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
 	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
 	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
-	OMAP_ECC_BCH8_CODE_HW
+	OMAP_ECC_BCH8_CODE_HW,
+	/* 16-bit ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH16_CODE_HW
 };
 
 struct gpmc_nand_regs {
@@ -57,6 +59,9 @@ struct gpmc_nand_regs {
 	void __iomem	*gpmc_bch_result1[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result2[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result3[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result4[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result5[GPMC_BCH_NUM_REMAINDER];
+	void __iomem	*gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER];
 };
 
 struct omap_nand_platform_data {
-- 
1.8.1


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

* [PATCH v1 2/4] mtd: nand: omap: add support for BCH16_ECC - ELM driver updates
  2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 1/4] mtd: nand: omap: add support for BCH16_ECC - DT updates Pekon Gupta
@ 2013-07-17 19:52 ` Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 3/4] mtd: nand: omap: add support for BCH16_ECC - GPMC " Pekon Gupta
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2013-07-17 19:52 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: dedekind1, tony, benoit.cousson, avinashphilipk, balbi,
	devicetree-discuss, Pekon Gupta

With increase in NAND flash densities occurence of bit-flips has increased.
Thus stronger ECC schemes are required for detecting and correcting multiple
simultaneous bit-flips in same NAND page. But stronger ECC schemes have large
ECC syndrome which require more space in OOB/Spare.
This patch add support for BCH16_ECC:
(a) BCH16_ECC can correct 16 bit-flips per 512Bytes of data.
(b) BCH16_ECC generates 26-bytes of ECC syndrome / 512B.

Due to (b) this scheme can only be used with NAND devices which have enough
OOB to satisfy following equation:
OOBsize per page >= 26 * (page-size / 512)

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 drivers/mtd/devices/elm.c         | 29 +++++++++++++++++++++++++++++
 include/linux/platform_data/elm.h |  8 +-------
 2 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
index fca436e..f50f36b 100644
--- a/drivers/mtd/devices/elm.c
+++ b/drivers/mtd/devices/elm.c
@@ -217,6 +217,35 @@ static void elm_load_syndrome(struct elm_info *info,
 				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_3 +
 						 offset), cpu_to_le32(val));
 				break;
+			case BCH16_ECC:
+				val =	*(ecc + 25) << 0  | *(ecc + 24) <<  8 |
+					*(ecc + 23) << 16 | *(ecc + 22) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc + 21) <<  0 | *(ecc + 20) <<  8 |
+					*(ecc + 19) << 16 | *(ecc + 18) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc + 17) <<  0 | *(ecc + 16) <<  8 |
+					*(ecc + 15) << 16 | *(ecc + 14) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_2 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc + 13) <<  0 | *(ecc + 12) <<  8 |
+					*(ecc + 11) << 16 | *(ecc + 10) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_3 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  9) <<  0 | *(ecc +  8) <<  8 |
+					*(ecc +  7) << 16 | *(ecc +  6) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_4 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  5) <<  0 | *(ecc +  4) <<  8 |
+					*(ecc +  3) << 16 | *(ecc +  2) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_5 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  1) <<  0 | *(ecc +  0) <<  8;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_6 +
+						 offset), cpu_to_le32(val));
+				break;
 			}
 		}
 	}
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
index d16465b..18b37d8 100644
--- a/include/linux/platform_data/elm.h
+++ b/include/linux/platform_data/elm.h
@@ -21,19 +21,13 @@
 enum bch_ecc {
 	BCH4_ECC = 0,
 	BCH8_ECC,
+	BCH16_ECC
 };
 
 /* ELM support 8 error syndrome process */
 #define ERROR_VECTOR_MAX		8
 #define ELM_MAX_DETECTABLE_ERRORS	16
 
-#define BCH8_ECC_OOB_BYTES		13
-#define BCH4_ECC_OOB_BYTES		7
-/* RBL requires 14 byte even though BCH8 uses only 13 byte */
-#define BCH8_SIZE			(BCH8_ECC_OOB_BYTES + 1)
-/* Uses 1 extra byte to handle erased pages */
-#define BCH4_SIZE			(BCH4_ECC_OOB_BYTES + 1)
-
 /**
  * struct elm_errorvec - error vector for elm
  * @error_reported:		set true for vectors error is reported
-- 
1.8.1


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

* [PATCH v1 3/4] mtd: nand: omap: add support for BCH16_ECC - GPMC driver updates
  2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 1/4] mtd: nand: omap: add support for BCH16_ECC - DT updates Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 2/4] mtd: nand: omap: add support for BCH16_ECC - ELM driver updates Pekon Gupta
@ 2013-07-17 19:52 ` Pekon Gupta
  2013-07-17 19:52 ` [PATCH v1 4/4] mtd: nand: omap: add support for BCH16_ECC - NAND " Pekon Gupta
  2013-08-02 15:56 ` [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Artem Bityutskiy
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2013-07-17 19:52 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: dedekind1, tony, benoit.cousson, avinashphilipk, balbi,
	devicetree-discuss, Pekon Gupta

With increase in NAND flash densities occurence of bit-flips has increased.
Thus stronger ECC schemes are required for detecting and correcting multiple
simultaneous bit-flips in same NAND page. But stronger ECC schemes have large
ECC syndrome which require more space in OOB/Spare.
This patch add support for BCH16_ECC:
(a) BCH16_ECC can correct 16 bit-flips per 512Bytes of data.
(b) BCH16_ECC generates 26-bytes of ECC syndrome / 512B.

Due to (b) this scheme can only be used with NAND devices which have enough
OOB to satisfy following equation:
OOBsize per page >= 26 * (page-size / 512)

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 arch/arm/mach-omap2/gpmc.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e19de21..0d5639e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -68,6 +68,9 @@
 #define	GPMC_ECC_BCH_RESULT_1	0x244	/* not available on OMAP2 */
 #define	GPMC_ECC_BCH_RESULT_2	0x248	/* not available on OMAP2 */
 #define	GPMC_ECC_BCH_RESULT_3	0x24c	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_4	0x300	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_5	0x304	/* not available on OMAP2 */
+#define	GPMC_ECC_BCH_RESULT_6	0x308	/* not available on OMAP2 */
 
 /* GPMC ECC control settings */
 #define GPMC_ECC_CTRL_ECCCLEAR		0x100
@@ -659,13 +662,19 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 
 	for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
 		reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
-					   GPMC_BCH_SIZE * i;
+					   (GPMC_BCH_SIZE * i);
 		reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
-					   GPMC_BCH_SIZE * i;
+					   (GPMC_BCH_SIZE * i);
 		reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
-					   GPMC_BCH_SIZE * i;
+					   (GPMC_BCH_SIZE * i);
 		reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
-					   GPMC_BCH_SIZE * i;
+					   (GPMC_BCH_SIZE * i);
+		reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 +
+					   (GPMC_BCH_SIZE * i);
+		reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 +
+					   (GPMC_BCH_SIZE * i);
+		reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 +
+					   (GPMC_BCH_SIZE * i);
 	}
 }
 
@@ -1348,7 +1357,8 @@ static const char * const nand_ecc_opts[] = {
 	[OMAP_ECC_BCH4_CODE_HW]			= "bch4_code_hw",
 	[OMAP_ECC_BCH4_CODE_HW_DETECTION_SW]	= "bch4_code_hw_detection_sw",
 	[OMAP_ECC_BCH8_CODE_HW]			= "bch8_code_hw",
-	[OMAP_ECC_BCH8_CODE_HW_DETECTION_SW]	= "bch8_code_hw_detection_sw"
+	[OMAP_ECC_BCH8_CODE_HW_DETECTION_SW]	= "bch8_code_hw_detection_sw",
+	[OMAP_ECC_BCH16_CODE_HW]		= "bch16_code_hw"
 };
 
 static const char * const nand_xfer_types[] = {
@@ -1389,7 +1399,7 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
-			if (!strcasecmp(s, nand_xfer_types[val])) {
+			if (!strcmp(s, nand_xfer_types[val])) {
 				gpmc_nand_data->xfer_type = val;
 				break;
 			}
-- 
1.8.1


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

* [PATCH v1 4/4] mtd: nand: omap: add support for BCH16_ECC - NAND driver updates
  2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
                   ` (2 preceding siblings ...)
  2013-07-17 19:52 ` [PATCH v1 3/4] mtd: nand: omap: add support for BCH16_ECC - GPMC " Pekon Gupta
@ 2013-07-17 19:52 ` Pekon Gupta
  2013-08-02 15:56 ` [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Artem Bityutskiy
  4 siblings, 0 replies; 6+ messages in thread
From: Pekon Gupta @ 2013-07-17 19:52 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: dedekind1, tony, benoit.cousson, avinashphilipk, balbi,
	devicetree-discuss, Pekon Gupta

With increase in NAND flash densities occurence of bit-flips has increased.
Thus stronger ECC schemes are required for detecting and correcting multiple
simultaneous bit-flips in same NAND page. But stronger ECC schemes have large
ECC syndrome which require more space in OOB/Spare.
This patch add support for BCH16_ECC:
(a) BCH16_ECC can correct 16 bit-flips per 512Bytes of data.
(b) BCH16_ECC generates 26-bytes of ECC syndrome / 512B.

Due to (b) this scheme can only be used with NAND devices which have enough
OOB to satisfy following equation:
OOBsize per page >= 26 * (page-size / 512)

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

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c2c3c6bb..a0cf487 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -130,9 +130,13 @@
 #define BADBLOCK_MARKER_LENGTH		0x2
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
-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};
+static u_char bch4_vector[]  = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
+static u_char bch8_vector[]  = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
+				0xac, 0x6b, 0xff, 0x99, 0x7b};
+static u_char bch16_vector[] = {0xf5, 0x24, 0x1c, 0xd0, 0x61, 0xb3, 0xf1, 0x55,
+				0x2e, 0x2c, 0x86, 0xa3, 0xed, 0x36, 0x1b, 0x78,
+				0x48, 0x76, 0xa9, 0x3b, 0x97, 0xd1, 0x7a, 0x93,
+				0x07, 0x0e};
 #endif
 static u8  bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f};
 static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
@@ -1066,6 +1070,19 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
 			eccsize1 = 28; /* OOB bits in nibbles per sector */
 		}
 		break;
+	case OMAP_ECC_BCH16_CODE_HW:
+		ecc_algo = 0x1;
+		bch_type = 0x2;
+		if (mode == GPMC_ECC_READ) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 52; /* ECC bits in nibbles per sector */
+			eccsize1 = 0;  /* non-ECC bits in nibbles per sector */
+		} else if (mode == GPMC_ECC_WRITE) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 0;  /* extra bits in nibbles per sector */
+			eccsize1 = 52; /* OOB bits in nibbles per sector */
+		}
+		break;
 	default:
 		pr_err("selected ECC scheme not supported or not enabled\n");
 	}
@@ -1159,6 +1176,41 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
 			*(ecc_ptr++) = ((val >>  8) & 0xFF);
 			*(ecc_ptr++) = ((val >>  0) & 0xFF);
 			break;
+		case OMAP_ECC_BCH16_CODE_HW:
+			val = readl(gpmc_regs->gpmc_bch_result6[i]);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result5[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result4[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result3[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result2[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result1[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result0[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			break;
 		default:
 			return -EINVAL;
 		}
@@ -1184,6 +1236,8 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
 		case OMAP_ECC_BCH8_CODE_HW:
 			*(ecc_ptr++) = 0x00;
 			break;
+		case OMAP_ECC_BCH16_CODE_HW:
+			break;
 		}
 		/* update pointer to next sector */
 		ecc_calc += eccbytes;
@@ -1225,7 +1279,6 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	/* Initialize elm error vector to zero */
 	memset(err_vec, 0, sizeof(err_vec));
-
 	for (i = 0; i < eccsteps ; i++) {
 		flag_read_ecc = 0;
 		ecc = calc_ecc + (i * eccbytes);
@@ -1239,12 +1292,16 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 		/* check if its a erased-page */
 		if (flag_read_ecc) {
 			switch (ecc_opt) {
+			case OMAP_ECC_BCH4_CODE_HW:
+				if (memcmp(ecc, bch4_vector, eccbytes))
+					err_vec[i].error_reported = true;
+				break;
 			case OMAP_ECC_BCH8_CODE_HW:
 				if (memcmp(ecc, bch8_vector, eccbytes))
 					err_vec[i].error_reported = true;
 				break;
-			case OMAP_ECC_BCH4_CODE_HW:
-				if (memcmp(ecc, bch4_vector, eccbytes))
+			case OMAP_ECC_BCH16_CODE_HW:
+				if (memcmp(ecc, bch16_vector, eccbytes))
 					err_vec[i].error_reported = true;
 				break;
 			default:
@@ -1282,6 +1339,10 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 							(eccbytes - 1);
 					pos = err_vec[i].error_loc[j];
 					break;
+				case OMAP_ECC_BCH16_CODE_HW:
+					error_max = SECTOR_BYTES + eccbytes;
+					pos = err_vec[i].error_loc[j];
+					break;
 				default:
 					return -EINVAL;
 				}
@@ -1757,6 +1818,33 @@ static int omap_nand_probe(struct platform_device *pdev)
 						omap_oobinfo.eccbytes;
 		goto custom_ecc_layout;
 #endif
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	case OMAP_ECC_BCH16_CODE_HW:
+		pr_info("using OMAP_ECC_BCH16_CODE_HW ECC scheme\n");
+		chip->ecc.mode		= NAND_ECC_HW;
+		chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		chip->ecc.bytes		= 26;
+		chip->ecc.strength	= 16;
+		chip->ecc.hwctl		= omap_enable_hwecc;
+		chip->ecc.correct	= omap_elm_correct_data;
+		chip->ecc.calculate	= omap_calculate_ecc_bch;
+		chip->ecc.read_page	= omap_read_page_bch;
+		chip->ecc.write_page	= omap_write_page_bch;
+		/* ELM H/W engine is used for locating errors */
+		if (is_elm_present(info, BCH16_ECC) < 0) {
+			pr_err("ELM module not detected, required for ECC\n");
+			err = -EINVAL;
+			goto out_release_mem_region;
+		}
+		/* define custom ECC layout */
+		omap_oobinfo.eccbytes	= chip->ecc.bytes *
+					   (mtd->writesize / chip->ecc.size);
+		omap_oobinfo.eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		omap_oobinfo.oobfree->offset = omap_oobinfo.eccpos[0] +
+						omap_oobinfo.eccbytes;
+		goto custom_ecc_layout;
+#endif
 	default:
 		pr_err("%s: selected ECC scheme not supported or not enabled",
 				DRIVER_NAME);
@@ -1777,8 +1865,8 @@ custom_ecc_layout:
 	/* check if NAND OOBSIZE meets ECC scheme requirement */
 	if (mtd->oobsize < (omap_oobinfo.eccbytes +
 					BADBLOCK_MARKER_LENGTH)) {
-		pr_err("not enough OOB bytes required = %d, available=%d\n",
-		       mtd->oobsize, omap_oobinfo.eccbytes);
+		pr_err("%s: not enough OOB bytes available=%d, required=%d\n",
+			DRIVER_NAME, mtd->oobsize, omap_oobinfo.eccbytes);
 		err = -EINVAL;
 		goto out_release_mem_region;
 	}
-- 
1.8.1


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

* Re: [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC
  2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
                   ` (3 preceding siblings ...)
  2013-07-17 19:52 ` [PATCH v1 4/4] mtd: nand: omap: add support for BCH16_ECC - NAND " Pekon Gupta
@ 2013-08-02 15:56 ` Artem Bityutskiy
  4 siblings, 0 replies; 6+ messages in thread
From: Artem Bityutskiy @ 2013-08-02 15:56 UTC (permalink / raw)
  To: Pekon Gupta
  Cc: linux-mtd, linux-omap, tony, benoit.cousson, avinashphilipk,
	balbi, devicetree-discuss

On Thu, 2013-07-18 at 01:22 +0530, Pekon Gupta wrote:
> This patch series add support of BCH16_ECC scheme.
> As BCH16_ECC scheme generates 26bytes of ECC syndrome per 512B data,
> hence this scheme is usable only for NAND devices having 4K or above
> page-size, as their OOB/spare area has enough space to accomodate ECC.
> 
> This patch series is applicable over an above following series:
> [1] [Patch] mtd:nand:omap2: clean-up of supported ECC schemes 
>  http://lists.infradead.org/pipermail/linux-mtd/2013-July/047530.html
> [2] [Patch] optimize and clean-up of OMAP NAND and ELM driver
>  http://lists.infradead.org/pipermail/linux-mtd/2013-July/047538.html
> 
> Also this BCH16_ECC patch series is sparsely tested, due to limited
> availability of boards with 4K/224NAND, so request the users to test
> the mentioned series, and provide Tested-by.

I wonder if anyone in the list could help reviewing this?

-- 
Best Regards,
Artem Bityutskiy


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

end of thread, other threads:[~2013-08-02 15:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-17 19:52 [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Pekon Gupta
2013-07-17 19:52 ` [PATCH v1 1/4] mtd: nand: omap: add support for BCH16_ECC - DT updates Pekon Gupta
2013-07-17 19:52 ` [PATCH v1 2/4] mtd: nand: omap: add support for BCH16_ECC - ELM driver updates Pekon Gupta
2013-07-17 19:52 ` [PATCH v1 3/4] mtd: nand: omap: add support for BCH16_ECC - GPMC " Pekon Gupta
2013-07-17 19:52 ` [PATCH v1 4/4] mtd: nand: omap: add support for BCH16_ECC - NAND " Pekon Gupta
2013-08-02 15:56 ` [PATCH v1 0/4] mtd: nand: omap: add support for BCH16_ECC Artem Bityutskiy

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).