Lines Matching full:nand

3  * Amlogic Meson Nand Flash Controller Driver
101 /* nand flash controller delay 3 ns */
124 struct nand_chip nand; member
258 static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand) in to_meson_nand() argument
260 return container_of(nand, struct meson_nfc_nand_chip, nand); in to_meson_nand()
263 static void meson_nfc_select_chip(struct nand_chip *nand, int chip) in meson_nfc_select_chip() argument
265 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_select_chip()
266 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_select_chip()
306 static int meson_nfc_is_boot_page(struct nand_chip *nand, int page) in meson_nfc_is_boot_page() argument
308 const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_is_boot_page()
310 return (nand->options & NAND_IS_BOOT_MEDIUM) && in meson_nfc_is_boot_page()
315 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, int page) in meson_nfc_cmd_access() argument
317 const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_cmd_access()
318 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_cmd_access()
324 if (nand->options & NAND_NEED_SCRAMBLING) in meson_nfc_cmd_access()
332 } else if (meson_nfc_is_boot_page(nand, page)) { in meson_nfc_cmd_access()
340 pagesize = nand->ecc.size >> 3; in meson_nfc_cmd_access()
341 pages = len / nand->ecc.size; in meson_nfc_cmd_access()
358 * The Nand flash controller is designed as two stages pipleline - in meson_nfc_drain_cmd()
361 * but the Nand flash controller still has two commands buffered, in meson_nfc_drain_cmd()
393 static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i) in meson_nfc_oob_ptr() argument
395 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_oob_ptr()
398 len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; in meson_nfc_oob_ptr()
403 static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i) in meson_nfc_data_ptr() argument
405 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_data_ptr()
408 temp = nand->ecc.size + nand->ecc.bytes; in meson_nfc_data_ptr()
414 static void meson_nfc_get_data_oob(struct nand_chip *nand, in meson_nfc_get_data_oob() argument
420 oob_len = nand->ecc.bytes + 2; in meson_nfc_get_data_oob()
421 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_get_data_oob()
423 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_get_data_oob()
424 memcpy(buf, dsrc, nand->ecc.size); in meson_nfc_get_data_oob()
425 buf += nand->ecc.size; in meson_nfc_get_data_oob()
427 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_get_data_oob()
433 static void meson_nfc_set_data_oob(struct nand_chip *nand, in meson_nfc_set_data_oob() argument
439 oob_len = nand->ecc.bytes + 2; in meson_nfc_set_data_oob()
440 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_set_data_oob()
442 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_set_data_oob()
443 memcpy(dsrc, buf, nand->ecc.size); in meson_nfc_set_data_oob()
444 buf += nand->ecc.size; in meson_nfc_set_data_oob()
446 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_set_data_oob()
452 static int meson_nfc_wait_no_rb_pin(struct nand_chip *nand, int timeout_ms, in meson_nfc_wait_no_rb_pin() argument
455 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_wait_no_rb_pin()
467 nand_status_op(nand, NULL); in meson_nfc_wait_no_rb_pin()
478 nand_exit_status_op(nand); in meson_nfc_wait_no_rb_pin()
511 static int meson_nfc_queue_rb(struct nand_chip *nand, int timeout_ms, in meson_nfc_queue_rb() argument
514 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_queue_rb()
527 return meson_nfc_wait_no_rb_pin(nand, timeout_ms, in meson_nfc_queue_rb()
534 static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_set_user_byte() argument
536 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_set_user_byte()
540 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_set_user_byte()
547 static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_get_user_byte() argument
549 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_get_user_byte()
553 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_get_user_byte()
560 static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, in meson_nfc_ecc_correct() argument
563 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_ecc_correct()
564 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_ecc_correct()
568 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_ecc_correct()
576 if ((nand->options & NAND_NEED_SCRAMBLING) && in meson_nfc_ecc_correct()
577 ECC_ZERO_CNT(*info) < nand->ecc.strength) { in meson_nfc_ecc_correct()
589 static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, in meson_nfc_dma_buffer_setup() argument
593 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_setup()
629 static void meson_nfc_dma_buffer_release(struct nand_chip *nand, in meson_nfc_dma_buffer_release() argument
633 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_release()
642 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_read_buf() argument
644 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_buf()
653 ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, in meson_nfc_read_buf()
663 meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); in meson_nfc_read_buf()
671 static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_write_buf() argument
673 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_buf()
677 ret = meson_nfc_dma_buffer_setup(nand, buf, len, NULL, in meson_nfc_write_buf()
687 meson_nfc_dma_buffer_release(nand, len, 0, DMA_TO_DEVICE); in meson_nfc_write_buf()
692 static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, in meson_nfc_rw_cmd_prepare_and_execute() argument
696 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_rw_cmd_prepare_and_execute()
697 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_rw_cmd_prepare_and_execute()
698 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_rw_cmd_prepare_and_execute()
721 if (nand->options & NAND_ROW_ADDR_3) in meson_nfc_rw_cmd_prepare_and_execute()
737 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tR_max), true); in meson_nfc_rw_cmd_prepare_and_execute()
745 static int meson_nfc_write_page_sub(struct nand_chip *nand, in meson_nfc_write_page_sub() argument
749 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_write_page_sub()
750 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_sub()
751 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_sub()
752 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_page_sub()
757 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_write_page_sub()
760 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_write_page_sub()
762 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRWRITE); in meson_nfc_write_page_sub()
766 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_write_page_sub()
772 meson_nfc_cmd_access(nand, raw, DIRWRITE, page); in meson_nfc_write_page_sub()
776 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tPROG_max), false); in meson_nfc_write_page_sub()
778 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE); in meson_nfc_write_page_sub()
783 static int meson_nfc_write_page_raw(struct nand_chip *nand, const u8 *buf, in meson_nfc_write_page_raw() argument
786 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_raw()
788 meson_nfc_set_data_oob(nand, buf, oob_buf); in meson_nfc_write_page_raw()
790 return meson_nfc_write_page_sub(nand, page, 1); in meson_nfc_write_page_raw()
793 static int meson_nfc_write_page_hwecc(struct nand_chip *nand, in meson_nfc_write_page_hwecc() argument
796 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_hwecc()
797 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_hwecc()
798 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_hwecc()
801 memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); in meson_nfc_write_page_hwecc()
802 meson_nfc_set_user_byte(nand, oob_buf); in meson_nfc_write_page_hwecc()
804 return meson_nfc_write_page_sub(nand, page, 0); in meson_nfc_write_page_hwecc()
808 struct nand_chip *nand, int raw) in meson_nfc_check_ecc_pages_valid() argument
810 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_check_ecc_pages_valid()
815 neccpages = raw ? 1 : nand->ecc.steps; in meson_nfc_check_ecc_pages_valid()
827 static int meson_nfc_read_page_sub(struct nand_chip *nand, in meson_nfc_read_page_sub() argument
830 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_sub()
831 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_page_sub()
832 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_sub()
836 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_read_page_sub()
839 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_read_page_sub()
841 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRREAD); in meson_nfc_read_page_sub()
845 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_read_page_sub()
851 meson_nfc_cmd_access(nand, raw, DIRREAD, page); in meson_nfc_read_page_sub()
854 meson_nfc_check_ecc_pages_valid(nfc, nand, raw); in meson_nfc_read_page_sub()
856 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_FROM_DEVICE); in meson_nfc_read_page_sub()
861 static int meson_nfc_read_page_raw(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_raw() argument
864 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_raw()
867 ret = meson_nfc_read_page_sub(nand, page, 1); in meson_nfc_read_page_raw()
871 meson_nfc_get_data_oob(nand, buf, oob_buf); in meson_nfc_read_page_raw()
876 static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_hwecc() argument
879 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_hwecc()
880 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_hwecc()
881 struct nand_ecc_ctrl *ecc = &nand->ecc; in meson_nfc_read_page_hwecc()
884 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_hwecc()
887 ret = meson_nfc_read_page_sub(nand, page, 0); in meson_nfc_read_page_hwecc()
891 meson_nfc_get_user_byte(nand, oob_buf); in meson_nfc_read_page_hwecc()
892 ret = meson_nfc_ecc_correct(nand, &bitflips, &correct_bitmap); in meson_nfc_read_page_hwecc()
898 if ((nand->options & NAND_NEED_SCRAMBLING) || !buf) { in meson_nfc_read_page_hwecc()
902 ret = meson_nfc_read_page_raw(nand, buf, 0, page); in meson_nfc_read_page_hwecc()
906 for (i = 0; i < nand->ecc.steps ; i++) { in meson_nfc_read_page_hwecc()
908 u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); in meson_nfc_read_page_hwecc()
930 static int meson_nfc_read_oob_raw(struct nand_chip *nand, int page) in meson_nfc_read_oob_raw() argument
932 return meson_nfc_read_page_raw(nand, NULL, 1, page); in meson_nfc_read_oob_raw()
935 static int meson_nfc_read_oob(struct nand_chip *nand, int page) in meson_nfc_read_oob() argument
937 return meson_nfc_read_page_hwecc(nand, NULL, 1, page); in meson_nfc_read_oob()
1027 static int meson_nfc_exec_op(struct nand_chip *nand, in meson_nfc_exec_op() argument
1030 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_exec_op()
1031 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_exec_op()
1038 err = meson_nfc_check_op(nand, op); in meson_nfc_exec_op()
1045 meson_nfc_select_chip(nand, op->cs); in meson_nfc_exec_op()
1072 meson_nfc_read_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1080 meson_nfc_write_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1085 meson_nfc_queue_rb(nand, instr->ctx.waitrdy.timeout_ms, in meson_nfc_exec_op()
1099 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_ecc() local
1101 if (section >= nand->ecc.steps) in meson_ooblayout_ecc()
1104 oobregion->offset = 2 + (section * (2 + nand->ecc.bytes)); in meson_ooblayout_ecc()
1105 oobregion->length = nand->ecc.bytes; in meson_ooblayout_ecc()
1113 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_free() local
1115 if (section >= nand->ecc.steps) in meson_ooblayout_free()
1118 oobregion->offset = section * (2 + nand->ecc.bytes); in meson_ooblayout_free()
1214 static void meson_nfc_free_buffer(struct nand_chip *nand) in meson_nfc_free_buffer() argument
1216 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_free_buffer()
1222 static int meson_chip_buffer_init(struct nand_chip *nand) in meson_chip_buffer_init() argument
1224 struct mtd_info *mtd = nand_to_mtd(nand); in meson_chip_buffer_init()
1225 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_chip_buffer_init()
1228 nsectors = mtd->writesize / nand->ecc.size; in meson_chip_buffer_init()
1247 int meson_nfc_setup_interface(struct nand_chip *nand, int csline, in meson_nfc_setup_interface() argument
1250 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_setup_interface()
1289 static int meson_nand_bch_mode(struct nand_chip *nand) in meson_nand_bch_mode() argument
1291 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_bch_mode()
1294 if (nand->ecc.strength > 60 || nand->ecc.strength < 8) in meson_nand_bch_mode()
1298 if (meson_ecc[i].strength == nand->ecc.strength && in meson_nand_bch_mode()
1299 meson_ecc[i].size == nand->ecc.size) { in meson_nand_bch_mode()
1308 static void meson_nand_detach_chip(struct nand_chip *nand) in meson_nand_detach_chip() argument
1310 meson_nfc_free_buffer(nand); in meson_nand_detach_chip()
1313 static int meson_nand_attach_chip(struct nand_chip *nand) in meson_nand_attach_chip() argument
1315 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nand_attach_chip()
1316 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_attach_chip()
1317 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nand_attach_chip()
1323 "%s:nand%d", in meson_nand_attach_chip()
1337 if (nand->bbt_options & NAND_BBT_USE_FLASH) in meson_nand_attach_chip()
1338 nand->bbt_options |= NAND_BBT_NO_OOB; in meson_nand_attach_chip()
1340 nand->options |= NAND_NO_SUBPAGE_WRITE; in meson_nand_attach_chip()
1342 ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, in meson_nand_attach_chip()
1351 ret = meson_nand_bch_mode(nand); in meson_nand_attach_chip()
1355 nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in meson_nand_attach_chip()
1356 nand->ecc.write_page_raw = meson_nfc_write_page_raw; in meson_nand_attach_chip()
1357 nand->ecc.write_page = meson_nfc_write_page_hwecc; in meson_nand_attach_chip()
1358 nand->ecc.write_oob_raw = nand_write_oob_std; in meson_nand_attach_chip()
1359 nand->ecc.write_oob = nand_write_oob_std; in meson_nand_attach_chip()
1361 nand->ecc.read_page_raw = meson_nfc_read_page_raw; in meson_nand_attach_chip()
1362 nand->ecc.read_page = meson_nfc_read_page_hwecc; in meson_nand_attach_chip()
1363 nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; in meson_nand_attach_chip()
1364 nand->ecc.read_oob = meson_nfc_read_oob; in meson_nand_attach_chip()
1366 if (nand->options & NAND_BUSWIDTH_16) { in meson_nand_attach_chip()
1370 ret = meson_chip_buffer_init(nand); in meson_nand_attach_chip()
1389 struct nand_chip *nand; in meson_nfc_nand_chip_init() local
1422 nand = &meson_chip->nand; in meson_nfc_nand_chip_init()
1423 nand->controller = &nfc->controller; in meson_nfc_nand_chip_init()
1424 nand->controller->ops = &meson_nand_controller_ops; in meson_nfc_nand_chip_init()
1425 nand_set_flash_node(nand, np); in meson_nfc_nand_chip_init()
1426 nand_set_controller_data(nand, nfc); in meson_nfc_nand_chip_init()
1428 nand->options |= NAND_USES_DMA; in meson_nfc_nand_chip_init()
1429 mtd = nand_to_mtd(nand); in meson_nfc_nand_chip_init()
1433 ret = of_property_read_u32(np, "nand-rb", &nand_rb_val); in meson_nfc_nand_chip_init()
1442 ret = nand_scan(nand, nsels); in meson_nfc_nand_chip_init()
1446 if (nand->options & NAND_IS_BOOT_MEDIUM) { in meson_nfc_nand_chip_init()
1452 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1461 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1469 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1486 mtd = nand_to_mtd(&meson_chip->nand); in meson_nfc_nand_chips_cleanup()
1489 nand_cleanup(&meson_chip->nand); in meson_nfc_nand_chips_cleanup()
1581 dev_err(dev, "failed to initialize NAND clock\n"); in meson_nfc_probe()
1603 dev_err(dev, "failed to init NAND chips\n"); in meson_nfc_probe()
1626 .name = "meson-nand",
1634 MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver");