Lines Matching +full:en7581 +full:- +full:snand

1 // SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/dma-mapping.h>
24 #include <linux/spi/spi-mem.h>
229 err = regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_OPFIFO_WDATA, in airoha_snand_set_fifo_op()
235 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_set_fifo_op()
242 err = regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_OPFIFO_WR, in airoha_snand_set_fifo_op()
247 return regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_set_fifo_op()
268 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_write_data_to_fifo()
276 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_write_data_to_fifo()
283 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_write_data_to_fifo()
304 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_read_data_from_fifo()
312 err = regmap_read(as_ctrl->regmap_ctrl, in airoha_snand_read_data_from_fifo()
319 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_read_data_from_fifo()
337 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
342 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
347 err = regmap_read_poll_timeout(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
354 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
359 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
366 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
372 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
377 err = regmap_write(as_ctrl->regmap_ctrl, in airoha_snand_set_mode()
387 return regmap_write(as_ctrl->regmap_ctrl, REG_SPI_CTRL_DUMMY, 0); in airoha_snand_set_mode()
398 data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); in airoha_snand_write_data()
420 data_len = min(len - i, SPI_MAX_TRANSFER_SIZE); in airoha_snand_read_data()
439 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_NFI_CNFG, in airoha_snand_nfi_init()
445 return regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR_EN, in airoha_snand_nfi_init()
454 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_nfi_config()
460 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_nfi_config()
466 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_nfi_config()
472 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_nfi_config()
478 switch (as_ctrl->nfi_cfg.spare_size) { in airoha_snand_nfi_config()
493 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, in airoha_snand_nfi_config()
498 switch (as_ctrl->nfi_cfg.page_size) { in airoha_snand_nfi_config()
510 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_PAGEFMT, in airoha_snand_nfi_config()
516 val = FIELD_PREP(SPI_NFI_SEC_NUM, as_ctrl->nfi_cfg.sec_num); in airoha_snand_nfi_config()
517 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_nfi_config()
523 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, in airoha_snand_nfi_config()
529 val = FIELD_PREP(SPI_NFI_CUS_SEC_SIZE, as_ctrl->nfi_cfg.sec_size); in airoha_snand_nfi_config()
530 return regmap_update_bits(as_ctrl->regmap_nfi, in airoha_snand_nfi_config()
537 if (op->addr.nbytes != 2) in airoha_snand_is_page_ops()
540 if (op->addr.buswidth != 1 && op->addr.buswidth != 2 && in airoha_snand_is_page_ops()
541 op->addr.buswidth != 4) in airoha_snand_is_page_ops()
544 switch (op->data.dir) { in airoha_snand_is_page_ops()
546 if (op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth > 0xf) in airoha_snand_is_page_ops()
550 if (op->addr.buswidth == 4) in airoha_snand_is_page_ops()
551 return op->data.buswidth == 4; in airoha_snand_is_page_ops()
553 if (op->addr.buswidth == 2) in airoha_snand_is_page_ops()
554 return op->data.buswidth == 2; in airoha_snand_is_page_ops()
557 return op->data.buswidth == 4 || op->data.buswidth == 2 || in airoha_snand_is_page_ops()
558 op->data.buswidth == 1; in airoha_snand_is_page_ops()
560 return !op->dummy.nbytes && op->addr.buswidth == 1 && in airoha_snand_is_page_ops()
561 (op->data.buswidth == 4 || op->data.buswidth == 1); in airoha_snand_is_page_ops()
575 as_ctrl = spi_controller_get_devdata(mem->spi->controller); in airoha_snand_adjust_op_size()
576 max_len = as_ctrl->nfi_cfg.sec_size; in airoha_snand_adjust_op_size()
577 max_len += as_ctrl->nfi_cfg.spare_size; in airoha_snand_adjust_op_size()
578 max_len *= as_ctrl->nfi_cfg.sec_num; in airoha_snand_adjust_op_size()
580 if (op->data.nbytes > max_len) in airoha_snand_adjust_op_size()
581 op->data.nbytes = max_len; in airoha_snand_adjust_op_size()
583 max_len = 1 + op->addr.nbytes + op->dummy.nbytes; in airoha_snand_adjust_op_size()
585 return -EOPNOTSUPP; in airoha_snand_adjust_op_size()
587 if (op->data.nbytes > 160 - max_len) in airoha_snand_adjust_op_size()
588 op->data.nbytes = 160 - max_len; in airoha_snand_adjust_op_size()
600 if (op->cmd.buswidth != 1) in airoha_snand_supports_op()
606 return (!op->addr.nbytes || op->addr.buswidth == 1) && in airoha_snand_supports_op()
607 (!op->dummy.nbytes || op->dummy.buswidth == 1) && in airoha_snand_supports_op()
608 (!op->data.nbytes || op->data.buswidth == 1); in airoha_snand_supports_op()
613 u8 *txrx_buf = spi_get_ctldata(desc->mem->spi); in airoha_snand_dirmap_create()
616 return -EINVAL; in airoha_snand_dirmap_create()
618 if (desc->info.offset + desc->info.length > U32_MAX) in airoha_snand_dirmap_create()
619 return -EINVAL; in airoha_snand_dirmap_create()
621 if (!airoha_snand_supports_op(desc->mem, &desc->info.op_tmpl)) in airoha_snand_dirmap_create()
622 return -EOPNOTSUPP; in airoha_snand_dirmap_create()
630 struct spi_mem_op *op = &desc->info.op_tmpl; in airoha_snand_dirmap_read()
631 struct spi_device *spi = desc->mem->spi; in airoha_snand_dirmap_read()
638 switch (op->cmd.opcode) { in airoha_snand_dirmap_read()
650 as_ctrl = spi_controller_get_devdata(spi->controller); in airoha_snand_dirmap_read()
659 dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_read()
661 err = dma_mapping_error(as_ctrl->dev, dma_addr); in airoha_snand_dirmap_read()
666 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, in airoha_snand_dirmap_read()
672 val = as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num; in airoha_snand_dirmap_read()
674 err = regmap_update_bits(as_ctrl->regmap_nfi, in airoha_snand_dirmap_read()
681 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL2, in airoha_snand_dirmap_read()
682 op->cmd.opcode); in airoha_snand_dirmap_read()
687 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, in airoha_snand_dirmap_read()
693 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_RD_CTL3, 0x0); in airoha_snand_dirmap_read()
698 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_dirmap_read()
704 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_dirmap_read()
709 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x0); in airoha_snand_dirmap_read()
714 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_dirmap_read()
719 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_dirmap_read()
724 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, in airoha_snand_dirmap_read()
735 err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, in airoha_snand_dirmap_read()
741 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR, in airoha_snand_dirmap_read()
750 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_read()
761 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_read()
769 struct spi_mem_op *op = &desc->info.op_tmpl; in airoha_snand_dirmap_write()
770 struct spi_device *spi = desc->mem->spi; in airoha_snand_dirmap_write()
777 as_ctrl = spi_controller_get_devdata(spi->controller); in airoha_snand_dirmap_write()
783 dma_addr = dma_map_single(as_ctrl->dev, txrx_buf, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_write()
785 err = dma_mapping_error(as_ctrl->dev, dma_addr); in airoha_snand_dirmap_write()
797 if (op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_QUAD || in airoha_snand_dirmap_write()
798 op->cmd.opcode == SPI_NAND_OP_PROGRAM_LOAD_RAMDON_QUAD) in airoha_snand_dirmap_write()
803 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_STRADDR, in airoha_snand_dirmap_write()
809 as_ctrl->nfi_cfg.sec_size * as_ctrl->nfi_cfg.sec_num); in airoha_snand_dirmap_write()
810 err = regmap_update_bits(as_ctrl->regmap_nfi, in airoha_snand_dirmap_write()
816 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL1, in airoha_snand_dirmap_write()
818 op->cmd.opcode)); in airoha_snand_dirmap_write()
822 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_MISC_CTL, in airoha_snand_dirmap_write()
827 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_PG_CTL2, 0x0); in airoha_snand_dirmap_write()
831 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_dirmap_write()
836 err = regmap_update_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_dirmap_write()
842 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CNFG, in airoha_snand_dirmap_write()
847 err = regmap_write(as_ctrl->regmap_nfi, REG_SPI_NFI_CMD, 0x80); in airoha_snand_dirmap_write()
851 err = regmap_clear_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_dirmap_write()
856 err = regmap_set_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, in airoha_snand_dirmap_write()
861 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, REG_SPI_NFI_INTR, in airoha_snand_dirmap_write()
867 err = regmap_read_poll_timeout(as_ctrl->regmap_nfi, in airoha_snand_dirmap_write()
878 err = regmap_write_bits(as_ctrl->regmap_nfi, REG_SPI_NFI_SNF_STA_CTL1, in airoha_snand_dirmap_write()
884 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_write()
893 dma_unmap_single(as_ctrl->dev, dma_addr, SPI_NAND_CACHE_SIZE, in airoha_snand_dirmap_write()
901 u8 data[8], cmd, opcode = op->cmd.opcode; in airoha_snand_exec_op()
905 as_ctrl = spi_controller_get_devdata(mem->spi->controller); in airoha_snand_exec_op()
923 put_unaligned_be64(op->addr.val, data); in airoha_snand_exec_op()
925 for (i = ARRAY_SIZE(data) - op->addr.nbytes; in airoha_snand_exec_op()
935 for (i = 0; i < op->dummy.nbytes; i++) { in airoha_snand_exec_op()
943 if (op->data.dir == SPI_MEM_DATA_IN) { in airoha_snand_exec_op()
944 err = airoha_snand_read_data(as_ctrl, op->data.buf.in, in airoha_snand_exec_op()
945 op->data.nbytes); in airoha_snand_exec_op()
949 err = airoha_snand_write_data(as_ctrl, 0x8, op->data.buf.out, in airoha_snand_exec_op()
950 op->data.nbytes); in airoha_snand_exec_op()
973 as_ctrl = spi_controller_get_devdata(spi->controller); in airoha_snand_setup()
974 txrx_buf = devm_kzalloc(as_ctrl->dev, SPI_NAND_CACHE_SIZE, in airoha_snand_setup()
977 return -ENOMEM; in airoha_snand_setup()
989 err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_CON, &val); in airoha_snand_nfi_setup()
995 err = regmap_read(as_ctrl->regmap_nfi, REG_SPI_NFI_SECCUS_SIZE, &val); in airoha_snand_nfi_setup()
1002 as_ctrl->nfi_cfg.sec_size = sec_size; in airoha_snand_nfi_setup()
1003 as_ctrl->nfi_cfg.sec_num = sec_num; in airoha_snand_nfi_setup()
1004 as_ctrl->nfi_cfg.page_size = round_down(sec_size * sec_num, 1024); in airoha_snand_nfi_setup()
1005 as_ctrl->nfi_cfg.spare_size = 16; in airoha_snand_nfi_setup()
1031 { .compatible = "airoha,en7581-snand" },
1039 struct device *dev = &pdev->dev; in airoha_snand_probe()
1046 return -ENOMEM; in airoha_snand_probe()
1049 as_ctrl->dev = dev; in airoha_snand_probe()
1055 as_ctrl->regmap_ctrl = devm_regmap_init_mmio(dev, base, in airoha_snand_probe()
1057 if (IS_ERR(as_ctrl->regmap_ctrl)) in airoha_snand_probe()
1058 return dev_err_probe(dev, PTR_ERR(as_ctrl->regmap_ctrl), in airoha_snand_probe()
1065 as_ctrl->regmap_nfi = devm_regmap_init_mmio(dev, base, in airoha_snand_probe()
1067 if (IS_ERR(as_ctrl->regmap_nfi)) in airoha_snand_probe()
1068 return dev_err_probe(dev, PTR_ERR(as_ctrl->regmap_nfi), in airoha_snand_probe()
1071 as_ctrl->spi_clk = devm_clk_get_enabled(dev, "spi"); in airoha_snand_probe()
1072 if (IS_ERR(as_ctrl->spi_clk)) in airoha_snand_probe()
1073 return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk), in airoha_snand_probe()
1076 err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32)); in airoha_snand_probe()
1080 ctrl->num_chipselect = 2; in airoha_snand_probe()
1081 ctrl->mem_ops = &airoha_snand_mem_ops; in airoha_snand_probe()
1082 ctrl->bits_per_word_mask = SPI_BPW_MASK(8); in airoha_snand_probe()
1083 ctrl->mode_bits = SPI_RX_DUAL; in airoha_snand_probe()
1084 ctrl->setup = airoha_snand_setup; in airoha_snand_probe()
1085 device_set_node(&ctrl->dev, dev_fwnode(dev)); in airoha_snand_probe()
1096 .name = "airoha-spi",
1103 MODULE_DESCRIPTION("Airoha SPI-NAND Flash Controller Driver");