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>
76 #define ECC_CHECK_RETURN_FF (-1)
91 /* nand flash controller delay 3 ns */
109 struct nand_chip nand; member
126 u32 strength; member
188 #define MESON_ECC_DATA(b, s) { .bch = (b), .strength = (s)}
199 static int meson_nand_calc_ecc_bytes(int step_size, int strength) in meson_nand_calc_ecc_bytes() argument
203 if (step_size == 512 && strength == 8) in meson_nand_calc_ecc_bytes()
206 ecc_bytes = DIV_ROUND_UP(strength * fls(step_size * 8), 8); in meson_nand_calc_ecc_bytes()
217 static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand) in to_meson_nand() argument
219 return container_of(nand, struct meson_nfc_nand_chip, nand); in to_meson_nand()
222 static void meson_nfc_select_chip(struct nand_chip *nand, int chip) in meson_nfc_select_chip() argument
224 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_select_chip()
225 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_select_chip()
228 if (chip < 0 || WARN_ON_ONCE(chip >= meson_chip->nsels)) in meson_nfc_select_chip()
231 nfc->param.chip_select = meson_chip->sels[chip] ? NAND_CE1 : NAND_CE0; in meson_nfc_select_chip()
232 nfc->param.rb_select = nfc->param.chip_select; in meson_nfc_select_chip()
233 nfc->timing.twb = meson_chip->twb; in meson_nfc_select_chip()
234 nfc->timing.tadl = meson_chip->tadl; in meson_nfc_select_chip()
235 nfc->timing.tbers_max = meson_chip->tbers_max; in meson_nfc_select_chip()
237 if (nfc->clk_rate != meson_chip->clk_rate) { in meson_nfc_select_chip()
238 ret = clk_set_rate(nfc->device_clk, meson_chip->clk_rate); in meson_nfc_select_chip()
240 dev_err(nfc->dev, "failed to set clock rate\n"); in meson_nfc_select_chip()
243 nfc->clk_rate = meson_chip->clk_rate; in meson_nfc_select_chip()
245 if (nfc->bus_timing != meson_chip->bus_timing) { in meson_nfc_select_chip()
246 value = (NFC_CLK_CYCLE - 1) | (meson_chip->bus_timing << 5); in meson_nfc_select_chip()
247 writel(value, nfc->reg_base + NFC_REG_CFG); in meson_nfc_select_chip()
248 writel((1 << 31), nfc->reg_base + NFC_REG_CMD); in meson_nfc_select_chip()
249 nfc->bus_timing = meson_chip->bus_timing; in meson_nfc_select_chip()
255 writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff), in meson_nfc_cmd_idle()
256 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_idle()
262 nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_seed()
265 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, in meson_nfc_cmd_access() argument
268 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_cmd_access()
270 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_cmd_access()
271 u32 bch = meson_chip->bch_mode, cmd; in meson_nfc_cmd_access()
272 int len = mtd->writesize, pagesize, pages; in meson_nfc_cmd_access()
274 pagesize = nand->ecc.size; in meson_nfc_cmd_access()
277 len = mtd->writesize + mtd->oobsize; in meson_nfc_cmd_access()
279 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_access()
283 pages = len / nand->ecc.size; in meson_nfc_cmd_access()
288 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_cmd_access()
296 * The Nand flash controller is designed as two stages pipleline - in meson_nfc_drain_cmd()
299 * but the Nand flash controller still has two commands buffered, in meson_nfc_drain_cmd()
315 ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size, in meson_nfc_wait_cmd_finish()
319 dev_err(nfc->dev, "wait for empty CMD FIFO time out\n"); in meson_nfc_wait_cmd_finish()
331 static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i) in meson_nfc_oob_ptr() argument
333 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_oob_ptr()
336 len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i; in meson_nfc_oob_ptr()
338 return meson_chip->data_buf + len; in meson_nfc_oob_ptr()
341 static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i) in meson_nfc_data_ptr() argument
343 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_data_ptr()
346 temp = nand->ecc.size + nand->ecc.bytes; in meson_nfc_data_ptr()
349 return meson_chip->data_buf + len; in meson_nfc_data_ptr()
352 static void meson_nfc_get_data_oob(struct nand_chip *nand, in meson_nfc_get_data_oob() argument
358 oob_len = nand->ecc.bytes + 2; in meson_nfc_get_data_oob()
359 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_get_data_oob()
361 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_get_data_oob()
362 memcpy(buf, dsrc, nand->ecc.size); in meson_nfc_get_data_oob()
363 buf += nand->ecc.size; in meson_nfc_get_data_oob()
365 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_get_data_oob()
371 static void meson_nfc_set_data_oob(struct nand_chip *nand, in meson_nfc_set_data_oob() argument
377 oob_len = nand->ecc.bytes + 2; in meson_nfc_set_data_oob()
378 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_set_data_oob()
380 dsrc = meson_nfc_data_ptr(nand, i); in meson_nfc_set_data_oob()
381 memcpy(dsrc, buf, nand->ecc.size); in meson_nfc_set_data_oob()
382 buf += nand->ecc.size; in meson_nfc_set_data_oob()
384 osrc = meson_nfc_oob_ptr(nand, i); in meson_nfc_set_data_oob()
395 meson_nfc_cmd_idle(nfc, nfc->timing.twb); in meson_nfc_queue_rb()
399 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_queue_rb()
401 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_queue_rb()
403 reinit_completion(&nfc->completion); in meson_nfc_queue_rb()
407 | nfc->param.chip_select | nfc->timing.tbers_max; in meson_nfc_queue_rb()
408 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_queue_rb()
410 ret = wait_for_completion_timeout(&nfc->completion, in meson_nfc_queue_rb()
413 ret = -1; in meson_nfc_queue_rb()
418 static void meson_nfc_set_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_set_user_byte() argument
420 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_set_user_byte()
424 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { in meson_nfc_set_user_byte()
425 info = &meson_chip->info_buf[i]; in meson_nfc_set_user_byte()
431 static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf) in meson_nfc_get_user_byte() argument
433 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_get_user_byte()
437 for (i = 0, count = 0; i < nand->ecc.steps; i++, count += 2) { in meson_nfc_get_user_byte()
438 info = &meson_chip->info_buf[i]; in meson_nfc_get_user_byte()
444 static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, in meson_nfc_ecc_correct() argument
447 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_ecc_correct()
448 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_ecc_correct()
452 for (i = 0; i < nand->ecc.steps; i++) { in meson_nfc_ecc_correct()
453 info = &meson_chip->info_buf[i]; in meson_nfc_ecc_correct()
455 mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); in meson_nfc_ecc_correct()
460 if ((nand->options & NAND_NEED_SCRAMBLING) && in meson_nfc_ecc_correct()
461 ECC_ZERO_CNT(*info) < nand->ecc.strength) { in meson_nfc_ecc_correct()
462 mtd->ecc_stats.corrected += ECC_ZERO_CNT(*info); in meson_nfc_ecc_correct()
467 ret = -EBADMSG; in meson_nfc_ecc_correct()
473 static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, in meson_nfc_dma_buffer_setup() argument
477 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_setup()
481 nfc->daddr = dma_map_single(nfc->dev, databuf, datalen, dir); in meson_nfc_dma_buffer_setup()
482 ret = dma_mapping_error(nfc->dev, nfc->daddr); in meson_nfc_dma_buffer_setup()
484 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
487 cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr); in meson_nfc_dma_buffer_setup()
488 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
490 cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr); in meson_nfc_dma_buffer_setup()
491 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
494 nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir); in meson_nfc_dma_buffer_setup()
495 ret = dma_mapping_error(nfc->dev, nfc->iaddr); in meson_nfc_dma_buffer_setup()
497 dev_err(nfc->dev, "DMA mapping error\n"); in meson_nfc_dma_buffer_setup()
498 dma_unmap_single(nfc->dev, in meson_nfc_dma_buffer_setup()
499 nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_setup()
502 cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); in meson_nfc_dma_buffer_setup()
503 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
505 cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr); in meson_nfc_dma_buffer_setup()
506 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_dma_buffer_setup()
512 static void meson_nfc_dma_buffer_release(struct nand_chip *nand, in meson_nfc_dma_buffer_release() argument
516 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_dma_buffer_release()
518 dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); in meson_nfc_dma_buffer_release()
520 dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); in meson_nfc_dma_buffer_release()
523 static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_read_buf() argument
525 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_buf()
532 return -ENOMEM; in meson_nfc_read_buf()
534 ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, in meson_nfc_read_buf()
540 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_read_buf()
544 meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); in meson_nfc_read_buf()
552 static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len) in meson_nfc_write_buf() argument
554 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_buf()
558 ret = meson_nfc_dma_buffer_setup(nand, buf, len, NULL, in meson_nfc_write_buf()
564 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_buf()
568 meson_nfc_dma_buffer_release(nand, len, 0, DMA_TO_DEVICE); in meson_nfc_write_buf()
573 static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, in meson_nfc_rw_cmd_prepare_and_execute() argument
576 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_rw_cmd_prepare_and_execute()
577 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_rw_cmd_prepare_and_execute()
579 nand_get_sdr_timings(&nand->data_interface); in meson_nfc_rw_cmd_prepare_and_execute()
580 u32 *addrs = nfc->cmdfifo.rw.addrs; in meson_nfc_rw_cmd_prepare_and_execute()
581 u32 cs = nfc->param.chip_select; in meson_nfc_rw_cmd_prepare_and_execute()
588 nfc->cmdfifo.rw.cmd0 = cs | NFC_CMD_CLE | cmd0; in meson_nfc_rw_cmd_prepare_and_execute()
591 if (mtd->writesize <= 512) { in meson_nfc_rw_cmd_prepare_and_execute()
592 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
602 if (nand->options & NAND_ROW_ADDR_3) in meson_nfc_rw_cmd_prepare_and_execute()
606 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
609 cmd_num--; in meson_nfc_rw_cmd_prepare_and_execute()
612 writel_relaxed(nfc->cmdfifo.cmd[i], in meson_nfc_rw_cmd_prepare_and_execute()
613 nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
616 nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART; in meson_nfc_rw_cmd_prepare_and_execute()
617 writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD); in meson_nfc_rw_cmd_prepare_and_execute()
618 meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max)); in meson_nfc_rw_cmd_prepare_and_execute()
620 meson_nfc_cmd_idle(nfc, nfc->timing.tadl); in meson_nfc_rw_cmd_prepare_and_execute()
626 static int meson_nfc_write_page_sub(struct nand_chip *nand, in meson_nfc_write_page_sub() argument
629 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_sub()
631 nand_get_sdr_timings(&nand->data_interface); in meson_nfc_write_page_sub()
632 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_sub()
633 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_write_page_sub()
638 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_write_page_sub()
640 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_write_page_sub()
641 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_write_page_sub()
643 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRWRITE); in meson_nfc_write_page_sub()
647 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_write_page_sub()
648 data_len, meson_chip->info_buf, in meson_nfc_write_page_sub()
653 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_write_page_sub()
655 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
658 meson_nfc_cmd_access(nand, raw, DIRWRITE, in meson_nfc_write_page_sub()
662 cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG; in meson_nfc_write_page_sub()
663 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_write_page_sub()
664 meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max)); in meson_nfc_write_page_sub()
666 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE); in meson_nfc_write_page_sub()
671 static int meson_nfc_write_page_raw(struct nand_chip *nand, const u8 *buf, in meson_nfc_write_page_raw() argument
674 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_raw()
676 meson_nfc_set_data_oob(nand, buf, oob_buf); in meson_nfc_write_page_raw()
678 return meson_nfc_write_page_sub(nand, page, 1); in meson_nfc_write_page_raw()
681 static int meson_nfc_write_page_hwecc(struct nand_chip *nand, in meson_nfc_write_page_hwecc() argument
684 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_write_page_hwecc()
685 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_write_page_hwecc()
686 u8 *oob_buf = nand->oob_poi; in meson_nfc_write_page_hwecc()
688 memcpy(meson_chip->data_buf, buf, mtd->writesize); in meson_nfc_write_page_hwecc()
689 memset(meson_chip->info_buf, 0, nand->ecc.steps * PER_INFO_BYTE); in meson_nfc_write_page_hwecc()
690 meson_nfc_set_user_byte(nand, oob_buf); in meson_nfc_write_page_hwecc()
692 return meson_nfc_write_page_sub(nand, page, 0); in meson_nfc_write_page_hwecc()
696 struct nand_chip *nand, int raw) in meson_nfc_check_ecc_pages_valid() argument
698 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_check_ecc_pages_valid()
703 neccpages = raw ? 1 : nand->ecc.steps; in meson_nfc_check_ecc_pages_valid()
704 info = &meson_chip->info_buf[neccpages - 1]; in meson_nfc_check_ecc_pages_valid()
713 static int meson_nfc_read_page_sub(struct nand_chip *nand, in meson_nfc_read_page_sub() argument
716 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_sub()
717 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_read_page_sub()
718 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_sub()
722 meson_nfc_select_chip(nand, nand->cur_cs); in meson_nfc_read_page_sub()
724 data_len = mtd->writesize + mtd->oobsize; in meson_nfc_read_page_sub()
725 info_len = nand->ecc.steps * PER_INFO_BYTE; in meson_nfc_read_page_sub()
727 ret = meson_nfc_rw_cmd_prepare_and_execute(nand, page, DIRREAD); in meson_nfc_read_page_sub()
731 ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, in meson_nfc_read_page_sub()
732 data_len, meson_chip->info_buf, in meson_nfc_read_page_sub()
737 if (nand->options & NAND_NEED_SCRAMBLING) { in meson_nfc_read_page_sub()
739 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
742 meson_nfc_cmd_access(nand, raw, DIRREAD, in meson_nfc_read_page_sub()
747 meson_nfc_check_ecc_pages_valid(nfc, nand, raw); in meson_nfc_read_page_sub()
749 meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_FROM_DEVICE); in meson_nfc_read_page_sub()
754 static int meson_nfc_read_page_raw(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_raw() argument
757 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_raw()
760 ret = meson_nfc_read_page_sub(nand, page, 1); in meson_nfc_read_page_raw()
764 meson_nfc_get_data_oob(nand, buf, oob_buf); in meson_nfc_read_page_raw()
769 static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf, in meson_nfc_read_page_hwecc() argument
772 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nfc_read_page_hwecc()
773 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_read_page_hwecc()
774 struct nand_ecc_ctrl *ecc = &nand->ecc; in meson_nfc_read_page_hwecc() local
777 u8 *oob_buf = nand->oob_poi; in meson_nfc_read_page_hwecc()
780 ret = meson_nfc_read_page_sub(nand, page, 0); in meson_nfc_read_page_hwecc()
784 meson_nfc_get_user_byte(nand, oob_buf); in meson_nfc_read_page_hwecc()
785 ret = meson_nfc_ecc_correct(nand, &bitflips, &correct_bitmap); in meson_nfc_read_page_hwecc()
788 memset(buf, 0xff, mtd->writesize); in meson_nfc_read_page_hwecc()
789 memset(oob_buf, 0xff, mtd->oobsize); in meson_nfc_read_page_hwecc()
791 if ((nand->options & NAND_NEED_SCRAMBLING) || !buf) { in meson_nfc_read_page_hwecc()
792 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
795 ret = meson_nfc_read_page_raw(nand, buf, 0, page); in meson_nfc_read_page_hwecc()
799 for (i = 0; i < nand->ecc.steps ; i++) { in meson_nfc_read_page_hwecc()
800 u8 *data = buf + i * ecc->size; in meson_nfc_read_page_hwecc()
801 u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); in meson_nfc_read_page_hwecc()
805 ret = nand_check_erased_ecc_chunk(data, ecc->size, in meson_nfc_read_page_hwecc()
806 oob, ecc->bytes + 2, in meson_nfc_read_page_hwecc()
808 ecc->strength); in meson_nfc_read_page_hwecc()
810 mtd->ecc_stats.failed++; in meson_nfc_read_page_hwecc()
812 mtd->ecc_stats.corrected += ret; in meson_nfc_read_page_hwecc()
816 } else if (buf && buf != meson_chip->data_buf) { in meson_nfc_read_page_hwecc()
817 memcpy(buf, meson_chip->data_buf, mtd->writesize); in meson_nfc_read_page_hwecc()
823 static int meson_nfc_read_oob_raw(struct nand_chip *nand, int page) in meson_nfc_read_oob_raw() argument
825 return meson_nfc_read_page_raw(nand, NULL, 1, page); in meson_nfc_read_oob_raw()
828 static int meson_nfc_read_oob(struct nand_chip *nand, int page) in meson_nfc_read_oob() argument
830 return meson_nfc_read_page_hwecc(nand, NULL, 1, page); in meson_nfc_read_oob()
843 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR)) in meson_nand_op_get_dma_safe_input_buf()
846 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.in)) in meson_nand_op_get_dma_safe_input_buf()
847 return instr->ctx.data.buf.in; in meson_nand_op_get_dma_safe_input_buf()
849 return kzalloc(instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_input_buf()
856 if (WARN_ON(instr->type != NAND_OP_DATA_IN_INSTR) || in meson_nand_op_put_dma_safe_input_buf()
860 if (buf == instr->ctx.data.buf.in) in meson_nand_op_put_dma_safe_input_buf()
863 memcpy(instr->ctx.data.buf.in, buf, instr->ctx.data.len); in meson_nand_op_put_dma_safe_input_buf()
870 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR)) in meson_nand_op_get_dma_safe_output_buf()
873 if (meson_nfc_is_buffer_dma_safe(instr->ctx.data.buf.out)) in meson_nand_op_get_dma_safe_output_buf()
874 return (void *)instr->ctx.data.buf.out; in meson_nand_op_get_dma_safe_output_buf()
876 return kmemdup(instr->ctx.data.buf.out, in meson_nand_op_get_dma_safe_output_buf()
877 instr->ctx.data.len, GFP_KERNEL); in meson_nand_op_get_dma_safe_output_buf()
884 if (WARN_ON(instr->type != NAND_OP_DATA_OUT_INSTR) || in meson_nand_op_put_dma_safe_output_buf()
888 if (buf != instr->ctx.data.buf.out) in meson_nand_op_put_dma_safe_output_buf()
892 static int meson_nfc_exec_op(struct nand_chip *nand, in meson_nfc_exec_op() argument
895 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_exec_op()
896 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nfc_exec_op()
902 meson_nfc_select_chip(nand, op->cs); in meson_nfc_exec_op()
903 for (op_id = 0; op_id < op->ninstrs; op_id++) { in meson_nfc_exec_op()
904 instr = &op->instrs[op_id]; in meson_nfc_exec_op()
905 delay_idle = DIV_ROUND_UP(PSEC_TO_NSEC(instr->delay_ns), in meson_nfc_exec_op()
906 meson_chip->level1_divider * in meson_nfc_exec_op()
908 switch (instr->type) { in meson_nfc_exec_op()
910 cmd = nfc->param.chip_select | NFC_CMD_CLE; in meson_nfc_exec_op()
911 cmd |= instr->ctx.cmd.opcode & 0xff; in meson_nfc_exec_op()
912 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
917 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in meson_nfc_exec_op()
918 cmd = nfc->param.chip_select | NFC_CMD_ALE; in meson_nfc_exec_op()
919 cmd |= instr->ctx.addr.addrs[i] & 0xff; in meson_nfc_exec_op()
920 writel(cmd, nfc->reg_base + NFC_REG_CMD); in meson_nfc_exec_op()
928 return -ENOMEM; in meson_nfc_exec_op()
929 meson_nfc_read_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
936 return -ENOMEM; in meson_nfc_exec_op()
937 meson_nfc_write_buf(nand, buf, instr->ctx.data.len); in meson_nfc_exec_op()
942 meson_nfc_queue_rb(nfc, instr->ctx.waitrdy.timeout_ms); in meson_nfc_exec_op()
943 if (instr->delay_ns) in meson_nfc_exec_op()
955 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_ecc() local
957 if (section >= nand->ecc.steps) in meson_ooblayout_ecc()
958 return -ERANGE; in meson_ooblayout_ecc()
960 oobregion->offset = 2 + (section * (2 + nand->ecc.bytes)); in meson_ooblayout_ecc()
961 oobregion->length = nand->ecc.bytes; in meson_ooblayout_ecc()
969 struct nand_chip *nand = mtd_to_nand(mtd); in meson_ooblayout_free() local
971 if (section >= nand->ecc.steps) in meson_ooblayout_free()
972 return -ERANGE; in meson_ooblayout_free()
974 oobregion->offset = section * (2 + nand->ecc.bytes); in meson_ooblayout_free()
975 oobregion->length = 2; in meson_ooblayout_free()
981 .ecc = meson_ooblayout_ecc,
990 nfc->core_clk = devm_clk_get(nfc->dev, "core"); in meson_nfc_clk_init()
991 if (IS_ERR(nfc->core_clk)) { in meson_nfc_clk_init()
992 dev_err(nfc->dev, "failed to get core clock\n"); in meson_nfc_clk_init()
993 return PTR_ERR(nfc->core_clk); in meson_nfc_clk_init()
996 nfc->device_clk = devm_clk_get(nfc->dev, "device"); in meson_nfc_clk_init()
997 if (IS_ERR(nfc->device_clk)) { in meson_nfc_clk_init()
998 dev_err(nfc->dev, "failed to get device clock\n"); in meson_nfc_clk_init()
999 return PTR_ERR(nfc->device_clk); in meson_nfc_clk_init()
1002 nfc->phase_tx = devm_clk_get(nfc->dev, "tx"); in meson_nfc_clk_init()
1003 if (IS_ERR(nfc->phase_tx)) { in meson_nfc_clk_init()
1004 dev_err(nfc->dev, "failed to get TX clk\n"); in meson_nfc_clk_init()
1005 return PTR_ERR(nfc->phase_tx); in meson_nfc_clk_init()
1008 nfc->phase_rx = devm_clk_get(nfc->dev, "rx"); in meson_nfc_clk_init()
1009 if (IS_ERR(nfc->phase_rx)) { in meson_nfc_clk_init()
1010 dev_err(nfc->dev, "failed to get RX clk\n"); in meson_nfc_clk_init()
1011 return PTR_ERR(nfc->phase_rx); in meson_nfc_clk_init()
1015 regmap_update_bits(nfc->reg_clk, in meson_nfc_clk_init()
1018 ret = clk_prepare_enable(nfc->core_clk); in meson_nfc_clk_init()
1020 dev_err(nfc->dev, "failed to enable core clock\n"); in meson_nfc_clk_init()
1024 ret = clk_prepare_enable(nfc->device_clk); in meson_nfc_clk_init()
1026 dev_err(nfc->dev, "failed to enable device clock\n"); in meson_nfc_clk_init()
1030 ret = clk_prepare_enable(nfc->phase_tx); in meson_nfc_clk_init()
1032 dev_err(nfc->dev, "failed to enable TX clock\n"); in meson_nfc_clk_init()
1036 ret = clk_prepare_enable(nfc->phase_rx); in meson_nfc_clk_init()
1038 dev_err(nfc->dev, "failed to enable RX clock\n"); in meson_nfc_clk_init()
1042 ret = clk_set_rate(nfc->device_clk, 24000000); in meson_nfc_clk_init()
1048 clk_disable_unprepare(nfc->phase_tx); in meson_nfc_clk_init()
1050 clk_disable_unprepare(nfc->device_clk); in meson_nfc_clk_init()
1052 clk_disable_unprepare(nfc->core_clk); in meson_nfc_clk_init()
1058 clk_disable_unprepare(nfc->phase_rx); in meson_nfc_disable_clk()
1059 clk_disable_unprepare(nfc->phase_tx); in meson_nfc_disable_clk()
1060 clk_disable_unprepare(nfc->device_clk); in meson_nfc_disable_clk()
1061 clk_disable_unprepare(nfc->core_clk); in meson_nfc_disable_clk()
1064 static void meson_nfc_free_buffer(struct nand_chip *nand) in meson_nfc_free_buffer() argument
1066 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_free_buffer()
1068 kfree(meson_chip->info_buf); in meson_nfc_free_buffer()
1069 kfree(meson_chip->data_buf); in meson_nfc_free_buffer()
1072 static int meson_chip_buffer_init(struct nand_chip *nand) in meson_chip_buffer_init() argument
1074 struct mtd_info *mtd = nand_to_mtd(nand); in meson_chip_buffer_init()
1075 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_chip_buffer_init()
1078 nsectors = mtd->writesize / nand->ecc.size; in meson_chip_buffer_init()
1080 page_bytes = mtd->writesize + mtd->oobsize; in meson_chip_buffer_init()
1083 meson_chip->data_buf = kmalloc(page_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1084 if (!meson_chip->data_buf) in meson_chip_buffer_init()
1085 return -ENOMEM; in meson_chip_buffer_init()
1087 meson_chip->info_buf = kmalloc(info_bytes, GFP_KERNEL); in meson_chip_buffer_init()
1088 if (!meson_chip->info_buf) { in meson_chip_buffer_init()
1089 kfree(meson_chip->data_buf); in meson_chip_buffer_init()
1090 return -ENOMEM; in meson_chip_buffer_init()
1097 int meson_nfc_setup_data_interface(struct nand_chip *nand, int csline, in meson_nfc_setup_data_interface() argument
1100 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nfc_setup_data_interface()
1106 return -ENOTSUPP; in meson_nfc_setup_data_interface()
1111 div = DIV_ROUND_UP((timings->tRC_min / 1000), NFC_CLK_CYCLE); in meson_nfc_setup_data_interface()
1112 bt_min = (timings->tREA_max + NFC_DEFAULT_DELAY) / div; in meson_nfc_setup_data_interface()
1113 bt_max = (NFC_DEFAULT_DELAY + timings->tRHOH_min + in meson_nfc_setup_data_interface()
1114 timings->tRC_min / 2) / div; in meson_nfc_setup_data_interface()
1116 meson_chip->twb = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tWB_max), in meson_nfc_setup_data_interface()
1118 meson_chip->tadl = DIV_ROUND_UP(PSEC_TO_NSEC(timings->tADL_min), in meson_nfc_setup_data_interface()
1120 tbers_clocks = DIV_ROUND_UP_ULL(PSEC_TO_NSEC(timings->tBERS_max), in meson_nfc_setup_data_interface()
1122 meson_chip->tbers_max = ilog2(tbers_clocks); in meson_nfc_setup_data_interface()
1124 meson_chip->tbers_max++; in meson_nfc_setup_data_interface()
1130 return -EINVAL; in meson_nfc_setup_data_interface()
1132 meson_chip->level1_divider = div; in meson_nfc_setup_data_interface()
1133 meson_chip->clk_rate = 1000000000 / meson_chip->level1_divider; in meson_nfc_setup_data_interface()
1134 meson_chip->bus_timing = (bt_min + bt_max) / 2 + 1; in meson_nfc_setup_data_interface()
1139 static int meson_nand_bch_mode(struct nand_chip *nand) in meson_nand_bch_mode() argument
1141 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_bch_mode()
1144 if (nand->ecc.strength > 60 || nand->ecc.strength < 8) in meson_nand_bch_mode()
1145 return -EINVAL; in meson_nand_bch_mode()
1148 if (meson_ecc[i].strength == nand->ecc.strength) { in meson_nand_bch_mode()
1149 meson_chip->bch_mode = meson_ecc[i].bch; in meson_nand_bch_mode()
1154 return -EINVAL; in meson_nand_bch_mode()
1157 static void meson_nand_detach_chip(struct nand_chip *nand) in meson_nand_detach_chip() argument
1159 meson_nfc_free_buffer(nand); in meson_nand_detach_chip()
1162 static int meson_nand_attach_chip(struct nand_chip *nand) in meson_nand_attach_chip() argument
1164 struct meson_nfc *nfc = nand_get_controller_data(nand); in meson_nand_attach_chip()
1165 struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); in meson_nand_attach_chip()
1166 struct mtd_info *mtd = nand_to_mtd(nand); in meson_nand_attach_chip()
1167 int nsectors = mtd->writesize / 1024; in meson_nand_attach_chip()
1170 if (!mtd->name) { in meson_nand_attach_chip()
1171 mtd->name = devm_kasprintf(nfc->dev, GFP_KERNEL, in meson_nand_attach_chip()
1172 "%s:nand%d", in meson_nand_attach_chip()
1173 dev_name(nfc->dev), in meson_nand_attach_chip()
1174 meson_chip->sels[0]); in meson_nand_attach_chip()
1175 if (!mtd->name) in meson_nand_attach_chip()
1176 return -ENOMEM; in meson_nand_attach_chip()
1179 if (nand->bbt_options & NAND_BBT_USE_FLASH) in meson_nand_attach_chip()
1180 nand->bbt_options |= NAND_BBT_NO_OOB; in meson_nand_attach_chip()
1182 nand->options |= NAND_NO_SUBPAGE_WRITE; in meson_nand_attach_chip()
1184 ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, in meson_nand_attach_chip()
1185 mtd->oobsize - 2 * nsectors); in meson_nand_attach_chip()
1187 dev_err(nfc->dev, "failed to ECC init\n"); in meson_nand_attach_chip()
1188 return -EINVAL; in meson_nand_attach_chip()
1193 ret = meson_nand_bch_mode(nand); in meson_nand_attach_chip()
1195 return -EINVAL; in meson_nand_attach_chip()
1197 nand->ecc.mode = NAND_ECC_HW; in meson_nand_attach_chip()
1198 nand->ecc.write_page_raw = meson_nfc_write_page_raw; in meson_nand_attach_chip()
1199 nand->ecc.write_page = meson_nfc_write_page_hwecc; in meson_nand_attach_chip()
1200 nand->ecc.write_oob_raw = nand_write_oob_std; in meson_nand_attach_chip()
1201 nand->ecc.write_oob = nand_write_oob_std; in meson_nand_attach_chip()
1203 nand->ecc.read_page_raw = meson_nfc_read_page_raw; in meson_nand_attach_chip()
1204 nand->ecc.read_page = meson_nfc_read_page_hwecc; in meson_nand_attach_chip()
1205 nand->ecc.read_oob_raw = meson_nfc_read_oob_raw; in meson_nand_attach_chip()
1206 nand->ecc.read_oob = meson_nfc_read_oob; in meson_nand_attach_chip()
1208 if (nand->options & NAND_BUSWIDTH_16) { in meson_nand_attach_chip()
1209 dev_err(nfc->dev, "16bits bus width not supported"); in meson_nand_attach_chip()
1210 return -EINVAL; in meson_nand_attach_chip()
1212 ret = meson_chip_buffer_init(nand); in meson_nand_attach_chip()
1214 return -ENOMEM; in meson_nand_attach_chip()
1231 struct nand_chip *nand; in meson_nfc_nand_chip_init() local
1239 return -EINVAL; in meson_nfc_nand_chip_init()
1245 return -ENOMEM; in meson_nfc_nand_chip_init()
1247 meson_chip->nsels = nsels; in meson_nfc_nand_chip_init()
1257 if (test_and_set_bit(tmp, &nfc->assigned_cs)) { in meson_nfc_nand_chip_init()
1259 return -EINVAL; in meson_nfc_nand_chip_init()
1263 nand = &meson_chip->nand; in meson_nfc_nand_chip_init()
1264 nand->controller = &nfc->controller; in meson_nfc_nand_chip_init()
1265 nand->controller->ops = &meson_nand_controller_ops; in meson_nfc_nand_chip_init()
1266 nand_set_flash_node(nand, np); in meson_nfc_nand_chip_init()
1267 nand_set_controller_data(nand, nfc); in meson_nfc_nand_chip_init()
1269 nand->options |= NAND_USE_BOUNCE_BUFFER; in meson_nfc_nand_chip_init()
1270 mtd = nand_to_mtd(nand); in meson_nfc_nand_chip_init()
1271 mtd->owner = THIS_MODULE; in meson_nfc_nand_chip_init()
1272 mtd->dev.parent = dev; in meson_nfc_nand_chip_init()
1274 ret = nand_scan(nand, nsels); in meson_nfc_nand_chip_init()
1281 nand_cleanup(nand); in meson_nfc_nand_chip_init()
1285 list_add_tail(&meson_chip->node, &nfc->chips); in meson_nfc_nand_chip_init()
1296 while (!list_empty(&nfc->chips)) { in meson_nfc_nand_chip_cleanup()
1297 meson_chip = list_first_entry(&nfc->chips, in meson_nfc_nand_chip_cleanup()
1299 mtd = nand_to_mtd(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1304 meson_nfc_free_buffer(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1305 nand_cleanup(&meson_chip->nand); in meson_nfc_nand_chip_cleanup()
1306 list_del(&meson_chip->node); in meson_nfc_nand_chip_cleanup()
1315 struct device_node *np = dev->of_node; in meson_nfc_nand_chips_init()
1336 cfg = readl(nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1341 writel(cfg, nfc->reg_base + NFC_REG_CFG); in meson_nfc_irq()
1343 complete(&nfc->completion); in meson_nfc_irq()
1357 .compatible = "amlogic,meson-gxl-nfc",
1360 .compatible = "amlogic,meson-axg-nfc",
1369 struct device *dev = &pdev->dev; in meson_nfc_probe()
1376 return -ENOMEM; in meson_nfc_probe()
1378 nfc->data = of_device_get_match_data(&pdev->dev); in meson_nfc_probe()
1379 if (!nfc->data) in meson_nfc_probe()
1380 return -ENODEV; in meson_nfc_probe()
1382 nand_controller_init(&nfc->controller); in meson_nfc_probe()
1383 INIT_LIST_HEAD(&nfc->chips); in meson_nfc_probe()
1384 init_completion(&nfc->completion); in meson_nfc_probe()
1386 nfc->dev = dev; in meson_nfc_probe()
1389 nfc->reg_base = devm_ioremap_resource(dev, res); in meson_nfc_probe()
1390 if (IS_ERR(nfc->reg_base)) in meson_nfc_probe()
1391 return PTR_ERR(nfc->reg_base); in meson_nfc_probe()
1393 nfc->reg_clk = in meson_nfc_probe()
1394 syscon_regmap_lookup_by_phandle(dev->of_node, in meson_nfc_probe()
1395 "amlogic,mmc-syscon"); in meson_nfc_probe()
1396 if (IS_ERR(nfc->reg_clk)) { in meson_nfc_probe()
1398 return PTR_ERR(nfc->reg_clk); in meson_nfc_probe()
1404 return -EINVAL; in meson_nfc_probe()
1409 dev_err(dev, "failed to initialize NAND clock\n"); in meson_nfc_probe()
1413 writel(0, nfc->reg_base + NFC_REG_CFG); in meson_nfc_probe()
1417 ret = -EINVAL; in meson_nfc_probe()
1431 dev_err(dev, "failed to init NAND chips\n"); in meson_nfc_probe()
1461 .name = "meson-nand",
1469 MODULE_DESCRIPTION("Amlogic's Meson NAND Flash Controller driver");