All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements
@ 2015-04-08 14:44 Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 1/8] mtd: vf610_nfc: remove caching of page in buffer Stefan Agner
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

This patchset contains various improvements and enhancements to the
NAND flash controller found on Vybrid (vf610) and other Freescale
platforms. It's a merge and follow up of two patchset sent earlier:
- mtd: vf610_nfc: remove caching of page in page buffer
  http://lists.denx.de/pipermail/u-boot/2015-April/209817.html
- mtd: vf610_nfc: use in-band bad block table
  http://lists.denx.de/pipermail/u-boot/2015-April/209889.html

The patch "mtd: vf610_nfc: support subpage write" has been dropped
as discussed. As a further consequence, this patchset includes a
patch which changes the behaviour of the SEQIN command (patch 3).

- Patch 1 to 3 fix non-critical issues or undesirable behavior.
- Patch 4 enhances the driver with a page read function with reads
  the OOB area only and also simplifies vf610_nfc_read_buf.
- Patch 5 switches to in-band bad block table which is a prerequisit
  for 32-error correction (patch 7) on 64 byte OOB.
- Patch 6 converts the driver to be configureable through Kconfig.
- Patch 7 enhances driver configuration for 32-error correction.
- Patch 8 allows reading the ONFI parameter page.

The changes between 1-4 has been discussed on the mailinglist lately.

Stefan Agner (8):
  mtd: vf610_nfc: remove caching of page in buffer
  mtd: vf610_nfc: remove read on SEQIN
  mtd: vf610_nfc: allow bitflips in an empty page
  mtd: vf610_nfc: implement OOB only read
  mtd: vf610_nfc: use in-band bad block table
  mtd: vf610_nfc: add Freescale NFC controller configs to Kconfig
  mtd: vf610_nfc: add 32-error correction option for HW ECC
  mtd: vf610_nfc: enable ONFI detection

 configs/vf610twr_defconfig   |   2 +
 doc/README.nand              |  18 ----
 drivers/mtd/nand/Kconfig     |  45 +++++++++
 drivers/mtd/nand/vf610_nfc.c | 232 ++++++++++++++++++++++---------------------
 include/configs/vf610twr.h   |   4 +-
 5 files changed, 168 insertions(+), 133 deletions(-)

-- 
2.3.5

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

* [U-Boot] [PATCH v2 1/8] mtd: vf610_nfc: remove caching of page in buffer
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 2/8] mtd: vf610_nfc: remove read on SEQIN Stefan Agner
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

To improve performance we remember the current page in the buffer
and avoid reading it twice. This implicit page cache increases
complexity while does not increase performance in real world cases.
This patch removes that feature.

Acked-by: Bill Pringlemeir <bpringlemeir@nbsps.com>
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/vf610_nfc.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index d98dd28..fa0bb9d 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -147,7 +147,6 @@ struct vf610_nfc {
 	uint               column;
 	int                spareonly;
 	int		   page_sz;
-	int                page;
 	/* Status and ID are in alternate locations. */
 	int                alt_buf;
 #define ALT_BUF_ID   1
@@ -347,7 +346,6 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 
 	switch (command) {
 	case NAND_CMD_PAGEPROG:
-		nfc->page = -1;
 		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
@@ -367,10 +365,6 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	case NAND_CMD_SEQIN: /* Pre-read for partial writes. */
 	case NAND_CMD_READ0:
 		column = 0;
-		/* Already read? */
-		if (nfc->page == page)
-			return;
-		nfc->page = page;
 		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
@@ -378,7 +372,6 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		break;
 
 	case NAND_CMD_ERASE1:
-		nfc->page = -1;
 		vf610_nfc_transfer_size(nfc->regs, 0);
 		vf610_nfc_send_commands(nfc->regs, command,
 					NAND_CMD_ERASE2, ERASE_CMD_CODE);
@@ -532,10 +525,8 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, u_char *dat)
 	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
 
 	/* ECC failed. */
-	if (flip > ecc_count) {
-		nfc->page = -1;
+	if (flip > ecc_count)
 		return -1;
-	}
 
 	/* Erased page. */
 	memset(dat, 0xff, nfc->chip.ecc.size);
-- 
2.3.5

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

* [U-Boot] [PATCH v2 2/8] mtd: vf610_nfc: remove read on SEQIN
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 1/8] mtd: vf610_nfc: remove caching of page in buffer Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 3/8] mtd: vf610_nfc: allow bitflips in an empty page Stefan Agner
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

Since we do not support sub-page writes anyway, reading the page
back to the controller on SEQIN command is not required. Remove
the page read on SEQIN.

However, the column/page values relevant to the SEQIN command, hence
set the column/row address on SEQIN command.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
This improved the write performance quite nicely. The nand write
command improves from 2.9MiB/s to 3.5MiB/s. A ubi write of a UBIFS
image which is around 100MiB improves from 34.5s to 27.1s. Measured
on a Colibri VF61 (512MiB Macronix NAND).

 drivers/mtd/nand/vf610_nfc.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index fa0bb9d..66b335d 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -345,24 +345,26 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	nfc->alt_buf	= 0;
 
 	switch (command) {
+	case NAND_CMD_SEQIN:
+		/* Use valid column/page from preread... */
+		vf610_nfc_addr_cycle(mtd, column, page);
+		/*
+		 * SEQIN => data => PAGEPROG sequence is done by the controller
+		 * hence we do not need to issue the command here...
+		 */
+		return;
 	case NAND_CMD_PAGEPROG:
 		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
-		vf610_nfc_addr_cycle(mtd, column, page);
 		break;
 
 	case NAND_CMD_RESET:
 		vf610_nfc_transfer_size(nfc->regs, 0);
 		vf610_nfc_send_command(nfc->regs, command, RESET_CMD_CODE);
 		break;
-	/*
-	 * NFC does not support sub-page reads and writes,
-	 * so emulate them using full page transfers.
-	 */
 	case NAND_CMD_READOOB:
 		nfc->spareonly = 1;
-	case NAND_CMD_SEQIN: /* Pre-read for partial writes. */
 	case NAND_CMD_READ0:
 		column = 0;
 		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
-- 
2.3.5

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

* [U-Boot] [PATCH v2 3/8] mtd: vf610_nfc: allow bitflips in an empty page
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 1/8] mtd: vf610_nfc: remove caching of page in buffer Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 2/8] mtd: vf610_nfc: remove read on SEQIN Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 4/8] mtd: vf610_nfc: implement OOB only read Stefan Agner
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

Allow bit flips in a empty page up to half of the recoverable
bits (strength / 2).

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/vf610_nfc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 66b335d..16485f5 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -527,7 +527,7 @@ static inline int vf610_nfc_correct_data(struct mtd_info *mtd, u_char *dat)
 	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
 
 	/* ECC failed. */
-	if (flip > ecc_count)
+	if (flip > ecc_count && flip > (nfc->chip.ecc.strength / 2))
 		return -1;
 
 	/* Erased page. */
-- 
2.3.5

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

* [U-Boot] [PATCH v2 4/8] mtd: vf610_nfc: implement OOB only read
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
                   ` (2 preceding siblings ...)
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 3/8] mtd: vf610_nfc: allow bitflips in an empty page Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 5/8] mtd: vf610_nfc: use in-band bad block table Stefan Agner
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

Implement read of OOB area only. When using column and sector size
properties, only parts of the page can be read. However, this works
only when hardware ECC is disabled, otherwise the ECC engine would
ruin the data in the buffer. To allow OOB only reads, three points
had to be addressed:
- Set ECC mode per command.
- Handle NAND_CMD_READOOB seperate. Make sure column and sector
  size is correctly set up, while disabling ECC.
- Now, the OOB data end up at the beginning of the buffer. Remove
  the special handling of OOB (spareonly).

Especially bad block scans benefit from this change. On a 512MiB
SLC NAND device, the bad block scan took 1.5s less than before.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/vf610_nfc.c | 99 ++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 59 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 16485f5..5d72b4a 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -145,8 +145,6 @@ struct vf610_nfc {
 	struct nand_chip   chip;
 	void __iomem	  *regs;
 	uint               column;
-	int                spareonly;
-	int		   page_sz;
 	/* Status and ID are in alternate locations. */
 	int                alt_buf;
 #define ALT_BUF_ID   1
@@ -319,8 +317,8 @@ static void vf610_nfc_addr_cycle(struct mtd_info *mtd, int column, int page)
 {
 	if (column != -1) {
 		struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-		if (nfc->chip.options | NAND_BUSWIDTH_16)
-			column = column/2;
+		if (nfc->chip.options & NAND_BUSWIDTH_16)
+			column = column / 2;
 		vf610_nfc_set_field(mtd, NFC_COL_ADDR, COL_ADDR_MASK,
 				    COL_ADDR_SHIFT, column);
 	}
@@ -329,6 +327,13 @@ static void vf610_nfc_addr_cycle(struct mtd_info *mtd, int column, int page)
 				    ROW_ADDR_SHIFT, page);
 }
 
+static inline void vf610_nfc_ecc_mode(struct mtd_info *mtd, int ecc_mode)
+{
+	vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
+			    CONFIG_ECC_MODE_MASK,
+			    CONFIG_ECC_MODE_SHIFT, ecc_mode);
+}
+
 static inline void vf610_nfc_transfer_size(void __iomem *regbase, int size)
 {
 	__raw_writel(size, regbase + NFC_SECTOR_SIZE);
@@ -339,10 +344,10 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 			      int column, int page)
 {
 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int page_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
 
-	nfc->column     = max(column, 0);
-	nfc->spareonly	= 0;
-	nfc->alt_buf	= 0;
+	nfc->column = max(column, 0);
+	nfc->alt_buf = 0;
 
 	switch (command) {
 	case NAND_CMD_SEQIN:
@@ -354,23 +359,36 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		 */
 		return;
 	case NAND_CMD_PAGEPROG:
-		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
+		page_sz += mtd->writesize + mtd->oobsize;
+		vf610_nfc_transfer_size(nfc->regs, page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
+		vf610_nfc_ecc_mode(mtd, ECC_45_BYTE);
 		break;
 
 	case NAND_CMD_RESET:
 		vf610_nfc_transfer_size(nfc->regs, 0);
 		vf610_nfc_send_command(nfc->regs, command, RESET_CMD_CODE);
 		break;
+
 	case NAND_CMD_READOOB:
-		nfc->spareonly = 1;
+		page_sz += mtd->oobsize;
+		column = mtd->writesize;
+		vf610_nfc_transfer_size(nfc->regs, page_sz);
+		vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
+					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
+		vf610_nfc_addr_cycle(mtd, column, page);
+		vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
+		break;
+
 	case NAND_CMD_READ0:
+		page_sz += mtd->writesize + mtd->oobsize;
 		column = 0;
-		vf610_nfc_transfer_size(nfc->regs, nfc->page_sz);
+		vf610_nfc_transfer_size(nfc->regs, page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(mtd, column, page);
+		vf610_nfc_ecc_mode(mtd, ECC_45_BYTE);
 		break;
 
 	case NAND_CMD_ERASE1:
@@ -399,46 +417,25 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	vf610_nfc_done(mtd);
 }
 
-static inline void vf610_nfc_read_spare(struct mtd_info *mtd, void *buf,
-					int len)
-{
-	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
-
-	len = min(mtd->oobsize, (uint)len);
-	if (len > 0)
-		vf610_nfc_memcpy(buf, nfc->regs + mtd->writesize, len);
-}
-
 /* Read data from NFC buffers */
 static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 	uint c = nfc->column;
-	uint l;
 
-	/* Handle main area */
-	if (!nfc->spareonly) {
-		l = min((uint)len, mtd->writesize - c);
-		nfc->column += l;
-
-		if (!nfc->alt_buf)
-			vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c,
-					 l);
-		else
-			if (nfc->alt_buf & ALT_BUF_ID)
-				*buf = vf610_nfc_get_id(mtd, c);
-			else
-				*buf = vf610_nfc_get_status(mtd);
-
-		buf += l;
-		len -= l;
+	switch (nfc->alt_buf) {
+	case ALT_BUF_ID:
+		*buf = vf610_nfc_get_id(mtd, c);
+		break;
+	case ALT_BUF_STAT:
+		*buf = vf610_nfc_get_status(mtd);
+		break;
+	default:
+		vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
+		break;
 	}
 
-	/* Handle spare area access */
-	if (len) {
-		nfc->column += len;
-		vf610_nfc_read_spare(mtd, buf, len);
-	}
+	nfc->column += len;
 }
 
 /* Write data to NFC buffers */
@@ -629,17 +626,9 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 	if (cfg.flash_bbt)
 		chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_CREATE;
 
-	/* Default to software ECC until flash ID. */
-	vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
-			    CONFIG_ECC_MODE_MASK,
-			    CONFIG_ECC_MODE_SHIFT, ECC_BYPASS);
-
 	chip->bbt_td = &bbt_main_descr;
 	chip->bbt_md = &bbt_mirror_descr;
 
-	nfc->page_sz = PAGE_2K + OOB_64;
-	nfc->page_sz += cfg.width == 16 ? 1 : 0;
-
 	/* Set configuration register. */
 	vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
 	vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
@@ -667,15 +656,12 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 
 	chip->ecc.mode = NAND_ECC_SOFT; /* default */
 
-	nfc->page_sz = mtd->writesize + mtd->oobsize;
-
 	/* Single buffer only, max 256 OOB minus ECC status */
-	if (nfc->page_sz > PAGE_2K + 256 - 8) {
+	if (mtd->writesize + mtd->oobsize > PAGE_2K + 256 - 8) {
 		dev_err(nfc->dev, "Unsupported flash size\n");
 		err = -ENXIO;
 		goto error;
 	}
-	nfc->page_sz += cfg.width == 16 ? 1 : 0;
 
 	if (cfg.hardware_ecc) {
 		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
@@ -696,11 +682,6 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 		chip->ecc.size = PAGE_2K;
 		chip->ecc.strength = 24;
 
-		/* set ECC mode to 45 bytes OOB with 24 bits correction */
-		vf610_nfc_set_field(mtd, NFC_FLASH_CONFIG,
-				    CONFIG_ECC_MODE_MASK,
-				    CONFIG_ECC_MODE_SHIFT, ECC_45_BYTE);
-
 		/* Enable ECC_STATUS */
 		vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
 	}
-- 
2.3.5

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

* [U-Boot] [PATCH v2 5/8] mtd: vf610_nfc: use in-band bad block table
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
                   ` (3 preceding siblings ...)
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 4/8] mtd: vf610_nfc: implement OOB only read Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 6/8] mtd: vf610_nfc: add Freescale NFC controller configs to Kconfig Stefan Agner
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

Use in-band bad block table (NAND_BBT_NO_OOB) which allows to
use the full OOB for hardare ECC purposes. Since there is no
ECC correction on the OOB it is also safer to use in-band area
to store the bad block table marker.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/vf610_nfc.c | 29 ++---------------------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 5d72b4a..05cbdf3 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -155,29 +155,6 @@ struct vf610_nfc {
 #define mtd_to_nfc(_mtd) \
 	(struct vf610_nfc *)((struct nand_chip *)_mtd->priv)->priv
 
-static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
-static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
-
-static struct nand_bbt_descr bbt_main_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
-		   NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	11,
-	.len = 4,
-	.veroffs = 15,
-	.maxblocks = 4,
-	.pattern = bbt_pattern,
-};
-
-static struct nand_bbt_descr bbt_mirror_descr = {
-	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
-		   NAND_BBT_2BIT | NAND_BBT_VERSION,
-	.offs =	11,
-	.len = 4,
-	.veroffs = 15,
-	.maxblocks = 4,
-	.pattern = mirror_pattern,
-};
-
 static struct nand_ecclayout vf610_nfc_ecc45 = {
 	.eccbytes = 45,
 	.eccpos = {19, 20, 21, 22, 23,
@@ -624,10 +601,8 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 
 	/* Bad block options. */
 	if (cfg.flash_bbt)
-		chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_CREATE;
-
-	chip->bbt_td = &bbt_main_descr;
-	chip->bbt_md = &bbt_mirror_descr;
+		chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB |
+				    NAND_BBT_CREATE;
 
 	/* Set configuration register. */
 	vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
-- 
2.3.5

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

* [U-Boot] [PATCH v2 6/8] mtd: vf610_nfc: add Freescale NFC controller configs to Kconfig
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
                   ` (4 preceding siblings ...)
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 5/8] mtd: vf610_nfc: use in-band bad block table Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 7/8] mtd: vf610_nfc: add 32-error correction option for HW ECC Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection Stefan Agner
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

This commit allows users to enable/disable the Freescale NFC
controller found in systems like Vybrid (VF610), MPC5125, MCF54418
or Kinetis K70 via Kconfig with more detailed help docs.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 configs/vf610twr_defconfig |  2 ++
 doc/README.nand            | 18 ------------------
 drivers/mtd/nand/Kconfig   | 30 ++++++++++++++++++++++++++++++
 include/configs/vf610twr.h |  3 ---
 4 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/configs/vf610twr_defconfig b/configs/vf610twr_defconfig
index 7de374a..5e0ac9f 100644
--- a/configs/vf610twr_defconfig
+++ b/configs/vf610twr_defconfig
@@ -1,3 +1,5 @@
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/vf610twr/imximage.cfg,ENV_IS_IN_MMC"
 CONFIG_ARM=y
 CONFIG_TARGET_VF610TWR=y
+CONFIG_NAND_VF610_NFC=y
+CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
diff --git a/doc/README.nand b/doc/README.nand
index 46d7edd..0ff5633 100644
--- a/doc/README.nand
+++ b/doc/README.nand
@@ -188,24 +188,6 @@ Configuration Options:
 	This is used by SoC platforms which do not have built-in ELM
 	hardware engine required for BCH ECC correction.
 
-   CONFIG_SYS_NAND_BUSWIDTH_16BIT
-	Indicates that NAND device has 16-bit wide data-bus. In absence of this
-	config, bus-width of NAND device is assumed to be either 8-bit and later
-	determined by reading ONFI params.
-	Above config is useful when NAND device's bus-width information cannot
-	be determined from on-chip ONFI params, like in following scenarios:
-	- SPL boot does not support reading of ONFI parameters. This is done to
-	  keep SPL code foot-print small.
-	- In current U-Boot flow using nand_init(), driver initialization
-	  happens in board_nand_init() which is called before any device probe
-	  (nand_scan_ident + nand_scan_tail), thus device's ONFI parameters are
-	  not available while configuring controller. So a static CONFIG_NAND_xx
-	  is needed to know the device's bus-width in advance.
-	Some drivers using above config are:
-	drivers/mtd/nand/mxc_nand.c
-	drivers/mtd/nand/ndfc.c
-	drivers/mtd/nand/omap_gpmc.c
-
 
 Platform specific options
 =========================
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 72825c3..0a9e96f 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -32,6 +32,36 @@ config NAND_DENALI_SPARE_AREA_SKIP_BYTES
 	  of OOB area before last ECC sector data starts.  This is potentially
 	  used to preserve the bad block marker in the OOB area.
 
+config NAND_VF610_NFC
+	bool "Support for Freescale NFC for VF610/MPC5125"
+	select SYS_NAND_SELF_INIT
+	help
+	  Enables support for NAND Flash Controller on some Freescale
+	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
+	  The driver supports a maximum 2k page size. The driver
+	  currently does not support hardware ECC.
+
+comment "Generic NAND options"
+
+# Enhance depends when converting drivers to Kconfig which use this config
+# option (mxc_nand, ndfc, omap_gpmc).
+config SYS_NAND_BUSWIDTH_16BIT
+	bool "Use 16-bit NAND interface"
+	depends on NAND_VF610_NFC
+	help
+	  Indicates that NAND device has 16-bit wide data-bus. In absence of this
+	  config, bus-width of NAND device is assumed to be either 8-bit and later
+	  determined by reading ONFI params.
+	  Above config is useful when NAND device's bus-width information cannot
+	  be determined from on-chip ONFI params, like in following scenarios:
+	  - SPL boot does not support reading of ONFI parameters. This is done to
+	    keep SPL code foot-print small.
+	  - In current U-Boot flow using nand_init(), driver initialization
+	    happens in board_nand_init() which is called before any device probe
+	    (nand_scan_ident + nand_scan_tail), thus device's ONFI parameters are
+	    not available while configuring controller. So a static CONFIG_NAND_xx
+	    is needed to know the device's bus-width in advance.
+
 if SPL
 
 config SPL_NAND_DENALI
diff --git a/include/configs/vf610twr.h b/include/configs/vf610twr.h
index 05bc7d0..621aa13 100644
--- a/include/configs/vf610twr.h
+++ b/include/configs/vf610twr.h
@@ -50,10 +50,7 @@
 #define CONFIG_CMD_NAND_TRIMFFS
 
 #ifdef CONFIG_CMD_NAND
-#define CONFIG_NAND_VF610_NFC
-#define CONFIG_SYS_NAND_SELF_INIT
 #define CONFIG_USE_ARCH_MEMCPY
-#define CONFIG_SYS_NAND_BUSWIDTH_16BIT
 #define CONFIG_SYS_MAX_NAND_DEVICE	1
 #define CONFIG_SYS_NAND_BASE		NFC_BASE_ADDR
 
-- 
2.3.5

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

* [U-Boot] [PATCH v2 7/8] mtd: vf610_nfc: add 32-error correction option for HW ECC
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
                   ` (5 preceding siblings ...)
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 6/8] mtd: vf610_nfc: add Freescale NFC controller configs to Kconfig Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection Stefan Agner
  7 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

Add option to choose between current 24-error correction and 32-error
correction through Kconfig. 32-error correction allow to use NAND
chips which require up to 8-bit error correction per 512 byte (when
using 2K pages).

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/Kconfig     | 15 +++++++++++++++
 drivers/mtd/nand/vf610_nfc.c | 40 +++++++++++++++++++++++++++++++++++-----
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 0a9e96f..d3269c4 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -62,6 +62,21 @@ config SYS_NAND_BUSWIDTH_16BIT
 	    not available while configuring controller. So a static CONFIG_NAND_xx
 	    is needed to know the device's bus-width in advance.
 
+choice
+	prompt "Hardware ECC strength"
+	depends on NAND_VF610_NFC
+	default SYS_NAND_VF610_NFC_45_ECC_BYTES
+	help
+	  Select the ECC strength used in the hardware BCH ECC block.
+
+config SYS_NAND_VF610_NFC_45_ECC_BYTES
+	bool "24-error correction (45 ECC bytes)"
+
+config SYS_NAND_VF610_NFC_60_ECC_BYTES
+	bool "32-error correction (60 ECC bytes)"
+
+endchoice
+
 if SPL
 
 config SPL_NAND_DENALI
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 05cbdf3..2c02ff5 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -71,6 +71,7 @@
 /* NFC ECC mode define */
 #define ECC_BYPASS			0
 #define ECC_45_BYTE			6
+#define ECC_60_BYTE			7
 
 /*** Register Mask and bit definitions */
 
@@ -155,7 +156,10 @@ struct vf610_nfc {
 #define mtd_to_nfc(_mtd) \
 	(struct vf610_nfc *)((struct nand_chip *)_mtd->priv)->priv
 
-static struct nand_ecclayout vf610_nfc_ecc45 = {
+#if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
+#define ECC_HW_MODE ECC_45_BYTE
+
+static struct nand_ecclayout vf610_nfc_ecc = {
 	.eccbytes = 45,
 	.eccpos = {19, 20, 21, 22, 23,
 		   24, 25, 26, 27, 28, 29, 30, 31,
@@ -167,6 +171,24 @@ static struct nand_ecclayout vf610_nfc_ecc45 = {
 		{.offset = 8,
 		 .length = 11} }
 };
+#elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
+#define ECC_HW_MODE ECC_60_BYTE
+
+static struct nand_ecclayout vf610_nfc_ecc = {
+	.eccbytes = 60,
+	.eccpos = { 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 },
+	.oobfree = {
+		{.offset = 2,
+		 .length = 2} }
+};
+#endif
 
 static inline u32 vf610_nfc_read(struct mtd_info *mtd, uint reg)
 {
@@ -340,7 +362,7 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_transfer_size(nfc->regs, page_sz);
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
-		vf610_nfc_ecc_mode(mtd, ECC_45_BYTE);
+		vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
 		break;
 
 	case NAND_CMD_RESET:
@@ -365,7 +387,7 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_send_commands(nfc->regs, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(mtd, column, page);
-		vf610_nfc_ecc_mode(mtd, ECC_45_BYTE);
+		vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
 		break;
 
 	case NAND_CMD_ERASE1:
@@ -645,7 +667,9 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 			goto error;
 		}
 
-		chip->ecc.layout = &vf610_nfc_ecc45;
+		/* Current HW ECC layouts only use 64 bytes of OOB */
+		if (mtd->oobsize > 64)
+			mtd->oobsize = 64;
 
 		/* propagate ecc.layout to mtd_info */
 		mtd->ecclayout = chip->ecc.layout;
@@ -653,9 +677,15 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 		chip->ecc.write_page = vf610_nfc_write_page;
 		chip->ecc.mode = NAND_ECC_HW;
 
-		chip->ecc.bytes = 45;
 		chip->ecc.size = PAGE_2K;
+		chip->ecc.layout = &vf610_nfc_ecc;
+#if defined(CONFIG_SYS_NAND_VF610_NFC_45_ECC_BYTES)
 		chip->ecc.strength = 24;
+		chip->ecc.bytes = 45;
+#elif defined(CONFIG_SYS_NAND_VF610_NFC_60_ECC_BYTES)
+		chip->ecc.strength = 32;
+		chip->ecc.bytes = 60;
+#endif
 
 		/* Enable ECC_STATUS */
 		vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
-- 
2.3.5

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

* [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection
  2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
                   ` (6 preceding siblings ...)
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 7/8] mtd: vf610_nfc: add 32-error correction option for HW ECC Stefan Agner
@ 2015-04-08 14:44 ` Stefan Agner
  2015-04-20 23:17   ` Scott Wood
  7 siblings, 1 reply; 11+ messages in thread
From: Stefan Agner @ 2015-04-08 14:44 UTC (permalink / raw)
  To: u-boot

This changes enable ONFI detection. The Read ID command now allows
one address byte which is needed for ONFI detection. To read the
ONFI parameter page, the NAND_CMD_PARAM need to be supported. The
CMD code enables one command and one address byte along with reading
data from flash using R/B#, as specified by ONFI.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/vf610_nfc.c | 65 ++++++++++++++++++++++++++++++++------------
 include/configs/vf610twr.h   |  1 +
 2 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 2c02ff5..99457d4 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -62,6 +62,7 @@
  * Briefly these are bitmasks of controller cycles.
  */
 #define READ_PAGE_CMD_CODE		0x7EE0
+#define READ_ONFI_PARAM_CMD_CODE	0x4860
 #define PROGRAM_PAGE_CMD_CODE		0x7FC0
 #define ERASE_CMD_CODE			0x4EC0
 #define READ_ID_CMD_CODE		0x4804
@@ -150,6 +151,7 @@ struct vf610_nfc {
 	int                alt_buf;
 #define ALT_BUF_ID   1
 #define ALT_BUF_STAT 2
+#define ALT_BUF_ONFI 3
 	struct clk        *clk;
 };
 
@@ -390,6 +392,15 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_ecc_mode(mtd, ECC_HW_MODE);
 		break;
 
+	case NAND_CMD_PARAM:
+		nfc->alt_buf = ALT_BUF_ONFI;
+		vf610_nfc_transfer_size(nfc->regs, 768);
+		vf610_nfc_send_command(nfc->regs, NAND_CMD_PARAM, READ_ONFI_PARAM_CMD_CODE);
+		vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
+		vf610_nfc_ecc_mode(mtd, ECC_BYPASS);
+		break;
+
 	case NAND_CMD_ERASE1:
 		vf610_nfc_transfer_size(nfc->regs, 0);
 		vf610_nfc_send_commands(nfc->regs, command,
@@ -399,8 +410,11 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 
 	case NAND_CMD_READID:
 		nfc->alt_buf = ALT_BUF_ID;
+		nfc->column = 0;
 		vf610_nfc_transfer_size(nfc->regs, 0);
 		vf610_nfc_send_command(nfc->regs, command, READ_ID_CMD_CODE);
+		vf610_nfc_set_field(mtd, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
 		break;
 
 	case NAND_CMD_STATUS:
@@ -422,17 +436,11 @@ static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 	uint c = nfc->column;
 
-	switch (nfc->alt_buf) {
-	case ALT_BUF_ID:
-		*buf = vf610_nfc_get_id(mtd, c);
-		break;
-	case ALT_BUF_STAT:
-		*buf = vf610_nfc_get_status(mtd);
-		break;
-	default:
-		vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
-		break;
-	}
+	/* Alternate buffers are only supported through read_byte */
+	if (nfc->alt_buf)
+		return;
+
+	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
 
 	nfc->column += len;
 }
@@ -453,8 +461,28 @@ static void vf610_nfc_write_buf(struct mtd_info *mtd, const u_char *buf,
 /* Read byte from NFC buffers */
 static u8 vf610_nfc_read_byte(struct mtd_info *mtd)
 {
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
 	u8 tmp;
-	vf610_nfc_read_buf(mtd, &tmp, sizeof(tmp));
+	uint c = nfc->column;
+
+	switch (nfc->alt_buf) {
+	case ALT_BUF_ID:
+		tmp = vf610_nfc_get_id(mtd, c);
+		break;
+	case ALT_BUF_STAT:
+		tmp = vf610_nfc_get_status(mtd);
+		break;
+	case ALT_BUF_ONFI:
+		/* Reverse byte since the controller uses big endianness */
+		c = nfc->column % 4;
+		c = nfc->column - c + (3 - c);
+		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+		break;
+	default:
+		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+		break;
+	}
+	nfc->column++;
 	return tmp;
 }
 
@@ -602,13 +630,11 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 	mtd->priv = chip;
 	chip->priv = nfc;
 
-	if (cfg.width == 16) {
+	if (cfg.width == 16)
 		chip->options |= NAND_BUSWIDTH_16;
-		vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
-	} else {
-		chip->options &= ~NAND_BUSWIDTH_16;
-		vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
-	}
+
+	/* Use 8-bit mode during initialization */
+	vf610_nfc_clear(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
 
 	/* Disable subpage writes as we do not provide ecc->hwctl */
 	chip->options |= NAND_NO_SUBPAGE_WRITE;
@@ -651,6 +677,9 @@ static int vf610_nfc_nand_init(int devnum, void __iomem *addr)
 		goto error;
 	}
 
+	if (cfg.width == 16)
+		vf610_nfc_set(mtd, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
 	chip->ecc.mode = NAND_ECC_SOFT; /* default */
 
 	/* Single buffer only, max 256 OOB minus ECC status */
diff --git a/include/configs/vf610twr.h b/include/configs/vf610twr.h
index 621aa13..aa31041 100644
--- a/include/configs/vf610twr.h
+++ b/include/configs/vf610twr.h
@@ -48,6 +48,7 @@
 /* NAND support */
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_NAND_TRIMFFS
+#define CONFIG_SYS_NAND_ONFI_DETECTION
 
 #ifdef CONFIG_CMD_NAND
 #define CONFIG_USE_ARCH_MEMCPY
-- 
2.3.5

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

* [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection
  2015-04-08 14:44 ` [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection Stefan Agner
@ 2015-04-20 23:17   ` Scott Wood
  2015-05-08 15:49     ` Stefan Agner
  0 siblings, 1 reply; 11+ messages in thread
From: Scott Wood @ 2015-04-20 23:17 UTC (permalink / raw)
  To: u-boot

On Wed, 2015-04-08 at 16:44 +0200, Stefan Agner wrote:
> +	case ALT_BUF_ONFI:
> +		/* Reverse byte since the controller uses big endianness */
> +		c = nfc->column % 4;
> +		c = nfc->column - c + (3 - c);

These two lines can be simplified to "c = nfc->column ^ 3;"

Doesn't this driver run on some big-endian targets, in which case you
wouldn't want to reverse?  I think you should instead be using in_be32()
and then extracting the byte within the word after it's been put into
cpu byte order.

> +		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
> +		break;
> +	default:
> +		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
> +		break;

Why is the byte order different here?  I guess you've been writing data
backwards onto the NAND chip?  Won't that mess up factory bad block
markers?

-Scott

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

* [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection
  2015-04-20 23:17   ` Scott Wood
@ 2015-05-08 15:49     ` Stefan Agner
  0 siblings, 0 replies; 11+ messages in thread
From: Stefan Agner @ 2015-05-08 15:49 UTC (permalink / raw)
  To: u-boot

On 2015-04-21 01:17, Scott Wood wrote:
> On Wed, 2015-04-08 at 16:44 +0200, Stefan Agner wrote:
>> +	case ALT_BUF_ONFI:
>> +		/* Reverse byte since the controller uses big endianness */
>> +		c = nfc->column % 4;
>> +		c = nfc->column - c + (3 - c);
> 
> These two lines can be simplified to "c = nfc->column ^ 3;"
> 
> Doesn't this driver run on some big-endian targets, in which case you
> wouldn't want to reverse?  I think you should instead be using in_be32()
> and then extracting the byte within the word after it's been put into
> cpu byte order.

Yes agreed, big endian platforms shouldn't be left out here, will fix
that.

>> +		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
>> +		break;
>> +	default:
>> +		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
>> +		break;
> 
> Why is the byte order different here?  I guess you've been writing data
> backwards onto the NAND chip?  Won't that mess up factory bad block
> markers?

Yes, the data end up backward in the NAND chip. I asked that myself to,
however, I have devices which definitely come with "naturally" looking
bad blocks. It seems that the whole pages are actually set to 0x00 on
those chips, although this is not specified in the data sheet. I will
try to figure out more...

--
Stefan

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

end of thread, other threads:[~2015-05-08 15:49 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-08 14:44 [U-Boot] [PATCH v2 0/8] mtd: vf610_nfc: various fixes and improvements Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 1/8] mtd: vf610_nfc: remove caching of page in buffer Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 2/8] mtd: vf610_nfc: remove read on SEQIN Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 3/8] mtd: vf610_nfc: allow bitflips in an empty page Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 4/8] mtd: vf610_nfc: implement OOB only read Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 5/8] mtd: vf610_nfc: use in-band bad block table Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 6/8] mtd: vf610_nfc: add Freescale NFC controller configs to Kconfig Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 7/8] mtd: vf610_nfc: add 32-error correction option for HW ECC Stefan Agner
2015-04-08 14:44 ` [U-Boot] [PATCH v2 8/8] mtd: vf610_nfc: enable ONFI detection Stefan Agner
2015-04-20 23:17   ` Scott Wood
2015-05-08 15:49     ` Stefan Agner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.