Lines Matching +full:nand +full:- +full:ecc +full:- +full:strength
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
3 * Amlogic Meson Nand Flash Controller Driver
10 #include <linux/dma-mapping.h>
13 #include <linux/clk-provider.h>
81 #define ECC_CHECK_RETURN_FF (-1)
98 /* nand flash controller delay 3 ns */
121 struct nand_chip nand; member
138 u32 strength; member
204 #define MESON_ECC_DATA(b, s, sz) { .bch = (b), .strength = (s), .size = (sz) }
216 static int meson_nand_calc_ecc_bytes(int step_size, int strength) in meson_nand_calc_ecc_bytes() argument
220 if (step_size == 512 && strength == 8) in meson_nand_calc_ecc_bytes()
223 ecc_bytes = DIV_ROUND_UP(strength * fls(step_size * 8), 8); in meson_nand_calc_ecc_bytes()
253 static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand) in to_meson_nand() argument
255 return container_of(nand, struct meson_nfc_nand_chip, nand); in to_meson_nand()
258 static void meson_nfc_select_chip(struct nand_chip *nand, int chip) in meson_nfc_select_chip() argument
260 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_select_chip()
261 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_select_chip()
264 if (chip < 0 || WARN_ON_ONCE(chip >= meson_chip->nsels)) in meson_nfc_select_chip()
267 nfc->param.chip_select = meson_chip->sels[chip] ? NAND_CE1 : NAND_CE0; in meson_nfc_select_chip()
268 nfc->param.rb_select = nfc->param.chip_select; in meson_nfc_select_chip()
269 nfc->timing.twb = meson_chip->twb; in meson_nfc_select_chip()
270 nfc->timing.tadl = meson_chip->tadl; in meson_nfc_select_chip()
271 nfc->timing.tbers_max = meson_chip->tbers_max; in meson_nfc_select_chip()
273 if (nfc->clk_rate != meson_chip->clk_rate) { in meson_nfc_select_chip()
274 ret = clk_set_rate(nfc->nand_clk, meson_chip->clk_rate); in meson_nfc_select_chip()
276 dev_err(nfc->dev, "failed to set clock rate\n"); in meson_nfc_select_chip()
279 nfc->clk_rate = meson_chip->clk_rate; in meson_nfc_select_chip()
281 if (nfc->bus_timing != meson_chip->bus_timing) { in meson_nfc_select_chip()
282 value = (NFC_CLK_CYCLE - 1) | (meson_chip->bus_timing << 5); in meson_nfc_select_chip()
283 writel(value, nfc->reg_base + NFC_REG_CFG); in meson_nfc_select_chip()
284 writel((1 << 31), nfc->reg_base + NFC_REG_CMD); in meson_nfc_select_chip()
285 nfc->bus_timing = meson_chip->bus_timing; in meson_nfc_select_chip()
291 writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff), in meson_nfc_cmd_idle()
292 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_idle()
298 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_seed()
301 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, in meson_nfc_cmd_access() argument
304 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_cmd_access()
306 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_cmd_access()
307 u32 bch = meson_chip->bch_mode, cmd; in meson_nfc_cmd_access()
308 int len = mtd->writesize, pagesize, pages; in meson_nfc_cmd_access()
310 pagesize = nand->ecc.size; in meson_nfc_cmd_access()
313 len = mtd->writesize + mtd->oobsize; in meson_nfc_cmd_access()
315 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_access()
319 pages = len / nand->ecc.size; in meson_nfc_cmd_access()
324 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_access()
332 * The Nand flash controller is designed as two stages pipleline - in meson_nfc_drain_cmd()
335 * but the Nand flash controller still has two commands buffered, in meson_nfc_drain_cmd()
351 ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size, in meson_nfc_wait_cmd_finish()
355 dev_err(nfc->dev, "wait for empty CMD FIFO time out\n"); in meson_nfc_wait_cmd_finish()
367 static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i) in meson_nfc_oob_ptr() argument
369 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_oob_ptr()
372 len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; in meson_nfc_oob_ptr()
374 return meson_chip->data_buf + len; in meson_nfc_oob_ptr()
377 static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i) in meson_nfc_data_ptr() argument
379 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_data_ptr()
382 temp = nand->ecc.size + nand->ecc.bytes; in meson_nfc_data_ptr()
385 return meson_chip->data_buf + len; in meson_nfc_data_ptr()
388 static void meson_nfc_get_data_oob(struct nand_chip *nand, in meson_nfc_get_data_oob() argument
394 oob_len = nand->ecc.bytes + 2; in meson_nfc_get_data_oob()
395 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_get_data_oob()
397 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_get_data_oob()
398 memcpy(buf, dsrc, nand->ecc.size); in meson_nfc_get_data_oob()
399 buf += nand->ecc.size; in meson_nfc_get_data_oob()
401 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_get_data_oob()
407 static void meson_nfc_set_data_oob(struct nand_chip *nand, in meson_nfc_set_data_oob() argument
413 oob_len = nand->ecc.bytes + 2; in meson_nfc_set_data_oob()
414 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_set_data_oob()
416 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_set_data_oob()
417 memcpy(dsrc, buf, nand->ecc.size); in meson_nfc_set_data_oob()
418 buf += nand->ecc.size; in meson_nfc_set_data_oob()
420 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_set_data_oob()
426 static int meson_nfc_wait_no_rb_pin(struct nand_chip *nand, int timeout_ms, in meson_nfc_wait_no_rb_pin() argument
429 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_wait_no_rb_pin()
432 meson_nfc_cmd_idle(nfc, nfc->timing.twb); in meson_nfc_wait_no_rb_pin()
436 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_no_rb_pin()
438 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_no_rb_pin()
440 reinit_completion(&nfc->completion); in meson_nfc_wait_no_rb_pin()
441 nand_status_op(nand, NULL); in meson_nfc_wait_no_rb_pin()
444 cmd = NFC_CMD_RB | NFC_CMD_RB_INT_NO_PIN | nfc->timing.tbers_max; in meson_nfc_wait_no_rb_pin()
445 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_wait_no_rb_pin()
447 if (!wait_for_completion_timeout(&nfc->completion, in meson_nfc_wait_no_rb_pin()
449 return -ETIMEDOUT; in meson_nfc_wait_no_rb_pin()
452 nand_exit_status_op(nand); in meson_nfc_wait_no_rb_pin()
462 meson_nfc_cmd_idle(nfc, nfc->timing.twb); in meson_nfc_wait_rb_pin()
466 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_rb_pin()
468 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_wait_rb_pin()
470 reinit_completion(&nfc->completion); in meson_nfc_wait_rb_pin()
474 | nfc->param.chip_select | nfc->timing.tbers_max; in meson_nfc_wait_rb_pin()
475 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_wait_rb_pin()
477 ret = wait_for_completion_timeout(&nfc->completion, in meson_nfc_wait_rb_pin()
480 ret = -1; in meson_nfc_wait_rb_pin()
485 static int meson_nfc_queue_rb(struct nand_chip *nand, int timeout_ms, in meson_nfc_queue_rb() argument
488 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_queue_rb()
490 if (nfc->no_rb_pin) { in meson_nfc_queue_rb()
494 * it will wait for interrupt - controllers checks IO in meson_nfc_queue_rb()
498 * needed (for all cases except page programming - this in meson_nfc_queue_rb()
501 return meson_nfc_wait_no_rb_pin(nand, timeout_ms, in meson_nfc_queue_rb()
508 static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_set_user_byte() argument
510 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_set_user_byte()
514 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_set_user_byte()
515 info = &meson_chip->info_buf[i]; in meson_nfc_set_user_byte()
521 static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_get_user_byte() argument
523 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_get_user_byte()
527 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) { in meson_nfc_get_user_byte()
528 info = &meson_chip->info_buf[i]; in meson_nfc_get_user_byte()
534 static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, in meson_nfc_ecc_correct() argument
537 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_ecc_correct()
538 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_ecc_correct()
542 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_ecc_correct()
543 info = &meson_chip->info_buf[i]; in meson_nfc_ecc_correct()
545 mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); in meson_nfc_ecc_correct()
550 if ((nand->options & NAND_NEED_SCRAMBLING) && in meson_nfc_ecc_correct()
551 ECC_ZERO_CNT(*info) < nand->ecc.strength) { in meson_nfc_ecc_correct()
552 mtd->ecc_stats.corrected += ECC_ZERO_CNT(*info); in meson_nfc_ecc_correct()
557 ret = -EBADMSG; in meson_nfc_ecc_correct()
563 static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, in meson_nfc_dma_buffer_setup() argument
567 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_setup()
571 nfc->daddr = dma_map_single(nfc->dev, databuf, datalen, dir); in meson_nfc_dma_buffer_setup()
572 ret = dma_mapping_error(nfc->dev, nfc->daddr); in meson_nfc_dma_buffer_setup()
574 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
577 cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr); in meson_nfc_dma_buffer_setup()
578 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
580 cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr); in meson_nfc_dma_buffer_setup()
581 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
584 nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir); in meson_nfc_dma_buffer_setup()
585 ret = dma_mapping_error(nfc->dev, nfc->iaddr); in meson_nfc_dma_buffer_setup()
587 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
588 dma_unmap_single(nfc->dev, in meson_nfc_dma_buffer_setup()
589 nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_setup()
592 nfc->info_bytes = infolen; in meson_nfc_dma_buffer_setup()
593 cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); in meson_nfc_dma_buffer_setup()
594 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
596 cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr); in meson_nfc_dma_buffer_setup()
597 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
603 static void meson_nfc_dma_buffer_release(struct nand_chip *nand, in meson_nfc_dma_buffer_release() argument
607 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_release()
609 dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_release()
611 dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); in meson_nfc_dma_buffer_release()
612 nfc->info_bytes = 0; in meson_nfc_dma_buffer_release()
616 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_read_buf() argument
618 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_buf()
625 return -ENOMEM; in meson_nfc_read_buf()
627 ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, in meson_nfc_read_buf()
633 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_read_buf()
637 meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); in meson_nfc_read_buf()
645 static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_write_buf() argument
647 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_buf()
651 ret = meson_nfc_dma_buffer_setup(nand, buf, len, NULL, in meson_nfc_write_buf()
657 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_buf()
661 meson_nfc_dma_buffer_release(nand, len, 0, DMA_TO_DEVICE); in meson_nfc_write_buf()
666 static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, in meson_nfc_rw_cmd_prepare_and_execute() argument
670 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_rw_cmd_prepare_and_execute()
671 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_rw_cmd_prepare_and_execute()
672 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_rw_cmd_prepare_and_execute()
673 u32 *addrs = nfc->cmdfifo.rw.addrs; in meson_nfc_rw_cmd_prepare_and_execute()
674 u32 cs = nfc->param.chip_select; in meson_nfc_rw_cmd_prepare_and_execute()
681 nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0; in meson_nfc_rw_cmd_prepare_and_execute()
684 if (mtd->writesize <= 512) { in meson_nfc_rw_cmd_prepare_and_execute()
685 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
695 if (nand->options & NAND_ROW_ADDR_3) in meson_nfc_rw_cmd_prepare_and_execute()
699 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
702 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
705 writel_relaxed(nfc->cmdfifo.cmd[i], in meson_nfc_rw_cmd_prepare_and_execute()
706 nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
709 nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART; in meson_nfc_rw_cmd_prepare_and_execute()
710 writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
711 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tR_max), true); in meson_nfc_rw_cmd_prepare_and_execute()
713 meson_nfc_cmd_idle(nfc, nfc->timing.tadl); in meson_nfc_rw_cmd_prepare_and_execute()
719 static int meson_nfc_write_page_sub(struct nand_chip *nand, in meson_nfc_write_page_sub() argument
723 nand_get_sdr_timings(nand_get_interface_config(nand)); in meson_nfc_write_page_sub()
724 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_sub()
725 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_sub()
726 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_page_sub()
731 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_write_page_sub()
733 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_write_page_sub()
734 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_write_page_sub()
736 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRWRITE); in meson_nfc_write_page_sub()
740 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_write_page_sub()
741 data_len, meson_chip->info_buf, in meson_nfc_write_page_sub()
746 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_write_page_sub()
748 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
751 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
755 cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG; in meson_nfc_write_page_sub()
756 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_page_sub()
757 meson_nfc_queue_rb(nand, PSEC_TO_MSEC(sdr->tPROG_max), false); in meson_nfc_write_page_sub()
759 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE); in meson_nfc_write_page_sub()
764 static int meson_nfc_write_page_raw(struct nand_chip *nand, const u8 *buf, in meson_nfc_write_page_raw() argument
767 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_raw()
769 meson_nfc_set_data_oob(nand, buf, oob_buf); in meson_nfc_write_page_raw()
771 return meson_nfc_write_page_sub(nand, page, 1); in meson_nfc_write_page_raw()
774 static int meson_nfc_write_page_hwecc(struct nand_chip *nand, in meson_nfc_write_page_hwecc() argument
777 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_hwecc()
778 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_hwecc()
779 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_hwecc()
781 memcpy(meson_chip->data_buf, buf, mtd->writesize); in meson_nfc_write_page_hwecc()
782 memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); in meson_nfc_write_page_hwecc()
783 meson_nfc_set_user_byte(nand, oob_buf); in meson_nfc_write_page_hwecc()
785 return meson_nfc_write_page_sub(nand, page, 0); in meson_nfc_write_page_hwecc()
789 struct nand_chip *nand, int raw) in meson_nfc_check_ecc_pages_valid() argument
791 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_check_ecc_pages_valid()
796 neccpages = raw ? 1 : nand->ecc.steps; in meson_nfc_check_ecc_pages_valid()
797 info = &meson_chip->info_buf[neccpages - 1]; in meson_nfc_check_ecc_pages_valid()
802 dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes, in meson_nfc_check_ecc_pages_valid()
808 static int meson_nfc_read_page_sub(struct nand_chip *nand, in meson_nfc_read_page_sub() argument
811 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_sub()
812 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_page_sub()
813 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_sub()
817 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_read_page_sub()
819 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_read_page_sub()
820 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_read_page_sub()
822 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRREAD); in meson_nfc_read_page_sub()
826 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_read_page_sub()
827 data_len, meson_chip->info_buf, in meson_nfc_read_page_sub()
832 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_read_page_sub()
834 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
837 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
842 meson_nfc_check_ecc_pages_valid(nfc, nand, raw); in meson_nfc_read_page_sub()
844 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_FROM_DEVICE); in meson_nfc_read_page_sub()
849 static int meson_nfc_read_page_raw(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_raw() argument
852 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_raw()
855 ret = meson_nfc_read_page_sub(nand, page, 1); in meson_nfc_read_page_raw()
859 meson_nfc_get_data_oob(nand, buf, oob_buf); in meson_nfc_read_page_raw()
864 static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_hwecc() argument
867 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_hwecc()
868 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_hwecc()
869 struct nand_ecc_ctrl *ecc = &nand->ecc; in meson_nfc_read_page_hwecc() local
872 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_hwecc()
875 ret = meson_nfc_read_page_sub(nand, page, 0); in meson_nfc_read_page_hwecc()
879 meson_nfc_get_user_byte(nand, oob_buf); in meson_nfc_read_page_hwecc()
880 ret = meson_nfc_ecc_correct(nand, &bitflips, &correct_bitmap); in meson_nfc_read_page_hwecc()
883 memset(buf, 0xff, mtd->writesize); in meson_nfc_read_page_hwecc()
884 memset(oob_buf, 0xff, mtd->oobsize); in meson_nfc_read_page_hwecc()
886 if ((nand->options & NAND_NEED_SCRAMBLING) || !buf) { in meson_nfc_read_page_hwecc()
887 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
890 ret = meson_nfc_read_page_raw(nand, buf, 0, page); in meson_nfc_read_page_hwecc()
894 for (i = 0; i < nand->ecc.steps ; i++) { in meson_nfc_read_page_hwecc()
895 u8 *data = buf + i * ecc->size; in meson_nfc_read_page_hwecc()
896 u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); in meson_nfc_read_page_hwecc()
900 ret = nand_check_erased_ecc_chunk(data, ecc->size, in meson_nfc_read_page_hwecc()
901 oob, ecc->bytes + 2, in meson_nfc_read_page_hwecc()
903 ecc->strength); in meson_nfc_read_page_hwecc()
905 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
907 mtd->ecc_stats.corrected += ret; in meson_nfc_read_page_hwecc()
911 } else if (buf && buf != meson_chip->data_buf) { in meson_nfc_read_page_hwecc()
912 memcpy(buf, meson_chip->data_buf, mtd->writesize); in meson_nfc_read_page_hwecc()
918 static int meson_nfc_read_oob_raw(struct nand_chip *nand, int page) in meson_nfc_read_oob_raw() argument
920 return meson_nfc_read_page_raw(nand, NULL, 1, page); in meson_nfc_read_oob_raw()
923 static int meson_nfc_read_oob(struct nand_chip *nand, int page) in meson_nfc_read_oob() argument
925 return meson_nfc_read_page_hwecc(nand, NULL, 1, page); in meson_nfc_read_oob()
941 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR)) in meson_nand_op_get_dma_safe_input_buf()
944 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.in)) in meson_nand_op_get_dma_safe_input_buf()
945 return instr->ctx.data.buf.in; in meson_nand_op_get_dma_safe_input_buf()
947 return kzalloc(instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_input_buf()
954 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR) || in meson_nand_op_put_dma_safe_input_buf()
958 if (buf == instr->ctx.data.buf.in) in meson_nand_op_put_dma_safe_input_buf()
961 memcpy(instr->ctx.data.buf.in, buf, instr->ctx.data.len); in meson_nand_op_put_dma_safe_input_buf()
968 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR)) in meson_nand_op_get_dma_safe_output_buf()
971 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.out)) in meson_nand_op_get_dma_safe_output_buf()
972 return (void *)instr->ctx.data.buf.out; in meson_nand_op_get_dma_safe_output_buf()
974 return kmemdup(instr->ctx.data.buf.out, in meson_nand_op_get_dma_safe_output_buf()
975 instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_output_buf()
982 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR) || in meson_nand_op_put_dma_safe_output_buf()
986 if (buf != instr->ctx.data.buf.out) in meson_nand_op_put_dma_safe_output_buf()
995 for (op_id = 0; op_id < op->ninstrs; op_id++) { in meson_nfc_check_op()
998 instr = &op->instrs[op_id]; in meson_nfc_check_op()
1000 switch (instr->type) { in meson_nfc_check_op()
1003 if (instr->ctx.data.len > NFC_CMD_RAW_LEN) in meson_nfc_check_op()
1004 return -ENOTSUPP; in meson_nfc_check_op()
1015 static int meson_nfc_exec_op(struct nand_chip *nand, in meson_nfc_exec_op() argument
1018 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_exec_op()
1019 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_exec_op()
1026 err = meson_nfc_check_op(nand, op); in meson_nfc_exec_op()
1033 meson_nfc_select_chip(nand, op->cs); in meson_nfc_exec_op()
1034 for (op_id = 0; op_id < op->ninstrs; op_id++) { in meson_nfc_exec_op()
1035 instr = &op->instrs[op_id]; in meson_nfc_exec_op()
1036 delay_idle = DIV_ROUND_UP(PSEC_TO_NSEC(instr->delay_ns), in meson_nfc_exec_op()
1037 meson_chip->level1_divider * in meson_nfc_exec_op()
1039 switch (instr->type) { in meson_nfc_exec_op()
1041 cmd = nfc->param.chip_select | NFC_CMD_CLE; in meson_nfc_exec_op()
1042 cmd |= instr->ctx.cmd.opcode & 0xff; in meson_nfc_exec_op()
1043 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
1048 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in meson_nfc_exec_op()
1049 cmd = nfc->param.chip_select | NFC_CMD_ALE; in meson_nfc_exec_op()
1050 cmd |= instr->ctx.addr.addrs[i] & 0xff; in meson_nfc_exec_op()
1051 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
1059 return -ENOMEM; in meson_nfc_exec_op()
1060 meson_nfc_read_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1067 return -ENOMEM; in meson_nfc_exec_op()
1068 meson_nfc_write_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
1073 meson_nfc_queue_rb(nand, instr->ctx.waitrdy.timeout_ms, in meson_nfc_exec_op()
1075 if (instr->delay_ns) in meson_nfc_exec_op()
1087 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_ecc() local
1089 if (section >= nand->ecc.steps) in meson_ooblayout_ecc()
1090 return -ERANGE; in meson_ooblayout_ecc()
1092 oobregion->offset = 2 + (section * (2 + nand->ecc.bytes)); in meson_ooblayout_ecc()
1093 oobregion->length = nand->ecc.bytes; in meson_ooblayout_ecc()
1101 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_free() local
1103 if (section >= nand->ecc.steps) in meson_ooblayout_free()
1104 return -ERANGE; in meson_ooblayout_free()
1106 oobregion->offset = section * (2 + nand->ecc.bytes); in meson_ooblayout_free()
1107 oobregion->length = 2; in meson_ooblayout_free()
1113 .ecc = meson_ooblayout_ecc,
1124 nfc->core_clk = devm_clk_get(nfc->dev, "core"); in meson_nfc_clk_init()
1125 if (IS_ERR(nfc->core_clk)) { in meson_nfc_clk_init()
1126 dev_err(nfc->dev, "failed to get core clock\n"); in meson_nfc_clk_init()
1127 return PTR_ERR(nfc->core_clk); in meson_nfc_clk_init()
1130 nfc->device_clk = devm_clk_get(nfc->dev, "device"); in meson_nfc_clk_init()
1131 if (IS_ERR(nfc->device_clk)) { in meson_nfc_clk_init()
1132 dev_err(nfc->dev, "failed to get device clock\n"); in meson_nfc_clk_init()
1133 return PTR_ERR(nfc->device_clk); in meson_nfc_clk_init()
1136 init.name = devm_kasprintf(nfc->dev, in meson_nfc_clk_init()
1138 dev_name(nfc->dev)); in meson_nfc_clk_init()
1140 return -ENOMEM; in meson_nfc_clk_init()
1146 nfc->nand_divider.reg = nfc->reg_clk; in meson_nfc_clk_init()
1147 nfc->nand_divider.shift = CLK_DIV_SHIFT; in meson_nfc_clk_init()
1148 nfc->nand_divider.width = CLK_DIV_WIDTH; in meson_nfc_clk_init()
1149 nfc->nand_divider.hw.init = &init; in meson_nfc_clk_init()
1150 nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED | in meson_nfc_clk_init()
1154 nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw); in meson_nfc_clk_init()
1155 if (IS_ERR(nfc->nand_clk)) in meson_nfc_clk_init()
1156 return PTR_ERR(nfc->nand_clk); in meson_nfc_clk_init()
1160 nfc->reg_clk); in meson_nfc_clk_init()
1162 ret = clk_prepare_enable(nfc->core_clk); in meson_nfc_clk_init()
1164 dev_err(nfc->dev, "failed to enable core clock\n"); in meson_nfc_clk_init()
1168 ret = clk_prepare_enable(nfc->device_clk); in meson_nfc_clk_init()
1170 dev_err(nfc->dev, "failed to enable device clock\n"); in meson_nfc_clk_init()
1174 ret = clk_prepare_enable(nfc->nand_clk); in meson_nfc_clk_init()
1176 dev_err(nfc->dev, "pre enable NFC divider fail\n"); in meson_nfc_clk_init()
1180 ret = clk_set_rate(nfc->nand_clk, 24000000); in meson_nfc_clk_init()
1187 clk_disable_unprepare(nfc->nand_clk); in meson_nfc_clk_init()
1189 clk_disable_unprepare(nfc->device_clk); in meson_nfc_clk_init()
1191 clk_disable_unprepare(nfc->core_clk); in meson_nfc_clk_init()
1197 clk_disable_unprepare(nfc->nand_clk); in meson_nfc_disable_clk()
1198 clk_disable_unprepare(nfc->device_clk); in meson_nfc_disable_clk()
1199 clk_disable_unprepare(nfc->core_clk); in meson_nfc_disable_clk()
1202 static void meson_nfc_free_buffer(struct nand_chip *nand) in meson_nfc_free_buffer() argument
1204 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_free_buffer()
1206 kfree(meson_chip->info_buf); in meson_nfc_free_buffer()
1207 kfree(meson_chip->data_buf); in meson_nfc_free_buffer()
1210 static int meson_chip_buffer_init(struct nand_chip *nand) in meson_chip_buffer_init() argument
1212 struct mtd_info *mtd = nand_to_mtd(nand); in meson_chip_buffer_init()
1213 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_chip_buffer_init()
1216 nsectors = mtd->writesize / nand->ecc.size; in meson_chip_buffer_init()
1218 page_bytes = mtd->writesize + mtd->oobsize; in meson_chip_buffer_init()
1221 meson_chip->data_buf = kmalloc(page_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1222 if (!meson_chip->data_buf) in meson_chip_buffer_init()
1223 return -ENOMEM; in meson_chip_buffer_init()
1225 meson_chip->info_buf = kmalloc(info_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1226 if (!meson_chip->info_buf) { in meson_chip_buffer_init()
1227 kfree(meson_chip->data_buf); in meson_chip_buffer_init()
1228 return -ENOMEM; in meson_chip_buffer_init()
1235 int meson_nfc_setup_interface(struct nand_chip *nand, int csline, in meson_nfc_setup_interface() argument
1238 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_setup_interface()
1244 return -ENOTSUPP; in meson_nfc_setup_interface()
1249 div = DIV_ROUND_UP((timings->tRC_min / 1000), NFC_CLK_CYCLE); in meson_nfc_setup_interface()
1250 bt_min = (timings->tREA_max + NFC_DEFAULT_DELAY) / div; in meson_nfc_setup_interface()
1251 bt_max = (NFC_DEFAULT_DELAY + timings->tRHOH_min + in meson_nfc_setup_interface()
1252 timings->tRC_min / 2) / div; in meson_nfc_setup_interface()
1254 meson_chip->twb = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tWB_max), in meson_nfc_setup_interface()
1256 meson_chip->tadl = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tADL_min), in meson_nfc_setup_interface()
1258 tbers_clocks = DIV_ROUND_UP_ULL(PSEC_TO_NSEC(timings->tBERS_max), in meson_nfc_setup_interface()
1260 meson_chip->tbers_max = ilog2(tbers_clocks); in meson_nfc_setup_interface()
1262 meson_chip->tbers_max++; in meson_nfc_setup_interface()
1268 return -EINVAL; in meson_nfc_setup_interface()
1270 meson_chip->level1_divider = div; in meson_nfc_setup_interface()
1271 meson_chip->clk_rate = 1000000000 / meson_chip->level1_divider; in meson_nfc_setup_interface()
1272 meson_chip->bus_timing = (bt_min + bt_max) / 2 + 1; in meson_nfc_setup_interface()
1277 static int meson_nand_bch_mode(struct nand_chip *nand) in meson_nand_bch_mode() argument
1279 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_bch_mode()
1282 if (nand->ecc.strength > 60 || nand->ecc.strength < 8) in meson_nand_bch_mode()
1283 return -EINVAL; in meson_nand_bch_mode()
1286 if (meson_ecc[i].strength == nand->ecc.strength && in meson_nand_bch_mode()
1287 meson_ecc[i].size == nand->ecc.size) { in meson_nand_bch_mode()
1288 meson_chip->bch_mode = meson_ecc[i].bch; in meson_nand_bch_mode()
1293 return -EINVAL; in meson_nand_bch_mode()
1296 static void meson_nand_detach_chip(struct nand_chip *nand) in meson_nand_detach_chip() argument
1298 meson_nfc_free_buffer(nand); in meson_nand_detach_chip()
1301 static int meson_nand_attach_chip(struct nand_chip *nand) in meson_nand_attach_chip() argument
1303 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nand_attach_chip()
1304 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_attach_chip()
1305 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nand_attach_chip()
1309 if (!mtd->name) { in meson_nand_attach_chip()
1310 mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, in meson_nand_attach_chip()
1311 "%s:nand%d", in meson_nand_attach_chip()
1312 dev_name(nfc->dev), in meson_nand_attach_chip()
1313 meson_chip->sels[0]); in meson_nand_attach_chip()
1314 if (!mtd->name) in meson_nand_attach_chip()
1315 return -ENOMEM; in meson_nand_attach_chip()
1318 raw_writesize = mtd->writesize + mtd->oobsize; in meson_nand_attach_chip()
1320 dev_err(nfc->dev, "too big write size in raw mode: %d > %ld\n", in meson_nand_attach_chip()
1322 return -EINVAL; in meson_nand_attach_chip()
1325 if (nand->bbt_options & NAND_BBT_USE_FLASH) in meson_nand_attach_chip()
1326 nand->bbt_options |= NAND_BBT_NO_OOB; in meson_nand_attach_chip()
1328 nand->options |= NAND_NO_SUBPAGE_WRITE; in meson_nand_attach_chip()
1330 ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, in meson_nand_attach_chip()
1331 mtd->oobsize - 2); in meson_nand_attach_chip()
1333 dev_err(nfc->dev, "failed to ECC init\n"); in meson_nand_attach_chip()
1334 return -EINVAL; in meson_nand_attach_chip()
1339 ret = meson_nand_bch_mode(nand); in meson_nand_attach_chip()
1341 return -EINVAL; in meson_nand_attach_chip()
1343 nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; in meson_nand_attach_chip()
1344 nand->ecc.write_page_raw = meson_nfc_write_page_raw; in meson_nand_attach_chip()
1345 nand->ecc.write_page = meson_nfc_write_page_hwecc; in meson_nand_attach_chip()
1346 nand->ecc.write_oob_raw = nand_write_oob_std; in meson_nand_attach_chip()
1347 nand->ecc.write_oob = nand_write_oob_std; in meson_nand_attach_chip()
1349 nand->ecc.read_page_raw = meson_nfc_read_page_raw; in meson_nand_attach_chip()
1350 nand->ecc.read_page = meson_nfc_read_page_hwecc; in meson_nand_attach_chip()
1351 nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; in meson_nand_attach_chip()
1352 nand->ecc.read_oob = meson_nfc_read_oob; in meson_nand_attach_chip()
1354 if (nand->options & NAND_BUSWIDTH_16) { in meson_nand_attach_chip()
1355 dev_err(nfc->dev, "16bits bus width not supported"); in meson_nand_attach_chip()
1356 return -EINVAL; in meson_nand_attach_chip()
1358 ret = meson_chip_buffer_init(nand); in meson_nand_attach_chip()
1360 return -ENOMEM; in meson_nand_attach_chip()
1377 struct nand_chip *nand; in meson_nfc_nand_chip_init() local
1386 return -EINVAL; in meson_nfc_nand_chip_init()
1392 return -ENOMEM; in meson_nfc_nand_chip_init()
1394 meson_chip->nsels = nsels; in meson_nfc_nand_chip_init()
1404 if (test_and_set_bit(tmp, &nfc->assigned_cs)) { in meson_nfc_nand_chip_init()
1406 return -EINVAL; in meson_nfc_nand_chip_init()
1410 nand = &meson_chip->nand; in meson_nfc_nand_chip_init()
1411 nand->controller = &nfc->controller; in meson_nfc_nand_chip_init()
1412 nand->controller->ops = &meson_nand_controller_ops; in meson_nfc_nand_chip_init()
1413 nand_set_flash_node(nand, np); in meson_nfc_nand_chip_init()
1414 nand_set_controller_data(nand, nfc); in meson_nfc_nand_chip_init()
1416 nand->options |= NAND_USES_DMA; in meson_nfc_nand_chip_init()
1417 mtd = nand_to_mtd(nand); in meson_nfc_nand_chip_init()
1418 mtd->owner = THIS_MODULE; in meson_nfc_nand_chip_init()
1419 mtd->dev.parent = dev; in meson_nfc_nand_chip_init()
1421 ret = of_property_read_u32(np, "nand-rb", &nand_rb_val); in meson_nfc_nand_chip_init()
1422 if (ret == -EINVAL) in meson_nfc_nand_chip_init()
1423 nfc->no_rb_pin = true; in meson_nfc_nand_chip_init()
1428 return -EINVAL; in meson_nfc_nand_chip_init()
1430 ret = nand_scan(nand, nsels); in meson_nfc_nand_chip_init()
1437 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1441 list_add_tail(&meson_chip->node, &nfc->chips); in meson_nfc_nand_chip_init()
1451 while (!list_empty(&nfc->chips)) { in meson_nfc_nand_chip_cleanup()
1452 meson_chip = list_first_entry(&nfc->chips, in meson_nfc_nand_chip_cleanup()
1454 mtd = nand_to_mtd(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1457 nand_cleanup(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1458 list_del(&meson_chip->node); in meson_nfc_nand_chip_cleanup()
1465 struct device_node *np = dev->of_node; in meson_nfc_nand_chips_init()
1486 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1491 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1493 complete(&nfc->completion); in meson_nfc_irq()
1507 .compatible = "amlogic,meson-gxl-nfc",
1510 .compatible = "amlogic,meson-axg-nfc",
1519 struct device *dev = &pdev->dev; in meson_nfc_probe()
1525 return -ENOMEM; in meson_nfc_probe()
1527 nfc->data = of_device_get_match_data(&pdev->dev); in meson_nfc_probe()
1528 if (!nfc->data) in meson_nfc_probe()
1529 return -ENODEV; in meson_nfc_probe()
1531 nand_controller_init(&nfc->controller); in meson_nfc_probe()
1532 INIT_LIST_HEAD(&nfc->chips); in meson_nfc_probe()
1533 init_completion(&nfc->completion); in meson_nfc_probe()
1535 nfc->dev = dev; in meson_nfc_probe()
1537 nfc->reg_base = devm_platform_ioremap_resource_byname(pdev, "nfc"); in meson_nfc_probe()
1538 if (IS_ERR(nfc->reg_base)) in meson_nfc_probe()
1539 return PTR_ERR(nfc->reg_base); in meson_nfc_probe()
1541 nfc->reg_clk = devm_platform_ioremap_resource_byname(pdev, "emmc"); in meson_nfc_probe()
1542 if (IS_ERR(nfc->reg_clk)) in meson_nfc_probe()
1543 return PTR_ERR(nfc->reg_clk); in meson_nfc_probe()
1547 return -EINVAL; in meson_nfc_probe()
1551 dev_err(dev, "failed to initialize NAND clock\n"); in meson_nfc_probe()
1555 writel(0, nfc->reg_base + NFC_REG_CFG); in meson_nfc_probe()
1559 ret = -EINVAL; in meson_nfc_probe()
1573 dev_err(dev, "failed to init NAND chips\n"); in meson_nfc_probe()
1596 .name = "meson-nand",
1604 MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver");