Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-11 Thread Ivan Djelic
On Thu, Oct 11, 2012 at 06:27:13AM +0100, Philip, Avinash wrote:
(...)
  Another simple strategy could use the fact that you add a 14th zero byte to
  the 13 BCH bytes for RBL compatibility:
 
 RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.
 
 So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
 we can go for same approaches in BCH4  BCH8 ecc scheme.
 
 If I understood correctly, software BCH ecc scheme is modifying calculated
 ecc data to handle bit flips in erased pages.
 
 If that is the only reason, whether same logic can go for same ECC calculation
 (remove modification of calculated ecc in case of software ecc correction)
 by adding an extra byte (0) in spare area to handle erased pages.
 
 So can you share if I am missing something?

Yes, the only reason why a constant polynomial is added to hw-generated ECC 
bytes is to transparently handle bitflips in erased pages.
Handling erased pages this way has several benefits over the zero byte hack:
- cleaner code, no checking of the zero byte
- no expensive scan of data+spare area when reading an erased block: this step 
can significantly slow down the initial UBI scan (lots of erased pages to read)
- no need to worry about the (very unlikely) possibility of having more than 4 
bitflips in the zero byte

OTOH, having the same ECC codes for both ELM and non-ELM chips with RBL 
compatibility sounds nice and would also simplify things.
Note: on platforms where we use SW BCH correction, we also use the MLC OMAP 
boot mode, which is more robust and not compatible with 8-bit/4-bit BCH layouts.

I don't know which way is better for the OMAP community:
1. Unifying ECC modes = loosing the constant polynomial benefits, but gaining 
RBL compat and simplifying code
2. Keeping separate ECC modes = code bloat

Tony, do you have an opinion on this ?

BTW, Afzal is submitting a series of patches [1] which are not compatible with 
your series; is there any plan to merge your patches ?

BR,
--
Ivan

[1] http://lists.infradead.org/pipermail/linux-mtd/2012-October/044374.html
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-11 Thread Philip, Avinash
On Thu, Oct 11, 2012 at 13:51:49, Ivan Djelic wrote:
 On Thu, Oct 11, 2012 at 06:27:13AM +0100, Philip, Avinash wrote:
 (...)
   Another simple strategy could use the fact that you add a 14th zero byte 
   to
   the 13 BCH bytes for RBL compatibility:
  
  RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.
  
  So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
  we can go for same approaches in BCH4  BCH8 ecc scheme.
  
  If I understood correctly, software BCH ecc scheme is modifying calculated
  ecc data to handle bit flips in erased pages.
  
  If that is the only reason, whether same logic can go for same ECC 
  calculation
  (remove modification of calculated ecc in case of software ecc correction)
  by adding an extra byte (0) in spare area to handle erased pages.
  
  So can you share if I am missing something?
 
 Yes, the only reason why a constant polynomial is added to hw-generated ECC
 bytes is to transparently handle bitflips in erased pages.
 Handling erased pages this way has several benefits over the zero byte hack:
 - cleaner code, no checking of the zero byte
 - no expensive scan of data+spare area when reading an erased block: this
   step can significantly slow down the initial UBI scan (lots of erased
pages to read)

Thanks for raising this point.
In order to reduce scan time of data+spare area when reading an erased block,
we can follow below steps

1. Create a standard ecc vector for erased page  check against it with 
calculated
   ecc of erased page.
2. If the vectors won't match, go for counting bit flips in erased page.
3. Again filtering of erased page can done by checking zero at fixed locations
   in spare area.
Note:
Reading of bits in erased page should done only for pages having bitflips.

 - no need to worry about the (very unlikely) possibility of having more
   than 4 bitflips in the zero byte
 
 OTOH, having the same ECC codes for both ELM and non-ELM chips with RBL
 compatibility sounds nice and would also simplify things.
 Note: on platforms where we use SW BCH correction, we also use the
 MLC OMAP boot mode, which is more robust and not compatible
 with 8-bit/4-bit BCH layouts.
 
 I don't know which way is better for the OMAP community:
 1. Unifying ECC modes = loosing the constant polynomial benefits,
but gaining RBL compat and simplifying code
 2. Keeping separate ECC modes = code bloat
 
 Tony, do you have an opinion on this ?
 
 BTW, Afzal is submitting a series of patches [1] which are not
 compatible with your series; is there any plan to merge your patches ?

My next series will be on top Afzal's changes.

Thanks
Avinash

 
 BR,
 --
 Ivan
 
 [1] http://lists.infradead.org/pipermail/linux-mtd/2012-October/044374.html
 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-11 Thread Tony Lindgren
* Ivan Djelic ivan.dje...@parrot.com [121011 01:23]:
 
 I don't know which way is better for the OMAP community:
 1. Unifying ECC modes = loosing the constant polynomial benefits, but gaining 
 RBL compat and simplifying code
 2. Keeping separate ECC modes = code bloat
 
 Tony, do you have an opinion on this ?

Well right now I'm mostly interested in making device
drivers independent of the arch/arm/*omap*/* code.
That's where Afzal's patches help quite a bit, so let's
get those in first. So from that point of view, option #1
above sounds better as the first step :)

Ideally of course option #1 should not limit us from
adding extra features in the long run.

Regards,

Tony 
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-10 Thread Ivan Djelic
On Tue, Oct 09, 2012 at 01:36:50PM +0100, Philip, Avinash wrote:
(...)
  There are at least 2 potential problems when reading an erased page with 
  bitflips:
  
  1. bitflip in data area and no bitflip in spare area (all 0xff)
  Your code will not perform any ECC correction.
  UBIFS does not like finding bitflips in empty pages, see for instance
  http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.
 
 In case of error correction using ELM, syndrome vector calculated after 
 reading
 Data area  OOB area. So handling of erased page requires a software 
 workaround.
 I am planning something as follows.
 
 I will first check calculated ecc, which would be zero for non error pages.
 Then I would check 0xFF in OOB area (for erased page) by checking number of
 bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
 set entire page as 0xFF if number of bit zeros is less than max bit flips
 (8 or 4) by counting the number of bit zero's in data area.
 
 This logic is implemented in fsmc_nand.c
 
 See commit
 mtd: fsmc: Newly erased page read algorithm implemented
 
  
  2. bitflip in ECC bytes in spare area
  Your code will report an uncorrectable error upon reading; if this happens 
  while reading a partially programmed UBI block,
  I guess you will lose data.
 
 In case of uncorrectable errors due to bit flips in spare area,
 I can go on checking number of bit zero's in data area + OOB area
 are less than max bit flips (8 or 4), I can go on setting the entire
 page as 0xFF.
 

OK, sounds reasonable.
Another simple strategy could use the fact that you add a 14th zero byte to
the 13 BCH bytes for RBL compatibility:

Upon reading:
 - if this 14th byte is zero (*) = page was programmed: perform ECC
   correction as usual
 - else, page was not programmed: do not perform ECC, read entire data+spare
   area, and set it to 0xff if less than 8 or 4 (max bitflips) zero bits
   were found

(*) for robustness to bitflip in 14th byte, replace condition
14th byte is zero by e.g. 14th byte has less than 4 bits set to 1.

What do you think ?

BR,
--
Ivan
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-10 Thread Philip, Avinash
On Wed, Oct 10, 2012 at 22:38:06, Ivan Djelic wrote:
 On Tue, Oct 09, 2012 at 01:36:50PM +0100, Philip, Avinash wrote:
 (...)
   There are at least 2 potential problems when reading an erased page with 
   bitflips:
   
   1. bitflip in data area and no bitflip in spare area (all 0xff)
   Your code will not perform any ECC correction.
   UBIFS does not like finding bitflips in empty pages, see for instance
   http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.
  
  In case of error correction using ELM, syndrome vector calculated after 
  reading
  Data area  OOB area. So handling of erased page requires a software 
  workaround.
  I am planning something as follows.
  
  I will first check calculated ecc, which would be zero for non error pages.
  Then I would check 0xFF in OOB area (for erased page) by checking number of
  bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
  set entire page as 0xFF if number of bit zeros is less than max bit flips
  (8 or 4) by counting the number of bit zero's in data area.
  
  This logic is implemented in fsmc_nand.c
  
  See commit
  mtd: fsmc: Newly erased page read algorithm implemented
  
   
   2. bitflip in ECC bytes in spare area
   Your code will report an uncorrectable error upon reading; if this 
   happens while reading a partially programmed UBI block,
   I guess you will lose data.
  
  In case of uncorrectable errors due to bit flips in spare area,
  I can go on checking number of bit zero's in data area + OOB area
  are less than max bit flips (8 or 4), I can go on setting the entire
  page as 0xFF.
  
 
 OK, sounds reasonable.
 Another simple strategy could use the fact that you add a 14th zero byte to
 the 13 BCH bytes for RBL compatibility:

RBL compatibility (14th byte) is applicable only for BCH8 ecc scheme.

So I am planning adding an extra byte (0) for BCH4 ecc scheme. So with this
we can go for same approaches in BCH4  BCH8 ecc scheme.

If I understood correctly, software BCH ecc scheme is modifying calculated
ecc data to handle bit flips in erased pages.

If that is the only reason, whether same logic can go for same ECC calculation
(remove modification of calculated ecc in case of software ecc correction)
by adding an extra byte (0) in spare area to handle erased pages.

So can you share if I am missing something?

 
 Upon reading:
  - if this 14th byte is zero (*) = page was programmed: perform ECC
correction as usual
  - else, page was not programmed: do not perform ECC, read entire data+spare
area, and set it to 0xff if less than 8 or 4 (max bitflips) zero bits
were found
 
 (*) for robustness to bitflip in 14th byte, replace condition
 14th byte is zero by e.g. 14th byte has less than 4 bits set to 1.
 
 What do you think ?

This seems logically good.

Thanks
Avinash

 
 BR,
 --
 Ivan
 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-09 Thread Philip, Avinash
On Fri, Oct 05, 2012 at 19:53:38, Ivan Djelic wrote:
 On Fri, Oct 05, 2012 at 09:51:50AM +0100, Philip, Avinash wrote:
  On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
   On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
 ELM module can be used for error correction of BCH 4  8 bit. Also
 support read  write page in one shot by adding custom read_page 
 write_page methods. This helps in optimizing code.
 
 New structure member is_elm_used is added to know the status of
 whether the ELM module is used for error correction or not.
 
 Note:
 ECC layout of BCH8 uses 14 bytes for 512 byte of data to make 
 compatible
 with RBL ECC layout, even though the requirement was only 13 byte. 
 This
 results a common ecc layout across RBL, U-boot  Linux.
 

See a few comments below,

(...)
 +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
 +   u_char *read_ecc, u_char *calc_ecc)
 +{
 +   struct omap_nand_info *info = container_of(mtd, struct 
 omap_nand_info,
 +   mtd);
 +   int eccsteps = info-nand.ecc.steps;
 +   int i , j, stat = 0;
 +   int eccsize, eccflag, size;
 +   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
 +   u_char *ecc_vec = calc_ecc;
 +   enum bch_ecc type;
 +   bool is_error_reported = false;
 +
 +   /* initialize elm error vector to zero */
 +   memset(err_vec, 0, sizeof(err_vec));
 +   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
 +   size = BCH8_SIZE;
 +   eccsize = BCH8_ECC_OOB_BYTES;
 +   type = BCH8_ECC;
 +   } else {
 +   size = BCH4_SIZE;
 +   eccsize = BCH4_SIZE;
 +   type = BCH4_ECC;
 +   }
 +
 +   for (i = 0; i  eccsteps ; i++) {
 +   eccflag = 0;/* initialize eccflag */
 +
 +   for (j = 0; (j  eccsize); j++) {
 +   if (read_ecc[j] != 0xFF) {
 +   eccflag = 1;/* data area is 
 flashed */

Just a reminder: this way of checking if a page has been programmed is 
not robust to bitflips,
so you may get into trouble with UBIFS on a fairly recent device.
  
  Sorry I missed this point.
  
  Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) 
  is 0xFF. If all data
  in spare area is 0xFF, conclude that the page is erased  no need of error 
  correction. In case
  of bit flip present in spare area, page will be reported as uncorrectable.
  But I am not understand understand  trouble with UBIFS on a fairly recent 
  device.
  Can you little elaborativ
 
 There are at least 2 potential problems when reading an erased page with 
 bitflips:
 
 1. bitflip in data area and no bitflip in spare area (all 0xff)
 Your code will not perform any ECC correction.
 UBIFS does not like finding bitflips in empty pages, see for instance
 http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.

In case of error correction using ELM, syndrome vector calculated after reading
Data area  OOB area. So handling of erased page requires a software workaround.
I am planning something as follows.

I will first check calculated ecc, which would be zero for non error pages.
Then I would check 0xFF in OOB area (for erased page) by checking number of
bit zeros in OOB area.  If it is 0xFF (number of bit zero count is zero),
set entire page as 0xFF if number of bit zeros is less than max bit flips
(8 or 4) by counting the number of bit zero's in data area.

This logic is implemented in fsmc_nand.c

See commit
mtd: fsmc: Newly erased page read algorithm implemented

 
 2. bitflip in ECC bytes in spare area
 Your code will report an uncorrectable error upon reading; if this happens 
 while reading a partially programmed UBI block,
 I guess you will lose data.

In case of uncorrectable errors due to bit flips in spare area,
I can go on checking number of bit zero's in data area + OOB area
are less than max bit flips (8 or 4), I can go on setting the entire
page as 0xFF.

Thanks
Avinash

 
 BR,
 --
 Ivan
 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-05 Thread Philip, Avinash
On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
 On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
  On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
   ELM module can be used for error correction of BCH 4  8 bit. Also
   support read  write page in one shot by adding custom read_page 
   write_page methods. This helps in optimizing code.
   
   New structure member is_elm_used is added to know the status of
   whether the ELM module is used for error correction or not.
   
   Note:
   ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
   with RBL ECC layout, even though the requirement was only 13 byte. This
   results a common ecc layout across RBL, U-boot  Linux.
   
  
  See a few comments below,
  
  (...)
   +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
   +   u_char *read_ecc, u_char *calc_ecc)
   +{
   +   struct omap_nand_info *info = container_of(mtd, struct 
   omap_nand_info,
   +   mtd);
   +   int eccsteps = info-nand.ecc.steps;
   +   int i , j, stat = 0;
   +   int eccsize, eccflag, size;
   +   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
   +   u_char *ecc_vec = calc_ecc;
   +   enum bch_ecc type;
   +   bool is_error_reported = false;
   +
   +   /* initialize elm error vector to zero */
   +   memset(err_vec, 0, sizeof(err_vec));
   +   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
   +   size = BCH8_SIZE;
   +   eccsize = BCH8_ECC_OOB_BYTES;
   +   type = BCH8_ECC;
   +   } else {
   +   size = BCH4_SIZE;
   +   eccsize = BCH4_SIZE;
   +   type = BCH4_ECC;
   +   }
   +
   +   for (i = 0; i  eccsteps ; i++) {
   +   eccflag = 0;/* initialize eccflag */
   +
   +   for (j = 0; (j  eccsize); j++) {
   +   if (read_ecc[j] != 0xFF) {
   +   eccflag = 1;/* data area is flashed */
  
  Just a reminder: this way of checking if a page has been programmed is not 
  robust to bitflips,
  so you may get into trouble with UBIFS on a fairly recent device.

Sorry I missed this point.

Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) is 
0xFF. If all data
in spare area is 0xFF, conclude that the page is erased  no need of error 
correction. In case
of bit flip present in spare area, page will be reported as uncorrectable.
But I am not understand understand  trouble with UBIFS on a fairly recent 
device.
Can you little elaborativ

Thanks
Avinash 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-05 Thread Ivan Djelic
On Fri, Oct 05, 2012 at 09:51:50AM +0100, Philip, Avinash wrote:
 On Thu, Oct 04, 2012 at 15:51:03, Philip, Avinash wrote:
  On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
   On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
ELM module can be used for error correction of BCH 4  8 bit. Also
support read  write page in one shot by adding custom read_page 
write_page methods. This helps in optimizing code.

New structure member is_elm_used is added to know the status of
whether the ELM module is used for error correction or not.

Note:
ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
with RBL ECC layout, even though the requirement was only 13 byte. This
results a common ecc layout across RBL, U-boot  Linux.

   
   See a few comments below,
   
   (...)
+static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
+   u_char *read_ecc, u_char *calc_ecc)
+{
+   struct omap_nand_info *info = container_of(mtd, struct 
omap_nand_info,
+   mtd);
+   int eccsteps = info-nand.ecc.steps;
+   int i , j, stat = 0;
+   int eccsize, eccflag, size;
+   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
+   u_char *ecc_vec = calc_ecc;
+   enum bch_ecc type;
+   bool is_error_reported = false;
+
+   /* initialize elm error vector to zero */
+   memset(err_vec, 0, sizeof(err_vec));
+   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
+   size = BCH8_SIZE;
+   eccsize = BCH8_ECC_OOB_BYTES;
+   type = BCH8_ECC;
+   } else {
+   size = BCH4_SIZE;
+   eccsize = BCH4_SIZE;
+   type = BCH4_ECC;
+   }
+
+   for (i = 0; i  eccsteps ; i++) {
+   eccflag = 0;/* initialize eccflag */
+
+   for (j = 0; (j  eccsize); j++) {
+   if (read_ecc[j] != 0xFF) {
+   eccflag = 1;/* data area is flashed 
*/
   
   Just a reminder: this way of checking if a page has been programmed is 
   not robust to bitflips,
   so you may get into trouble with UBIFS on a fairly recent device.
 
 Sorry I missed this point.
 
 Here we were checking data in spare area (only in ecc layout 14*4 for BCH8) 
 is 0xFF. If all data
 in spare area is 0xFF, conclude that the page is erased  no need of error 
 correction. In case
 of bit flip present in spare area, page will be reported as uncorrectable.
 But I am not understand understand  trouble with UBIFS on a fairly recent 
 device.
 Can you little elaborativ

There are at least 2 potential problems when reading an erased page with 
bitflips:

1. bitflip in data area and no bitflip in spare area (all 0xff)
Your code will not perform any ECC correction.
UBIFS does not like finding bitflips in empty pages, see for instance
http://lists.infradead.org/pipermail/linux-mtd/2012-March/040328.html.

2. bitflip in ECC bytes in spare area
Your code will report an uncorrectable error upon reading; if this happens 
while reading a partially programmed UBI block,
I guess you will lose data.

BR,
--
Ivan
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-04 Thread Philip, Avinash
On Thu, Oct 04, 2012 at 00:50:45, Ivan Djelic wrote:
 On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
  ELM module can be used for error correction of BCH 4  8 bit. Also
  support read  write page in one shot by adding custom read_page 
  write_page methods. This helps in optimizing code.
  
  New structure member is_elm_used is added to know the status of
  whether the ELM module is used for error correction or not.
  
  Note:
  ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
  with RBL ECC layout, even though the requirement was only 13 byte. This
  results a common ecc layout across RBL, U-boot  Linux.
  
 
 See a few comments below,
 
 (...)
  +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
  +   u_char *read_ecc, u_char *calc_ecc)
  +{
  +   struct omap_nand_info *info = container_of(mtd, struct 
  omap_nand_info,
  +   mtd);
  +   int eccsteps = info-nand.ecc.steps;
  +   int i , j, stat = 0;
  +   int eccsize, eccflag, size;
  +   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
  +   u_char *ecc_vec = calc_ecc;
  +   enum bch_ecc type;
  +   bool is_error_reported = false;
  +
  +   /* initialize elm error vector to zero */
  +   memset(err_vec, 0, sizeof(err_vec));
  +   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
  +   size = BCH8_SIZE;
  +   eccsize = BCH8_ECC_OOB_BYTES;
  +   type = BCH8_ECC;
  +   } else {
  +   size = BCH4_SIZE;
  +   eccsize = BCH4_SIZE;
  +   type = BCH4_ECC;
  +   }
  +
  +   for (i = 0; i  eccsteps ; i++) {
  +   eccflag = 0;/* initialize eccflag */
  +
  +   for (j = 0; (j  eccsize); j++) {
  +   if (read_ecc[j] != 0xFF) {
  +   eccflag = 1;/* data area is flashed */
 
 Just a reminder: this way of checking if a page has been programmed is not 
 robust to bitflips,
 so you may get into trouble with UBIFS on a fairly recent device.
 
 (...)
  @@ -1039,14 +1180,45 @@ static void omap3_enable_hwecc_bch(struct mtd_info 
  *mtd, int mode)
  
  nerrors = info-nand.ecc.strength;
  dev_width = (chip-options  NAND_BUSWIDTH_16) ? 1 : 0;
  +#ifdef CONFIG_MTD_NAND_OMAP_BCH
  +   if (info-is_elm_used) {
  +   /*
  +* Program GPMC to perform correction on (steps * 512) byte
  +* sector at a time.
  +*/
  +   gpmc_enable_hwecc_bch(info-gpmc_cs, mode, dev_width,
  +   info-nand.ecc.steps, nerrors);
  +   return;
  +   }
  +#endif
  /*
  -* Program GPMC to perform correction on one 512-byte sector at a 
  time.
  -* Using 4 sectors at a time (i.e. ecc.size = 2048) is also 
  possible and
  -* gives a slight (5%) performance gain (but requires additional 
  code).
  +* Program GPMC to perform correction on one 512-byte sector at
  +* a time.
 
 Why removing the comment about 4-sector perf gain ? :-)

With this patch, support for reading 4 sectors (max 8) is available.
Hence I am removing it.

 
 (...)
  @@ -1146,35 +1402,62 @@ static int omap3_init_bch(struct mtd_info *mtd, int 
  ecc_opt)
  goto fail;
  }
  
  -   /* initialize GPMC BCH engine */
  -   ret = gpmc_init_hwecc_bch(info-gpmc_cs, 1, max_errors);
  -   if (ret)
  -   goto fail;
  -
  -   /* software bch library is only used to detect and locate errors */
  -   info-bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
  -   if (!info-bch)
  -   goto fail;
  +   info-nand.ecc.size = 512;
  +   info-nand.ecc.hwctl = omap3_enable_hwecc_bch;
  +   info-nand.ecc.mode = NAND_ECC_HW;
  +   info-nand.ecc.strength = hw_errors;
  
  -   info-nand.ecc.size= 512;
  -   info-nand.ecc.hwctl   = omap3_enable_hwecc_bch;
  -   info-nand.ecc.correct = omap3_correct_data_bch;
  -   info-nand.ecc.mode= NAND_ECC_HW;
  +   if (info-is_elm_used  (mtd-writesize = 4096)) {
  +   enum bch_ecc bch_type;
  
  -   /*
  -* The number of corrected errors in an ecc block that will trigger
  -* block scrubbing defaults to the ecc strength (4 or 8).
  -* Set mtd-bitflip_threshold here to define a custom threshold.
  -*/
  +   if (hw_errors == BCH8_MAX_ERROR) {
  +   bch_type = BCH8_ECC;
  +   info-nand.ecc.bytes = BCH8_SIZE;
  +   } else {
  +   bch_type = BCH4_ECC;
  +   info-nand.ecc.bytes = BCH4_SIZE;
  +   }
  
  -   if (max_errors == 8) {
  -   info-nand.ecc.strength  = 8;
  -   info-nand.ecc.bytes = 13;
  -   info-nand.ecc.calculate = 

[PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-03 Thread Philip, Avinash
ELM module can be used for error correction of BCH 4  8 bit. Also
support read  write page in one shot by adding custom read_page 
write_page methods. This helps in optimizing code.

New structure member is_elm_used is added to know the status of
whether the ELM module is used for error correction or not.

Note:
ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
with RBL ECC layout, even though the requirement was only 13 byte. This
results a common ecc layout across RBL, U-boot  Linux.

Signed-off-by: Philip, Avinash avinashphi...@ti.com
---
:100644 100644 af511a9... 8fd6ddb... M  drivers/mtd/nand/omap2.c
:100644 100644 1a68c1e... 5b7054e... M  
include/linux/platform_data/mtd-nand-omap2.h
 drivers/mtd/nand/omap2.c |  359 +++---
 include/linux/platform_data/mtd-nand-omap2.h |1 +
 2 files changed, 328 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index af511a9..8fd6ddb 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -30,6 +30,7 @@
 #include plat/dma.h
 #include plat/gpmc.h
 #include linux/platform_data/mtd-nand-omap2.h
+#include linux/platform_data/elm.h
 
 #defineDRIVER_NAME omap2-nand
 #defineOMAP_NAND_TIMEOUT_MS5000
@@ -114,6 +115,12 @@
 #define BCH8_MAX_ERROR 8   /* upto 8 bit coorectable */
 #define BCH4_MAX_ERROR 4   /* upto 4 bit correctable */
 
+#define SECTOR_BYTES   512
+/* 4 bit padding to make byte aligned, 56 = 52 + 4 */
+#define BCH4_BIT_PAD   4
+#define BCH8_ECC_MAX   ((SECTOR_BYTES + BCH8_ECC_OOB_BYTES) * 8)
+#define BCH4_ECC_MAX   ((SECTOR_BYTES + BCH4_SIZE) * 8)
+
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -153,6 +160,8 @@ struct omap_nand_info {
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
struct bch_control *bch;
struct nand_ecclayout   ecclayout;
+   boolis_elm_used;
+   struct device   *elm_dev;
 #endif
 };
 
@@ -892,6 +901,138 @@ static int omap_correct_data(struct mtd_info *mtd, u_char 
*dat,
return stat;
 }
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+/**
+ * omap_elm_correct_data - corrects page data area in case error reported
+ * @mtd:   MTD device structure
+ * @dat:   page data
+ * @read_ecc:  ecc read from nand flash
+ * @calc_ecc:  ecc read from HW ECC registers
+ *
+ * Check the read ecc vector from OOB area to see the page is flashed.
+ * If flashed, check any error reported by checking calculated ecc vector.
+ * For non error page, calculated ecc will be zero. For error pages,
+ * a non-zero valid syndrome polynomial reported in calculated ecc vector.
+ * Pass this non-zero syndrome polynomial to 'elm_decode_bch_error_page'
+ * with elm error vector updated for error reported sectors.
+ * On returning from this function, elm error vector updated with
+ * - number of correctable errors, error location if correctable.
+ * - if pages are non-correctable, updated with elm error vector
+ *   error uncorrectable.
+ */
+static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
+   u_char *read_ecc, u_char *calc_ecc)
+{
+   struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
+   mtd);
+   int eccsteps = info-nand.ecc.steps;
+   int i , j, stat = 0;
+   int eccsize, eccflag, size;
+   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
+   u_char *ecc_vec = calc_ecc;
+   enum bch_ecc type;
+   bool is_error_reported = false;
+
+   /* initialize elm error vector to zero */
+   memset(err_vec, 0, sizeof(err_vec));
+   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
+   size = BCH8_SIZE;
+   eccsize = BCH8_ECC_OOB_BYTES;
+   type = BCH8_ECC;
+   } else {
+   size = BCH4_SIZE;
+   eccsize = BCH4_SIZE;
+   type = BCH4_ECC;
+   }
+
+   for (i = 0; i  eccsteps ; i++) {
+   eccflag = 0;/* initialize eccflag */
+
+   for (j = 0; (j  eccsize); j++) {
+   if (read_ecc[j] != 0xFF) {
+   eccflag = 1;/* data area is flashed */
+   break;
+   }
+   }
+
+   /* check calculated ecc if data area is flashed */
+   if (eccflag == 1) {
+   eccflag = 0;
+   /*
+* check any error reported, in case of error
+* non zero ecc reported.
+*/
+   for (j = 0; (j  eccsize); j++) {
+   if (calc_ecc[j] != 0) {
+   

Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support

2012-10-03 Thread Ivan Djelic
On Wed, Oct 03, 2012 at 03:29:49PM +0100, Philip, Avinash wrote:
 ELM module can be used for error correction of BCH 4  8 bit. Also
 support read  write page in one shot by adding custom read_page 
 write_page methods. This helps in optimizing code.
 
 New structure member is_elm_used is added to know the status of
 whether the ELM module is used for error correction or not.
 
 Note:
 ECC layout of BCH8 uses 14 bytes for 512 byte of data to make compatible
 with RBL ECC layout, even though the requirement was only 13 byte. This
 results a common ecc layout across RBL, U-boot  Linux.
 

See a few comments below,

(...)
 +static int omap_elm_correct_data(struct mtd_info *mtd, u_char *dat,
 +   u_char *read_ecc, u_char *calc_ecc)
 +{
 +   struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +   mtd);
 +   int eccsteps = info-nand.ecc.steps;
 +   int i , j, stat = 0;
 +   int eccsize, eccflag, size;
 +   struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
 +   u_char *ecc_vec = calc_ecc;
 +   enum bch_ecc type;
 +   bool is_error_reported = false;
 +
 +   /* initialize elm error vector to zero */
 +   memset(err_vec, 0, sizeof(err_vec));
 +   if (info-nand.ecc.strength == BCH8_MAX_ERROR) {
 +   size = BCH8_SIZE;
 +   eccsize = BCH8_ECC_OOB_BYTES;
 +   type = BCH8_ECC;
 +   } else {
 +   size = BCH4_SIZE;
 +   eccsize = BCH4_SIZE;
 +   type = BCH4_ECC;
 +   }
 +
 +   for (i = 0; i  eccsteps ; i++) {
 +   eccflag = 0;/* initialize eccflag */
 +
 +   for (j = 0; (j  eccsize); j++) {
 +   if (read_ecc[j] != 0xFF) {
 +   eccflag = 1;/* data area is flashed */

Just a reminder: this way of checking if a page has been programmed is not 
robust to bitflips,
so you may get into trouble with UBIFS on a fairly recent device.

(...)
 @@ -1039,14 +1180,45 @@ static void omap3_enable_hwecc_bch(struct mtd_info 
 *mtd, int mode)
 
 nerrors = info-nand.ecc.strength;
 dev_width = (chip-options  NAND_BUSWIDTH_16) ? 1 : 0;
 +#ifdef CONFIG_MTD_NAND_OMAP_BCH
 +   if (info-is_elm_used) {
 +   /*
 +* Program GPMC to perform correction on (steps * 512) byte
 +* sector at a time.
 +*/
 +   gpmc_enable_hwecc_bch(info-gpmc_cs, mode, dev_width,
 +   info-nand.ecc.steps, nerrors);
 +   return;
 +   }
 +#endif
 /*
 -* Program GPMC to perform correction on one 512-byte sector at a 
 time.
 -* Using 4 sectors at a time (i.e. ecc.size = 2048) is also possible 
 and
 -* gives a slight (5%) performance gain (but requires additional 
 code).
 +* Program GPMC to perform correction on one 512-byte sector at
 +* a time.

Why removing the comment about 4-sector perf gain ? :-)

(...)
 @@ -1146,35 +1402,62 @@ static int omap3_init_bch(struct mtd_info *mtd, int 
 ecc_opt)
 goto fail;
 }
 
 -   /* initialize GPMC BCH engine */
 -   ret = gpmc_init_hwecc_bch(info-gpmc_cs, 1, max_errors);
 -   if (ret)
 -   goto fail;
 -
 -   /* software bch library is only used to detect and locate errors */
 -   info-bch = init_bch(13, max_errors, 0x201b /* hw polynomial */);
 -   if (!info-bch)
 -   goto fail;
 +   info-nand.ecc.size = 512;
 +   info-nand.ecc.hwctl = omap3_enable_hwecc_bch;
 +   info-nand.ecc.mode = NAND_ECC_HW;
 +   info-nand.ecc.strength = hw_errors;
 
 -   info-nand.ecc.size= 512;
 -   info-nand.ecc.hwctl   = omap3_enable_hwecc_bch;
 -   info-nand.ecc.correct = omap3_correct_data_bch;
 -   info-nand.ecc.mode= NAND_ECC_HW;
 +   if (info-is_elm_used  (mtd-writesize = 4096)) {
 +   enum bch_ecc bch_type;
 
 -   /*
 -* The number of corrected errors in an ecc block that will trigger
 -* block scrubbing defaults to the ecc strength (4 or 8).
 -* Set mtd-bitflip_threshold here to define a custom threshold.
 -*/
 +   if (hw_errors == BCH8_MAX_ERROR) {
 +   bch_type = BCH8_ECC;
 +   info-nand.ecc.bytes = BCH8_SIZE;
 +   } else {
 +   bch_type = BCH4_ECC;
 +   info-nand.ecc.bytes = BCH4_SIZE;
 +   }
 
 -   if (max_errors == 8) {
 -   info-nand.ecc.strength  = 8;
 -   info-nand.ecc.bytes = 13;
 -   info-nand.ecc.calculate = omap3_calculate_ecc_bch8;
 +   info-nand.ecc.correct = omap_elm_correct_data;
 +   info-nand.ecc.calculate = omap3_calculate_ecc_bch;
 +   info-nand.ecc.read_page = omap_read_page_bch;
 +   info-nand.ecc.write_page =