Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support
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
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
* 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
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
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
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
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
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
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 =
Re: [PATCH 4/4] mtd: nand: omap2: Add data correction support
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 =