Lines Matching full:ecc

213  * sunxi HW ECC infos: stores information related to HW ECC support
215 * @mode: the sunxi ECC mode field deduced from ECC requirements
216 * @layout: the OOB layout depending on the ECC requirements and the
217 * selected ECC mode
685 static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc) in sunxi_nfc_randomizer_state() argument
693 if (ecc) { in sunxi_nfc_randomizer_state()
704 int page, bool ecc) in sunxi_nfc_randomizer_config() argument
715 state = sunxi_nfc_randomizer_state(mtd, page, ecc); in sunxi_nfc_randomizer_config()
754 bool ecc, int page) in sunxi_nfc_randomizer_write_buf() argument
756 sunxi_nfc_randomizer_config(mtd, page, ecc); in sunxi_nfc_randomizer_write_buf()
763 int len, bool ecc, int page) in sunxi_nfc_randomizer_read_buf() argument
765 sunxi_nfc_randomizer_config(mtd, page, ecc); in sunxi_nfc_randomizer_read_buf()
775 struct sunxi_nand_hw_ecc *data = nand->ecc.priv; in sunxi_nfc_hw_ecc_enable()
783 if (nand->ecc.size == 512) in sunxi_nfc_hw_ecc_enable()
815 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunk() local
823 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page); in sunxi_nfc_hw_ecc_read_chunk()
825 if (data_off + ecc->size != oob_off) in sunxi_nfc_hw_ecc_read_chunk()
841 *cur_off = oob_off + ecc->bytes + 4; in sunxi_nfc_hw_ecc_read_chunk()
850 memset(data, pattern, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
851 memset(oob, pattern, ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunk()
858 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
861 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page); in sunxi_nfc_hw_ecc_read_chunk()
870 nand->read_buf(mtd, data, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
872 nand->read_buf(mtd, oob, ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunk()
875 ret = nand_check_erased_ecc_chunk(data, ecc->size, in sunxi_nfc_hw_ecc_read_chunk()
876 oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
877 NULL, 0, ecc->strength); in sunxi_nfc_hw_ecc_read_chunk()
909 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_extra_oob() local
910 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_read_extra_oob()
942 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_chunk() local
948 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page); in sunxi_nfc_hw_ecc_write_chunk()
963 if (data_off + ecc->size != oob_off) in sunxi_nfc_hw_ecc_write_chunk()
980 *cur_off = oob_off + ecc->bytes + 4; in sunxi_nfc_hw_ecc_write_chunk()
990 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_extra_oob() local
991 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_write_extra_oob()
1010 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_read_page() local
1017 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_read_page()
1018 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_page()
1019 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_page()
1047 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_read_subpage() local
1054 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1055 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) { in sunxi_nfc_hw_ecc_read_subpage()
1056 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1057 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_subpage()
1078 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_write_page() local
1083 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_write_page()
1084 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_page()
1085 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_page()
1111 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_write_subpage() local
1116 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1117 i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) { in sunxi_nfc_hw_ecc_write_subpage()
1118 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1119 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_subpage()
1140 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_syndrome_ecc_read_page() local
1147 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_syndrome_ecc_read_page()
1148 int data_off = i * (ecc->size + ecc->bytes + 4); in sunxi_nfc_hw_syndrome_ecc_read_page()
1149 int oob_off = data_off + ecc->size; in sunxi_nfc_hw_syndrome_ecc_read_page()
1150 u8 *data = buf + (i * ecc->size); in sunxi_nfc_hw_syndrome_ecc_read_page()
1151 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_syndrome_ecc_read_page()
1176 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_syndrome_ecc_write_page() local
1181 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_syndrome_ecc_write_page()
1182 int data_off = i * (ecc->size + ecc->bytes + 4); in sunxi_nfc_hw_syndrome_ecc_write_page()
1183 int oob_off = data_off + ecc->size; in sunxi_nfc_hw_syndrome_ecc_write_page()
1184 const u8 *data = buf + (i * ecc->size); in sunxi_nfc_hw_syndrome_ecc_write_page()
1185 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_syndrome_ecc_write_page()
1386 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_common_ecc_ctrl_init() argument
1399 if (ecc->size != 512 && ecc->size != 1024) in sunxi_nand_hw_common_ecc_ctrl_init()
1402 /* Prefer 1k ECC chunk over 512 ones */ in sunxi_nand_hw_common_ecc_ctrl_init()
1403 if (ecc->size == 512 && mtd->writesize > 512) { in sunxi_nand_hw_common_ecc_ctrl_init()
1404 ecc->size = 1024; in sunxi_nand_hw_common_ecc_ctrl_init()
1405 ecc->strength *= 2; in sunxi_nand_hw_common_ecc_ctrl_init()
1408 /* Add ECC info retrieval from DT */ in sunxi_nand_hw_common_ecc_ctrl_init()
1410 if (ecc->strength <= strengths[i]) { in sunxi_nand_hw_common_ecc_ctrl_init()
1412 * Update ecc->strength value with the actual strength in sunxi_nand_hw_common_ecc_ctrl_init()
1413 * that will be used by the ECC engine. in sunxi_nand_hw_common_ecc_ctrl_init()
1415 ecc->strength = strengths[i]; in sunxi_nand_hw_common_ecc_ctrl_init()
1428 /* HW ECC always request ECC bytes for 1024 bytes blocks */ in sunxi_nand_hw_common_ecc_ctrl_init()
1429 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); in sunxi_nand_hw_common_ecc_ctrl_init()
1431 /* HW ECC always work with even numbers of ECC bytes */ in sunxi_nand_hw_common_ecc_ctrl_init()
1432 ecc->bytes = ALIGN(ecc->bytes, 2); in sunxi_nand_hw_common_ecc_ctrl_init()
1435 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_common_ecc_ctrl_init()
1437 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) { in sunxi_nand_hw_common_ecc_ctrl_init()
1442 layout->eccbytes = (ecc->bytes * nsectors); in sunxi_nand_hw_common_ecc_ctrl_init()
1444 ecc->layout = layout; in sunxi_nand_hw_common_ecc_ctrl_init()
1445 ecc->priv = data; in sunxi_nand_hw_common_ecc_ctrl_init()
1456 static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_common_ecc_ctrl_cleanup() argument
1458 kfree(ecc->priv); in sunxi_nand_hw_common_ecc_ctrl_cleanup()
1463 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_ecc_ctrl_init() argument
1470 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc); in sunxi_nand_hw_ecc_ctrl_init()
1474 ecc->read_page = sunxi_nfc_hw_ecc_read_page; in sunxi_nand_hw_ecc_ctrl_init()
1475 ecc->write_page = sunxi_nfc_hw_ecc_write_page; in sunxi_nand_hw_ecc_ctrl_init()
1476 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1477 ecc->write_subpage = sunxi_nfc_hw_ecc_write_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1478 layout = ecc->layout; in sunxi_nand_hw_ecc_ctrl_init()
1479 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_ecc_ctrl_init()
1486 ecc->bytes; in sunxi_nand_hw_ecc_ctrl_init()
1498 for (j = 0; j < ecc->bytes; j++) in sunxi_nand_hw_ecc_ctrl_init()
1499 layout->eccpos[(ecc->bytes * i) + j] = in sunxi_nand_hw_ecc_ctrl_init()
1504 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) { in sunxi_nand_hw_ecc_ctrl_init()
1508 ecc->bytes; in sunxi_nand_hw_ecc_ctrl_init()
1510 ((ecc->bytes + 4) * nsectors); in sunxi_nand_hw_ecc_ctrl_init()
1517 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_syndrome_ecc_ctrl_init() argument
1524 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc); in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1528 ecc->prepad = 4; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1529 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1530 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1532 layout = ecc->layout; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1533 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1535 for (i = 0; i < (ecc->bytes * nsectors); i++) in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1545 static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) in sunxi_nand_ecc_cleanup() argument
1547 switch (ecc->mode) { in sunxi_nand_ecc_cleanup()
1550 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc); in sunxi_nand_ecc_cleanup()
1553 kfree(ecc->layout); in sunxi_nand_ecc_cleanup()
1560 static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc) in sunxi_nand_ecc_init() argument
1565 if (!ecc->size) { in sunxi_nand_ecc_init()
1566 ecc->size = nand->ecc_step_ds; in sunxi_nand_ecc_init()
1567 ecc->strength = nand->ecc_strength_ds; in sunxi_nand_ecc_init()
1570 if (!ecc->size || !ecc->strength) in sunxi_nand_ecc_init()
1573 switch (ecc->mode) { in sunxi_nand_ecc_init()
1577 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc); in sunxi_nand_ecc_init()
1582 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc); in sunxi_nand_ecc_init()
1587 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL); in sunxi_nand_ecc_init()
1588 if (!ecc->layout) in sunxi_nand_ecc_init()
1590 ecc->layout->oobfree[0].length = mtd->oobsize; in sunxi_nand_ecc_init()
1703 * Set the ECC mode to the default value in case nothing is specified in sunxi_nand_chip_init()
1706 nand->ecc.mode = NAND_ECC_HW; in sunxi_nand_chip_init()
1733 ret = sunxi_nand_ecc_init(mtd, &nand->ecc); in sunxi_nand_chip_init()
1735 dev_err(dev, "ECC init failed: %d\n", ret); in sunxi_nand_chip_init()
1791 sunxi_nand_ecc_cleanup(&chip->nand.ecc); in sunxi_nand_chips_cleanup()