Lines Matching +full:clk +full:- +full:out +full:- +full:strength
1 // SPDX-License-Identifier: GPL-2.0
3 // Driver for the SPI-NAND mode of Mediatek NAND Flash Interface
7 // This driver is based on the SPI-NAND mtd driver from Mediatek SDK:
13 // like the following: (sizeof(FDM + ECC) = snf->nfi_cfg.spare_size)
14 // +---------+------+------+---------+------+------+-----+
16 // +---------+------+------+---------+------+------+-----+
17 // With auto-format turned on, DMA only returns this part:
18 // +---------+---------+-----+
20 // +---------+---------+-----+
23 // With auto-format off, all ((Sector+FDM+ECC)*nsectors) will be read over DMA
25 // auto-format is off.
27 // However, Linux SPI-NAND driver expects the data returned as:
28 // +------+-----+
30 // +------+-----+
34 // Here's how this spi-mem driver operates when reading:
35 // 1. Always set snf->autofmt = true in prepare_io_req (even when ECC is off).
37 // de-interleaved sector data and set FDM registers.
39 // +---------+---------+-----+------+------+-----+
41 // +---------+---------+-----+------+------+-----+
43 // read the data with auto-format off into the bounce buffer and copy
52 // as the bad block mark. After de-interleaving, this byte appears at [pagesize]
59 // (page_size - (nsectors - 1) * spare_size) in the DMA buffer.
62 // We can't disagree with the BootROM, so after de-interleaving, we need to
64 // 1. Store the BBM at [page_size - (nsectors - 1) * spare_size] to [page_size],
66 // 2. Store the page data byte at [pagesize + (nsectors-1) * fdm] back to
67 // [page_size - (nsectors - 1) * spare_size]
75 #include <linux/clk.h>
77 #include <linux/dma-mapping.h>
81 #include <linux/mtd/nand-ecc-mtk.h>
83 #include <linux/spi/spi-mem.h>
304 struct clk *nfi_clk;
305 struct clk *pad_clk;
306 struct clk *nfi_hclk;
323 struct nand_ecc_engine *eng = nand->ecc.engine; in nand_to_mtk_snand()
330 if (snf->buf_len >= size) in snand_prepare_bouncebuf()
332 kfree(snf->buf); in snand_prepare_bouncebuf()
333 snf->buf = kmalloc(size, GFP_KERNEL); in snand_prepare_bouncebuf()
334 if (!snf->buf) in snand_prepare_bouncebuf()
335 return -ENOMEM; in snand_prepare_bouncebuf()
336 snf->buf_len = size; in snand_prepare_bouncebuf()
337 memset(snf->buf, 0xff, snf->buf_len); in snand_prepare_bouncebuf()
343 return readl(snf->nfi_base + reg); in nfi_read32()
348 writel(val, snf->nfi_base + reg); in nfi_write32()
353 writew(val, snf->nfi_base + reg); in nfi_write16()
360 val = readl(snf->nfi_base + reg); in nfi_rmw32()
363 writel(val, snf->nfi_base + reg); in nfi_rmw32()
372 val = nfi_read32(snf, i & ~(es - 1)); in nfi_read_data()
385 ret = readw_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val, in mtk_nfi_reset()
386 !(val & snf->caps->mastersta_mask), 0, in mtk_nfi_reset()
389 dev_err(snf->dev, "NFI master is still busy after reset\n"); in mtk_nfi_reset()
393 ret = readl_poll_timeout(snf->nfi_base + NFI_STA, val, in mtk_nfi_reset()
394 !(val & (NFI_FSM | snf->caps->nandfsm_mask)), 0, in mtk_nfi_reset()
397 dev_err(snf->dev, "Failed to reset NFI\n"); in mtk_nfi_reset()
401 fifo_mask = ((snf->caps->fifo_size - 1) << FIFO_RD_REMAIN_S) | in mtk_nfi_reset()
402 ((snf->caps->fifo_size - 1) << FIFO_WR_REMAIN_S); in mtk_nfi_reset()
403 ret = readw_poll_timeout(snf->nfi_base + NFI_FIFOSTA, val, in mtk_nfi_reset()
406 dev_err(snf->dev, "NFI FIFOs are not empty\n"); in mtk_nfi_reset()
420 ret = readl_poll_timeout(snf->nfi_base + SNF_STA_CTL1, val, in mtk_snand_mac_reset()
423 dev_err(snf->dev, "Failed to reset SNFI MAC\n"); in mtk_snand_mac_reset()
442 ret = readl_poll_timeout(snf->nfi_base + SNF_MAC_CTL, val, in mtk_snand_mac_trigger()
445 dev_err(snf->dev, "Timed out waiting for WIP_READY\n"); in mtk_snand_mac_trigger()
449 ret = readl_poll_timeout(snf->nfi_base + SNF_MAC_CTL, val, !(val & WIP), in mtk_snand_mac_trigger()
452 dev_err(snf->dev, "Timed out waiting for WIP cleared\n"); in mtk_snand_mac_trigger()
470 if (op->data.dir == SPI_MEM_DATA_IN) { in mtk_snand_mac_io()
471 rx_len = op->data.nbytes; in mtk_snand_mac_io()
472 rx_buf = op->data.buf.in; in mtk_snand_mac_io()
474 tx_buf = op->data.buf.out; in mtk_snand_mac_io()
479 for (i = 0; i < op->cmd.nbytes; i++, reg_offs++) { in mtk_snand_mac_io()
480 b = (op->cmd.opcode >> ((op->cmd.nbytes - i - 1) * 8)) & 0xff; in mtk_snand_mac_io()
483 nfi_write32(snf, SNF_GPRAM + reg_offs - 3, val); in mtk_snand_mac_io()
488 for (i = 0; i < op->addr.nbytes; i++, reg_offs++) { in mtk_snand_mac_io()
489 b = (op->addr.val >> ((op->addr.nbytes - i - 1) * 8)) & 0xff; in mtk_snand_mac_io()
492 nfi_write32(snf, SNF_GPRAM + reg_offs - 3, val); in mtk_snand_mac_io()
497 for (i = 0; i < op->dummy.nbytes; i++, reg_offs++) { in mtk_snand_mac_io()
499 nfi_write32(snf, SNF_GPRAM + reg_offs - 3, val); in mtk_snand_mac_io()
504 if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_snand_mac_io()
505 for (i = 0; i < op->data.nbytes; i++, reg_offs++) { in mtk_snand_mac_io()
508 nfi_write32(snf, SNF_GPRAM + reg_offs - 3, val); in mtk_snand_mac_io()
518 dev_dbg(snf->dev, "%d: %08X", i, in mtk_snand_mac_io()
521 dev_dbg(snf->dev, "SNF TX: %u RX: %u", reg_offs, rx_len); in mtk_snand_mac_io()
537 int spare_idx = -1; in mtk_snand_setup_pagefmt()
544 if (snf->nfi_cfg.page_size == page_size && in mtk_snand_setup_pagefmt()
545 snf->nfi_cfg.oob_size == oob_size) in mtk_snand_setup_pagefmt()
548 nsectors = page_size / snf->caps->sector_size; in mtk_snand_setup_pagefmt()
549 if (nsectors > snf->caps->max_sectors) { in mtk_snand_setup_pagefmt()
550 dev_err(snf->dev, "too many sectors required.\n"); in mtk_snand_setup_pagefmt()
554 if (snf->caps->sector_size == 512) { in mtk_snand_setup_pagefmt()
567 if (snf->caps->sector_size == 512) in mtk_snand_setup_pagefmt()
573 if (snf->caps->sector_size == 512) in mtk_snand_setup_pagefmt()
579 if (snf->caps->sector_size == 512) in mtk_snand_setup_pagefmt()
588 dev_err(snf->dev, "unsupported page size.\n"); in mtk_snand_setup_pagefmt()
595 if (snf->caps->sector_size == 1024) in mtk_snand_setup_pagefmt()
598 for (i = snf->caps->num_spare_size - 1; i >= 0; i--) { in mtk_snand_setup_pagefmt()
599 if (snf->caps->spare_sizes[i] <= spare_size) { in mtk_snand_setup_pagefmt()
600 spare_size = snf->caps->spare_sizes[i]; in mtk_snand_setup_pagefmt()
601 if (snf->caps->sector_size == 1024) in mtk_snand_setup_pagefmt()
609 dev_err(snf->dev, "unsupported spare size: %u\n", spare_size); in mtk_snand_setup_pagefmt()
614 (snf->caps->fdm_ecc_size << NFI_FDM_ECC_NUM_S) | in mtk_snand_setup_pagefmt()
615 (snf->caps->fdm_size << NFI_FDM_NUM_S) | in mtk_snand_setup_pagefmt()
620 snf->nfi_cfg.page_size = page_size; in mtk_snand_setup_pagefmt()
621 snf->nfi_cfg.oob_size = oob_size; in mtk_snand_setup_pagefmt()
622 snf->nfi_cfg.nsectors = nsectors; in mtk_snand_setup_pagefmt()
623 snf->nfi_cfg.spare_size = spare_size; in mtk_snand_setup_pagefmt()
625 dev_dbg(snf->dev, "page format: (%u + %u) * %u\n", in mtk_snand_setup_pagefmt()
626 snf->caps->sector_size, spare_size, nsectors); in mtk_snand_setup_pagefmt()
629 dev_err(snf->dev, "page size %u + %u is not supported\n", page_size, in mtk_snand_setup_pagefmt()
631 return -EOPNOTSUPP; in mtk_snand_setup_pagefmt()
638 return -ERANGE; in mtk_snand_ooblayout_ecc()
647 if (section >= ms->nfi_cfg.nsectors) in mtk_snand_ooblayout_free()
648 return -ERANGE; in mtk_snand_ooblayout_free()
650 oobfree->length = ms->caps->fdm_size - 1; in mtk_snand_ooblayout_free()
651 oobfree->offset = section * ms->caps->fdm_size + 1; in mtk_snand_ooblayout_free()
663 struct nand_ecc_props *conf = &nand->ecc.ctx.conf; in mtk_snand_ecc_init_ctx()
664 struct nand_ecc_props *reqs = &nand->ecc.requirements; in mtk_snand_ecc_init_ctx()
665 struct nand_ecc_props *user = &nand->ecc.user_conf; in mtk_snand_ecc_init_ctx()
667 int step_size = 0, strength = 0, desired_correction = 0, steps; in mtk_snand_ecc_init_ctx() local
673 ret = mtk_snand_setup_pagefmt(snf, nand->memorg.pagesize, in mtk_snand_ecc_init_ctx()
674 nand->memorg.oobsize); in mtk_snand_ecc_init_ctx()
680 return -ENOMEM; in mtk_snand_ecc_init_ctx()
682 nand->ecc.ctx.priv = ecc_cfg; in mtk_snand_ecc_init_ctx()
684 if (user->step_size && user->strength) { in mtk_snand_ecc_init_ctx()
685 step_size = user->step_size; in mtk_snand_ecc_init_ctx()
686 strength = user->strength; in mtk_snand_ecc_init_ctx()
688 } else if (reqs->step_size && reqs->strength) { in mtk_snand_ecc_init_ctx()
689 step_size = reqs->step_size; in mtk_snand_ecc_init_ctx()
690 strength = reqs->strength; in mtk_snand_ecc_init_ctx()
693 if (step_size && strength) { in mtk_snand_ecc_init_ctx()
694 steps = mtd->writesize / step_size; in mtk_snand_ecc_init_ctx()
695 desired_correction = steps * strength; in mtk_snand_ecc_init_ctx()
696 strength = desired_correction / snf->nfi_cfg.nsectors; in mtk_snand_ecc_init_ctx()
699 ecc_cfg->mode = ECC_NFI_MODE; in mtk_snand_ecc_init_ctx()
700 ecc_cfg->sectors = snf->nfi_cfg.nsectors; in mtk_snand_ecc_init_ctx()
701 ecc_cfg->len = snf->caps->sector_size + snf->caps->fdm_ecc_size; in mtk_snand_ecc_init_ctx()
703 // calculate the max possible strength under current page format in mtk_snand_ecc_init_ctx()
704 parity_bits = mtk_ecc_get_parity_bits(snf->ecc); in mtk_snand_ecc_init_ctx()
705 max_ecc_bytes = snf->nfi_cfg.spare_size - snf->caps->fdm_size; in mtk_snand_ecc_init_ctx()
706 ecc_cfg->strength = max_ecc_bytes * 8 / parity_bits; in mtk_snand_ecc_init_ctx()
707 mtk_ecc_adjust_strength(snf->ecc, &ecc_cfg->strength); in mtk_snand_ecc_init_ctx()
709 // if there's a user requested strength, find the minimum strength that in mtk_snand_ecc_init_ctx()
710 // meets the requirement. Otherwise use the maximum strength which is in mtk_snand_ecc_init_ctx()
712 if (ecc_user && strength) { in mtk_snand_ecc_init_ctx()
713 u32 s_next = ecc_cfg->strength - 1; in mtk_snand_ecc_init_ctx()
716 mtk_ecc_adjust_strength(snf->ecc, &s_next); in mtk_snand_ecc_init_ctx()
717 if (s_next >= ecc_cfg->strength) in mtk_snand_ecc_init_ctx()
719 if (s_next < strength) in mtk_snand_ecc_init_ctx()
721 s_next = ecc_cfg->strength - 1; in mtk_snand_ecc_init_ctx()
727 conf->step_size = snf->caps->sector_size; in mtk_snand_ecc_init_ctx()
728 conf->strength = ecc_cfg->strength; in mtk_snand_ecc_init_ctx()
730 if (ecc_cfg->strength < strength) in mtk_snand_ecc_init_ctx()
731 dev_warn(snf->dev, "unable to fulfill ECC of %u bits.\n", in mtk_snand_ecc_init_ctx()
732 strength); in mtk_snand_ecc_init_ctx()
733 dev_info(snf->dev, "ECC strength: %u bits per %u bytes\n", in mtk_snand_ecc_init_ctx()
734 ecc_cfg->strength, snf->caps->sector_size); in mtk_snand_ecc_init_ctx()
753 ret = mtk_snand_setup_pagefmt(snf, nand->memorg.pagesize, in mtk_snand_ecc_prepare_io_req()
754 nand->memorg.oobsize); in mtk_snand_ecc_prepare_io_req()
757 snf->autofmt = true; in mtk_snand_ecc_prepare_io_req()
758 snf->ecc_cfg = ecc_cfg; in mtk_snand_ecc_prepare_io_req()
768 snf->ecc_cfg = NULL; in mtk_snand_ecc_finish_io_req()
769 snf->autofmt = false; in mtk_snand_ecc_finish_io_req()
770 if ((req->mode == MTD_OPS_RAW) || (req->type != NAND_PAGE_READ)) in mtk_snand_ecc_finish_io_req()
773 if (snf->ecc_stats.failed) in mtk_snand_ecc_finish_io_req()
774 mtd->ecc_stats.failed += snf->ecc_stats.failed; in mtk_snand_ecc_finish_io_req()
775 mtd->ecc_stats.corrected += snf->ecc_stats.corrected; in mtk_snand_ecc_finish_io_req()
776 return snf->ecc_stats.failed ? -EBADMSG : snf->ecc_stats.bitflips; in mtk_snand_ecc_finish_io_req()
792 for (i = 0; i < snf->nfi_cfg.nsectors; i++) { in mtk_snand_read_fdm()
796 for (j = 0; j < snf->caps->fdm_size; j++) in mtk_snand_read_fdm()
799 oobptr += snf->caps->fdm_size; in mtk_snand_read_fdm()
805 u32 fdm_size = snf->caps->fdm_size; in mtk_snand_write_fdm()
810 for (i = 0; i < snf->nfi_cfg.nsectors; i++) { in mtk_snand_write_fdm()
820 << ((j - 4) * 8); in mtk_snand_write_fdm()
834 if (!snf->caps->bbm_swap || snf->nfi_cfg.nsectors == 1) in mtk_snand_bm_swap()
839 buf_bbm_pos = snf->nfi_cfg.page_size - in mtk_snand_bm_swap()
840 (snf->nfi_cfg.nsectors - 1) * snf->nfi_cfg.spare_size; in mtk_snand_bm_swap()
841 fdm_bbm_pos = snf->nfi_cfg.page_size + in mtk_snand_bm_swap()
842 (snf->nfi_cfg.nsectors - 1) * snf->caps->fdm_size; in mtk_snand_bm_swap()
844 swap(snf->buf[fdm_bbm_pos], buf[buf_bbm_pos]); in mtk_snand_bm_swap()
851 if (!snf->caps->bbm_swap || snf->nfi_cfg.nsectors == 1) in mtk_snand_fdm_bm_swap()
855 fdm_bbm_pos1 = snf->nfi_cfg.page_size; in mtk_snand_fdm_bm_swap()
856 fdm_bbm_pos2 = snf->nfi_cfg.page_size + in mtk_snand_fdm_bm_swap()
857 (snf->nfi_cfg.nsectors - 1) * snf->caps->fdm_size; in mtk_snand_fdm_bm_swap()
858 swap(snf->buf[fdm_bbm_pos1], snf->buf[fdm_bbm_pos2]); in mtk_snand_fdm_bm_swap()
864 u8 *buf = snf->buf; in mtk_snand_read_page_cache()
865 u8 *buf_fdm = buf + snf->nfi_cfg.page_size; in mtk_snand_read_page_cache()
867 u32 op_addr = op->addr.val; in mtk_snand_read_page_cache()
870 u32 dummy_clk = (op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth); in mtk_snand_read_page_cache()
872 u32 dma_len = snf->buf_len; in mtk_snand_read_page_cache()
877 if (snf->autofmt) { in mtk_snand_read_page_cache()
881 dma_len = snf->nfi_cfg.page_size; in mtk_snand_read_page_cache()
883 if (op->data.ecc) in mtk_snand_read_page_cache()
887 // Bits higher than that in op->addr are kept and sent over SPI in mtk_snand_read_page_cache()
890 last_bit = fls(snf->nfi_cfg.page_size + snf->nfi_cfg.oob_size); in mtk_snand_read_page_cache()
891 mask = (1 << last_bit) - 1; in mtk_snand_read_page_cache()
896 if (rd_offset == 0 && op->data.nbytes >= snf->nfi_cfg.page_size) in mtk_snand_read_page_cache()
897 buf = op->data.buf.in; in mtk_snand_read_page_cache()
905 (op->cmd.opcode << DATA_READ_CMD_S)); in mtk_snand_read_page_cache()
911 if (op->data.buswidth == 4) in mtk_snand_read_page_cache()
912 rd_mode = op->addr.buswidth == 4 ? DATA_READ_MODE_QUAD : in mtk_snand_read_page_cache()
914 else if (op->data.buswidth == 2) in mtk_snand_read_page_cache()
915 rd_mode = op->addr.buswidth == 2 ? DATA_READ_MODE_DUAL : in mtk_snand_read_page_cache()
924 rd_bytes = (snf->nfi_cfg.spare_size + snf->caps->sector_size) * in mtk_snand_read_page_cache()
925 snf->nfi_cfg.nsectors; in mtk_snand_read_page_cache()
934 nfi_write32(snf, NFI_CON, (snf->nfi_cfg.nsectors << CON_SEC_NUM_S)); in mtk_snand_read_page_cache()
936 buf_dma = dma_map_single(snf->dev, buf, dma_len, DMA_FROM_DEVICE); in mtk_snand_read_page_cache()
937 ret = dma_mapping_error(snf->dev, buf_dma); in mtk_snand_read_page_cache()
939 dev_err(snf->dev, "DMA mapping failed.\n"); in mtk_snand_read_page_cache()
943 if (op->data.ecc) { in mtk_snand_read_page_cache()
944 snf->ecc_cfg->op = ECC_DECODE; in mtk_snand_read_page_cache()
945 ret = mtk_ecc_enable(snf->ecc, snf->ecc_cfg); in mtk_snand_read_page_cache()
951 reinit_completion(&snf->op_done); in mtk_snand_read_page_cache()
961 &snf->op_done, usecs_to_jiffies(SNFI_POLL_INTERVAL))) { in mtk_snand_read_page_cache()
962 dev_err(snf->dev, "DMA timed out for reading from cache.\n"); in mtk_snand_read_page_cache()
963 ret = -ETIMEDOUT; in mtk_snand_read_page_cache()
968 ret = readl_poll_timeout(snf->nfi_base + NFI_BYTELEN, val, in mtk_snand_read_page_cache()
969 BUS_SEC_CNTR(val) >= snf->nfi_cfg.nsectors, 0, in mtk_snand_read_page_cache()
972 dev_err(snf->dev, "Timed out waiting for BUS_SEC_CNTR\n"); in mtk_snand_read_page_cache()
977 ret = readl_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val, in mtk_snand_read_page_cache()
978 !(val & snf->caps->mastersta_mask), 0, in mtk_snand_read_page_cache()
981 dev_err(snf->dev, "Timed out waiting for bus becoming idle\n"); in mtk_snand_read_page_cache()
985 if (op->data.ecc) { in mtk_snand_read_page_cache()
986 ret = mtk_ecc_wait_done(snf->ecc, ECC_DECODE); in mtk_snand_read_page_cache()
988 dev_err(snf->dev, "wait ecc done timeout\n"); in mtk_snand_read_page_cache()
992 mtk_ecc_get_stats(snf->ecc, &snf->ecc_stats, in mtk_snand_read_page_cache()
993 snf->nfi_cfg.nsectors); in mtk_snand_read_page_cache()
996 dma_unmap_single(snf->dev, buf_dma, dma_len, DMA_FROM_DEVICE); in mtk_snand_read_page_cache()
998 if (snf->autofmt) { in mtk_snand_read_page_cache()
1000 if (snf->caps->bbm_swap) { in mtk_snand_read_page_cache()
1008 memset(op->data.buf.in, 0xff, op->data.nbytes); in mtk_snand_read_page_cache()
1009 snf->ecc_stats.bitflips = 0; in mtk_snand_read_page_cache()
1010 snf->ecc_stats.failed = 0; in mtk_snand_read_page_cache()
1011 snf->ecc_stats.corrected = 0; in mtk_snand_read_page_cache()
1013 if (buf == op->data.buf.in) { in mtk_snand_read_page_cache()
1014 u32 cap_len = snf->buf_len - snf->nfi_cfg.page_size; in mtk_snand_read_page_cache()
1015 u32 req_left = op->data.nbytes - snf->nfi_cfg.page_size; in mtk_snand_read_page_cache()
1018 memcpy(op->data.buf.in + snf->nfi_cfg.page_size, in mtk_snand_read_page_cache()
1021 } else if (rd_offset < snf->buf_len) { in mtk_snand_read_page_cache()
1022 u32 cap_len = snf->buf_len - rd_offset; in mtk_snand_read_page_cache()
1024 if (op->data.nbytes < cap_len) in mtk_snand_read_page_cache()
1025 cap_len = op->data.nbytes; in mtk_snand_read_page_cache()
1026 memcpy(op->data.buf.in, snf->buf + rd_offset, cap_len); in mtk_snand_read_page_cache()
1030 if (op->data.ecc) in mtk_snand_read_page_cache()
1031 mtk_ecc_disable(snf->ecc); in mtk_snand_read_page_cache()
1036 dma_unmap_single(snf->dev, buf_dma, dma_len, DMA_FROM_DEVICE); in mtk_snand_read_page_cache()
1058 u32 op_addr = op->addr.val; in mtk_snand_write_page_cache()
1064 u32 dma_len = snf->buf_len; in mtk_snand_write_page_cache()
1069 if (snf->autofmt) { in mtk_snand_write_page_cache()
1073 dma_len = snf->nfi_cfg.page_size; in mtk_snand_write_page_cache()
1075 if (op->data.ecc) in mtk_snand_write_page_cache()
1078 last_bit = fls(snf->nfi_cfg.page_size + snf->nfi_cfg.oob_size); in mtk_snand_write_page_cache()
1079 mask = (1 << last_bit) - 1; in mtk_snand_write_page_cache()
1087 memset(snf->buf, 0xff, wr_offset); in mtk_snand_write_page_cache()
1089 cap_len = snf->buf_len - wr_offset; in mtk_snand_write_page_cache()
1090 if (op->data.nbytes < cap_len) in mtk_snand_write_page_cache()
1091 cap_len = op->data.nbytes; in mtk_snand_write_page_cache()
1092 memcpy(snf->buf + wr_offset, op->data.buf.out, cap_len); in mtk_snand_write_page_cache()
1093 if (snf->autofmt) { in mtk_snand_write_page_cache()
1094 if (snf->caps->bbm_swap) { in mtk_snand_write_page_cache()
1096 mtk_snand_bm_swap(snf, snf->buf); in mtk_snand_write_page_cache()
1098 mtk_snand_write_fdm(snf, snf->buf + snf->nfi_cfg.page_size); in mtk_snand_write_page_cache()
1102 nfi_write32(snf, SNF_PG_CTL1, (op->cmd.opcode << PG_LOAD_CMD_S)); in mtk_snand_write_page_cache()
1108 if (op->data.buswidth == 4) in mtk_snand_write_page_cache()
1115 wr_bytes = (snf->nfi_cfg.spare_size + snf->caps->sector_size) * in mtk_snand_write_page_cache()
1116 snf->nfi_cfg.nsectors; in mtk_snand_write_page_cache()
1125 nfi_write32(snf, NFI_CON, (snf->nfi_cfg.nsectors << CON_SEC_NUM_S)); in mtk_snand_write_page_cache()
1126 buf_dma = dma_map_single(snf->dev, snf->buf, dma_len, DMA_TO_DEVICE); in mtk_snand_write_page_cache()
1127 ret = dma_mapping_error(snf->dev, buf_dma); in mtk_snand_write_page_cache()
1129 dev_err(snf->dev, "DMA mapping failed.\n"); in mtk_snand_write_page_cache()
1133 if (op->data.ecc) { in mtk_snand_write_page_cache()
1134 snf->ecc_cfg->op = ECC_ENCODE; in mtk_snand_write_page_cache()
1135 ret = mtk_ecc_enable(snf->ecc, snf->ecc_cfg); in mtk_snand_write_page_cache()
1141 reinit_completion(&snf->op_done); in mtk_snand_write_page_cache()
1152 &snf->op_done, usecs_to_jiffies(SNFI_POLL_INTERVAL))) { in mtk_snand_write_page_cache()
1153 dev_err(snf->dev, "DMA timed out for program load.\n"); in mtk_snand_write_page_cache()
1154 ret = -ETIMEDOUT; in mtk_snand_write_page_cache()
1159 ret = readl_poll_timeout(snf->nfi_base + NFI_ADDRCNTR, val, in mtk_snand_write_page_cache()
1160 NFI_SEC_CNTR(val) >= snf->nfi_cfg.nsectors, 0, in mtk_snand_write_page_cache()
1163 dev_err(snf->dev, "Timed out waiting for NFI_SEC_CNTR\n"); in mtk_snand_write_page_cache()
1166 if (op->data.ecc) in mtk_snand_write_page_cache()
1167 mtk_ecc_disable(snf->ecc); in mtk_snand_write_page_cache()
1169 dma_unmap_single(snf->dev, buf_dma, dma_len, DMA_TO_DEVICE); in mtk_snand_write_page_cache()
1189 * mtk_snand_is_page_ops() - check if the op is a controller supported page op.
1190 * @op: spi-mem op to check
1195 * instructions found on SPI-NAND with 2-byte address.
1202 if (op->addr.nbytes != 2) in mtk_snand_is_page_ops()
1205 if (op->addr.buswidth != 1 && op->addr.buswidth != 2 && in mtk_snand_is_page_ops()
1206 op->addr.buswidth != 4) in mtk_snand_is_page_ops()
1210 if (op->data.dir == SPI_MEM_DATA_IN) { in mtk_snand_is_page_ops()
1212 if (op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth > in mtk_snand_is_page_ops()
1215 // quad io / quad out in mtk_snand_is_page_ops()
1216 if ((op->addr.buswidth == 4 || op->addr.buswidth == 1) && in mtk_snand_is_page_ops()
1217 op->data.buswidth == 4) in mtk_snand_is_page_ops()
1220 // dual io / dual out in mtk_snand_is_page_ops()
1221 if ((op->addr.buswidth == 2 || op->addr.buswidth == 1) && in mtk_snand_is_page_ops()
1222 op->data.buswidth == 2) in mtk_snand_is_page_ops()
1226 if (op->addr.buswidth == 1 && op->data.buswidth == 1) in mtk_snand_is_page_ops()
1228 } else if (op->data.dir == SPI_MEM_DATA_OUT) { in mtk_snand_is_page_ops()
1230 if (op->dummy.nbytes) in mtk_snand_is_page_ops()
1232 // program load quad out in mtk_snand_is_page_ops()
1233 if (op->addr.buswidth == 1 && op->data.buswidth == 4) in mtk_snand_is_page_ops()
1236 if (op->addr.buswidth == 1 && op->data.buswidth == 1) in mtk_snand_is_page_ops()
1247 if (op->cmd.nbytes != 1 || op->cmd.buswidth != 1) in mtk_snand_supports_op()
1251 return ((op->addr.nbytes == 0 || op->addr.buswidth == 1) && in mtk_snand_supports_op()
1252 (op->dummy.nbytes == 0 || op->dummy.buswidth == 1) && in mtk_snand_supports_op()
1253 (op->data.nbytes == 0 || op->data.buswidth == 1)); in mtk_snand_supports_op()
1258 struct mtk_snand *ms = spi_controller_get_devdata(mem->spi->controller); in mtk_snand_adjust_op_size()
1266 if (ms->autofmt) in mtk_snand_adjust_op_size()
1268 l = ms->caps->sector_size + ms->nfi_cfg.spare_size; in mtk_snand_adjust_op_size()
1269 l *= ms->nfi_cfg.nsectors; in mtk_snand_adjust_op_size()
1270 if (op->data.nbytes > l) in mtk_snand_adjust_op_size()
1271 op->data.nbytes = l; in mtk_snand_adjust_op_size()
1273 size_t hl = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; in mtk_snand_adjust_op_size()
1276 return -EOPNOTSUPP; in mtk_snand_adjust_op_size()
1277 if (op->data.nbytes > SNF_GPRAM_SIZE - hl) in mtk_snand_adjust_op_size()
1278 op->data.nbytes = SNF_GPRAM_SIZE - hl; in mtk_snand_adjust_op_size()
1285 struct mtk_snand *ms = spi_controller_get_devdata(mem->spi->controller); in mtk_snand_exec_op()
1287 dev_dbg(ms->dev, "OP %02x ADDR %08llX@%d:%u DATA %d:%u", op->cmd.opcode, in mtk_snand_exec_op()
1288 op->addr.val, op->addr.buswidth, op->addr.nbytes, in mtk_snand_exec_op()
1289 op->data.buswidth, op->data.nbytes); in mtk_snand_exec_op()
1291 if (op->data.dir == SPI_MEM_DATA_IN) in mtk_snand_exec_op()
1322 complete(&snf->op_done); in mtk_snand_irq()
1327 { .compatible = "mediatek,mt7622-snand", .data = &mt7622_snand_caps },
1328 { .compatible = "mediatek,mt7629-snand", .data = &mt7629_snand_caps },
1329 { .compatible = "mediatek,mt7986-snand", .data = &mt7986_snand_caps },
1337 struct device_node *np = pdev->dev.of_node; in mtk_snand_probe()
1347 return -EINVAL; in mtk_snand_probe()
1349 ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*ms)); in mtk_snand_probe()
1351 return -ENOMEM; in mtk_snand_probe()
1356 ms->ctlr = ctlr; in mtk_snand_probe()
1357 ms->caps = dev_id->data; in mtk_snand_probe()
1359 ms->ecc = of_mtk_ecc_get(np); in mtk_snand_probe()
1360 if (IS_ERR(ms->ecc)) in mtk_snand_probe()
1361 return PTR_ERR(ms->ecc); in mtk_snand_probe()
1362 else if (!ms->ecc) in mtk_snand_probe()
1363 return -ENODEV; in mtk_snand_probe()
1365 ms->nfi_base = devm_platform_ioremap_resource(pdev, 0); in mtk_snand_probe()
1366 if (IS_ERR(ms->nfi_base)) { in mtk_snand_probe()
1367 ret = PTR_ERR(ms->nfi_base); in mtk_snand_probe()
1371 ms->dev = &pdev->dev; in mtk_snand_probe()
1373 ms->nfi_clk = devm_clk_get_enabled(&pdev->dev, "nfi_clk"); in mtk_snand_probe()
1374 if (IS_ERR(ms->nfi_clk)) { in mtk_snand_probe()
1375 ret = PTR_ERR(ms->nfi_clk); in mtk_snand_probe()
1376 dev_err(&pdev->dev, "unable to get nfi_clk, err = %d\n", ret); in mtk_snand_probe()
1380 ms->pad_clk = devm_clk_get_enabled(&pdev->dev, "pad_clk"); in mtk_snand_probe()
1381 if (IS_ERR(ms->pad_clk)) { in mtk_snand_probe()
1382 ret = PTR_ERR(ms->pad_clk); in mtk_snand_probe()
1383 dev_err(&pdev->dev, "unable to get pad_clk, err = %d\n", ret); in mtk_snand_probe()
1387 ms->nfi_hclk = devm_clk_get_optional_enabled(&pdev->dev, "nfi_hclk"); in mtk_snand_probe()
1388 if (IS_ERR(ms->nfi_hclk)) { in mtk_snand_probe()
1389 ret = PTR_ERR(ms->nfi_hclk); in mtk_snand_probe()
1390 dev_err(&pdev->dev, "unable to get nfi_hclk, err = %d\n", ret); in mtk_snand_probe()
1394 init_completion(&ms->op_done); in mtk_snand_probe()
1396 ms->irq = platform_get_irq(pdev, 0); in mtk_snand_probe()
1397 if (ms->irq < 0) { in mtk_snand_probe()
1398 ret = ms->irq; in mtk_snand_probe()
1401 ret = devm_request_irq(ms->dev, ms->irq, mtk_snand_irq, 0x0, in mtk_snand_probe()
1402 "mtk-snand", ms); in mtk_snand_probe()
1404 dev_err(ms->dev, "failed to request snfi irq\n"); in mtk_snand_probe()
1408 ret = dma_set_mask(ms->dev, DMA_BIT_MASK(32)); in mtk_snand_probe()
1410 dev_err(ms->dev, "failed to set dma mask\n"); in mtk_snand_probe()
1417 ret = of_property_read_u32(np, "rx-sample-delay-ns", &val); in mtk_snand_probe()
1422 ret = of_property_read_u32(np, "mediatek,rx-latch-latency-ns", &val); in mtk_snand_probe()
1424 spi_freq = clk_get_rate(ms->pad_clk); in mtk_snand_probe()
1434 dev_err(ms->dev, "failed to set initial page format\n"); in mtk_snand_probe()
1439 ms->ecc_eng.dev = &pdev->dev; in mtk_snand_probe()
1440 ms->ecc_eng.integration = NAND_ECC_ENGINE_INTEGRATION_PIPELINED; in mtk_snand_probe()
1441 ms->ecc_eng.ops = &mtk_snfi_ecc_engine_ops; in mtk_snand_probe()
1442 ms->ecc_eng.priv = ms; in mtk_snand_probe()
1444 ret = nand_ecc_register_on_host_hw_engine(&ms->ecc_eng); in mtk_snand_probe()
1446 dev_err(&pdev->dev, "failed to register ecc engine.\n"); in mtk_snand_probe()
1450 ctlr->num_chipselect = 1; in mtk_snand_probe()
1451 ctlr->mem_ops = &mtk_snand_mem_ops; in mtk_snand_probe()
1452 ctlr->mem_caps = &mtk_snand_mem_caps; in mtk_snand_probe()
1453 ctlr->bits_per_word_mask = SPI_BPW_MASK(8); in mtk_snand_probe()
1454 ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; in mtk_snand_probe()
1455 ctlr->dev.of_node = pdev->dev.of_node; in mtk_snand_probe()
1458 dev_err(&pdev->dev, "spi_register_controller failed.\n"); in mtk_snand_probe()
1464 mtk_ecc_release(ms->ecc); in mtk_snand_probe()
1474 mtk_ecc_release(ms->ecc); in mtk_snand_remove()
1475 kfree(ms->buf); in mtk_snand_remove()
1482 .name = "mtk-snand",
1491 MODULE_DESCRIPTION("MeidaTek SPI-NAND Flash Controller Driver");