Lines Matching full:ecc
173 * struct sunxi_nand_hw_ecc - stores information related to HW ECC support
175 * @mode: the sunxi ECC mode field deduced from ECC requirements
186 * @ecc: ECC controller structure
196 struct sunxi_nand_hw_ecc *ecc; member
604 bool ecc) in sunxi_nfc_randomizer_state() argument
613 if (ecc) { in sunxi_nfc_randomizer_state()
624 bool ecc) in sunxi_nfc_randomizer_config() argument
634 state = sunxi_nfc_randomizer_state(nand, page, ecc); in sunxi_nfc_randomizer_config()
671 bool ecc, int page) in sunxi_nfc_randomizer_write_buf() argument
673 sunxi_nfc_randomizer_config(nand, page, ecc); in sunxi_nfc_randomizer_write_buf()
680 int len, bool ecc, int page) in sunxi_nfc_randomizer_read_buf() argument
682 sunxi_nfc_randomizer_config(nand, page, ecc); in sunxi_nfc_randomizer_read_buf()
697 ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(sunxi_nand->ecc->mode) | in sunxi_nfc_hw_ecc_enable()
700 if (nand->ecc.size == 512) in sunxi_nfc_hw_ecc_enable()
775 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_correct() local
794 memset(data, pattern, ecc->size); in sunxi_nfc_hw_ecc_correct()
797 memset(oob, pattern, ecc->bytes + 4); in sunxi_nfc_hw_ecc_correct()
815 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunk() local
823 sunxi_nfc_randomizer_read_buf(nand, 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()
856 ecc->size, false); in sunxi_nfc_hw_ecc_read_chunk()
859 ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
861 nand_change_read_column_op(nand, oob_off, oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
864 ret = nand_check_erased_ecc_chunk(data, ecc->size, in sunxi_nfc_hw_ecc_read_chunk()
865 oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
866 NULL, 0, ecc->strength); in sunxi_nfc_hw_ecc_read_chunk()
870 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
875 sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
893 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_extra_oob() local
894 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_read_extra_oob()
921 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunks_dma() local
931 ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, nchunks, in sunxi_nfc_hw_ecc_read_chunks_dma()
968 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_chunks_dma()
969 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunks_dma()
978 /* ECC errors are handled in the second loop. */ in sunxi_nfc_hw_ecc_read_chunks_dma()
986 oob, ecc->bytes + 4, false); in sunxi_nfc_hw_ecc_read_chunks_dma()
1000 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_chunks_dma()
1001 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_chunks_dma()
1015 data, ecc->size, in sunxi_nfc_hw_ecc_read_chunks_dma()
1021 oob, ecc->bytes + 4, false); in sunxi_nfc_hw_ecc_read_chunks_dma()
1023 ret = nand_check_erased_ecc_chunk(data, ecc->size, in sunxi_nfc_hw_ecc_read_chunks_dma()
1024 oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunks_dma()
1026 ecc->strength); in sunxi_nfc_hw_ecc_read_chunks_dma()
1049 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_chunk() local
1055 sunxi_nfc_randomizer_write_buf(nand, data, ecc->size, false, page); in sunxi_nfc_hw_ecc_write_chunk()
1057 if (data_off + ecc->size != oob_off) in sunxi_nfc_hw_ecc_write_chunk()
1076 *cur_off = oob_off + ecc->bytes + 4; in sunxi_nfc_hw_ecc_write_chunk()
1086 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_extra_oob() local
1087 int offset = ((ecc->bytes + 4) * ecc->steps); in sunxi_nfc_hw_ecc_write_extra_oob()
1107 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_page() local
1118 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_read_page()
1119 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_page()
1120 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_page()
1153 nand->ecc.steps); in sunxi_nfc_hw_ecc_read_page_dma()
1166 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_subpage() local
1176 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1177 i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) { in sunxi_nfc_hw_ecc_read_subpage()
1178 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_read_subpage()
1179 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_read_subpage()
1201 int nchunks = DIV_ROUND_UP(data_offs + readlen, nand->ecc.size); in sunxi_nfc_hw_ecc_read_subpage_dma()
1222 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_page() local
1231 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_write_page()
1232 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_page()
1233 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_page()
1259 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_subpage() local
1268 for (i = data_offs / ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1269 i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) { in sunxi_nfc_hw_ecc_write_subpage()
1270 int data_off = i * ecc->size; in sunxi_nfc_hw_ecc_write_subpage()
1271 int oob_off = i * (ecc->bytes + 4); in sunxi_nfc_hw_ecc_write_subpage()
1293 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_page_dma() local
1304 ret = sunxi_nfc_dma_op_prepare(nfc, buf, ecc->size, ecc->steps, in sunxi_nfc_hw_ecc_write_page_dma()
1309 for (i = 0; i < ecc->steps; i++) { in sunxi_nfc_hw_ecc_write_page_dma()
1310 const u8 *oob = nand->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_ecc_write_page_dma()
1362 return nand->ecc.read_page(nand, buf, 1, page); in sunxi_nfc_hw_ecc_read_oob()
1372 ret = nand->ecc.write_page(nand, buf, 1, page); in sunxi_nfc_hw_ecc_write_oob()
1575 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_ooblayout_ecc() local
1577 if (section >= ecc->steps) in sunxi_nand_ooblayout_ecc()
1580 oobregion->offset = section * (ecc->bytes + 4) + 4; in sunxi_nand_ooblayout_ecc()
1581 oobregion->length = ecc->bytes; in sunxi_nand_ooblayout_ecc()
1590 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_ooblayout_free() local
1592 if (section > ecc->steps) in sunxi_nand_ooblayout_free()
1600 if (!section && ecc->engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) { in sunxi_nand_ooblayout_free()
1607 oobregion->offset = section * (ecc->bytes + 4); in sunxi_nand_ooblayout_free()
1609 if (section < ecc->steps) in sunxi_nand_ooblayout_free()
1618 .ecc = sunxi_nand_ooblayout_ecc,
1624 kfree(sunxi_nand->ecc); in sunxi_nand_hw_ecc_ctrl_cleanup()
1628 struct nand_ecc_ctrl *ecc, in sunxi_nand_hw_ecc_ctrl_init() argument
1640 if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH) { in sunxi_nand_hw_ecc_ctrl_init()
1643 ecc->size = 1024; in sunxi_nand_hw_ecc_ctrl_init()
1644 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_ecc_ctrl_init()
1649 /* 4 non-ECC bytes are added before each ECC bytes section */ in sunxi_nand_hw_ecc_ctrl_init()
1656 ecc->strength = bytes * 8 / fls(8 * ecc->size); in sunxi_nand_hw_ecc_ctrl_init()
1659 if (strengths[i] > ecc->strength) in sunxi_nand_hw_ecc_ctrl_init()
1664 ecc->strength = 0; in sunxi_nand_hw_ecc_ctrl_init()
1666 ecc->strength = strengths[i - 1]; in sunxi_nand_hw_ecc_ctrl_init()
1669 if (ecc->size != 512 && ecc->size != 1024) in sunxi_nand_hw_ecc_ctrl_init()
1672 sunxi_nand->ecc = kzalloc(sizeof(*sunxi_nand->ecc), GFP_KERNEL); in sunxi_nand_hw_ecc_ctrl_init()
1673 if (!sunxi_nand->ecc) in sunxi_nand_hw_ecc_ctrl_init()
1676 /* Prefer 1k ECC chunk over 512 ones */ in sunxi_nand_hw_ecc_ctrl_init()
1677 if (ecc->size == 512 && mtd->writesize > 512) { in sunxi_nand_hw_ecc_ctrl_init()
1678 ecc->size = 1024; in sunxi_nand_hw_ecc_ctrl_init()
1679 ecc->strength *= 2; in sunxi_nand_hw_ecc_ctrl_init()
1682 /* Add ECC info retrieval from DT */ in sunxi_nand_hw_ecc_ctrl_init()
1684 if (ecc->strength <= strengths[i]) { in sunxi_nand_hw_ecc_ctrl_init()
1686 * Update ecc->strength value with the actual strength in sunxi_nand_hw_ecc_ctrl_init()
1687 * that will be used by the ECC engine. in sunxi_nand_hw_ecc_ctrl_init()
1689 ecc->strength = strengths[i]; in sunxi_nand_hw_ecc_ctrl_init()
1700 sunxi_nand->ecc->mode = i; in sunxi_nand_hw_ecc_ctrl_init()
1702 /* HW ECC always request ECC bytes for 1024 bytes blocks */ in sunxi_nand_hw_ecc_ctrl_init()
1703 ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * 1024), 8); in sunxi_nand_hw_ecc_ctrl_init()
1705 /* HW ECC always work with even numbers of ECC bytes */ in sunxi_nand_hw_ecc_ctrl_init()
1706 ecc->bytes = ALIGN(ecc->bytes, 2); in sunxi_nand_hw_ecc_ctrl_init()
1708 nsectors = mtd->writesize / ecc->size; in sunxi_nand_hw_ecc_ctrl_init()
1710 if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) { in sunxi_nand_hw_ecc_ctrl_init()
1715 ecc->read_oob = sunxi_nfc_hw_ecc_read_oob; in sunxi_nand_hw_ecc_ctrl_init()
1716 ecc->write_oob = sunxi_nfc_hw_ecc_write_oob; in sunxi_nand_hw_ecc_ctrl_init()
1720 ecc->read_page = sunxi_nfc_hw_ecc_read_page_dma; in sunxi_nand_hw_ecc_ctrl_init()
1721 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage_dma; in sunxi_nand_hw_ecc_ctrl_init()
1722 ecc->write_page = sunxi_nfc_hw_ecc_write_page_dma; in sunxi_nand_hw_ecc_ctrl_init()
1725 ecc->read_page = sunxi_nfc_hw_ecc_read_page; in sunxi_nand_hw_ecc_ctrl_init()
1726 ecc->read_subpage = sunxi_nfc_hw_ecc_read_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1727 ecc->write_page = sunxi_nfc_hw_ecc_write_page; in sunxi_nand_hw_ecc_ctrl_init()
1731 ecc->write_subpage = sunxi_nfc_hw_ecc_write_subpage; in sunxi_nand_hw_ecc_ctrl_init()
1732 ecc->read_oob_raw = nand_read_oob_std; in sunxi_nand_hw_ecc_ctrl_init()
1733 ecc->write_oob_raw = nand_write_oob_std; in sunxi_nand_hw_ecc_ctrl_init()
1738 kfree(sunxi_nand->ecc); in sunxi_nand_hw_ecc_ctrl_init()
1745 struct nand_ecc_ctrl *ecc = &sunxi_nand->nand.ecc; in sunxi_nand_ecc_cleanup() local
1747 switch (ecc->engine_type) { in sunxi_nand_ecc_cleanup()
1761 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_attach_chip() local
1773 if (!ecc->size) { in sunxi_nand_attach_chip()
1774 ecc->size = requirements->step_size; in sunxi_nand_attach_chip()
1775 ecc->strength = requirements->strength; in sunxi_nand_attach_chip()
1778 if (!ecc->size || !ecc->strength) in sunxi_nand_attach_chip()
1781 switch (ecc->engine_type) { in sunxi_nand_attach_chip()
1783 ret = sunxi_nand_hw_ecc_ctrl_init(nand, ecc, np); in sunxi_nand_attach_chip()
2015 * Set the ECC mode to the default value in case nothing is specified in sunxi_nand_chip_init()
2018 nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in sunxi_nand_chip_init()