• Home
  • Raw
  • Download

Lines Matching full:nand

3  * Amlogic Meson Nand Flash Controller Driver
91 /* nand flash controller delay 3 ns */
109 struct nand_chip nand; member
218 static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand) in to_meson_nand() argument
220 return container_of(nand, struct meson_nfc_nand_chip, nand); in to_meson_nand()
223 static void meson_nfc_select_chip(struct nand_chip *nand, int chip) in meson_nfc_select_chip() argument
225 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_select_chip()
226 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_select_chip()
266 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, in meson_nfc_cmd_access() argument
269 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_cmd_access()
271 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_cmd_access()
275 pagesize = nand->ecc.size; in meson_nfc_cmd_access()
284 pages = len / nand->ecc.size; in meson_nfc_cmd_access()
297 * The Nand flash controller is designed as two stages pipleline - in meson_nfc_drain_cmd()
300 * but the Nand flash controller still has two commands buffered, in meson_nfc_drain_cmd()
332 static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i) in meson_nfc_oob_ptr() argument
334 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_oob_ptr()
337 len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; in meson_nfc_oob_ptr()
342 static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i) in meson_nfc_data_ptr() argument
344 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_data_ptr()
347 temp = nand->ecc.size + nand->ecc.bytes; in meson_nfc_data_ptr()
353 static void meson_nfc_get_data_oob(struct nand_chip *nand, in meson_nfc_get_data_oob() argument
359 oob_len = nand->ecc.bytes + 2; in meson_nfc_get_data_oob()
360 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_get_data_oob()
362 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_get_data_oob()
363 memcpy(buf, dsrc, nand->ecc.size); in meson_nfc_get_data_oob()
364 buf += nand->ecc.size; in meson_nfc_get_data_oob()
366 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_get_data_oob()
372 static void meson_nfc_set_data_oob(struct nand_chip *nand, in meson_nfc_set_data_oob() argument
378 oob_len = nand->ecc.bytes + 2; in meson_nfc_set_data_oob()
379 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_set_data_oob()
381 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_set_data_oob()
382 memcpy(dsrc, buf, nand->ecc.size); in meson_nfc_set_data_oob()
383 buf += nand->ecc.size; in meson_nfc_set_data_oob()
385 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_set_data_oob()
419 static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_set_user_byte() argument
421 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_set_user_byte()
425 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { in meson_nfc_set_user_byte()
432 static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_get_user_byte() argument
434 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_get_user_byte()
438 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { in meson_nfc_get_user_byte()
445 static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, in meson_nfc_ecc_correct() argument
448 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_ecc_correct()
449 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_ecc_correct()
453 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_ecc_correct()
461 if ((nand->options & NAND_NEED_SCRAMBLING) && in meson_nfc_ecc_correct()
462 ECC_ZERO_CNT(*info) < nand->ecc.strength) { in meson_nfc_ecc_correct()
474 static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, in meson_nfc_dma_buffer_setup() argument
478 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_setup()
514 static void meson_nfc_dma_buffer_release(struct nand_chip *nand, in meson_nfc_dma_buffer_release() argument
518 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_release()
527 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_read_buf() argument
529 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_buf()
538 ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, in meson_nfc_read_buf()
548 meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); in meson_nfc_read_buf()
556 static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_write_buf() argument
558 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_buf()
562 ret = meson_nfc_dma_buffer_setup(nand, buf, len, NULL, in meson_nfc_write_buf()
572 meson_nfc_dma_buffer_release(nand, len, 0, DMA_TO_DEVICE); in meson_nfc_write_buf()
577 static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, in meson_nfc_rw_cmd_prepare_and_execute() argument
581 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_rw_cmd_prepare_and_execute()
582 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_rw_cmd_prepare_and_execute()
583 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_rw_cmd_prepare_and_execute()
606 if (nand->options & NAND_ROW_ADDR_3) in meson_nfc_rw_cmd_prepare_and_execute()
630 static int meson_nfc_write_page_sub(struct nand_chip *nand, in meson_nfc_write_page_sub() argument
634 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_write_page_sub()
635 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_sub()
636 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_sub()
637 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_page_sub()
642 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_write_page_sub()
645 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_write_page_sub()
647 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRWRITE); in meson_nfc_write_page_sub()
651 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_write_page_sub()
657 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_write_page_sub()
659 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
662 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
670 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE); in meson_nfc_write_page_sub()
675 static int meson_nfc_write_page_raw(struct nand_chip *nand, const u8 *buf, in meson_nfc_write_page_raw() argument
678 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_raw()
680 meson_nfc_set_data_oob(nand, buf, oob_buf); in meson_nfc_write_page_raw()
682 return meson_nfc_write_page_sub(nand, page, 1); in meson_nfc_write_page_raw()
685 static int meson_nfc_write_page_hwecc(struct nand_chip *nand, in meson_nfc_write_page_hwecc() argument
688 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_hwecc()
689 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_hwecc()
690 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_hwecc()
693 memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); in meson_nfc_write_page_hwecc()
694 meson_nfc_set_user_byte(nand, oob_buf); in meson_nfc_write_page_hwecc()
696 return meson_nfc_write_page_sub(nand, page, 0); in meson_nfc_write_page_hwecc()
700 struct nand_chip *nand, int raw) in meson_nfc_check_ecc_pages_valid() argument
702 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_check_ecc_pages_valid()
707 neccpages = raw ? 1 : nand->ecc.steps; in meson_nfc_check_ecc_pages_valid()
719 static int meson_nfc_read_page_sub(struct nand_chip *nand, in meson_nfc_read_page_sub() argument
722 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_sub()
723 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_page_sub()
724 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_sub()
728 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_read_page_sub()
731 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_read_page_sub()
733 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRREAD); in meson_nfc_read_page_sub()
737 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_read_page_sub()
743 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_read_page_sub()
745 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
748 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
753 meson_nfc_check_ecc_pages_valid(nfc, nand, raw); in meson_nfc_read_page_sub()
755 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_FROM_DEVICE); in meson_nfc_read_page_sub()
760 static int meson_nfc_read_page_raw(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_raw() argument
763 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_raw()
766 ret = meson_nfc_read_page_sub(nand, page, 1); in meson_nfc_read_page_raw()
770 meson_nfc_get_data_oob(nand, buf, oob_buf); in meson_nfc_read_page_raw()
775 static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_hwecc() argument
778 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_hwecc()
779 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_hwecc()
780 struct nand_ecc_ctrl *ecc = &nand->ecc; in meson_nfc_read_page_hwecc()
783 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_hwecc()
786 ret = meson_nfc_read_page_sub(nand, page, 0); in meson_nfc_read_page_hwecc()
790 meson_nfc_get_user_byte(nand, oob_buf); in meson_nfc_read_page_hwecc()
791 ret = meson_nfc_ecc_correct(nand, &bitflips, &correct_bitmap); in meson_nfc_read_page_hwecc()
797 if ((nand->options & NAND_NEED_SCRAMBLING) || !buf) { in meson_nfc_read_page_hwecc()
801 ret = meson_nfc_read_page_raw(nand, buf, 0, page); in meson_nfc_read_page_hwecc()
805 for (i = 0; i < nand->ecc.steps ; i++) { in meson_nfc_read_page_hwecc()
807 u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); in meson_nfc_read_page_hwecc()
829 static int meson_nfc_read_oob_raw(struct nand_chip *nand, int page) in meson_nfc_read_oob_raw() argument
831 return meson_nfc_read_page_raw(nand, NULL, 1, page); in meson_nfc_read_oob_raw()
834 static int meson_nfc_read_oob(struct nand_chip *nand, int page) in meson_nfc_read_oob() argument
836 return meson_nfc_read_page_hwecc(nand, NULL, 1, page); in meson_nfc_read_oob()
898 static int meson_nfc_exec_op(struct nand_chip *nand, in meson_nfc_exec_op() argument
901 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_exec_op()
902 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_exec_op()
911 meson_nfc_select_chip(nand, op->cs); in meson_nfc_exec_op()
938 meson_nfc_read_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
946 meson_nfc_write_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
964 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_ecc() local
966 if (section >= nand->ecc.steps) in meson_ooblayout_ecc()
969 oobregion->offset = 2 + (section * (2 + nand->ecc.bytes)); in meson_ooblayout_ecc()
970 oobregion->length = nand->ecc.bytes; in meson_ooblayout_ecc()
978 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_free() local
980 if (section >= nand->ecc.steps) in meson_ooblayout_free()
983 oobregion->offset = section * (2 + nand->ecc.bytes); in meson_ooblayout_free()
1076 static void meson_nfc_free_buffer(struct nand_chip *nand) in meson_nfc_free_buffer() argument
1078 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_free_buffer()
1084 static int meson_chip_buffer_init(struct nand_chip *nand) in meson_chip_buffer_init() argument
1086 struct mtd_info *mtd = nand_to_mtd(nand); in meson_chip_buffer_init()
1087 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_chip_buffer_init()
1090 nsectors = mtd->writesize / nand->ecc.size; in meson_chip_buffer_init()
1109 int meson_nfc_setup_interface(struct nand_chip *nand, int csline, in meson_nfc_setup_interface() argument
1112 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_setup_interface()
1151 static int meson_nand_bch_mode(struct nand_chip *nand) in meson_nand_bch_mode() argument
1153 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_bch_mode()
1156 if (nand->ecc.strength > 60 || nand->ecc.strength < 8) in meson_nand_bch_mode()
1160 if (meson_ecc[i].strength == nand->ecc.strength) { in meson_nand_bch_mode()
1169 static void meson_nand_detach_chip(struct nand_chip *nand) in meson_nand_detach_chip() argument
1171 meson_nfc_free_buffer(nand); in meson_nand_detach_chip()
1174 static int meson_nand_attach_chip(struct nand_chip *nand) in meson_nand_attach_chip() argument
1176 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nand_attach_chip()
1177 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_attach_chip()
1178 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nand_attach_chip()
1184 "%s:nand%d", in meson_nand_attach_chip()
1191 if (nand->bbt_options & NAND_BBT_USE_FLASH) in meson_nand_attach_chip()
1192 nand->bbt_options |= NAND_BBT_NO_OOB; in meson_nand_attach_chip()
1194 nand->options |= NAND_NO_SUBPAGE_WRITE; in meson_nand_attach_chip()
1196 ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, in meson_nand_attach_chip()
1205 ret = meson_nand_bch_mode(nand); in meson_nand_attach_chip()
1209 nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in meson_nand_attach_chip()
1210 nand->ecc.write_page_raw = meson_nfc_write_page_raw; in meson_nand_attach_chip()
1211 nand->ecc.write_page = meson_nfc_write_page_hwecc; in meson_nand_attach_chip()
1212 nand->ecc.write_oob_raw = nand_write_oob_std; in meson_nand_attach_chip()
1213 nand->ecc.write_oob = nand_write_oob_std; in meson_nand_attach_chip()
1215 nand->ecc.read_page_raw = meson_nfc_read_page_raw; in meson_nand_attach_chip()
1216 nand->ecc.read_page = meson_nfc_read_page_hwecc; in meson_nand_attach_chip()
1217 nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; in meson_nand_attach_chip()
1218 nand->ecc.read_oob = meson_nfc_read_oob; in meson_nand_attach_chip()
1220 if (nand->options & NAND_BUSWIDTH_16) { in meson_nand_attach_chip()
1224 ret = meson_chip_buffer_init(nand); in meson_nand_attach_chip()
1243 struct nand_chip *nand; in meson_nfc_nand_chip_init() local
1275 nand = &meson_chip->nand; in meson_nfc_nand_chip_init()
1276 nand->controller = &nfc->controller; in meson_nfc_nand_chip_init()
1277 nand->controller->ops = &meson_nand_controller_ops; in meson_nfc_nand_chip_init()
1278 nand_set_flash_node(nand, np); in meson_nfc_nand_chip_init()
1279 nand_set_controller_data(nand, nfc); in meson_nfc_nand_chip_init()
1281 nand->options |= NAND_USES_DMA; in meson_nfc_nand_chip_init()
1282 mtd = nand_to_mtd(nand); in meson_nfc_nand_chip_init()
1286 ret = nand_scan(nand, nsels); in meson_nfc_nand_chip_init()
1293 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1311 mtd = nand_to_mtd(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1316 nand_cleanup(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1418 dev_err(dev, "failed to initialize NAND clock\n"); in meson_nfc_probe()
1440 dev_err(dev, "failed to init NAND chips\n"); in meson_nfc_probe()
1470 .name = "meson-nand",
1478 MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver");