diff mbox

[v2] mtd: nand: support BENAND (Built-in ECC NAND)

Message ID F3B6523425E7914AA6214ED358D820AF2674E3EA@TGXML341.toshiba.local
State Superseded, archived
Headers show

Commit Message

katsuki.uwatoko@toshiba.co.jp Feb. 21, 2013, 6:17 a.m. UTC
This enables support for BENAND, which is an SLC NAND flash solution
with embedded error correction code (ECC), currently supports only
128bytes OOB type.

In the read sequence, "status read command" is executed to check the
ECC status after read data. If bitflips occur, these are
automatically corrected by BENAND and the status indicates the result.

The write sequence is the same as raw write and the ECC data are
automatically written to OOB by BENAND.

Signed-off-by: UWATOKO Katsuki <katsuki.uwatoko@toshiba.co.jp>
---
 drivers/mtd/nand/Kconfig        |   11 ++++
 drivers/mtd/nand/Makefile       |    1 +
 drivers/mtd/nand/nand_base.c    |   25 +++++++++
 drivers/mtd/nand/nand_benand.c  |  113 +++++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h        |    7 +++
 include/linux/mtd/nand_benand.h |   43 +++++++++++++++
 6 files changed, 200 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/nand_benand.c
 create mode 100644 include/linux/mtd/nand_benand.h

Comments

Matthieu CASTET Feb. 21, 2013, 9:50 a.m. UTC | #1
katsuki.uwatoko@toshiba.co.jp a écrit :
> This enables support for BENAND, which is an SLC NAND flash solution
> with embedded error correction code (ECC), currently supports only
> 128bytes OOB type.
> 
> In the read sequence, "status read command" is executed to check the
> ECC status after read data. If bitflips occur, these are
> automatically corrected by BENAND and the status indicates the result.
> 
> The write sequence is the same as raw write and the ECC data are
> automatically written to OOB by BENAND.
> 
> Signed-off-by: UWATOKO Katsuki <katsuki.uwatoko@toshiba.co.jp>

> +       case NAND_ECC_BENAND:
> +               if (!IS_ENABLED(CONFIG_MTD_NAND_BENAND)) {
> +                       pr_warn("CONFIG_MTD_BENAND not enabled\n");
> +                       BUG();
> +               }
> +
> +               chip->ecc.read_page = nand_read_page_benand;
> +               chip->ecc.write_page = nand_write_page_raw;
> +               chip->ecc.read_page_raw = nand_read_page_raw;
> +               chip->ecc.write_page_raw = nand_write_page_raw;
> +               chip->ecc.read_oob = nand_read_oob_std;
> +               chip->ecc.write_oob = nand_write_oob_std;
> +
Do you have a way to disable internal ecc ?

If not read_page_raw and write_page_raw won't do what is expected :
- read without ecc correction
- write without writing ecc or write custom ecc

I don't know if it could cause some problem.


Matthieu
katsuki.uwatoko@toshiba.co.jp Feb. 22, 2013, 6:23 a.m. UTC | #2
Hi,

> > +       case NAND_ECC_BENAND:
> > +               if (!IS_ENABLED(CONFIG_MTD_NAND_BENAND)) {
> > +                       pr_warn("CONFIG_MTD_BENAND not enabled\n");
> > +                       BUG();
> > +               }
> > +
> > +               chip->ecc.read_page = nand_read_page_benand;
> > +               chip->ecc.write_page = nand_write_page_raw;
> > +               chip->ecc.read_page_raw = nand_read_page_raw;
> > +               chip->ecc.write_page_raw = nand_write_page_raw;
> > +               chip->ecc.read_oob = nand_read_oob_std;
> > +               chip->ecc.write_oob = nand_write_oob_std;
> > +
> Do you have a way to disable internal ecc ?

Does "internal ecc" mean the BENAND's ECC function? If so, we cannot disable it.
This means that we cannot read the raw data, which is not corrected, 
unless there are too many bitflips for BENAND to correct.

> If not read_page_raw and write_page_raw won't do what is expected :
> - read without ecc correction
> - write without writing ecc or write custom ecc
> 
> I don't know if it could cause some problem.

I think that "writing ecc/ecc correction" would be just waste
and any other problems do not happen as long as these functions
do not destroy the OOB for BENAND ECC.
pekon gupta Feb. 25, 2013, 9:06 a.m. UTC | #3
Hi,

> This enables support for BENAND, which is an SLC NAND flash solution
> with embedded error correction code (ECC), currently supports only
> 128bytes OOB type.
> 
> In the read sequence, "status read command" is executed to check the
> ECC status after read data. If bitflips occur, these are
> automatically corrected by BENAND and the status indicates the result.
> 
> The write sequence is the same as raw write and the ECC data are
> automatically written to OOB by BENAND.

Just inquisitive, can anyone please share any throughput comparison between 'BENAND' & 'normal NAND' devices having same capacity and working on same clock-freq ?

(a) Usually on-chip memory controllers work on faster clock frequencies, as compared to the NAND devices connected to them externally on board.
Thus I assume, ECC computation & correction can be done at faster rate.

(b) However, on other hand BENAND(s) have luxury of accessing the Flash storage array locally, thus eliminating I/O delays | un-optimized IO signal timing from the access-path.

So, if you can share the details throughput comparison between the two types of NAND devices, under various conditions it would be helpful.


with regards, pekon
Matthieu CASTET Feb. 25, 2013, 9:24 a.m. UTC | #4
Gupta, Pekon a écrit :
> Hi,
> 
>> This enables support for BENAND, which is an SLC NAND flash solution
>> with embedded error correction code (ECC), currently supports only
>> 128bytes OOB type.
>>
>> In the read sequence, "status read command" is executed to check the
>> ECC status after read data. If bitflips occur, these are
>> automatically corrected by BENAND and the status indicates the result.
>>
>> The write sequence is the same as raw write and the ECC data are
>> automatically written to OOB by BENAND.
> 
> Just inquisitive, can anyone please share any throughput comparison between 'BENAND' & 'normal NAND' devices having same capacity and working on same clock-freq ?
> 
> (a) Usually on-chip memory controllers work on faster clock frequencies, as compared to the NAND devices connected to them externally on board.
> Thus I assume, ECC computation & correction can be done at faster rate.
> 
> (b) However, on other hand BENAND(s) have luxury of accessing the Flash storage array locally, thus eliminating I/O delays | un-optimized IO signal timing from the access-path.
> 
> So, if you can share the details throughput comparison between the two types of NAND devices, under various conditions it would be helpful.
> 
You always have to transfer the data from/to the nand devices to/from the host.

- Either the ecc internal controller is fast and the throughput are the same
than 'normal nand' (assuming the ecc controller on the host is fast),
- either it is slow and the throughput is limited by the internal ecc controller
(throughput is slower than 'normal nand')


Matthieu
pekon gupta Feb. 25, 2013, 9:38 a.m. UTC | #5
> -----Original Message-----
> From: Matthieu CASTET [mailto:matthieu.castet@parrot.com]
> Sent: Monday, February 25, 2013 2:54 PM
> To: Gupta, Pekon
> Cc: katsuki.uwatoko@toshiba.co.jp; linux-mtd@lists.infradead.org
> Subject: Re: [PATCH v2] mtd: nand: support BENAND (Built-in ECC NAND)
> 
> Gupta, Pekon a écrit :
> > Hi,
> >
> >> This enables support for BENAND, which is an SLC NAND flash solution
> >> with embedded error correction code (ECC), currently supports only
> >> 128bytes OOB type.
> >>
> >> In the read sequence, "status read command" is executed to check the
> >> ECC status after read data. If bitflips occur, these are
> >> automatically corrected by BENAND and the status indicates the result.
> >>
> >> The write sequence is the same as raw write and the ECC data are
> >> automatically written to OOB by BENAND.
> >
> > Just inquisitive, can anyone please share any throughput comparison
> between 'BENAND' & 'normal NAND' devices having same capacity and
> working on same clock-freq ?
> >
> > (a) Usually on-chip memory controllers work on faster clock frequencies, as
> compared to the NAND devices connected to them externally on board.
> > Thus I assume, ECC computation & correction can be done at faster rate.
> >
> > (b) However, on other hand BENAND(s) have luxury of accessing the Flash
> storage array locally, thus eliminating I/O delays | un-optimized IO signal
> timing from the access-path.
> >
> > So, if you can share the details throughput comparison between the two
> types of NAND devices, under various conditions it would be helpful.
> >
> You always have to transfer the data from/to the nand devices to/from the
> host.
> 
> - Either the ecc internal controller is fast and the throughput are the same
> than 'normal nand' (assuming the ecc controller on the host is fast),
> - either it is slow and the throughput is limited by the internal ecc controller
> (throughput is slower than 'normal nand')
> 
I agree about the data portion.. 
But assuming there is no file-system OOB metadata | cleanmarker to be stored (like in UBIFS)
Do we still need to transfer OOB data from Host processor to NAND device ?
If yes, then ECC calculation & correction which at times is main bottle-neck in NAND accesses, 
may be best done at Host-processor side.. 

Also, In-case there is some file-system metadata to be stored in OOB|spare area along with ECC,
how do we ensure that layout of metadata does not overlap with ECC syndrome in BENAND ?
Is the BENAND capable of re-adjusting its ECC layout ? 


with regards, pekon

> 
> Matthieu
Ricard Wanderlof Feb. 25, 2013, 10:18 a.m. UTC | #6
On Mon, 25 Feb 2013, Gupta, Pekon wrote:

> But assuming there is no file-system OOB metadata | cleanmarker to be stored (like in UBIFS)
> Do we still need to transfer OOB data from Host processor to NAND device ?
> If yes, then ECC calculation & correction which at times is main bottle-neck in NAND accesses,
> may be best done at Host-processor side..
>
> Also, In-case there is some file-system metadata to be stored in OOB|spare area along with ECC,
> how do we ensure that layout of metadata does not overlap with ECC syndrome in BENAND ?
> Is the BENAND capable of re-adjusting its ECC layout ?

BENAND uses a separate non-addressable area for its on-chip ECC. Thus, 
the complete OOB area is available for the user (except bad block marker 
bytes).

IIUC, however, BENAND has a restriction on how data can written to the 
flash. For instance, for a BENAND with 2k pages and 64 bytes OOB per page, 
each 512 byte area is paired with 16 bytes of the OOB. When writing using 
the on-chip ECC, one must write the 512 area of the main page followed by 
the paired 16 bytes in the OOB area, without writing a new column address 
to the flash. It is also possible just to write the main area, but then 
the paired OOB bytes cannot be written at a later date, as that will cause 
overwriting of the on-chip ECC, causing read errors during subsequent 
read.

I don't know if it's possible to write the whole 2k page in one go, 
followed immediately by the 64 byte OOB. I think not, but the 
documentation is not clear on this point IMHO, and I have not tested it.

The most efficient use of BENAND is probably to avoid using the OOB if 
possible, and just use the main area. This does require that the driver be 
configured accordingly which is a pity in a production environment where 
one wants to have as wide a range of chips to choose from during the 
production run.

/Ricard
Matthieu CASTET Feb. 25, 2013, 11:10 a.m. UTC | #7
Ricard Wanderlof a écrit :
> On Mon, 25 Feb 2013, Gupta, Pekon wrote:
> 
>> But assuming there is no file-system OOB metadata | cleanmarker to be stored (like in UBIFS)
>> Do we still need to transfer OOB data from Host processor to NAND device ?
>> If yes, then ECC calculation & correction which at times is main bottle-neck in NAND accesses,
>> may be best done at Host-processor side..
>>
>> Also, In-case there is some file-system metadata to be stored in OOB|spare area along with ECC,
>> how do we ensure that layout of metadata does not overlap with ECC syndrome in BENAND ?
>> Is the BENAND capable of re-adjusting its ECC layout ?
> 
> BENAND uses a separate non-addressable area for its on-chip ECC. Thus, 
> the complete OOB area is available for the user (except bad block marker 
> bytes).
There are 2 generations of BENAND :
- old generation that use oob for its on-chip ECC
- new generation that use a separate non-addressable area

I believe the patch is for the old generation because it create a special layout :

+
+static struct nand_ecclayout benand_oob_128 = {
+       .oobfree = {
+               {.offset = 2, .length = 3},
+               {.offset = 18, .length = 3},
+               {.offset = 34, .length = 3},
+               {.offset = 50, .length = 3},
+               {.offset = 66, .length = 3},
+               {.offset = 82, .length = 3},
+               {.offset = 98, .length = 3},
+               {.offset = 114, .length = 3},
+       }
+};


> 
> IIUC, however, BENAND has a restriction on how data can written to the 
> flash. For instance, for a BENAND with 2k pages and 64 bytes OOB per page, 
> each 512 byte area is paired with 16 bytes of the OOB. When writing using 
> the on-chip ECC, one must write the 512 area of the main page followed by 
> the paired 16 bytes in the OOB area, without writing a new column address 
> to the flash. It is also possible just to write the main area, but then 
> the paired OOB bytes cannot be written at a later date, as that will cause 
> overwriting of the on-chip ECC, causing read errors during subsequent 
> read.
> 
> I don't know if it's possible to write the whole 2k page in one go, 
> followed immediately by the 64 byte OOB. I think not, but the 
> documentation is not clear on this point IMHO, and I have not tested it.
I think it is possible : on our test we didn't deactivate the soc nand
controller ecc : it wrote 2K of data + OOB with its ecc. And it was working.

I believe it is what they wanted when using a separate non-addressable area.
They wanted to provide new generation nand flash that require more ecc
correction, but that is transparent for the host (very little software
modification : check status bit in read).



> 
> The most efficient use of BENAND is probably to avoid using the OOB if 
> possible, and just use the main area. This does require that the driver be 
> configured accordingly which is a pity in a production environment where 
> one wants to have as wide a range of chips to choose from during the 
> production run.

Yes using OOB is asking for trouble with new nand.


Matthieu
pekon gupta Feb. 25, 2013, 11:35 a.m. UTC | #8
> Ricard Wanderlof a écrit :
> > On Mon, 25 Feb 2013, Gupta, Pekon wrote:
> >
> >> But assuming there is no file-system OOB metadata | cleanmarker to be
> stored (like in UBIFS)
> >> Do we still need to transfer OOB data from Host processor to NAND
> device ?
> >> If yes, then ECC calculation & correction which at times is main bottle-neck
> in NAND accesses,
> >> may be best done at Host-processor side..
> >>
> >> Also, In-case there is some file-system metadata to be stored in
> OOB|spare area along with ECC,
> >> how do we ensure that layout of metadata does not overlap with ECC
> syndrome in BENAND ?
> >> Is the BENAND capable of re-adjusting its ECC layout ?
> >
> > BENAND uses a separate non-addressable area for its on-chip ECC. Thus,
> > the complete OOB area is available for the user (except bad block marker
> > bytes).
> There are 2 generations of BENAND :
> - old generation that use oob for its on-chip ECC
> - new generation that use a separate non-addressable area
> 
> I believe the patch is for the old generation because it create a special layout
> :
> 
> +
> +static struct nand_ecclayout benand_oob_128 = {
> +       .oobfree = {
> +               {.offset = 2, .length = 3},
> +               {.offset = 18, .length = 3},
> +               {.offset = 34, .length = 3},
> +               {.offset = 50, .length = 3},
> +               {.offset = 66, .length = 3},
> +               {.offset = 82, .length = 3},
> +               {.offset = 98, .length = 3},
> +               {.offset = 114, .length = 3},
> +       }
> +};
> 
> 
> >
> > IIUC, however, BENAND has a restriction on how data can written to the
> > flash. For instance, for a BENAND with 2k pages and 64 bytes OOB per page,
> > each 512 byte area is paired with 16 bytes of the OOB. When writing using
> > the on-chip ECC, one must write the 512 area of the main page followed by
> > the paired 16 bytes in the OOB area, without writing a new column address
> > to the flash. It is also possible just to write the main area, but then
> > the paired OOB bytes cannot be written at a later date, as that will cause
> > overwriting of the on-chip ECC, causing read errors during subsequent
> > read.
> >
Thanks much.. This was a nice information. 
This probably also means that on-die ECC would also cover the meta-data 
present in OOB area, that is why BENAND require 16bytes of OOB to be input 
along with 512bytes main-area data.

> > I don't know if it's possible to write the whole 2k page in one go,
> > followed immediately by the 64 byte OOB. I think not, but the
> > documentation is not clear on this point IMHO, and I have not tested it.
> >
> I think it is possible : on our test we didn't deactivate the soc nand
> controller ecc : it wrote 2K of data + OOB with its ecc. And it was working.
> 
However, above test shows that OOB area is not covered in on-die ECC calculation.
You can check if OOB area was also covered in on-die ECC calculation, 
by purposely introducing a bit-flip in OOB area.


> I believe it is what they wanted when using a separate non-addressable area.
> They wanted to provide new generation nand flash that require more ecc
> correction, but that is transparent for the host (very little software
> modification : check status bit in read).
> 
But having separate ECC checks:
- One by Host-Processor (stored in OOB),
- And another on-die ECC (stored in non-accessible area)
May not actually help in finding more number of bit-flips, because both 
algorithms may be just duplicating each. 
(example: Calculating BCH8 twice does not increase its capability to 
detect more number of errors, because both checks are on same main-data).

> 
> 
> >
> > The most efficient use of BENAND is probably to avoid using the OOB if
> > possible, and just use the main area. This does require that the driver be
> > configured accordingly which is a pity in a production environment where
> > one wants to have as wide a range of chips to choose from during the
> > production run.
> 
> Yes using OOB is asking for trouble with new nand.
>
In such case, is it correct to assume both JFFS2 and YAFFS2 (with out-of-band tags), 
cannot be used with Old-type BENAND, (which use oob-data for its on-die ECC) ?
because both JFFS2 and YAFFS2 save some metadata in OOB.


with regards, pekon 
> 
> Matthieu
katsuki.uwatoko@toshiba.co.jp Feb. 26, 2013, 2:41 a.m. UTC | #9
> > > Just inquisitive, can anyone please share any throughput comparison
> > between 'BENAND' & 'normal NAND' devices having same capacity and
> > working on same clock-freq ?

I think that the following would be helpful.

http://www.toshiba-components.com/memory/benand.html
http://www.toshiba-components.com/memory/data/BENAND%20QA_V1.0_121031.pdf
http://www.toshiba-components.com/memory/data/Whitepaper_BENAND_11_2012.pdf

> But assuming there is no file-system OOB metadata | cleanmarker to be stored (like in UBIFS)
> Do we still need to transfer OOB data from Host processor to NAND device ?

No, we don't.

> how do we ensure that layout of metadata does not overlap with ECC syndrome in BENAND ?
> Is the BENAND capable of re-adjusting its ECC layout ? 

The area which we can use is defined as nand_ecclayout in nand_benand.c.
And the area is covered by the built-in ECC.

+static struct nand_ecclayout benand_oob_128 = {
+	.oobfree = {
+		{.offset = 2, .length = 3},
+		{.offset = 18, .length = 3},
+		{.offset = 34, .length = 3},
+		{.offset = 50, .length = 3},
+		{.offset = 66, .length = 3},
+		{.offset = 82, .length = 3},
+		{.offset = 98, .length = 3},
+		{.offset = 114, .length = 3},
+	}
+};

In the case of 24nm products, which are NOT 128bytes OOB type, 
the whole area of OOB can be available and is covered by the built-in ECC.
Artem Bityutskiy March 11, 2013, 8:57 a.m. UTC | #10
On Thu, 2013-02-21 at 06:17 +0000, katsuki.uwatoko@toshiba.co.jp wrote:
> This enables support for BENAND, which is an SLC NAND flash solution
> with embedded error correction code (ECC), currently supports only
> 128bytes OOB type.
> 
> In the read sequence, "status read command" is executed to check the
> ECC status after read data. If bitflips occur, these are
> automatically corrected by BENAND and the status indicates the result.
> 
> The write sequence is the same as raw write and the ECC data are
> automatically written to OOB by BENAND.
> 
> Signed-off-by: UWATOKO Katsuki <katsuki.uwatoko@toshiba.co.jp>

Hi Katsuki, thanks for the patch. I would really like to see someone's
ack or Tested-by on it. Anyonwe?

Does Toshiba still produce SLC BENANDs?
katsuki.uwatoko@toshiba.co.jp March 18, 2013, 2:40 a.m. UTC | #11
Hi Artem,

I'm sorry for the delay in my response.

On Mon, 11 Mar 2013 10:57:29 +0200, Artem Bityutskiy wrote:
> Hi Katsuki, thanks for the patch. I would really like to see someone's
> ack or Tested-by on it. Anyonwe?
> 
> Does Toshiba still produce SLC BENANDs?

Yes. We can still get SLC BENANDs.
diff mbox

Patch

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 4883139..acf0c25 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -37,6 +37,17 @@  config MTD_NAND_ECC_BCH
 	  ECC codes. They are used with NAND devices requiring more than 1 bit
 	  of error correction.
 
+config MTD_NAND_BENAND
+	bool "Support BENAND (embedded ECC NAND)"
+	default n
+	help
+	  This enables support for BENAND, which is an SLC NAND flash
+	  solution with embedded error correction code (ECC).
+	  currently supports only 128bytes OOB type.
+	  In the read sequence, "status read command" is executed to check
+	  the ECC status after read data.
+	  The write sequence is the same as raw write.
+
 config MTD_SM_COMMON
 	tristate
 	default n
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2cbd091..f58dee8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -5,6 +5,7 @@ 
 obj-$(CONFIG_MTD_NAND)			+= nand.o
 obj-$(CONFIG_MTD_NAND_ECC)		+= nand_ecc.o
 obj-$(CONFIG_MTD_NAND_BCH)		+= nand_bch.o
+obj-$(CONFIG_MTD_NAND_BENAND)		+= nand_benand.o
 obj-$(CONFIG_MTD_NAND_IDS)		+= nand_ids.o
 obj-$(CONFIG_MTD_SM_COMMON) 		+= sm_common.o
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1a03b7f..9cbef8c 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -43,6 +43,7 @@ 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/nand_bch.h>
+#include <linux/mtd/nand_benand.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/leds.h>
@@ -3076,6 +3077,11 @@  static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
 		extid >>= 2;
 		/* Get buswidth information */
 		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+
+		/* check BENAND (embedded ECC) */
+		if (id_data[0] == NAND_MFR_TOSHIBA &&
+		    (id_data[4] & NAND_ECCENGINE))
+			nand_benand_setupecc(mtd, &(chip->ecc.mode));
 	}
 }
 
@@ -3530,6 +3536,25 @@  int nand_scan_tail(struct mtd_info *mtd)
 			chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
 		break;
 
+	case NAND_ECC_BENAND:
+		if (!IS_ENABLED(CONFIG_MTD_NAND_BENAND)) {
+			pr_warn("CONFIG_MTD_BENAND not enabled\n");
+			BUG();
+		}
+
+		chip->ecc.read_page = nand_read_page_benand;
+		chip->ecc.write_page = nand_write_page_raw;
+		chip->ecc.read_page_raw = nand_read_page_raw;
+		chip->ecc.write_page_raw = nand_write_page_raw;
+		chip->ecc.read_oob = nand_read_oob_std;
+		chip->ecc.write_oob = nand_write_oob_std;
+
+		if (nand_benand_init(mtd)) {
+			pr_warn("BENAND initialization failed!\n");
+			BUG();
+		}
+		break;
+
 	case NAND_ECC_NONE:
 		pr_warn("NAND_ECC_NONE selected by board driver. "
 			   "This is not recommended!\n");
diff --git a/drivers/mtd/nand/nand_benand.c b/drivers/mtd/nand/nand_benand.c
new file mode 100644
index 0000000..fe8008d
--- /dev/null
+++ b/drivers/mtd/nand/nand_benand.c
@@ -0,0 +1,113 @@ 
+/*
+ * This file provides functions for BENAND, which is an SLC NAND flash
+ * solution with embedded error correction code (ECC).
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2013
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_benand.h>
+
+static struct nand_ecclayout benand_oob_128 = {
+	.oobfree = {
+		{.offset = 2, .length = 3},
+		{.offset = 18, .length = 3},
+		{.offset = 34, .length = 3},
+		{.offset = 50, .length = 3},
+		{.offset = 66, .length = 3},
+		{.offset = 82, .length = 3},
+		{.offset = 98, .length = 3},
+		{.offset = 114, .length = 3},
+	}
+};
+
+/**
+ * nand_read_page_raw - [Intern] read raw page data with benand.
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: caller requires OOB data read to chip->oob_poi
+ * @page: page number to read
+ *
+ * Not for syndrome calculating ECC controllers, which use a special oob layout.
+ */
+
+int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip,
+			  uint8_t *buf, int oob_required, int page)
+{
+	u8 status;
+	unsigned int max_bitflips = 0;
+
+	chip->ecc.read_page_raw(mtd, chip, buf, oob_required, page);
+
+	/* Check Read Status */
+
+	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+	status = chip->read_byte(mtd);
+
+	if (status & NAND_STATUS_FAIL)
+		/* uncorrectable error */
+		mtd->ecc_stats.failed++;
+	else if (status & NAND_CHIP_READ_STATUS) {
+		/* correctable error
+		   How many bits have been corrected is unknown.
+		   therefore bitflips is set to ecc.strength. */
+		mtd->ecc_stats.corrected += chip->ecc.strength;
+		max_bitflips = chip->ecc.strength;
+	}
+
+	return max_bitflips;
+}
+EXPORT_SYMBOL(nand_read_page_benand);
+
+void nand_benand_setupecc(struct mtd_info *mtd, nand_ecc_modes_t *mode)
+{
+	/* support only 128bytes OOB type */
+	if (mtd->oobsize == 128)
+		*mode = NAND_ECC_BENAND;
+}
+
+int nand_benand_init(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	chip->ecc.size = mtd->writesize;
+
+	if (mtd->oobsize == 128) {
+		chip->ecc.layout = &benand_oob_128;
+		chip->ecc.bytes = 72;      /* 9B * (4096B/512B) */
+		chip->ecc.strength = 32;   /* 4b * (4096B/512B) */
+	} else {
+		pr_warn("%d unsupported oobsize in benand_init\n",
+			mtd->oobsize);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(nand_benand_init);
+
+MODULE_AUTHOR("TOSHIBA Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("BENAND (embedded ECC NAND) support");
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 24e9159..b01c4bf 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -129,6 +129,7 @@  extern int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 /* Status bits */
 #define NAND_STATUS_FAIL	0x01
 #define NAND_STATUS_FAIL_N1	0x02
+#define NAND_CHIP_READ_STATUS   0x08  /* for BENAND */
 #define NAND_STATUS_TRUE_READY	0x20
 #define NAND_STATUS_READY	0x40
 #define NAND_STATUS_WP		0x80
@@ -143,6 +144,7 @@  typedef enum {
 	NAND_ECC_HW_SYNDROME,
 	NAND_ECC_HW_OOB_FIRST,
 	NAND_ECC_SOFT_BCH,
+	NAND_ECC_BENAND,
 } nand_ecc_modes_t;
 
 /*
@@ -575,6 +577,11 @@  struct nand_chip {
 #define NAND_MFR_MACRONIX	0xc2
 #define NAND_MFR_EON		0x92
 
+/*
+ * 5th ID Data
+ */
+#define NAND_ECCENGINE		(1<<7)  /* ECC engine on chip */
+
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
  * @name:	Identify the device type
diff --git a/include/linux/mtd/nand_benand.h b/include/linux/mtd/nand_benand.h
new file mode 100644
index 0000000..a047b6f
--- /dev/null
+++ b/include/linux/mtd/nand_benand.h
@@ -0,0 +1,43 @@ 
+/*
+ * (C) Copyright TOSHIBA CORPORATION 2013
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is the header for the NAND BENAND implementation.
+ */
+
+#ifndef __MTD_NAND_BENAND_H__
+#define __MTD_NAND_BENAND_H__
+
+#if defined(CONFIG_MTD_NAND_BENAND)
+
+void nand_benand_setupecc(struct mtd_info *mtd, nand_ecc_modes_t *mode);
+
+int nand_read_page_benand(struct mtd_info *mtd, struct nand_chip *chip,
+			  uint8_t *buf, int oob_required, int page);
+
+int nand_benand_init(struct mtd_info *mtd);
+
+#else /* !CONFIG_MTD_NAND_BENAND */
+
+static inline void nand_benand_setupecc(struct mtd_info *mtd,
+					nand_ecc_modes_t *mode) {}
+
+static inline int nand_read_page_benand(struct mtd_info *mtd,
+					struct nand_chip *chip,
+					uint8_t *buf, int oob_required,
+					int page)
+{
+	return -1;
+}
+
+static inline int nand_benand_init(struct mtd_info *mtd)
+{
+	return -1;
+}
+
+#endif /* CONFIG_MTD_NAND_BENAND */
+#endif /* __MTD_NAND_BENAND_H__ */