Lines Matching full:ecc
212 * sunxi HW ECC infos: stores information related to HW ECC support
214 * @mode: the sunxi ECC mode field deduced from ECC requirements
215 * @layout: the OOB layout depending on the ECC requirements and the
216 * selected ECC mode
684 static u16 sunxi_nfc_randomizer_state(struct mtd_info *mtd, int page, bool ecc) in sunxi_nfc_randomizer_state() argument
692 if (ecc) { in sunxi_nfc_randomizer_state()
703 int page, bool ecc) in sunxi_nfc_randomizer_config() argument
714 state = sunxi_nfc_randomizer_state(mtd, page, ecc); in sunxi_nfc_randomizer_config()
753 bool ecc, int page) in sunxi_nfc_randomizer_write_buf() argument
755 sunxi_nfc_randomizer_config(mtd, page, ecc); in sunxi_nfc_randomizer_write_buf()
762 int len, bool ecc, int page) in sunxi_nfc_randomizer_read_buf() argument
764 sunxi_nfc_randomizer_config(mtd, page, ecc); in sunxi_nfc_randomizer_read_buf()
774 struct sunxi_nand_hw_ecc *data = nand->ecc.priv; in sunxi_nfc_hw_ecc_enable()
782 if (nand->ecc.size == 512) in sunxi_nfc_hw_ecc_enable()
814 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunk() local
822 sunxi_nfc_randomizer_read_buf(mtd, NULL, ecc->size, false, page); in sunxi_nfc_hw_ecc_read_chunk()
824 if (data_off + ecc->size != oob_off) in sunxi_nfc_hw_ecc_read_chunk()
840 *cur_off = oob_off + ecc->bytes + 4; in sunxi_nfc_hw_ecc_read_chunk()
849 memset(data, pattern, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
850 memset(oob, pattern, ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunk()
857 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
860 sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page); in sunxi_nfc_hw_ecc_read_chunk()
869 nand->read_buf(mtd, data, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
871 nand->read_buf(mtd, oob, ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunk()
874 ret = nand_check_erased_ecc_chunk(data, ecc->size, in sunxi_nfc_hw_ecc_read_chunk()
875 oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
876 NULL, 0, ecc->strength); in sunxi_nfc_hw_ecc_read_chunk()
908 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_extra_oob() local
909 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_read_extra_oob()
941 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_chunk() local
947 sunxi_nfc_randomizer_write_buf(mtd, data, ecc->size, false, page); in sunxi_nfc_hw_ecc_write_chunk()
962 if (data_off + ecc->size != oob_off) in sunxi_nfc_hw_ecc_write_chunk()
979 *cur_off = oob_off + ecc->bytes + 4; in sunxi_nfc_hw_ecc_write_chunk()
989 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_extra_oob() local
990 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_write_extra_oob()
1009 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_read_page() local
1016 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_read_page()
1017 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_page()
1018 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_page()
1046 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_read_subpage() local
1053 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1054 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) { in sunxi_nfc_hw_ecc_read_subpage()
1055 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1056 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_subpage()
1077 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_write_page() local
1082 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_write_page()
1083 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_page()
1084 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_page()
1110 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_ecc_write_subpage() local
1115 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1116 i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) { in sunxi_nfc_hw_ecc_write_subpage()
1117 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1118 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_subpage()
1139 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_syndrome_ecc_read_page() local
1146 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_syndrome_ecc_read_page()
1147 int data_off = i * (ecc->size + ecc->bytes + 4); in sunxi_nfc_hw_syndrome_ecc_read_page()
1148 int oob_off = data_off + ecc->size; in sunxi_nfc_hw_syndrome_ecc_read_page()
1149 u8 *data = buf + (i * ecc->size); in sunxi_nfc_hw_syndrome_ecc_read_page()
1150 u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_syndrome_ecc_read_page()
1175 struct nand_ecc_ctrl *ecc = &chip->ecc; in sunxi_nfc_hw_syndrome_ecc_write_page() local
1180 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_syndrome_ecc_write_page()
1181 int data_off = i * (ecc->size + ecc->bytes + 4); in sunxi_nfc_hw_syndrome_ecc_write_page()
1182 int oob_off = data_off + ecc->size; in sunxi_nfc_hw_syndrome_ecc_write_page()
1183 const u8 *data = buf + (i * ecc->size); in sunxi_nfc_hw_syndrome_ecc_write_page()
1184 const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_syndrome_ecc_write_page()
1385 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_common_ecc_ctrl_init() argument
1398 if (ecc->size != 512 && ecc->size != 1024) in sunxi_nand_hw_common_ecc_ctrl_init()
1401 /* Prefer 1k ECC chunk over 512 ones */ in sunxi_nand_hw_common_ecc_ctrl_init()
1402 if (ecc->size == 512 && mtd->writesize > 512) { in sunxi_nand_hw_common_ecc_ctrl_init()
1403 ecc->size = 1024; in sunxi_nand_hw_common_ecc_ctrl_init()
1404 ecc->strength *= 2; in sunxi_nand_hw_common_ecc_ctrl_init()
1407 /* Add ECC info retrieval from DT */ in sunxi_nand_hw_common_ecc_ctrl_init()
1409 if (ecc->strength <= strengths[i]) { in sunxi_nand_hw_common_ecc_ctrl_init()
1411 * Update ecc->strength value with the actual strength in sunxi_nand_hw_common_ecc_ctrl_init()
1412 * that will be used by the ECC engine. in sunxi_nand_hw_common_ecc_ctrl_init()
1414 ecc->strength = strengths[i]; in sunxi_nand_hw_common_ecc_ctrl_init()
1427 /* HW ECC always request ECC bytes for 1024 bytes blocks */ in sunxi_nand_hw_common_ecc_ctrl_init()
1428 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); in sunxi_nand_hw_common_ecc_ctrl_init()
1430 /* HW ECC always work with even numbers of ECC bytes */ in sunxi_nand_hw_common_ecc_ctrl_init()
1431 ecc->bytes = ALIGN(ecc->bytes, 2); in sunxi_nand_hw_common_ecc_ctrl_init()
1434 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_common_ecc_ctrl_init()
1436 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) { in sunxi_nand_hw_common_ecc_ctrl_init()
1441 layout->eccbytes = (ecc->bytes * nsectors); in sunxi_nand_hw_common_ecc_ctrl_init()
1443 ecc->layout = layout; in sunxi_nand_hw_common_ecc_ctrl_init()
1444 ecc->priv = data; in sunxi_nand_hw_common_ecc_ctrl_init()
1455 static void sunxi_nand_hw_common_ecc_ctrl_cleanup(struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_common_ecc_ctrl_cleanup() argument
1457 kfree(ecc->priv); in sunxi_nand_hw_common_ecc_ctrl_cleanup()
1462 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_ecc_ctrl_init() argument
1469 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc); in sunxi_nand_hw_ecc_ctrl_init()
1473 ecc->read_page = sunxi_nfc_hw_ecc_read_page; in sunxi_nand_hw_ecc_ctrl_init()
1474 ecc->write_page = sunxi_nfc_hw_ecc_write_page; in sunxi_nand_hw_ecc_ctrl_init()
1475 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1476 ecc->write_subpage = sunxi_nfc_hw_ecc_write_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1477 layout = ecc->layout; in sunxi_nand_hw_ecc_ctrl_init()
1478 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_ecc_ctrl_init()
1485 ecc->bytes; in sunxi_nand_hw_ecc_ctrl_init()
1497 for (j = 0; j < ecc->bytes; j++) in sunxi_nand_hw_ecc_ctrl_init()
1498 layout->eccpos[(ecc->bytes * i) + j] = in sunxi_nand_hw_ecc_ctrl_init()
1503 if (mtd->oobsize > (ecc->bytes + 4) * nsectors) { in sunxi_nand_hw_ecc_ctrl_init()
1507 ecc->bytes; in sunxi_nand_hw_ecc_ctrl_init()
1509 ((ecc->bytes + 4) * nsectors); in sunxi_nand_hw_ecc_ctrl_init()
1516 struct nand_ecc_ctrl *ecc) in sunxi_nand_hw_syndrome_ecc_ctrl_init() argument
1523 ret = sunxi_nand_hw_common_ecc_ctrl_init(mtd, ecc); in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1527 ecc->prepad = 4; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1528 ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1529 ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1531 layout = ecc->layout; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1532 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1534 for (i = 0; i < (ecc->bytes * nsectors); i++) in sunxi_nand_hw_syndrome_ecc_ctrl_init()
1544 static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) in sunxi_nand_ecc_cleanup() argument
1546 switch (ecc->mode) { in sunxi_nand_ecc_cleanup()
1549 sunxi_nand_hw_common_ecc_ctrl_cleanup(ecc); in sunxi_nand_ecc_cleanup()
1552 kfree(ecc->layout); in sunxi_nand_ecc_cleanup()
1559 static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc) in sunxi_nand_ecc_init() argument
1564 if (!ecc->size) { in sunxi_nand_ecc_init()
1565 ecc->size = nand->ecc_step_ds; in sunxi_nand_ecc_init()
1566 ecc->strength = nand->ecc_strength_ds; in sunxi_nand_ecc_init()
1569 if (!ecc->size || !ecc->strength) in sunxi_nand_ecc_init()
1572 switch (ecc->mode) { in sunxi_nand_ecc_init()
1576 ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc); in sunxi_nand_ecc_init()
1581 ret = sunxi_nand_hw_syndrome_ecc_ctrl_init(mtd, ecc); in sunxi_nand_ecc_init()
1586 ecc->layout = kzalloc(sizeof(*ecc->layout), GFP_KERNEL); in sunxi_nand_ecc_init()
1587 if (!ecc->layout) in sunxi_nand_ecc_init()
1589 ecc->layout->oobfree[0].length = mtd->oobsize; in sunxi_nand_ecc_init()
1702 * Set the ECC mode to the default value in case nothing is specified in sunxi_nand_chip_init()
1705 nand->ecc.mode = NAND_ECC_HW; in sunxi_nand_chip_init()
1732 ret = sunxi_nand_ecc_init(mtd, &nand->ecc); in sunxi_nand_chip_init()
1734 dev_err(dev, "ECC init failed: %d\n", ret); in sunxi_nand_chip_init()
1790 sunxi_nand_ecc_cleanup(&chip->nand.ecc); in sunxi_nand_chips_cleanup()