public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver
@ 2013-08-29 10:56 Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform Pekon Gupta
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

*changes in v3*
[PATCH 1/5] (complete change) 
	- ecc-scheme is selection is controller by s/w, not CONFIG_NAND_xx
	- added omap_select_ecc_scheme(), as common function to handle all
	  ecc-scheme related configurations for both board_nand_init() &
	  omap_nand_switch_ecc().
	- removed un-used defines from asm/arch-am33xx/omap_gpmc.h
	- updated doc/REAME.nand
[PATCH 2/5] removed un-used defines from asm/omap_gpmc.h
[PATCH 3/5] removed omap_calculate_ecc_bch_sw() and omap_calculate_ecc()
		and merged their logic into omap_calculate_ecc_bch()
[PATCH 4/5] updated return error-code in-case of invalid conditions
[PATCH 5/5] (new) for board/ti/am335x/README

*changes in v2*
- added documentation for CONFIG_NAND_OMAP_xx in doc/README.nand
- added CONFIG_BCH along with CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
  to include software library lib/bch.c
- fixed board_nand_init() and omap_enable_hwecc()

*original v1*
This patch series updates BCH8_ECC schemes in mtd/nand/omap_gpmc.c driver
- adds scalability for higher ECC schemes in future.
- removes CONFIG_AM335x and it makes it generic for all platforms.
- optimizes read_data paths

Pekon Gupta (5):
[PATCH 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform
[PATCH 2/5] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes
[PATCH 3/5] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes
[PATCH 4/5] mtd: nand: omap: optimized chip->ecc.correct() for H/W ECC schemes
[PATCH 5/5]  board/ti/am335x/README: update for NAND boot

 arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  48 +-
 arch/arm/include/asm/omap_gpmc.h             |   7 -
 board/ti/am335x/README                       |  59 +-
 doc/README.nand                              |  13 +
 drivers/mtd/nand/omap_gpmc.c                 | 796 +++++++++++----------------
 include/configs/am335x_evm.h                 |   2 +
 6 files changed, 383 insertions(+), 542 deletions(-)

-- 
1.8.1

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

* [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
@ 2013-08-29 10:56 ` Pekon Gupta
  2013-08-29 15:01   ` Tom Rini
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 2/5] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes Pekon Gupta
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

BCH8_ECC scheme implemented in omap_gpmc.c driver has following favours
+-----------------------------------+-----------------+-----------------+
|ECC Scheme                         | ECC Calculation | Error Detection |
+-----------------------------------+-----------------+-----------------+
|OMAP_ECC_BCH8_CODE_HW              |GPMC             |ELM H/W engine   |
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW |GPMC             |S/W BCH library  |
+-----------------------------------+-----------------+-----------------+

Current implementation limits the BCH8_CODE_HW only for AM33xx device family.
(using CONFIG_AM33XX). However, other SoC families (like TI81xx) also have
ELM hardware module, and can support ECC error detection using ELM.

This patch
- removes CONFIG_AM33xx
	Thus this driver can be reused by all devices having ELM h/w engine.
- adds omap_select_ecc_scheme()
	A common function to handle ecc-scheme related configurations. This
	can be used both during device-probe and via user-space u-boot commads
	to change ecc-scheme.
- adds CONFIG_BCH
	S/W library (lib/bch.c) required by OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
  	is enabled by CONFIG_BCH.
- adds CONFIG_SYS_NAND_ECCSCHEME (new)
	user specified CONFIG to determine ecc-scheme used during boot
- adds CONFIG_SYS_NAND_ONFI_DETECTION
	enable auto-detection of ONFI compliant devices

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  48 +----
 doc/README.nand                              |  13 ++
 drivers/mtd/nand/omap_gpmc.c                 | 291 ++++++++++++++++-----------
 include/configs/am335x_evm.h                 |   2 +
 4 files changed, 195 insertions(+), 159 deletions(-)

diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
index 00ad1d0..69982c1 100644
--- a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
+++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
@@ -7,42 +7,16 @@
 #ifndef __ASM_ARCH_OMAP_GPMC_H
 #define __ASM_ARCH_OMAP_GPMC_H
 
-/* These GPMC_NAND_HW_BCHx_ECC_LAYOUT defines are based on AM33xx ELM */
-#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\
-	.eccbytes = 32,\
-	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
-				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
-				28, 29, 30, 31, 32, 33},\
-	.oobfree = {\
-		{.offset = 34,\
-		 .length = 30 } } \
-}
+enum omap_ecc {
+	/* 1-bit  ECC calculation by Software, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_SW = 0,
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	/* ECC layout compatible to legacy ROMCODE. */
+	OMAP_ECC_HAM1_CODE_HW_ROMCODE,
+	/* 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
+};
 
-#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\
-	.eccbytes = 56,\
-	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
-				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
-				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
-				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
-				52, 53, 54, 55, 56, 57},\
-	.oobfree = {\
-		{.offset = 58,\
-		 .length = 6 } } \
-}
-
-#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\
-	.eccbytes = 104,\
-	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
-				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
-				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
-				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
-				52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
-				64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
-				76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
-				88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
-				100, 101, 102, 103, 104, 105},\
-	.oobfree = {\
-		{.offset = 106,\
-		 .length = 8 } } \
-}
 #endif /* __ASM_ARCH_OMAP_GPMC_H */
diff --git a/doc/README.nand b/doc/README.nand
index 913e9b5..f72f618 100644
--- a/doc/README.nand
+++ b/doc/README.nand
@@ -169,6 +169,19 @@ Configuration Options:
       Please convert your driver even if you don't need the extra
       flexibility, so that one day we can eliminate the old mechanism.
 
+   CONFIG_SYS_NAND_ONFI_DETECTION
+	Enables detection of ONFI compliant devices during probe.
+	And fetching device parameters flashed on device, by parsing
+	ONFI parameter page.
+
+   CONFIG_BCH
+	Enables software based BCH ECC algorithm present in lib/bch.c
+	This is used by SoC platforms which do not have in-build hardware
+	engine to calculate and correct BCH ECC.
+
+   CONFIG_SYS_NAND_ECCSCHEME
+	specifies which ECC scheme to use.
+
 NOTE:
 =====
 
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index ec1787f..f97e862 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -15,15 +15,13 @@
 #include <linux/bch.h>
 #include <linux/compiler.h>
 #include <nand.h>
-#ifdef CONFIG_AM33XX
 #include <asm/arch/elm.h>
-#endif
+
+#define BADBLOCK_MARKER_LENGTH	0x2
+#define SECTOR_BYTES		512
 
 static uint8_t cs;
-static __maybe_unused struct nand_ecclayout hw_nand_oob =
-	GPMC_NAND_HW_ECC_LAYOUT;
-static __maybe_unused struct nand_ecclayout hw_bch8_nand_oob =
-	GPMC_NAND_HW_BCH8_ECC_LAYOUT;
+static __maybe_unused struct nand_ecclayout omap_ecclayout;
 
 /*
  * omap_nand_hwcontrol - Set the address pointers corretly for the
@@ -233,6 +231,7 @@ struct nand_bch_priv {
 	uint8_t type;
 	uint8_t nibbles;
 	struct bch_control *control;
+	enum omap_ecc ecc_scheme;
 };
 
 /* bch types */
@@ -274,17 +273,15 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
 {
 	uint32_t val;
 	uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
-#ifdef CONFIG_AM33XX
 	uint32_t unused_length = 0;
-#endif
 	uint32_t wr_mode = BCH_WRAPMODE_6;
 	struct nand_bch_priv *bch = chip->priv;
 
 	/* Clear the ecc result registers, select ecc reg as 1 */
 	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
 
-#ifdef CONFIG_AM33XX
-	wr_mode = BCH_WRAPMODE_1;
+	if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
+		wr_mode = BCH_WRAPMODE_1;
 
 	switch (bch->nibbles) {
 	case ECC_BCH4_NIBBLES:
@@ -320,7 +317,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
 		val |= (unused_length << 22);
 		break;
 	}
-#else
+	} else {
 	/*
 	 * This ecc_size_config setting is for BCH sw library.
 	 *
@@ -333,7 +330,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
 	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
 	 */
 	val = (32 << 22) | (0 << 12);
-#endif
+	}
 	/* ecc size configuration */
 	writel(val, &gpmc_cfg->ecc_size_config);
 
@@ -376,9 +373,8 @@ static void __maybe_unused omap_ecc_disable(struct mtd_info *mtd)
 }
 
 /*
- * BCH8 support (needs ELM and thus AM33xx-only)
+ * BCH support using ELM module
  */
-#ifdef CONFIG_AM33XX
 /*
  * omap_read_bch8_result - Read BCH result for BCH8 level
  *
@@ -631,20 +627,19 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 	return 0;
 }
-#endif /* CONFIG_AM33XX */
 
 /*
  * OMAP3 BCH8 support (with BCH library)
  */
-#ifdef CONFIG_NAND_OMAP_BCH8
+#ifdef CONFIG_BCH
 /*
- *  omap_calculate_ecc_bch - Read BCH ECC result
+ *  omap_calculate_ecc_bch_sw - Read BCH ECC result
  *
  *  @mtd:	MTD device structure
  *  @dat:	The pointer to data on which ecc is computed (unused here)
  *  @ecc:	The ECC output buffer
  */
-static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
+static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd, const uint8_t *dat,
 				uint8_t *ecc)
 {
 	int ret = 0;
@@ -689,13 +684,13 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
 }
 
 /**
- * omap_correct_data_bch - Decode received data and correct errors
+ * omap_correct_data_bch_sw - Decode received data and correct errors
  * @mtd: MTD device structure
  * @data: page data
  * @read_ecc: ecc read from nand flash
  * @calc_ecc: ecc read from HW ECC registers
  */
-static int omap_correct_data_bch(struct mtd_info *mtd, u_char *data,
+static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
 				 u_char *read_ecc, u_char *calc_ecc)
 {
 	int i, count;
@@ -752,7 +747,120 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
 		chip_priv->control = NULL;
 	}
 }
-#endif /* CONFIG_NAND_OMAP_BCH8 */
+#endif /* CONFIG_BCH */
+
+/**
+ * omap_select_ecc_scheme - configures driver for particular ecc-scheme
+ * @nand: NAND chip device structure
+ * @ecc_scheme: ecc scheme to configure
+ * @pagesize: number of main-area bytes per page of NAND device
+ * @oobsize: number of OOB/spare bytes per page of NAND device
+ */
+static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
+		unsigned int pagesize, unsigned int oobsize) {
+	struct nand_bch_priv	*bch		= nand->priv;
+	struct nand_ecclayout	*ecclayout	= nand->ecc.layout;
+	int i;
+
+	/* Reset ecc interface */
+	nand->ecc.mode			= NAND_ECC_NONE;
+	nand->ecc.read_page		= NULL;
+	nand->ecc.write_page		= NULL;
+	nand->ecc.read_oob		= NULL;
+	nand->ecc.write_oob		= NULL;
+	nand->ecc.hwctl			= NULL;
+	nand->ecc.correct		= NULL;
+	nand->ecc.calculate		= NULL;
+
+	switch (ecc_scheme) {
+	case OMAP_ECC_HAM1_CODE_SW:
+		printf("nand: selected OMAP_ECC_HAM1_CODE_SW\n");
+		nand->ecc.mode		= NAND_ECC_SOFT;
+		nand->ecc.layout	= NULL;
+		nand->ecc.size		= 0;
+		nand->ecc.strength	= 1;
+		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_SW;
+		break;
+	case OMAP_ECC_HAM1_CODE_HW_ROMCODE:
+		printf("nand: selected OMAP_ECC_HAM1_CODE_HW_ROMCODE\n");
+		nand->ecc.mode		= NAND_ECC_HW;
+		nand->ecc.strength	= 1;
+		nand->ecc.size		= 512;
+		nand->ecc.bytes		= 3;
+		nand->ecc.hwctl		= omap_enable_hwecc;
+		nand->ecc.correct	= omap_correct_data;
+		nand->ecc.calculate	= omap_calculate_ecc;
+		/* define ecc-layout */
+		ecclayout->eccbytes	= nand->ecc.bytes *
+						(pagesize / SECTOR_BYTES);
+		for (i = 0; i < ecclayout->eccbytes; i++)
+			ecclayout->eccpos[i] = i +
+						BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree[0].offset = i +
+						BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
+						BADBLOCK_MARKER_LENGTH;
+		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_HW_ROMCODE;
+		break;
+#ifdef CONFIG_BCH
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+		printf("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand->ecc.mode		= NAND_ECC_HW;
+		nand->ecc.strength	= 8;
+		nand->ecc.size		= 512;
+		nand->ecc.bytes		= 13;
+		nand->ecc.hwctl		= omap_enable_ecc_bch;
+		nand->ecc.correct	= omap_correct_data_bch_sw;
+		nand->ecc.calculate	= omap_calculate_ecc_bch_sw;
+		/* BCH SW library is used for error detection */
+		bch_priv.control	= init_bch(13, 8, 0x201b);
+		if (!bch_priv.control) {
+			printf("nand: err: could not init_bch()\n");
+			return -ENODEV;
+		}
+		/* define ecc-layout */
+		ecclayout->eccbytes	= nand->ecc.bytes *
+						(pagesize / SECTOR_BYTES);
+		for (i = 0; i < ecclayout->eccbytes; i++)
+			ecclayout->eccpos[i] = i + (oobsize -
+						ecclayout->eccbytes);
+		ecclayout->oobfree[0].offset = BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
+						BADBLOCK_MARKER_LENGTH;
+		omap_hwecc_init_bch(nand, NAND_ECC_READ);
+		bch->ecc_scheme		= OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+		break;
+#endif
+	case OMAP_ECC_BCH8_CODE_HW:
+		printf("nand: selected OMAP_ECC_BCH8_CODE_HW\n");
+		nand->ecc.mode		= NAND_ECC_HW;
+		nand->ecc.strength	= 8;
+		nand->ecc.size		= 512;
+		nand->ecc.bytes		= 14;
+		nand->ecc.read_page	= omap_read_page_bch;
+		nand->ecc.hwctl		= omap_enable_ecc_bch;
+		nand->ecc.correct	= omap_correct_data_bch;
+		nand->ecc.calculate	= omap_calculate_ecc_bch;
+		/* ELM is used for ECC error detection */
+		elm_init();
+		/* define ecc-layout */
+		ecclayout->eccbytes	= nand->ecc.bytes *
+						(pagesize / SECTOR_BYTES);
+		for (i = 0; i < ecclayout->eccbytes; i++)
+			ecclayout->eccpos[i] = i +
+						BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree[0].offset = i +
+						BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
+						BADBLOCK_MARKER_LENGTH;
+		bch->ecc_scheme		= OMAP_ECC_BCH8_CODE_HW;
+		break;
+	default:
+		printf("nand: error: ecc scheme not enabled or supported\n");
+		return -EINVAL;
+	}
+	return 0;
+}
 
 #ifndef CONFIG_SPL_BUILD
 /*
@@ -767,67 +875,41 @@ void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
 {
 	struct nand_chip *nand;
 	struct mtd_info *mtd;
+	struct nand_bch_priv *bch;
+	int err = 0;
 
 	if (nand_curr_device < 0 ||
 	    nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
 	    !nand_info[nand_curr_device].name) {
-		printf("Error: Can't switch ecc, no devices available\n");
+		printf("nand: error: no devices available\n");
 		return;
 	}
 
 	mtd = &nand_info[nand_curr_device];
 	nand = mtd->priv;
-
+	bch = nand->priv;
 	nand->options |= NAND_OWN_BUFFERS;
-
-	/* Reset ecc interface */
-	nand->ecc.mode = NAND_ECC_NONE;
-	nand->ecc.read_page = NULL;
-	nand->ecc.write_page = NULL;
-	nand->ecc.read_oob = NULL;
-	nand->ecc.write_oob = NULL;
-	nand->ecc.hwctl = NULL;
-	nand->ecc.correct = NULL;
-	nand->ecc.calculate = NULL;
-	nand->ecc.strength = eccstrength;
-
 	/* Setup the ecc configurations again */
-	if (hardware) {
+	if (hardware)
 		if (eccstrength == 1) {
-			nand->ecc.mode = NAND_ECC_HW;
-			nand->ecc.layout = &hw_nand_oob;
-			nand->ecc.size = 512;
-			nand->ecc.bytes = 3;
-			nand->ecc.hwctl = omap_enable_hwecc;
-			nand->ecc.correct = omap_correct_data;
-			nand->ecc.calculate = omap_calculate_ecc;
-			omap_hwecc_init(nand);
-			printf("1-bit hamming HW ECC selected\n");
-		}
-#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
-		else if (eccstrength == 8) {
-			nand->ecc.mode = NAND_ECC_HW;
-			nand->ecc.layout = &hw_bch8_nand_oob;
-			nand->ecc.size = 512;
-#ifdef CONFIG_AM33XX
-			nand->ecc.bytes = 14;
-			nand->ecc.read_page = omap_read_page_bch;
-#else
-			nand->ecc.bytes = 13;
-#endif
-			nand->ecc.hwctl = omap_enable_ecc_bch;
-			nand->ecc.correct = omap_correct_data_bch;
-			nand->ecc.calculate = omap_calculate_ecc_bch;
-			omap_hwecc_init_bch(nand, NAND_ECC_READ);
-			printf("8-bit BCH HW ECC selected\n");
+			err = omap_select_ecc_scheme(nand,
+					OMAP_ECC_HAM1_CODE_HW_ROMCODE,
+					mtd->writesize, mtd->oobsize);
+		} else if (eccstrength == 8) {
+			err = omap_select_ecc_scheme(nand,
+					OMAP_ECC_BCH8_CODE_HW,
+					mtd->writesize, mtd->oobsize);
+		} else {
+			printf("nand: error: unsupported ECC scheme\n");
+			err = -EINVAL;
 		}
-#endif
-	} else {
-		nand->ecc.mode = NAND_ECC_SOFT;
-		/* Use mtd default settings */
-		nand->ecc.layout = NULL;
-		nand->ecc.size = 0;
-		printf("SW ECC selected\n");
+	else
+		err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
+					mtd->writesize, mtd->oobsize);
+	if (err) {
+		printf("nand: error: could not switch ecc, reverting\n");
+		omap_select_ecc_scheme(nand, bch->ecc_scheme,
+				       mtd->writesize, mtd->oobsize);
 	}
 
 	/* Update NAND handling after ECC mode switch */
@@ -854,6 +936,10 @@ void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
  */
 int board_nand_init(struct nand_chip *nand)
 {
+	struct mtd_info *mtd;
+#ifdef CONFIG_SPL_BUILD
+	struct mtd_info	nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
+#endif
 	int32_t gpmc_config = 0;
 	cs = 0;
 
@@ -873,7 +959,7 @@ int board_nand_init(struct nand_chip *nand)
 		cs++;
 	}
 	if (cs >= GPMC_MAX_CS) {
-		printf("NAND: Unable to find NAND settings in "
+		printf("nand: error: Unable to find NAND settings in "
 			"GPMC Configuration - quitting\n");
 		return -ENODEV;
 	}
@@ -883,66 +969,27 @@ int board_nand_init(struct nand_chip *nand)
 	gpmc_config |= 0x10;
 	writel(gpmc_config, &gpmc_cfg->config);
 
+	mtd		= &nand_info[0];
+	mtd->priv	= nand;
 	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
 	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
-
-	nand->cmd_ctrl = omap_nand_hwcontrol;
-	nand->options = NAND_NO_PADDING | NAND_CACHEPRG;
+	nand->priv	= &bch_priv;
+	nand->cmd_ctrl	= omap_nand_hwcontrol;
+	nand->options	= NAND_NO_PADDING | NAND_CACHEPRG;
 	/* If we are 16 bit dev, our gpmc config tells us that */
 	if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)
 		nand->options |= NAND_BUSWIDTH_16;
 
 	nand->chip_delay = 100;
-
-#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
-#ifdef CONFIG_AM33XX
-	/* AM33xx uses the ELM */
-	/* required in case of BCH */
-	elm_init();
-#else
-	/*
-	 * Whereas other OMAP based SoC do not have the ELM, they use the BCH
-	 * SW library.
-	 */
-	bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */);
-	if (!bch_priv.control) {
-		puts("Could not init_bch()\n");
-		return -ENODEV;
+	nand->ecc.layout = &omap_ecclayout;
+
+	/* select ECC scheme */
+	if (omap_select_ecc_scheme(nand, CONFIG_SYS_NAND_ECCSCHEME,
+				   CONFIG_SYS_NAND_PAGE_SIZE,
+				   CONFIG_SYS_NAND_OOBSIZE)) {
+		printf("nand: error: cannot select ecc scheme\n");
+		return -EINVAL;
 	}
-#endif
-	/* BCH info that will be correct for SPL or overridden otherwise. */
-	nand->priv = &bch_priv;
-#endif
-
-	/* Default ECC mode */
-#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8)
-	nand->ecc.mode = NAND_ECC_HW;
-	nand->ecc.layout = &hw_bch8_nand_oob;
-	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
-	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
-	nand->ecc.strength = 8;
-	nand->ecc.hwctl = omap_enable_ecc_bch;
-	nand->ecc.correct = omap_correct_data_bch;
-	nand->ecc.calculate = omap_calculate_ecc_bch;
-#ifdef CONFIG_AM33XX
-	nand->ecc.read_page = omap_read_page_bch;
-#endif
-	omap_hwecc_init_bch(nand, NAND_ECC_READ);
-#else
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
-	nand->ecc.mode = NAND_ECC_SOFT;
-#else
-	nand->ecc.mode = NAND_ECC_HW;
-	nand->ecc.layout = &hw_nand_oob;
-	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
-	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
-	nand->ecc.hwctl = omap_enable_hwecc;
-	nand->ecc.correct = omap_correct_data;
-	nand->ecc.calculate = omap_calculate_ecc;
-	nand->ecc.strength = 1;
-	omap_hwecc_init(nand);
-#endif
-#endif
 
 #ifdef CONFIG_SPL_BUILD
 	if (nand->options & NAND_BUSWIDTH_16)
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index e0a87f8..db0cbdb 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -259,6 +259,7 @@
 
 #define CONFIG_SYS_NAND_ECCSIZE		512
 #define CONFIG_SYS_NAND_ECCBYTES	14
+#define CONFIG_SYS_NAND_ECCSCHEME	3
 
 #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000
@@ -351,6 +352,7 @@
 
 /* NAND support */
 #ifdef CONFIG_NAND
+#define CONFIG_SYS_NAND_ONFI_DETECTION
 #define CONFIG_CMD_NAND
 #define GPMC_NAND_ECC_LP_x16_LAYOUT	1
 #if !defined(CONFIG_SPI_BOOT) && !defined(CONFIG_NOR_BOOT)
-- 
1.8.1

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

* [U-Boot] [PATCH v3 2/5] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform Pekon Gupta
@ 2013-08-29 10:56 ` Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 3/5] mtd: nand: omap: optimize chip->ecc.calculate() " Pekon Gupta
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

chip->ecc.hwctl() is used for preparing the H/W controller before read/write
NAND accesses (like assigning data-buf, enabling ECC scheme configs, etc.)

Though all ECC schemes in OMAP NAND driver use GPMC controller for generating
ECC syndrome (for both Read/Write accesses). But but in current code
HAM1_ECC and BCHx_ECC schemes implement individual function to achieve this.
This patch
(1) removes omap_hwecc_init() and omap_hwecc_init_bch()
as chip->ecc.hwctl will re-initializeGPMC before every read/write call.
omap_hwecc_init_bch() -> omap_enable_ecc_bch()

(2) merges the GPMC configuration code for all ECC schemes into
single omap_enable_hwecc(), thus adding scalability for future ECC schemes.
omap_enable_hwecc() + omap_enable_ecc_bch() -> omap_enable_hwecc()

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 arch/arm/include/asm/omap_gpmc.h |   7 --
 drivers/mtd/nand/omap_gpmc.c     | 193 +++++++++++----------------------------
 2 files changed, 55 insertions(+), 145 deletions(-)

diff --git a/arch/arm/include/asm/omap_gpmc.h b/arch/arm/include/asm/omap_gpmc.h
index dd40cb6..9660842 100644
--- a/arch/arm/include/asm/omap_gpmc.h
+++ b/arch/arm/include/asm/omap_gpmc.h
@@ -14,13 +14,6 @@
 #define GPMC_BUF_EMPTY	0
 #define GPMC_BUF_FULL	1
 
-#define ECCCLEAR	(0x1 << 8)
-#define ECCRESULTREG1	(0x1 << 0)
-#define ECCSIZE512BYTE	0xFF
-#define ECCSIZE1	(ECCSIZE512BYTE << 22)
-#define ECCSIZE0	(ECCSIZE512BYTE << 12)
-#define ECCSIZE0SEL	(0x000 << 0)
-
 /* Generic ECC Layouts */
 /* Large Page x8 NAND device Layout */
 #ifdef GPMC_NAND_ECC_LP_x8_LAYOUT
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index f97e862..0af4fa4 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -19,6 +19,8 @@
 
 #define BADBLOCK_MARKER_LENGTH	0x2
 #define SECTOR_BYTES		512
+#define ECCCLEAR		(0x1 << 8)
+#define ECCRESULTREG1		(0x1 << 0)
 
 static uint8_t cs;
 static __maybe_unused struct nand_ecclayout omap_ecclayout;
@@ -60,21 +62,6 @@ int omap_spl_dev_ready(struct mtd_info *mtd)
 }
 #endif
 
-/*
- * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
- *                   GPMC controller
- * @mtd:        MTD device structure
- *
- */
-static void __maybe_unused omap_hwecc_init(struct nand_chip *chip)
-{
-	/*
-	 * Init ECC Control Register
-	 * Clear all ECC | Enable Reg1
-	 */
-	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
-	writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL, &gpmc_cfg->ecc_size_config);
-}
 
 /*
  * gen_true_ecc - This function will generate true ECC value, which
@@ -192,38 +179,6 @@ static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
 }
 
 /*
- * omap_enable_ecc - This function enables the hardware ecc functionality
- * @mtd:        MTD device structure
- * @mode:       Read/Write mode
- */
-static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
-{
-	struct nand_chip *chip = mtd->priv;
-	uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
-
-	switch (mode) {
-	case NAND_ECC_READ:
-	case NAND_ECC_WRITE:
-		/* Clear the ecc result registers, select ecc reg as 1 */
-		writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
-
-		/*
-		 * Size 0 = 0xFF, Size1 is 0xFF - both are 512 bytes
-		 * tell all regs to generate size0 sized regs
-		 * we just have a single ECC engine for all CS
-		 */
-		writel(ECCSIZE1 | ECCSIZE0 | ECCSIZE0SEL,
-			&gpmc_cfg->ecc_size_config);
-		val = (dev_width << 7) | (cs << 1) | (0x1);
-		writel(val, &gpmc_cfg->ecc_config);
-		break;
-	default:
-		printf("Error: Unrecognized Mode[%d]!\n", mode);
-		break;
-	}
-}
-
-/*
  * Generic BCH interface
  */
 struct nand_bch_priv {
@@ -263,103 +218,66 @@ static __maybe_unused struct nand_bch_priv bch_priv = {
 };
 
 /*
- * omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
- *				GPMC controller
+ * omap_enable_hwecc - configures GPMC as per ECC scheme before read/write
  * @mtd:	MTD device structure
  * @mode:	Read/Write mode
  */
 __maybe_unused
-static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
+static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 {
-	uint32_t val;
-	uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
-	uint32_t unused_length = 0;
-	uint32_t wr_mode = BCH_WRAPMODE_6;
-	struct nand_bch_priv *bch = chip->priv;
-
-	/* Clear the ecc result registers, select ecc reg as 1 */
-	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
-
-	if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) {
-		wr_mode = BCH_WRAPMODE_1;
-
-	switch (bch->nibbles) {
-	case ECC_BCH4_NIBBLES:
-		unused_length = 3;
-		break;
-	case ECC_BCH8_NIBBLES:
-		unused_length = 2;
-		break;
-	case ECC_BCH16_NIBBLES:
-		unused_length = 0;
+	struct nand_chip	*nand	= mtd->priv;
+	struct nand_bch_priv	*bch	= nand->priv;
+	unsigned int dev_width = (nand->options & NAND_BUSWIDTH_16) ? 1 : 0;
+	unsigned int ecc_algo = 0;
+	unsigned int bch_type = 0;
+	unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
+	u32 ecc_size_config_val = 0;
+	u32 ecc_config_val = 0;
+
+	switch (bch->ecc_scheme) {
+	case OMAP_ECC_HAM1_CODE_SW:
+	case OMAP_ECC_HAM1_CODE_HW_ROMCODE:
+		ecc_algo = 0x0;
+		bch_type = 0x0;
+		bch_wrapmode = 0x00;
+		eccsize0 = 0xFF;
+		eccsize1 = 0xFF;
 		break;
-	}
-
-	/*
-	 * This is ecc_size_config for ELM mode.
-	 * Here we are using different settings for read and write access and
-	 * also depending on BCH strength.
-	 */
-	switch (mode) {
-	case NAND_ECC_WRITE:
-		/* write access only setup eccsize1 config */
-		val = ((unused_length + bch->nibbles) << 22);
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+	case OMAP_ECC_BCH8_CODE_HW:
+		ecc_algo = 0x1;
+		bch_type = 0x1;
+		if (mode == NAND_ECC_WRITE) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 0;  /* extra bits in nibbles per sector */
+			eccsize1 = 28; /* OOB bits in nibbles per sector */
+		} else {
+			bch_wrapmode = 0x01;
+			eccsize0 = 26; /* ECC bits in nibbles per sector */
+			eccsize1 = 2;  /* non-ECC bits in nibbles per sector */
+		}
 		break;
-
-	case NAND_ECC_READ:
 	default:
-		/*
-		 * by default eccsize0 selected for ecc1resultsize
-		 * eccsize0 config.
-		 */
-		val  = (bch->nibbles << 12);
-		/* eccsize1 config */
-		val |= (unused_length << 22);
-		break;
-	}
-	} else {
-	/*
-	 * This ecc_size_config setting is for BCH sw library.
-	 *
-	 * Note: we only support BCH8 currently with BCH sw library!
-	 * Should be really easy to adobt to BCH4, however some omap3 have
-	 * flaws with BCH4.
-	 *
-	 * Here we are using wrapping mode 6 both for reading and writing, with:
-	 *  size0 = 0  (no additional protected byte in spare area)
-	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)
-	 */
-	val = (32 << 22) | (0 << 12);
+		printf("nand: error: invalid driver configuration\n");
+		return;
 	}
-	/* ecc size configuration */
-	writel(val, &gpmc_cfg->ecc_size_config);
-
-	/*
-	 * Configure the ecc engine in gpmc
-	 * We assume 512 Byte sector pages for access to NAND.
-	 */
-	val  = (1 << 16);		/* enable BCH mode */
-	val |= (bch->type << 12);	/* setup BCH type */
-	val |= (wr_mode << 8);		/* setup wrapping mode */
-	val |= (dev_width << 7);	/* setup device width (16 or 8 bit) */
-	val |= (cs << 1);		/* setup chip select to work on */
-	debug("set ECC_CONFIG=0x%08x\n", val);
-	writel(val, &gpmc_cfg->ecc_config);
-}
-
-/*
- * omap_enable_ecc_bch - This function enables the bch h/w ecc functionality
- * @mtd:	MTD device structure
- * @mode:	Read/Write mode
- */
-__maybe_unused
-static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
-{
-	struct nand_chip *chip = mtd->priv;
-
-	omap_hwecc_init_bch(chip, mode);
-	/* enable ecc */
-	writel((readl(&gpmc_cfg->ecc_config) | 0x1), &gpmc_cfg->ecc_config);
+	/* Clear ecc and enable bits */
+	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
+	/* Configure ecc size for BCH */
+	ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
+	writel(ecc_size_config_val, &gpmc_cfg->ecc_size_config);
+
+	/* Configure device details for BCH engine */
+	ecc_config_val = ((ecc_algo << 16)	| /* HAM1 | BCHx */
+			(bch_type << 12)	| /* BCH4/BCH8/BCH16 */
+			(bch_wrapmode << 8)	| /* wrap mode */
+			(dev_width << 7)	| /* bus width */
+			(0x0 << 4)		| /* number of sectors */
+			(cs <<  1)		| /* ECC CS */
+			(0x0));			/* disable ECC */
+	writel(ecc_config_val, &gpmc_cfg->ecc_config);
+	/* enable ECC engine */
+	writel(ecc_config_val | 0x1, &gpmc_cfg->ecc_config);
 }
 
 /*
@@ -809,7 +727,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
 		nand->ecc.strength	= 8;
 		nand->ecc.size		= 512;
 		nand->ecc.bytes		= 13;
-		nand->ecc.hwctl		= omap_enable_ecc_bch;
+		nand->ecc.hwctl		= omap_enable_hwecc;
 		nand->ecc.correct	= omap_correct_data_bch_sw;
 		nand->ecc.calculate	= omap_calculate_ecc_bch_sw;
 		/* BCH SW library is used for error detection */
@@ -827,7 +745,6 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
 		ecclayout->oobfree[0].offset = BADBLOCK_MARKER_LENGTH;
 		ecclayout->oobfree[0].length = oobsize - nand->ecc.bytes -
 						BADBLOCK_MARKER_LENGTH;
-		omap_hwecc_init_bch(nand, NAND_ECC_READ);
 		bch->ecc_scheme		= OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
 		break;
 #endif
@@ -838,7 +755,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
 		nand->ecc.size		= 512;
 		nand->ecc.bytes		= 14;
 		nand->ecc.read_page	= omap_read_page_bch;
-		nand->ecc.hwctl		= omap_enable_ecc_bch;
+		nand->ecc.hwctl		= omap_enable_hwecc;
 		nand->ecc.correct	= omap_correct_data_bch;
 		nand->ecc.calculate	= omap_calculate_ecc_bch;
 		/* ELM is used for ECC error detection */
-- 
1.8.1

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

* [U-Boot] [PATCH v3 3/5] mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 2/5] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes Pekon Gupta
@ 2013-08-29 10:56 ` Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 4/5] mtd: nand: omap: optimized chip->ecc.correct() " Pekon Gupta
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

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 multiple chip->calculate API for different ECC schemes
  omap_calculate_ecc() + omap_calculate_ecc_bch() + omap_calculate_ecc_bch_sw()
				==> omap_calculate_ecc()
- removes omap_ecc_disable() and instead uses it as inline.

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

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 0af4fa4..e914c73 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -143,42 +143,6 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
 }
 
 /*
- *  omap_calculate_ecc - Generate non-inverted ECC bytes.
- *
- *  Using noninverted ECC can be considered ugly since writing a blank
- *  page ie. padding will clear the ECC bytes. This is no problem as
- *  long nobody is trying to write data on the seemingly unused page.
- *  Reading an erased page will produce an ECC mismatch between
- *  generated and read ECC bytes that has to be dealt with separately.
- *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
- *  is used, the result of read will be 0x0 while the ECC offsets of the
- *  spare area will be 0xFF which will result in an ECC mismatch.
- *  @mtd:	MTD structure
- *  @dat:	unused
- *  @ecc_code:	ecc_code buffer
- */
-static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
-		const uint8_t *dat, uint8_t *ecc_code)
-{
-	u_int32_t val;
-
-	/* Start Reading from HW ECC1_Result = 0x200 */
-	val = readl(&gpmc_cfg->ecc1_result);
-
-	ecc_code[0] = val & 0xFF;
-	ecc_code[1] = (val >> 16) & 0xFF;
-	ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
-
-	/*
-	 * Stop reading anymore ECC vals and clear old results
-	 * enable will be called if more reads are required
-	 */
-	writel(0x000, &gpmc_cfg->ecc_config);
-
-	return 0;
-}
-
-/*
  * Generic BCH interface
  */
 struct nand_bch_priv {
@@ -281,54 +245,77 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 }
 
 /*
- * 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
- */
-/*
- * omap_read_bch8_result - Read BCH result for BCH8 level
+ *  omap_calculate_ecc - Read ECC result
+ *  @mtd:	MTD structure
+ *  @dat:	unused
+ *  @ecc_code:	ecc_code buffer
  *
- * @mtd:	MTD device structure
- * @big_endian:	When set read register 3 first
- * @ecc_code:	Read syndrome from BCH result registers
+ *  Using noninverted ECC can be considered ugly since writing a blank
+ *  page ie. padding will clear the ECC bytes. This is no problem as
+ *  long nobody is trying to write data on the seemingly unused page.
+ *  Reading an erased page will produce an ECC mismatch between
+ *  generated and read ECC bytes that has to be dealt with separately.
+ *  E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
+ *  is used, the result of read will be 0x0 while the ECC offsets of the
+ *  spare area will be 0xFF which will result in an ECC mismatch.
  */
-static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
+static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
 				uint8_t *ecc_code)
 {
-	uint32_t *ptr;
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint32_t *ptr, val = 0;
 	int8_t i = 0, j;
 
-	if (big_endian) {
+	switch (bch->ecc_scheme) {
+	case OMAP_ECC_HAM1_CODE_HW_ROMCODE:
+		val = readl(&gpmc_cfg->ecc1_result);
+		ecc_code[0] = val & 0xFF;
+		ecc_code[1] = (val >> 16) & 0xFF;
+		ecc_code[2] = ((val >> 8) & 0x0F) | ((val >> 20) & 0xF0);
+		break;
+#ifdef CONFIG_BCH
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+		val	= readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[3]);
+		*ecc_code++ = 0xef ^ (val & 0xFF);
+		val	= readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[2]);
+		*ecc_code++ = 0x51 ^ ((val >> 24) & 0xFF);
+		*ecc_code++ = 0x2e ^ ((val >> 16) & 0xFF);
+		*ecc_code++ = 0x09 ^ ((val >>  8) & 0xFF);
+		*ecc_code++ = 0xed ^ ((val >>  0) & 0xFF);
+		val	= readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[1]);
+		*ecc_code++ = 0x93 ^ ((val >> 24) & 0xFF);
+		*ecc_code++ = 0x9a ^ ((val >> 16) & 0xFF);
+		*ecc_code++ = 0xc2 ^ ((val >>  8) & 0xFF);
+		*ecc_code++ = 0x97 ^ ((val >>  0) & 0xFF);
+		val	= readl(&gpmc_cfg->bch_result_0_3[0].bch_result_x[0]);
+		*ecc_code++ = 0x79 ^ ((val >> 24) & 0xFF);
+		*ecc_code++ = 0xe5 ^ ((val >> 16) & 0xFF);
+		*ecc_code++ = 0x24 ^ ((val >>  8) & 0xFF);
+		*ecc_code++ = 0xb5 ^ ((val >>  0) & 0xFF);
+		break;
+#endif
+	case OMAP_ECC_BCH8_CODE_HW:
 		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
-		ecc_code[i++] = readl(ptr) & 0xFF;
+		val = readl(ptr);
+		ecc_code[i++] = (val >>  0) & 0xFF;
 		ptr--;
 		for (j = 0; j < 3; j++) {
-			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
-			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
-			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
-			ecc_code[i++] = readl(ptr) & 0xFF;
+			val = readl(ptr);
+			ecc_code[i++] = (val >> 24) & 0xFF;
+			ecc_code[i++] = (val >> 16) & 0xFF;
+			ecc_code[i++] = (val >>  8) & 0xFF;
+			ecc_code[i++] = (val >>  0) & 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:
+		printf("nand: error: invalid driver configuration\n");
+		return -EINVAL;
 	}
+	/* clear result and disable engine */
+	writel((readl(&gpmc_cfg->ecc_config) & ~0x1), &gpmc_cfg->ecc_config);
+	return 0;
 }
 
 /*
@@ -367,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
@@ -550,57 +508,6 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
  * OMAP3 BCH8 support (with BCH library)
  */
 #ifdef CONFIG_BCH
-/*
- *  omap_calculate_ecc_bch_sw - Read BCH ECC result
- *
- *  @mtd:	MTD device structure
- *  @dat:	The pointer to data on which ecc is computed (unused here)
- *  @ecc:	The ECC output buffer
- */
-static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd, const uint8_t *dat,
-				uint8_t *ecc)
-{
-	int ret = 0;
-	size_t i;
-	unsigned long nsectors, val1, val2, val3, val4;
-
-	nsectors = ((readl(&gpmc_cfg->ecc_config) >> 4) & 0x7) + 1;
-
-	for (i = 0; i < nsectors; i++) {
-		/* Read hw-computed remainder */
-		val1 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[0]);
-		val2 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[1]);
-		val3 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[2]);
-		val4 = readl(&gpmc_cfg->bch_result_0_3[i].bch_result_x[3]);
-
-		/*
-		 * Add constant polynomial to remainder, in order to get an ecc
-		 * sequence of 0xFFs for a buffer filled with 0xFFs.
-		 */
-		*ecc++ = 0xef ^ (val4 & 0xFF);
-		*ecc++ = 0x51 ^ ((val3 >> 24) & 0xFF);
-		*ecc++ = 0x2e ^ ((val3 >> 16) & 0xFF);
-		*ecc++ = 0x09 ^ ((val3 >> 8) & 0xFF);
-		*ecc++ = 0xed ^ (val3 & 0xFF);
-		*ecc++ = 0x93 ^ ((val2 >> 24) & 0xFF);
-		*ecc++ = 0x9a ^ ((val2 >> 16) & 0xFF);
-		*ecc++ = 0xc2 ^ ((val2 >> 8) & 0xFF);
-		*ecc++ = 0x97 ^ (val2 & 0xFF);
-		*ecc++ = 0x79 ^ ((val1 >> 24) & 0xFF);
-		*ecc++ = 0xe5 ^ ((val1 >> 16) & 0xFF);
-		*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);
-
-	return ret;
-}
-
 /**
  * omap_correct_data_bch_sw - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -729,7 +636,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
 		nand->ecc.bytes		= 13;
 		nand->ecc.hwctl		= omap_enable_hwecc;
 		nand->ecc.correct	= omap_correct_data_bch_sw;
-		nand->ecc.calculate	= omap_calculate_ecc_bch_sw;
+		nand->ecc.calculate	= omap_calculate_ecc;
 		/* BCH SW library is used for error detection */
 		bch_priv.control	= init_bch(13, 8, 0x201b);
 		if (!bch_priv.control) {
@@ -757,7 +664,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand, int ecc_scheme,
 		nand->ecc.read_page	= omap_read_page_bch;
 		nand->ecc.hwctl		= omap_enable_hwecc;
 		nand->ecc.correct	= omap_correct_data_bch;
-		nand->ecc.calculate	= omap_calculate_ecc_bch;
+		nand->ecc.calculate	= omap_calculate_ecc;
 		/* ELM is used for ECC error detection */
 		elm_init();
 		/* define ecc-layout */
-- 
1.8.1

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

* [U-Boot] [PATCH v3 4/5] mtd: nand: omap: optimized chip->ecc.correct() for H/W ECC schemes
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
                   ` (2 preceding siblings ...)
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 3/5] mtd: nand: omap: optimize chip->ecc.calculate() " Pekon Gupta
@ 2013-08-29 10:56 ` Pekon Gupta
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot Pekon Gupta
  2013-08-29 16:06 ` [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Tom Rini
  5 siblings, 0 replies; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

chip->ecc.correct() is used for detecting and correcting bit-flips during read
operations. In omap-nand driver it implemented as:
(a) omap_correct_data(): for h/w based ECC_HAM1 scheme
(b) omap_correct_data_bch() + CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
	for ECC_BCH8 scheme using GPMC and software lib/bch.c
(c) omap_correct_data_bch() + CONFIG_NAND_OMAP_ECC_BCH8_CODE_HW
	for ECC_BCH8 scheme using GPMC and ELM

This patch updates (c)
- checks for calc_ecc[]==0x00 so that error_correction is not required for
  known good pages.
- adds scalability for other ECC_BCHx scheme by merging following
  omap_rotate_ecc_bch() + omap_fix_errors_bch() => omap_correct_data_bch()
- fixing logic for bit-flip correction based on error_loc[count]

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

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index e914c73..9e94e9e 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -21,6 +21,8 @@
 #define SECTOR_BYTES		512
 #define ECCCLEAR		(0x1 << 8)
 #define ECCRESULTREG1		(0x1 << 0)
+/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
+#define BCH4_BIT_PAD		4
 
 static uint8_t cs;
 static __maybe_unused struct nand_ecclayout omap_ecclayout;
@@ -319,77 +321,6 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
 }
 
 /*
- * omap_rotate_ecc_bch - Rotate the syndrome bytes
- *
- * @mtd:	MTD device structure
- * @calc_ecc:	ECC read from ECC registers
- * @syndrome:	Rotated syndrome will be retuned in this array
- *
- */
-static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
-		uint8_t *syndrome)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct nand_bch_priv *bch = chip->priv;
-	uint8_t n_bytes = 0;
-	int8_t i, j;
-
-	switch (bch->type) {
-	case ECC_BCH4:
-		n_bytes = 8;
-		break;
-
-	case ECC_BCH16:
-		n_bytes = 28;
-		break;
-
-	case ECC_BCH8:
-	default:
-		n_bytes = 13;
-		break;
-	}
-
-	for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
-		syndrome[i] =  calc_ecc[j];
-}
-
-/*
- * omap_fix_errors_bch - Correct bch error in the data
- *
- * @mtd:	MTD device structure
- * @data:	Data read from flash
- * @error_count:Number of errors in data
- * @error_loc:	Locations of errors in the data
- *
- */
-static void omap_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
-		uint32_t error_count, uint32_t *error_loc)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct nand_bch_priv *bch = chip->priv;
-	uint8_t count = 0;
-	uint32_t error_byte_pos;
-	uint32_t error_bit_mask;
-	uint32_t last_bit = (bch->nibbles * 4) - 1;
-
-	/* Flip all bits as specified by the error location array. */
-	/* FOR( each found error location flip the bit ) */
-	for (count = 0; count < error_count; count++) {
-		if (error_loc[count] > last_bit) {
-			/* Remove the ECC spare bits from correction. */
-			error_loc[count] -= (last_bit + 1);
-			/* Offset bit in data region */
-			error_byte_pos = ((512 * 8) -
-					(error_loc[count]) - 1) / 8;
-			/* Error Bit mask */
-			error_bit_mask = 0x1 << (error_loc[count] % 8);
-			/* Toggle the error bit to make the correction. */
-			data[error_byte_pos] ^= error_bit_mask;
-		}
-	}
-}
-
-/*
  * omap_correct_data_bch - Compares the ecc read from nand spare area
  * with ECC registers values and corrects one bit error if it has occured
  *
@@ -405,16 +336,26 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
 {
 	struct nand_chip *chip = mtd->priv;
 	struct nand_bch_priv *bch = chip->priv;
+	uint32_t eccbytes = chip->ecc.bytes;
 	uint8_t syndrome[28];
-	uint32_t error_count = 0;
+	uint32_t error_count = 0, error_max;
 	uint32_t error_loc[8];
-	uint32_t i, ecc_flag;
+	uint32_t i, j, ecc_flag = 0;
+	uint8_t count, err = 0;
+	uint32_t byte_pos, bit_pos;
+
+	/* check calculated ecc */
+	for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++)
+		if (calc_ecc[i] != 0x00)
+			ecc_flag = 1;
+	if (!ecc_flag)
+		return 0;
 
+	/* check for whether its a erased-page */
 	ecc_flag = 0;
-	for (i = 0; i < chip->ecc.bytes; i++)
+	for (i = 0; i < chip->ecc.bytes && !ecc_flag; i++)
 		if (read_ecc[i] != 0xff)
 			ecc_flag = 1;
-
 	if (!ecc_flag)
 		return 0;
 
@@ -425,20 +366,42 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
 	 * while reading ECC result we read it in big endian.
 	 * Hence while loading to ELM we have rotate to get the right endian.
 	 */
-	omap_rotate_ecc_bch(mtd, calc_ecc, syndrome);
+	for (i = 0, j = (eccbytes-1); i < eccbytes; i++, j--)
+		syndrome[i] =  calc_ecc[j];
 
 	/* use elm module to check for errors */
 	if (elm_check_error(syndrome, bch->nibbles, &error_count,
 				error_loc) != 0) {
-		printf("ECC: uncorrectable.\n");
-		return -1;
+		printf("nand: error: uncorrectable ECC errors\n");
+		return -EINVAL;
 	}
 
 	/* correct bch error */
-	if (error_count > 0)
-		omap_fix_errors_bch(mtd, dat, error_count, error_loc);
+	for (count = 0; count < error_count; count++) {
+		switch (bch->type) {
+		case ECC_BCH4:
+			error_max = SECTOR_BYTES + (eccbytes - 1);
+			/* add 4 to take care 4 bit padding */
+			error_loc[count] += BCH4_BIT_PAD;
+			break;
+		case ECC_BCH8:
+			/* 14th byte in ECC is reserved to match ROM layout */
+			error_max = SECTOR_BYTES + (eccbytes - 1);
+			break;
+		default:
+			return -EINVAL;
+		}
+		byte_pos = error_max - ((error_loc[count] - 1) / 8);
+		bit_pos  = error_loc[count] % 8;
 
-	return 0;
+		if (byte_pos < SECTOR_BYTES)
+			dat[byte_pos] ^= 1 << bit_pos;
+		else if (byte_pos < error_max)
+			read_ecc[byte_pos - SECTOR_BYTES] = 1 << bit_pos;
+		else
+			err = -EBADMSG;
+	}
+	return (err) ? err : error_count;
 }
 
 /**
-- 
1.8.1

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

* [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
                   ` (3 preceding siblings ...)
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 4/5] mtd: nand: omap: optimized chip->ecc.correct() " Pekon Gupta
@ 2013-08-29 10:56 ` Pekon Gupta
  2013-08-29 12:56   ` Tom Rini
  2013-08-29 16:06 ` [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Tom Rini
  5 siblings, 1 reply; 12+ messages in thread
From: Pekon Gupta @ 2013-08-29 10:56 UTC (permalink / raw)
  To: u-boot

NAND boot mode on AM335x EVM has been verified, and steps
to use it has been documented and update in this README

Signed-off-by: Pekon Gupta <pekon@ti.com>
---
 board/ti/am335x/README | 59 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 17 deletions(-)

diff --git a/board/ti/am335x/README b/board/ti/am335x/README
index 67b5246..ef28b00 100644
--- a/board/ti/am335x/README
+++ b/board/ti/am335x/README
@@ -20,23 +20,48 @@ NAND
 The AM335x GP EVM ships with a 256MiB NAND available in most profiles.  In
 this example to program the NAND we assume that an SD card has been
 inserted with the files to write in the first SD slot and that mtdparts
-have been configured correctly for the board.  As a time saving measure we
-load MLO into memory in one location, copy it into the three locatations
-that the ROM checks for additional valid copies, then load U-Boot into
-memory.  We then write that whole section of memory to NAND.
-
-U-Boot # mmc rescan
-U-Boot # env default -f -a
-U-Boot # nand erase.chip
-U-Boot # saveenv
-U-Boot # load mmc 0 81000000 MLO
-U-Boot # cp.b 81000000 81020000 20000
-U-Boot # cp.b 81000000 81040000 20000
-U-Boot # cp.b 81000000 81060000 20000
-U-Boot # load mmc 0 81080000 u-boot.img
-U-Boot # nand write 81000000 0 260000
-U-Boot # load mmc 0 ${loadaddr} uImage
-U-Boot # nand write ${loadaddr} kernel 500000
+have been configured correctly for the board. we load MLO into memory, then
+write it to NAND. Multiple redundant copies of MLO are stored for backup.
+
+Step-1: Building u-boot for NAND boot
+	Set following CONFIGxx options for NAND device.
+	CONFIG_SYS_NAND_PAGE_SIZE	number of main bytes in NAND page
+	CONFIG_SYS_NAND_OOBSIZE		number of OOB bytes in NAND page
+	CONFIG_SYS_NAND_BLOCK_SIZE	number of bytes in NAND erase-block
+	CONFIG_SYS_NAND_ECCPOS		ECC map for NAND page
+	CONFIG_SYS_NAND_ECCSCHEME	ECC scheme used by NAND
+					0 - HAM1_SW
+					1 - HAM1_HW
+					2 - BCH4_SW  (unsupported)
+					3 - BCH4_HW  (unsupported)
+					4 - BCH8_SW
+					5 - BCH8_HW
+
+Step-2: Flashing NAND via MMC/SD
+	# select BOOTSEL to MMC/SD boot and boot from MMC/SD card
+	U-Boot # mmc rescan
+	# erase flash
+	U-Boot # nand erase.chip
+	U-Boot # env default -f -a
+	U-Boot # saveenv
+	# redundant copies of MLO are kept as backup
+	U-Boot # load mmc 0 0x81000000 MLO
+	U-Boot # nand write 0x81000000 0x00000 0x20000
+	U-Boot # nand write 0x81000000 0x20000 0x20000
+	U-Boot # nand write 0x81000000 0x40000 0x20000
+	U-Boot # nand write 0x81000000 0x60000 0x20000
+	# flash u-boot.img
+	U-Boot # load mmc 0 0x81000000 u-boot.img
+	U-Boot # nand write 0x81000000 0x80000 0x60000
+	# flash kernel image
+	U-Boot # load mmc 0 0x81000000 uImage
+	U-Boot # nand write 0x81000000 {kernel-load-address} 0x500000
+	# flash filesystem image
+	U-Boot # load mmc 0 0x81000000 {filesystem-image}
+	U-Boot # nand write 0x81000000 {filesystem-load-address} 0x300000
+
+Step-3: Set BOOTSEL pin to select NAND boot, and POR the device.
+	The device should boot from images flashed on NAND device.
 
 NOR
 ===
-- 
1.8.1

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

* [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot Pekon Gupta
@ 2013-08-29 12:56   ` Tom Rini
       [not found]     ` <20980858CB6D3A4BAE95CA194937D5E73EA05DA1@DBDE04.ent.ti.com>
  0 siblings, 1 reply; 12+ messages in thread
From: Tom Rini @ 2013-08-29 12:56 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/29/2013 06:56 AM, Pekon Gupta wrote:
> NAND boot mode on AM335x EVM has been verified, and steps
> to use it has been documented and update in this README
> 
> Signed-off-by: Pekon Gupta <pekon@ti.com>
[snip]
> +	# redundant copies of MLO are kept as backup
> +	U-Boot # load mmc 0 0x81000000 MLO
> +	U-Boot # nand write 0x81000000 0x00000 0x20000
> +	U-Boot # nand write 0x81000000 0x20000 0x20000
> +	U-Boot # nand write 0x81000000 0x40000 0x20000
> +	U-Boot # nand write 0x81000000 0x60000 0x20000
> +	# flash u-boot.img
> +	U-Boot # load mmc 0 0x81000000 u-boot.img
> +	U-Boot # nand write 0x81000000 0x80000 0x60000

I had lumped these as a series of copies/loads and a single write as the
write operation was the long (time wise) part of the process.

> +	# flash kernel image
> +	U-Boot # load mmc 0 0x81000000 uImage
> +	U-Boot # nand write 0x81000000 {kernel-load-address} 0x500000
> +	# flash filesystem image
> +	U-Boot # load mmc 0 0x81000000 {filesystem-image}
> +	U-Boot # nand write 0x81000000 {filesystem-load-address} 0x300000

These should also reference real variables or MTD parts names.
- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSH0ThAAoJENk4IS6UOR1WvAcP/1zGffL7YBeZ+zAljZ3J19CD
K2xo7Tz6oRiUsvuRAhju6BtSXYL9Un+LMJYt6nh2EUPyBy4IVwQiJY65yComKrfX
+3t4gB7YcL1J7AafGLCUsvcEuenSSH+Q4oadNN0c1ZG014ZbH/6Gad3mVjZL7afZ
Ywehirtkht6YFu1y08V2mre2TfHsi2gGU4/TZLrSvPMRUj/xPUUFLkfCau4VRJlO
9AxqoIgOPRtPRI/e9DowMIMaiF7Z0yYKs8aM+sePmGmyf/cds2+fYVEBj2ZYd6hm
rlMuor2sr+6ARkgycrnRD4rJXJNJVkF+oFnqJVaiDacTHGhEQlbj3JKaSXH5q8zy
deB3wmfrd+pFLk3iqcH2nz+qPO/+9EtZPjjmzrM/lOZadClqZMo5f/ODSq3boDcV
4d3NRTAIIA9u0DhIJhuYy8lctSzIlHyXU2FTbR3TloGOMtjBtPf6w/5tMoe8K6ho
zCmzkMuNigZG8lCfTRRIW8WQvpxkPCnpBMX70yfmaBvKE0XRyb3sU55ulDqKsSDN
cyvkDaaO18IGXzTmMP+H5pB311UskIO739f+/hbm2j/wV/rdV83RY/eTHHbkWILG
Jd6LUdvUJ342aPZUzEwv2xBp2OnrMrOMY10/o4+d2bKcDhr6vze68Cm9RIQoN9U/
DfS9Wd4sHbjVQ0vbti6i
=gBNv
-----END PGP SIGNATURE-----

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

* [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot
       [not found]     ` <20980858CB6D3A4BAE95CA194937D5E73EA05DA1@DBDE04.ent.ti.com>
@ 2013-08-29 13:08       ` Tom Rini
  0 siblings, 0 replies; 12+ messages in thread
From: Tom Rini @ 2013-08-29 13:08 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/29/2013 09:01 AM, Gupta, Pekon wrote:
>>
>> On 08/29/2013 06:56 AM, Pekon Gupta wrote:
>>> NAND boot mode on AM335x EVM has been verified, and steps
>>> to use it has been documented and update in this README
>>>
>>> Signed-off-by: Pekon Gupta <pekon@ti.com>
>> [snip]
>>> +	# redundant copies of MLO are kept as backup
>>> +	U-Boot # load mmc 0 0x81000000 MLO
>>> +	U-Boot # nand write 0x81000000 0x00000 0x20000
>>> +	U-Boot # nand write 0x81000000 0x20000 0x20000
>>> +	U-Boot # nand write 0x81000000 0x40000 0x20000
>>> +	U-Boot # nand write 0x81000000 0x60000 0x20000
>>> +	# flash u-boot.img
>>> +	U-Boot # load mmc 0 0x81000000 u-boot.img
>>> +	U-Boot # nand write 0x81000000 0x80000 0x60000
>>
>> I had lumped these as a series of copies/loads and a single write as the
>> write operation was the long (time wise) part of the process.
>>
> Yes, I could see your comment. I just separated each for clarity to user. 
> feel you can drop this one..
> 
>>> +	# flash kernel image
>>> +	U-Boot # load mmc 0 0x81000000 uImage
>>> +	U-Boot # nand write 0x81000000 {kernel-load-address} 0x500000
>>> +	# flash filesystem image
>>> +	U-Boot # load mmc 0 0x81000000 {filesystem-image}
>>> +	U-Boot # nand write 0x81000000 {filesystem-load-address} 0x300000
>>
>> These should also reference real variables or MTD parts names.
> Opps sorry my bad.. 
> I looked it from different angle, just as an example.
> Therefore I added comments above each command to explain each step.
> 
> Anyways this particular patch is just updating README. So, if you may
> drop this PATCH 5/5..

No, I want the README updated, it's helpful.  We should just reference
the other example things we setup like mtdparts (and make use of
${filesize} :)  Thanks!

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSH0fpAAoJENk4IS6UOR1WypsP/RvksLKO3oIUgmCCblr8BnhN
tp1kKIW4P5h90tZ9h7/dPg3Iy77DyZIncEAveu7oDrYYOwL4ThxbRW5oc8UymY6w
ZHD9HZPPzsoDwgDEY4wcL+DkDtqfPZJRewbGWJhb6v7yadFzM4hkW/peGHiEmTWQ
wPCai0ZzlI7A2nSiCvq2nYmjRR59GFupdjbwubzLIUgv9qGAOkd8muZLBpnchU5i
Na1/DLIdzwpEN1GrtmOuLo/TTxBO8rR87R7OAR8zQSmnAAeDYiPzCvZ3k6Ys40S1
7HOK8fP6zmMRor91OsFJ2AsnF2yYJyqp5uBj9hfLfjcKVJdMbSzJMXOxE5H1BRZ+
WlqhFZkTo0DM/Ssrpy9WVgzeqyE2mfE3zST7vb2Y0J4BFGVoX0egFfuKS/x2D71C
mgDPXk31uhT8PmF4VwJiHi9ZW917IpMi1u4PqavrAslY7PHOxDos8YJ8lPqI9C0O
RpyL3YgIQW4uikxxVfeIHlOzLDYNMqxFdS4GBq/towV7JefayV8d+n3B7igKPFcd
DJh7TzHIhGAKD0xN2DDILg1+twRRGvvb1eL1dyNocSzN5mTeaVFZiM3+2FZ8mFff
9sra+ZLoF6+0sF/7+uT1edwVeHeiy25uPTq3m7p/GDpr5Lv99bpgnT105hOT4HSL
JShvbj5X7740l6ofYh2l
=M1AD
-----END PGP SIGNATURE-----

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

* [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform Pekon Gupta
@ 2013-08-29 15:01   ` Tom Rini
  0 siblings, 0 replies; 12+ messages in thread
From: Tom Rini @ 2013-08-29 15:01 UTC (permalink / raw)
  To: u-boot

On Thu, Aug 29, 2013 at 04:26:41PM +0530, Pekon Gupta wrote:

> BCH8_ECC scheme implemented in omap_gpmc.c driver has following favours
> +-----------------------------------+-----------------+-----------------+
> |ECC Scheme                         | ECC Calculation | Error Detection |
> +-----------------------------------+-----------------+-----------------+
> |OMAP_ECC_BCH8_CODE_HW              |GPMC             |ELM H/W engine   |
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW |GPMC             |S/W BCH library  |
> +-----------------------------------+-----------------+-----------------+
> 
> Current implementation limits the BCH8_CODE_HW only for AM33xx device family.
> (using CONFIG_AM33XX). However, other SoC families (like TI81xx) also have
> ELM hardware module, and can support ECC error detection using ELM.
> 
> This patch
> - removes CONFIG_AM33xx
> 	Thus this driver can be reused by all devices having ELM h/w engine.
> - adds omap_select_ecc_scheme()
> 	A common function to handle ecc-scheme related configurations. This
> 	can be used both during device-probe and via user-space u-boot commads
> 	to change ecc-scheme.
> - adds CONFIG_BCH
> 	S/W library (lib/bch.c) required by OMAP_ECC_BCH8_CODE_HW_DETECTION_SW
>   	is enabled by CONFIG_BCH.
> - adds CONFIG_SYS_NAND_ECCSCHEME (new)
> 	user specified CONFIG to determine ecc-scheme used during boot
> - adds CONFIG_SYS_NAND_ONFI_DETECTION
> 	enable auto-detection of ONFI compliant devices
> 
> Signed-off-by: Pekon Gupta <pekon@ti.com>
> ---
>  arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  48 +----
>  doc/README.nand                              |  13 ++
>  drivers/mtd/nand/omap_gpmc.c                 | 291 ++++++++++++++++-----------
>  include/configs/am335x_evm.h                 |   2 +
>  4 files changed, 195 insertions(+), 159 deletions(-)

For the am33xx related parts:
Reviewed-by: Tom Rini <trini@ti.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130829/9f5f899b/attachment.pgp>

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

* [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver
  2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
                   ` (4 preceding siblings ...)
  2013-08-29 10:56 ` [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot Pekon Gupta
@ 2013-08-29 16:06 ` Tom Rini
       [not found]   ` <20980858CB6D3A4BAE95CA194937D5E73EA07FF2@DBDE04.ent.ti.com>
  5 siblings, 1 reply; 12+ messages in thread
From: Tom Rini @ 2013-08-29 16:06 UTC (permalink / raw)
  To: u-boot

On Thu, Aug 29, 2013 at 04:26:40PM +0530, Pekon Gupta wrote:
> *changes in v3*
> [PATCH 1/5] (complete change) 
> 	- ecc-scheme is selection is controller by s/w, not CONFIG_NAND_xx
> 	- added omap_select_ecc_scheme(), as common function to handle all
> 	  ecc-scheme related configurations for both board_nand_init() &
> 	  omap_nand_switch_ecc().
> 	- removed un-used defines from asm/arch-am33xx/omap_gpmc.h
> 	- updated doc/REAME.nand
> [PATCH 2/5] removed un-used defines from asm/omap_gpmc.h
> [PATCH 3/5] removed omap_calculate_ecc_bch_sw() and omap_calculate_ecc()
> 		and merged their logic into omap_calculate_ecc_bch()
> [PATCH 4/5] updated return error-code in-case of invalid conditions
> [PATCH 5/5] (new) for board/ti/am335x/README

Note that with the series applied, we see:
NAND:  nand: selected OMAP_ECC_BCH8_CODE_HW
256 MiB

I think we should move the selected message to a debug().

That said, I'm seeing a nice performance increase, both with and without
the dcache patch also applied, so yay!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130829/f7f01635/attachment.pgp>

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

* [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver
       [not found]   ` <20980858CB6D3A4BAE95CA194937D5E73EA07FF2@DBDE04.ent.ti.com>
@ 2013-08-29 17:47     ` Tom Rini
       [not found]       ` <20980858CB6D3A4BAE95CA194937D5E73EA0AA07@DBDE04.ent.ti.com>
  0 siblings, 1 reply; 12+ messages in thread
From: Tom Rini @ 2013-08-29 17:47 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/29/2013 01:26 PM, Gupta, Pekon wrote:
>>
>> On Thu, Aug 29, 2013 at 04:26:40PM +0530, Pekon Gupta wrote:
>>> *changes in v3*
>>> [PATCH 1/5] (complete change)
>>> 	- ecc-scheme is selection is controller by s/w, not CONFIG_NAND_xx
>>> 	- added omap_select_ecc_scheme(), as common function to handle
>> all
>>> 	  ecc-scheme related configurations for both board_nand_init() &
>>> 	  omap_nand_switch_ecc().
>>> 	- removed un-used defines from asm/arch-am33xx/omap_gpmc.h
>>> 	- updated doc/REAME.nand
>>> [PATCH 2/5] removed un-used defines from asm/omap_gpmc.h
>>> [PATCH 3/5] removed omap_calculate_ecc_bch_sw() and
>> omap_calculate_ecc()
>>> 		and merged their logic into omap_calculate_ecc_bch()
>>> [PATCH 4/5] updated return error-code in-case of invalid conditions
>>> [PATCH 5/5] (new) for board/ti/am335x/README
>>
>> Note that with the series applied, we see:
>> NAND:  nand: selected OMAP_ECC_BCH8_CODE_HW
>> 256 MiB
>>
> The first part of string "NAND:   " is coming from 
> arch/arm/lib/board.c:582 	puts("NAND:  ");
> I'm not sure why it was added, seems legacy code..
> And same is copied to all other arch/xx/lib/board.c
> However as this print is not giving much of info, so can this be removed ?

NAND + size is useful information.

>> I think we should move the selected message to a debug().
>>
> Second part of string "nand: selected OMAP_ECC_BCH8_CODE_HW" was
> specifically added in board_nand_init() because currently there is no way
> to identify the ECC scheme being used in u-boot. Unless digging into
>  source code and reviewing board file.
> And many time end-users face ECC scheme mis-match between u-boot
> and linux when flashing kernel and file-system from u-boot.
> Thus this print helps in identifying the ECC scheme being used from logs.
> So, please keep this print "nand: selected <ecc-scheme>" ..  ?

I'd rather not as we should have left the mis-match problems in the
past.  We don't generally offer commands to switch ECC schemes as
everyone is using the same now.  When we do need to offer switching for
legacy reasons that's when we should say what we're on.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSH4ksAAoJENk4IS6UOR1W208QAJkXCvdm1gsIB7vjL8zf4Yi8
CGNm7B2d5K1kubP21LzClgf52T5ImMFlqXpvJJ/BPjwEnanPS6zXeBrzc1zRZZft
Y8Q6VlnPl094zDof9TdEoa51L6XmRqc8zRcdELvJLatrw0fd2htuJrXdUgi46a3M
MeukhTHWT0IkbOixFuI22eiaN8YC5api5ljZvMcNJMXXkCbcgb0C743BPiRHasFI
nslOhfJShU/XhNuhtOqKnN6oen5nuzYi7O2DFPS55ipkiz+ekKon8pVU587WXtTW
ML5Hb+8tutgkZwhMXG0tWKaLv7Bhk9zKPmfLAyqJrdOulGeIRxRRVBrI0Vi9kcJ4
a6dO2g3+zOyNkZ//ejIjFvVNRBCK1+eSPxY0KxNATIghn4IuGLC2tGB1BUap2+hR
odBZzgETLcomyzpLnVOCMl+FVCPaAE0qKsqdz3h6O+qPYY+bSIFyzTJNioj7d2ws
LADJoR5FM+rTo8/mQrsQwbGT2sMPENeeLYrjSkKRMBLQonItp5SOyZPMPUwp42sx
Ih6tmvZkQM4sWt2okAZltOhbtzx8uPmKDKsE8UIZKB4uF4okP86SjsidguUhj2g6
NmutHKNiwcz4Pppe9IhigusgL9TrVMTSq4yefzOeLY2iKnouqog1RCevdly2BQaZ
iqbOYt1DuccSoIzat68h
=aNQx
-----END PGP SIGNATURE-----

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

* [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver
       [not found]       ` <20980858CB6D3A4BAE95CA194937D5E73EA0AA07@DBDE04.ent.ti.com>
@ 2013-09-04 12:51         ` Tom Rini
  0 siblings, 0 replies; 12+ messages in thread
From: Tom Rini @ 2013-09-04 12:51 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/02/2013 10:56 AM, Gupta, Pekon wrote:
>> On 08/29/2013 01:26 PM, Gupta, Pekon wrote:
>>>>
[snip]
>>>> I think we should move the selected message to a debug().
>>>>
>>> Second part of string "nand: selected OMAP_ECC_BCH8_CODE_HW" was
>>> specifically added in board_nand_init() because currently there is no way
>>> to identify the ECC scheme being used in u-boot. Unless digging into
>>>  source code and reviewing board file.
>>> And many time end-users face ECC scheme mis-match between u-boot
>>> and linux when flashing kernel and file-system from u-boot.
>>> Thus this print helps in identifying the ECC scheme being used from logs.
>>> So, please keep this print "nand: selected <ecc-scheme>" ..  ?
>>
>> I'd rather not as we should have left the mis-match problems in the
>> past.  We don't generally offer commands to switch ECC schemes as
>> everyone is using the same now.  When we do need to offer switching for
>> legacy reasons that's when we should say what we're on.
>>
> I think we should not deprecate the 'ecc_switching_utility', bcoz there are
> multiple scenarios even in newer devices where it is useful..
> 
> Example-1: using built-in NAND devices
[snip]

The ROM already needs to handle this mode and simply go with "on die
ECC" and we need to mirror this behaviour.

> Example-2: upgrading ECC on legacy devices
> There are many users with devices in production, who would like to
> upgrade to newer ECC schemes (like BCH16), only  when these drivers
> are stable. Such users depend on u-boot to switch newer ECC schemes
> (like BCH16) and then re-flash upgraded kernel and file-systems on 
> remote machines.
> In such cases also 'ecc_switching_utility' is helpful.

But they've got a problem today, which is that the ROM demands BCH16
already, so they have to use BCH16 or not be booting from NAND.

> Though I don't want to be stubborn here.. 
> But if your plan is to completely remove 'ecc_switching_utility' support
> then I would move back to V2 version of this patch, where ecc scheme
> is selected by #CONFIGS, so that only that code footprint gets optimized.
> 
> Please let me know, which way to go forward..
> - [Patch V2 xx] where ECC selection is via #CONFIGS
> - [Patch V3 xx] where ECC selection can be done via software
> 	 (ecc_switching_utility)
> 	 Incase you opt for [V3], my humble request is to keep
> 	 above prints and not to convert them into 'debug' (please) :-)

We need to do run-time detection of what ecc mode is to be used.  We
don't want to expose the 'nandecc' type command we have on OMAP3 without
a real case (and I don't count ones that can be constructed as an
example on beaglebone + capes, but I do count real hardware designs).

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSJyzJAAoJENk4IS6UOR1WfiQP/Rwr5Gcqvg4RP6Rp7ppN0HSm
suzbjCTgsWxY9SeSEO1L4GiGWRxZSAKkdE/KSYTPRPfjrdev+i6poZfoI6JlMK64
d/HnI37yAV4dOYA3tQImyXfZi+8teWKqm4vXyRsQqq9tJFmGppX4iRV9G8OVBUJv
lZVEw+OpW2Fktq+jcMskwGz3TKYmMTDh4GlcQnX3BHltkOGe1lkCMmQoxxyAYkfO
/O1gvwrvUhzkjgkRIG18rlHW34qMZqflAIfHNjSxXLpeuDYkCi6EsCJHTpelQuYG
3+9fAGY4zSleR+e29QfrgyuOSwR3s+ElZ1VmNRl7e0TeE9yb20frZCJhfYAq1vYu
wjeKJcfkscPRYaGTUc7jhyyMgK2hrCk9kVCOdRfUrJe+ElaqlhU1/ugOADQky8bN
QxqGwhSpPT8tLKBrUaIqix3DOMdt1yQXos+qhaFba73zMO+gwAtEHVWQELQIASLD
K3mAcs3vfDzMvLke95xPNLA7KP09O9LV892ND+5v8/6UVDUQX2IyEjTjLKDeG7Ae
P9OgE90UlbgxC7vEbtt1rxDLrhLr57EECigKjFhFsfFdSMkj+FEnyxb0Dmp+5JRY
s0QxaRAz4nvpFW1KcTY2fhIaqiYEgLEMRcgcwiQeVxqezQAtRFlK9xAX7DmCjw5K
zgzrEslpmfYxi3+DcF4Y
=K7aI
-----END PGP SIGNATURE-----

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

end of thread, other threads:[~2013-09-04 12:51 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-29 10:56 [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Pekon Gupta
2013-08-29 10:56 ` [U-Boot] [PATCH v3 1/5] mtd: nand: omap: enable BCH ECC scheme using ELM for generic platform Pekon Gupta
2013-08-29 15:01   ` Tom Rini
2013-08-29 10:56 ` [U-Boot] [PATCH v3 2/5] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes Pekon Gupta
2013-08-29 10:56 ` [U-Boot] [PATCH v3 3/5] mtd: nand: omap: optimize chip->ecc.calculate() " Pekon Gupta
2013-08-29 10:56 ` [U-Boot] [PATCH v3 4/5] mtd: nand: omap: optimized chip->ecc.correct() " Pekon Gupta
2013-08-29 10:56 ` [U-Boot] [PATCH v3 5/5] board/ti/am335x/README: update for NAND boot Pekon Gupta
2013-08-29 12:56   ` Tom Rini
     [not found]     ` <20980858CB6D3A4BAE95CA194937D5E73EA05DA1@DBDE04.ent.ti.com>
2013-08-29 13:08       ` Tom Rini
2013-08-29 16:06 ` [U-Boot] [PATCH v3 0/5] mtd: nand: omap: optimize and clean-up of OMAP NAND driver Tom Rini
     [not found]   ` <20980858CB6D3A4BAE95CA194937D5E73EA07FF2@DBDE04.ent.ti.com>
2013-08-29 17:47     ` Tom Rini
     [not found]       ` <20980858CB6D3A4BAE95CA194937D5E73EA0AA07@DBDE04.ent.ti.com>
2013-09-04 12:51         ` Tom Rini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox