summaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorHan Xu <han.xu@nxp.com>2016-02-09 14:33:41 -0600
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit6d83bd51d8dae406870a87978bd615fd31f6ea8b (patch)
tree2c325db4b02e31a5deb402511fc39fe109536e5a /drivers/mtd
parent2829350a762919ee22f11309345e538ee7b9c417 (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.c34
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);