Lines Matching full:nand
161 * struct sunxi_nand_chip_sel - stores information related to NAND Chip Select
163 * @cs: the NAND CS id used to communicate with a NAND Chip
181 * struct sunxi_nand_chip - stores NAND chip device related information
183 * @node: used to store NAND chips into a list
184 * @nand: base NAND chip structure
185 * @clk_rate: clk_rate required for this NAND chip
186 * @timing_cfg: TIMING_CFG register value for this NAND chip
187 * @timing_ctl: TIMING_CTL register value for this NAND chip
188 * @nsels: number of CS lines required by the NAND chip
193 struct nand_chip nand; member
201 static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) in to_sunxi_nand() argument
203 return container_of(nand, struct sunxi_nand_chip, nand); in to_sunxi_nand()
207 * NAND Controller capabilities structure: stores NAND controller capabilities
222 * struct sunxi_nfc - stores sunxi NAND controller information
226 * @regs: NAND controller registers
227 * @ahb_clk: NAND controller AHB clock
228 * @mod_clk: NAND controller mod clock
229 * @reset: NAND controller reset line
231 * @clk_rate: NAND controller current clock rate
232 * @chips: a list containing all the NAND chips attached to this NAND
234 * @complete: a completion object used to wait for NAND controller events
235 * @dmac: the DMA channel attached to the NAND controller
341 dev_err(nfc->dev, "wait for NAND controller reset timedout\n"); in sunxi_nfc_rst()
405 static void sunxi_nfc_select_chip(struct nand_chip *nand, unsigned int cs) in sunxi_nfc_select_chip() argument
407 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_select_chip()
408 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); in sunxi_nfc_select_chip()
409 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_select_chip()
420 ctl |= NFC_CE_SEL(sel->cs) | NFC_EN | NFC_PAGE_SHIFT(nand->page_shift); in sunxi_nfc_select_chip()
436 static void sunxi_nfc_read_buf(struct nand_chip *nand, uint8_t *buf, int len) in sunxi_nfc_read_buf() argument
438 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); in sunxi_nfc_read_buf()
439 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_read_buf()
473 static void sunxi_nfc_write_buf(struct nand_chip *nand, const uint8_t *buf, in sunxi_nfc_write_buf() argument
476 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); in sunxi_nfc_write_buf()
477 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_write_buf()
592 static u16 sunxi_nfc_randomizer_state(struct nand_chip *nand, int page, in sunxi_nfc_randomizer_state() argument
595 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_randomizer_state()
612 static void sunxi_nfc_randomizer_config(struct nand_chip *nand, int page, in sunxi_nfc_randomizer_config() argument
615 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_config()
619 if (!(nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_randomizer_config()
623 state = sunxi_nfc_randomizer_state(nand, page, ecc); in sunxi_nfc_randomizer_config()
628 static void sunxi_nfc_randomizer_enable(struct nand_chip *nand) in sunxi_nfc_randomizer_enable() argument
630 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_enable()
632 if (!(nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_randomizer_enable()
639 static void sunxi_nfc_randomizer_disable(struct nand_chip *nand) in sunxi_nfc_randomizer_disable() argument
641 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_disable()
643 if (!(nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_randomizer_disable()
650 static void sunxi_nfc_randomize_bbm(struct nand_chip *nand, int page, u8 *bbm) in sunxi_nfc_randomize_bbm() argument
652 u16 state = sunxi_nfc_randomizer_state(nand, page, true); in sunxi_nfc_randomize_bbm()
658 static void sunxi_nfc_randomizer_write_buf(struct nand_chip *nand, in sunxi_nfc_randomizer_write_buf() argument
662 sunxi_nfc_randomizer_config(nand, page, ecc); in sunxi_nfc_randomizer_write_buf()
663 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_randomizer_write_buf()
664 sunxi_nfc_write_buf(nand, buf, len); in sunxi_nfc_randomizer_write_buf()
665 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_randomizer_write_buf()
668 static void sunxi_nfc_randomizer_read_buf(struct nand_chip *nand, uint8_t *buf, in sunxi_nfc_randomizer_read_buf() argument
671 sunxi_nfc_randomizer_config(nand, page, ecc); in sunxi_nfc_randomizer_read_buf()
672 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_randomizer_read_buf()
673 sunxi_nfc_read_buf(nand, buf, len); in sunxi_nfc_randomizer_read_buf()
674 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_randomizer_read_buf()
677 static void sunxi_nfc_hw_ecc_enable(struct nand_chip *nand) in sunxi_nfc_hw_ecc_enable() argument
679 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_enable()
680 struct sunxi_nand_hw_ecc *data = nand->ecc.priv; in sunxi_nfc_hw_ecc_enable()
689 if (nand->ecc.size == 512) in sunxi_nfc_hw_ecc_enable()
695 static void sunxi_nfc_hw_ecc_disable(struct nand_chip *nand) in sunxi_nfc_hw_ecc_disable() argument
697 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_disable()
716 static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob, in sunxi_nfc_hw_ecc_get_prot_oob_bytes() argument
719 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_get_prot_oob_bytes()
725 if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_hw_ecc_get_prot_oob_bytes()
726 sunxi_nfc_randomize_bbm(nand, page, oob); in sunxi_nfc_hw_ecc_get_prot_oob_bytes()
729 static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, in sunxi_nfc_hw_ecc_set_prot_oob_bytes() argument
733 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_set_prot_oob_bytes()
737 if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) { in sunxi_nfc_hw_ecc_set_prot_oob_bytes()
739 sunxi_nfc_randomize_bbm(nand, page, user_data); in sunxi_nfc_hw_ecc_set_prot_oob_bytes()
747 static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, in sunxi_nfc_hw_ecc_update_stats() argument
750 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_update_stats()
760 static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob, in sunxi_nfc_hw_ecc_correct() argument
763 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_correct()
764 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_correct()
796 static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand, in sunxi_nfc_hw_ecc_read_chunk() argument
803 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_read_chunk()
804 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunk()
810 nand_change_read_column_op(nand, data_off, NULL, 0, false); in sunxi_nfc_hw_ecc_read_chunk()
812 sunxi_nfc_randomizer_read_buf(nand, NULL, ecc->size, false, page); in sunxi_nfc_hw_ecc_read_chunk()
815 nand_change_read_column_op(nand, oob_off, NULL, 0, false); in sunxi_nfc_hw_ecc_read_chunk()
821 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_hw_ecc_read_chunk()
826 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_hw_ecc_read_chunk()
832 ret = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, 0, in sunxi_nfc_hw_ecc_read_chunk()
843 if (nand->options & NAND_NEED_SCRAMBLING) in sunxi_nfc_hw_ecc_read_chunk()
844 nand_change_read_column_op(nand, data_off, data, in sunxi_nfc_hw_ecc_read_chunk()
850 nand_change_read_column_op(nand, oob_off, oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
862 nand_change_read_column_op(nand, oob_off, NULL, 0, in sunxi_nfc_hw_ecc_read_chunk()
864 sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + 4, in sunxi_nfc_hw_ecc_read_chunk()
867 sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, 0, in sunxi_nfc_hw_ecc_read_chunk()
872 sunxi_nfc_hw_ecc_update_stats(nand, max_bitflips, ret); in sunxi_nfc_hw_ecc_read_chunk()
877 static void sunxi_nfc_hw_ecc_read_extra_oob(struct nand_chip *nand, in sunxi_nfc_hw_ecc_read_extra_oob() argument
881 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_read_extra_oob()
882 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_extra_oob()
890 nand_change_read_column_op(nand, mtd->writesize, NULL, 0, in sunxi_nfc_hw_ecc_read_extra_oob()
894 sunxi_nfc_read_buf(nand, oob + offset, len); in sunxi_nfc_hw_ecc_read_extra_oob()
896 sunxi_nfc_randomizer_read_buf(nand, oob + offset, len, in sunxi_nfc_hw_ecc_read_extra_oob()
903 static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf, in sunxi_nfc_hw_ecc_read_chunks_dma() argument
907 bool randomized = nand->options & NAND_NEED_SCRAMBLING; in sunxi_nfc_hw_ecc_read_chunks_dma()
908 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_read_chunks_dma()
909 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_read_chunks_dma()
910 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_chunks_dma()
925 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_read_chunks_dma()
926 sunxi_nfc_randomizer_config(nand, page, false); in sunxi_nfc_hw_ecc_read_chunks_dma()
927 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_hw_ecc_read_chunks_dma()
941 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_hw_ecc_read_chunks_dma()
942 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_read_chunks_dma()
955 u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_read_chunks_dma()
958 ret = sunxi_nfc_hw_ecc_correct(nand, randomized ? data : NULL, in sunxi_nfc_hw_ecc_read_chunks_dma()
968 nand_change_read_column_op(nand, in sunxi_nfc_hw_ecc_read_chunks_dma()
972 sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i, in sunxi_nfc_hw_ecc_read_chunks_dma()
979 sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret); in sunxi_nfc_hw_ecc_read_chunks_dma()
987 u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_read_chunks_dma()
998 nand_change_read_column_op(nand, data_off, in sunxi_nfc_hw_ecc_read_chunks_dma()
1003 nand_change_read_column_op(nand, in sunxi_nfc_hw_ecc_read_chunks_dma()
1014 sunxi_nfc_hw_ecc_update_stats(nand, &max_bitflips, ret); in sunxi_nfc_hw_ecc_read_chunks_dma()
1019 sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, in sunxi_nfc_hw_ecc_read_chunks_dma()
1026 static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, in sunxi_nfc_hw_ecc_write_chunk() argument
1032 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_write_chunk()
1033 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_chunk()
1037 nand_change_write_column_op(nand, data_off, NULL, 0, false); in sunxi_nfc_hw_ecc_write_chunk()
1039 sunxi_nfc_randomizer_write_buf(nand, data, ecc->size, false, page); in sunxi_nfc_hw_ecc_write_chunk()
1042 nand_change_write_column_op(nand, oob_off, NULL, 0, false); in sunxi_nfc_hw_ecc_write_chunk()
1048 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_hw_ecc_write_chunk()
1049 sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page); in sunxi_nfc_hw_ecc_write_chunk()
1056 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_hw_ecc_write_chunk()
1065 static void sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand, in sunxi_nfc_hw_ecc_write_extra_oob() argument
1069 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_write_extra_oob()
1070 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_extra_oob()
1078 nand_change_write_column_op(nand, offset + mtd->writesize, in sunxi_nfc_hw_ecc_write_extra_oob()
1081 sunxi_nfc_randomizer_write_buf(nand, oob + offset, len, false, page); in sunxi_nfc_hw_ecc_write_extra_oob()
1087 static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, in sunxi_nfc_hw_ecc_read_page() argument
1090 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_read_page()
1091 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_page()
1096 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_read_page()
1098 nand_read_page_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_read_page()
1100 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_read_page()
1106 u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_read_page()
1108 ret = sunxi_nfc_hw_ecc_read_chunk(nand, data, data_off, oob, in sunxi_nfc_hw_ecc_read_page()
1119 sunxi_nfc_hw_ecc_read_extra_oob(nand, nand->oob_poi, &cur_off, in sunxi_nfc_hw_ecc_read_page()
1122 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_read_page()
1127 static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf, in sunxi_nfc_hw_ecc_read_page_dma() argument
1132 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_read_page_dma()
1134 nand_read_page_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_read_page_dma()
1136 ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, oob_required, page, in sunxi_nfc_hw_ecc_read_page_dma()
1137 nand->ecc.steps); in sunxi_nfc_hw_ecc_read_page_dma()
1142 return sunxi_nfc_hw_ecc_read_page(nand, buf, oob_required, page); in sunxi_nfc_hw_ecc_read_page_dma()
1145 static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, in sunxi_nfc_hw_ecc_read_subpage() argument
1149 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_read_subpage()
1150 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_read_subpage()
1154 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_read_subpage()
1156 nand_read_page_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_read_subpage()
1158 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_read_subpage()
1165 u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_read_subpage()
1167 ret = sunxi_nfc_hw_ecc_read_chunk(nand, data, data_off, in sunxi_nfc_hw_ecc_read_subpage()
1176 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_read_subpage()
1181 static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, in sunxi_nfc_hw_ecc_read_subpage_dma() argument
1185 int nchunks = DIV_ROUND_UP(data_offs + readlen, nand->ecc.size); in sunxi_nfc_hw_ecc_read_subpage_dma()
1188 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_read_subpage_dma()
1190 nand_read_page_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_read_subpage_dma()
1192 ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, false, page, nchunks); in sunxi_nfc_hw_ecc_read_subpage_dma()
1197 return sunxi_nfc_hw_ecc_read_subpage(nand, data_offs, readlen, in sunxi_nfc_hw_ecc_read_subpage_dma()
1201 static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand, in sunxi_nfc_hw_ecc_write_page() argument
1205 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_write_page()
1206 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_page()
1209 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_write_page()
1211 nand_prog_page_begin_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_write_page()
1213 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_write_page()
1219 const u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_write_page()
1221 ret = sunxi_nfc_hw_ecc_write_chunk(nand, data, data_off, oob, in sunxi_nfc_hw_ecc_write_page()
1228 if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_hw_ecc_write_page()
1229 sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, in sunxi_nfc_hw_ecc_write_page()
1232 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_write_page()
1234 return nand_prog_page_end_op(nand); in sunxi_nfc_hw_ecc_write_page()
1237 static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand, in sunxi_nfc_hw_ecc_write_subpage() argument
1242 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_write_subpage()
1243 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_subpage()
1246 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_write_subpage()
1248 nand_prog_page_begin_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_write_subpage()
1250 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_write_subpage()
1257 const u8 *oob = nand->oob_poi + oob_off; in sunxi_nfc_hw_ecc_write_subpage()
1259 ret = sunxi_nfc_hw_ecc_write_chunk(nand, data, data_off, oob, in sunxi_nfc_hw_ecc_write_subpage()
1266 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_write_subpage()
1268 return nand_prog_page_end_op(nand); in sunxi_nfc_hw_ecc_write_subpage()
1271 static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand, in sunxi_nfc_hw_ecc_write_page_dma() argument
1276 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_write_page_dma()
1277 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nfc_hw_ecc_write_page_dma()
1281 sunxi_nfc_select_chip(nand, nand->cur_cs); in sunxi_nfc_hw_ecc_write_page_dma()
1293 const u8 *oob = nand->oob_poi + (i * (ecc->bytes + 4)); in sunxi_nfc_hw_ecc_write_page_dma()
1295 sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page); in sunxi_nfc_hw_ecc_write_page_dma()
1298 nand_prog_page_begin_op(nand, page, 0, NULL, 0); in sunxi_nfc_hw_ecc_write_page_dma()
1300 sunxi_nfc_hw_ecc_enable(nand); in sunxi_nfc_hw_ecc_write_page_dma()
1301 sunxi_nfc_randomizer_config(nand, page, false); in sunxi_nfc_hw_ecc_write_page_dma()
1302 sunxi_nfc_randomizer_enable(nand); in sunxi_nfc_hw_ecc_write_page_dma()
1317 sunxi_nfc_randomizer_disable(nand); in sunxi_nfc_hw_ecc_write_page_dma()
1318 sunxi_nfc_hw_ecc_disable(nand); in sunxi_nfc_hw_ecc_write_page_dma()
1325 if (oob_required || (nand->options & NAND_NEED_SCRAMBLING)) in sunxi_nfc_hw_ecc_write_page_dma()
1327 sunxi_nfc_hw_ecc_write_extra_oob(nand, nand->oob_poi, in sunxi_nfc_hw_ecc_write_page_dma()
1330 return nand_prog_page_end_op(nand); in sunxi_nfc_hw_ecc_write_page_dma()
1333 return sunxi_nfc_hw_ecc_write_page(nand, buf, oob_required, page); in sunxi_nfc_hw_ecc_write_page_dma()
1336 static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *nand, int page) in sunxi_nfc_hw_ecc_read_oob() argument
1338 u8 *buf = nand_get_data_buf(nand); in sunxi_nfc_hw_ecc_read_oob()
1340 return nand->ecc.read_page(nand, buf, 1, page); in sunxi_nfc_hw_ecc_read_oob()
1343 static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) in sunxi_nfc_hw_ecc_write_oob() argument
1345 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nfc_hw_ecc_write_oob()
1346 u8 *buf = nand_get_data_buf(nand); in sunxi_nfc_hw_ecc_write_oob()
1350 ret = nand->ecc.write_page(nand, buf, 1, page); in sunxi_nfc_hw_ecc_write_oob()
1355 return nand_prog_page_end_op(nand); in sunxi_nfc_hw_ecc_write_oob()
1379 static int sunxi_nfc_setup_data_interface(struct nand_chip *nand, int csline, in sunxi_nfc_setup_data_interface() argument
1382 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); in sunxi_nfc_setup_data_interface()
1383 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_setup_data_interface()
1469 * the sunxi NAND controller does not allow us to have different in sunxi_nfc_setup_data_interface()
1510 * TODO: according to ONFI specs this value only applies for DDR NAND, in sunxi_nfc_setup_data_interface()
1552 struct nand_chip *nand = mtd_to_nand(mtd); in sunxi_nand_ooblayout_ecc() local
1553 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_ooblayout_ecc()
1567 struct nand_chip *nand = mtd_to_nand(mtd); in sunxi_nand_ooblayout_free() local
1568 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_ooblayout_free()
1605 static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand, in sunxi_nand_hw_ecc_ctrl_init() argument
1610 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nand_hw_ecc_ctrl_init()
1611 struct mtd_info *mtd = nand_to_mtd(nand); in sunxi_nand_hw_ecc_ctrl_init()
1701 nand->options |= NAND_USE_BOUNCE_BUFFER; in sunxi_nand_hw_ecc_ctrl_init()
1733 static int sunxi_nand_attach_chip(struct nand_chip *nand) in sunxi_nand_attach_chip() argument
1735 struct nand_ecc_ctrl *ecc = &nand->ecc; in sunxi_nand_attach_chip()
1736 struct device_node *np = nand_get_flash_node(nand); in sunxi_nand_attach_chip()
1739 if (nand->bbt_options & NAND_BBT_USE_FLASH) in sunxi_nand_attach_chip()
1740 nand->bbt_options |= NAND_BBT_NO_OOB; in sunxi_nand_attach_chip()
1742 if (nand->options & NAND_NEED_SCRAMBLING) in sunxi_nand_attach_chip()
1743 nand->options |= NAND_NO_SUBPAGE_WRITE; in sunxi_nand_attach_chip()
1745 nand->options |= NAND_SUBPAGE_READ; in sunxi_nand_attach_chip()
1748 ecc->size = nand->base.eccreq.step_size; in sunxi_nand_attach_chip()
1749 ecc->strength = nand->base.eccreq.strength; in sunxi_nand_attach_chip()
1757 ret = sunxi_nand_hw_ecc_ctrl_init(nand, ecc, np); in sunxi_nand_attach_chip()
1771 static int sunxi_nfc_exec_subop(struct nand_chip *nand, in sunxi_nfc_exec_subop() argument
1774 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_exec_subop()
1867 static int sunxi_nfc_soft_waitrdy(struct nand_chip *nand, in sunxi_nfc_soft_waitrdy() argument
1870 return nand_soft_waitrdy(nand, in sunxi_nfc_soft_waitrdy()
1904 static int sunxi_nfc_exec_op(struct nand_chip *nand, in sunxi_nfc_exec_op() argument
1907 struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); in sunxi_nfc_exec_op()
1910 sunxi_nfc_select_chip(nand, op->cs); in sunxi_nfc_exec_op()
1917 return nand_op_parser_exec_op(nand, parser, op, check_only); in sunxi_nfc_exec_op()
1931 struct nand_chip *nand; in sunxi_nand_chip_init() local
1984 nand = &sunxi_nand->nand; in sunxi_nand_chip_init()
1986 nand->controller = &nfc->controller; in sunxi_nand_chip_init()
1987 nand->controller->ops = &sunxi_nand_controller_ops; in sunxi_nand_chip_init()
1993 nand->ecc.mode = NAND_ECC_HW; in sunxi_nand_chip_init()
1994 nand_set_flash_node(nand, np); in sunxi_nand_chip_init()
1996 mtd = nand_to_mtd(nand); in sunxi_nand_chip_init()
1999 ret = nand_scan(nand, nsels); in sunxi_nand_chip_init()
2006 nand_release(nand); in sunxi_nand_chip_init()
2023 dev_err(dev, "too many NAND chips: %d (max = 8)\n", nchips); in sunxi_nand_chips_init()
2046 nand_release(&sunxi_nand->nand); in sunxi_nand_chips_cleanup()
2047 sunxi_nand_ecc_cleanup(&sunxi_nand->nand.ecc); in sunxi_nand_chips_cleanup()
2124 0, "sunxi-nand", nfc); in sunxi_nfc_probe()
2152 dev_err(dev, "failed to init nand chips\n"); in sunxi_nfc_probe()
2200 .compatible = "allwinner,sun4i-a10-nand",
2204 .compatible = "allwinner,sun8i-a23-nand-controller",
2223 MODULE_DESCRIPTION("Allwinner NAND Flash Controller driver");