diff options
author | Dmitry Lavnikevich <d.lavnikevich@sam-solutions.com> | 2014-03-10 14:39:53 +0300 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2014-03-12 21:26:37 +0100 |
commit | 3676454f5cb571fe1370d3d8f9b67704c08cb9b3 (patch) | |
tree | 15ffc664f67aa34e3726aba661cedb9868d211df | |
parent | c15680099e23142d1a04cab99cf88212c7ad3404 (diff) | |
download | barebox-3676454f5cb571fe1370d3d8f9b67704c08cb9b3.tar.gz barebox-3676454f5cb571fe1370d3d8f9b67704c08cb9b3.tar.xz |
nand: mxs: Fix for calculating ecc strength on some types of NAND flash
Was tested on NAND with {writesize=4096, oobsize=224} and
{writesize=2048, oobsize=64}.
This patch will not break any NAND that was working
before. Implemented calculation way may be used for other NAND chips
with writesize == 2048 but oobsize != 64.
Signed-off-by: Dmitry Lavnikevich <d.lavnikevich@sam-solutions.com>
Signed-off-by: Grigory Milev <g.milev@sam-solutions.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | drivers/mtd/nand/nand_mxs.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index 237a423d3e..b06b558b08 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -234,18 +234,31 @@ static uint32_t mxs_nand_aux_status_offset(void) static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size, uint32_t page_oob_size) { + int ecc_chunk_count = mxs_nand_ecc_chunk_cnt(page_data_size); + int ecc_strength = 0; + int gf_len = 13; /* length of Galois Field for non-DDR nand */ + + /* + * Possibly this if-else calculation may be removed since + * ecc_strength calculated after it is taken from kernel driver + * and therefore should work for all cases. But it was tested only + * on devices with {data_size = 2046, oob_size = 64} and + * {data_size = 4096, oob_size = 224} configuration. + */ if (page_data_size == 2048) return 8; - - if (page_data_size == 4096) { + else if (page_data_size == 4096) { if (page_oob_size == 128) return 8; - if (page_oob_size == 218) return 16; } - return 0; + ecc_strength = ((page_oob_size - MXS_NAND_METADATA_SIZE) * 8) + / (gf_len * ecc_chunk_count); + + /* We need the minor even number. */ + return rounddown(ecc_strength, 2); } static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size, |