diff options
author | Han Xu <han.xu@nxp.com> | 2016-02-09 14:33:41 -0600 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 6d83bd51d8dae406870a87978bd615fd31f6ea8b (patch) | |
tree | 2c325db4b02e31a5deb402511fc39fe109536e5a /drivers/mtd | |
parent | 2829350a762919ee22f11309345e538ee7b9c417 (diff) |
MLK-12394-2: mtd: gpmi: update NAND new raw page access functions
support the bch layout with dedicate ecc for meta
Signed-off-by: Han Xu <han.xu@nxp.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a3f734d78a93..b395bef4e4d3 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1721,6 +1721,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, size_t oob_byte_off; uint8_t *oob = chip->oob_poi; int step; + int ecc_chunk_count; chip->read_buf(mtd, tmp_buf, mtd->writesize + mtd->oobsize); @@ -1748,9 +1749,21 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, oob_bit_off = nfc_geo->metadata_size * 8; src_bit_off = oob_bit_off; + ecc_chunk_count = nfc_geo->ecc_chunk_count; + /* if bch requires dedicate ecc for meta */ + if (nfc_geo->ecc_for_meta) { + if (oob_required) + gpmi_copy_bits(oob, oob_bit_off, + tmp_buf, src_bit_off, + eccbits); + + src_bit_off += eccbits; + oob_bit_off += eccbits; + ecc_chunk_count = nfc_geo->ecc_chunk_count - 1; + } /* Extract interleaved payload data and ECC bits */ - for (step = 0; step < nfc_geo->ecc_chunk_count; step++) { + for (step = 0; step < ecc_chunk_count; step++) { if (buf) gpmi_copy_bits(buf, step * eccsize * 8, tmp_buf, src_bit_off, @@ -1758,7 +1771,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, src_bit_off += eccsize * 8; /* Align last ECC block to align a byte boundary */ - if (step == nfc_geo->ecc_chunk_count - 1 && + if (step == ecc_chunk_count - 1 && (oob_bit_off + eccbits) % 8) eccbits += 8 - ((oob_bit_off + eccbits) % 8); @@ -1810,6 +1823,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, size_t oob_bit_off; size_t oob_byte_off; int step; + int ecc_chunk_count; /* * Initialize all bits to 1 in case we don't have a buffer for the @@ -1826,16 +1840,28 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, memcpy(tmp_buf, oob, nfc_geo->metadata_size); oob_bit_off = nfc_geo->metadata_size * 8; dst_bit_off = oob_bit_off; + ecc_chunk_count = nfc_geo->ecc_chunk_count; + + /* if bch requires dedicate ecc for meta */ + if (nfc_geo->ecc_for_meta) { + if (oob_required) + gpmi_copy_bits(tmp_buf, dst_bit_off, + oob, oob_bit_off, eccbits); + + dst_bit_off += eccbits; + oob_bit_off += eccbits; + ecc_chunk_count = nfc_geo->ecc_chunk_count - 1; + } /* Interleave payload data and ECC bits */ - for (step = 0; step < nfc_geo->ecc_chunk_count; step++) { + for (step = 0; step < ecc_chunk_count; step++) { if (buf) gpmi_copy_bits(tmp_buf, dst_bit_off, buf, step * eccsize * 8, eccsize * 8); dst_bit_off += eccsize * 8; /* Align last ECC block to align a byte boundary */ - if (step == nfc_geo->ecc_chunk_count - 1 && + if (step == ecc_chunk_count - 1 && (oob_bit_off + eccbits) % 8) eccbits += 8 - ((oob_bit_off + eccbits) % 8); |