Lines Matching full:nfc
5 * https://github.com/yuq/sunxi-nfc-mtd
171 * NFC
255 struct sunxi_nfc *nfc = dev_id; in sunxi_nfc_interrupt() local
256 u32 st = readl(nfc->regs + NFC_REG_ST); in sunxi_nfc_interrupt()
257 u32 ien = readl(nfc->regs + NFC_REG_INT); in sunxi_nfc_interrupt()
263 complete(&nfc->complete); in sunxi_nfc_interrupt()
265 writel(st & NFC_INT_MASK, nfc->regs + NFC_REG_ST); in sunxi_nfc_interrupt()
266 writel(~st & ien & NFC_INT_MASK, nfc->regs + NFC_REG_INT); in sunxi_nfc_interrupt()
271 static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events, in sunxi_nfc_wait_events() argument
283 init_completion(&nfc->complete); in sunxi_nfc_wait_events()
285 writel(events, nfc->regs + NFC_REG_INT); in sunxi_nfc_wait_events()
287 ret = wait_for_completion_timeout(&nfc->complete, in sunxi_nfc_wait_events()
294 writel(0, nfc->regs + NFC_REG_INT); in sunxi_nfc_wait_events()
298 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status, in sunxi_nfc_wait_events()
303 writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST); in sunxi_nfc_wait_events()
306 dev_err(nfc->dev, "wait interrupt timedout\n"); in sunxi_nfc_wait_events()
311 static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc) in sunxi_nfc_wait_cmd_fifo_empty() argument
316 ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status, in sunxi_nfc_wait_cmd_fifo_empty()
320 dev_err(nfc->dev, "wait for empty cmd FIFO timedout\n"); in sunxi_nfc_wait_cmd_fifo_empty()
325 static int sunxi_nfc_rst(struct sunxi_nfc *nfc) in sunxi_nfc_rst() argument
330 writel(0, nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_rst()
331 writel(NFC_RESET, nfc->regs + NFC_REG_CTL); in sunxi_nfc_rst()
333 ret = readl_poll_timeout(nfc->regs + NFC_REG_CTL, ctl, in sunxi_nfc_rst()
337 dev_err(nfc->dev, "wait for NAND controller reset timedout\n"); in sunxi_nfc_rst()
348 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_dma_op_prepare() local
360 ret = dma_map_sg(nfc->dev, sg, 1, ddir); in sunxi_nfc_dma_op_prepare()
364 dmad = dmaengine_prep_slave_sg(nfc->dmac, sg, 1, tdir, DMA_CTRL_ACK); in sunxi_nfc_dma_op_prepare()
370 writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RAM_METHOD, in sunxi_nfc_dma_op_prepare()
371 nfc->regs + NFC_REG_CTL); in sunxi_nfc_dma_op_prepare()
372 writel(nchunks, nfc->regs + NFC_REG_SECTOR_NUM); in sunxi_nfc_dma_op_prepare()
373 writel(chunksize, nfc->regs + NFC_REG_CNT); in sunxi_nfc_dma_op_prepare()
383 writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD, in sunxi_nfc_dma_op_prepare()
384 nfc->regs + NFC_REG_CTL); in sunxi_nfc_dma_op_prepare()
387 dma_unmap_sg(nfc->dev, sg, 1, ddir); in sunxi_nfc_dma_op_prepare()
396 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_dma_op_cleanup() local
398 dma_unmap_sg(nfc->dev, sg, 1, ddir); in sunxi_nfc_dma_op_cleanup()
399 writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD, in sunxi_nfc_dma_op_cleanup()
400 nfc->regs + NFC_REG_CTL); in sunxi_nfc_dma_op_cleanup()
407 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_dev_ready() local
414 dev_err(nfc->dev, "cannot check R/B NAND status!\n"); in sunxi_nfc_dev_ready()
420 return !!(readl(nfc->regs + NFC_REG_ST) & mask); in sunxi_nfc_dev_ready()
427 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_select_chip() local
437 ctl = readl(nfc->regs + NFC_REG_CTL) & in sunxi_nfc_select_chip()
452 writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA); in sunxi_nfc_select_chip()
454 if (nfc->clk_rate != sunxi_nand->clk_rate) { in sunxi_nfc_select_chip()
455 clk_set_rate(nfc->mod_clk, sunxi_nand->clk_rate); in sunxi_nfc_select_chip()
456 nfc->clk_rate = sunxi_nand->clk_rate; in sunxi_nfc_select_chip()
460 writel(sunxi_nand->timing_ctl, nfc->regs + NFC_REG_TIMING_CTL); in sunxi_nfc_select_chip()
461 writel(sunxi_nand->timing_cfg, nfc->regs + NFC_REG_TIMING_CFG); in sunxi_nfc_select_chip()
462 writel(ctl, nfc->regs + NFC_REG_CTL); in sunxi_nfc_select_chip()
471 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_read_buf() local
482 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_read_buf()
486 writel(cnt, nfc->regs + NFC_REG_CNT); in sunxi_nfc_read_buf()
488 writel(tmp, nfc->regs + NFC_REG_CMD); in sunxi_nfc_read_buf()
494 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, poll, 0); in sunxi_nfc_read_buf()
499 memcpy_fromio(buf + offs, nfc->regs + NFC_RAM0_BASE, in sunxi_nfc_read_buf()
510 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_write_buf() local
521 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_write_buf()
525 writel(cnt, nfc->regs + NFC_REG_CNT); in sunxi_nfc_write_buf()
526 memcpy_toio(nfc->regs + NFC_RAM0_BASE, buf + offs, cnt); in sunxi_nfc_write_buf()
529 writel(tmp, nfc->regs + NFC_REG_CMD); in sunxi_nfc_write_buf()
535 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, poll, 0); in sunxi_nfc_write_buf()
557 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nfc_cmd_ctrl() local
573 nfc->regs + NFC_REG_RCMD_SET); in sunxi_nfc_cmd_ctrl()
582 nfc->regs + NFC_REG_ADDR_LOW); in sunxi_nfc_cmd_ctrl()
587 nfc->regs + NFC_REG_ADDR_HIGH); in sunxi_nfc_cmd_ctrl()
589 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_cmd_ctrl()
593 writel(cmd, nfc->regs + NFC_REG_CMD); in sunxi_nfc_cmd_ctrl()
597 sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); in sunxi_nfc_cmd_ctrl()
713 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_config() local
714 u32 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_randomizer_config()
720 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_randomizer_config()
722 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_SEED_MSK; in sunxi_nfc_randomizer_config()
723 writel(ecc_ctl | NFC_RANDOM_SEED(state), nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_randomizer_config()
729 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_enable() local
734 writel(readl(nfc->regs + NFC_REG_ECC_CTL) | NFC_RANDOM_EN, in sunxi_nfc_randomizer_enable()
735 nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_randomizer_enable()
741 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_randomizer_disable() local
746 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_RANDOM_EN, in sunxi_nfc_randomizer_disable()
747 nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_randomizer_disable()
780 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_enable() local
784 ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_hw_ecc_enable()
793 writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_hw_ecc_enable()
799 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_disable() local
801 writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, in sunxi_nfc_hw_ecc_disable()
802 nfc->regs + NFC_REG_ECC_CTL); in sunxi_nfc_hw_ecc_disable()
822 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_get_prot_oob_bytes() local
824 sunxi_nfc_user_data_to_buf(readl(nfc->regs + NFC_REG_USER_DATA(step)), in sunxi_nfc_hw_ecc_get_prot_oob_bytes()
837 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_set_prot_oob_bytes() local
848 nfc->regs + NFC_REG_USER_DATA(step)); in sunxi_nfc_hw_ecc_set_prot_oob_bytes()
866 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_correct() local
878 if (unlikely(!(readl(nfc->regs + NFC_REG_PAT_ID) & 0x1))) { in sunxi_nfc_hw_ecc_correct()
894 tmp = readl(nfc->regs + NFC_REG_ECC_ERR_CNT(step)); in sunxi_nfc_hw_ecc_correct()
907 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_read_chunk() local
921 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_hw_ecc_read_chunk()
927 nfc->regs + NFC_REG_CMD); in sunxi_nfc_hw_ecc_read_chunk()
929 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0); in sunxi_nfc_hw_ecc_read_chunk()
937 readl(nfc->regs + NFC_REG_ECC_ST), in sunxi_nfc_hw_ecc_read_chunk()
951 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, in sunxi_nfc_hw_ecc_read_chunk()
963 memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size); in sunxi_nfc_hw_ecc_read_chunk()
1013 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_read_chunks_dma() local
1020 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_hw_ecc_read_chunks_dma()
1034 NAND_CMD_READSTART, nfc->regs + NFC_REG_RCMD_SET); in sunxi_nfc_hw_ecc_read_chunks_dma()
1036 dma_async_issue_pending(nfc->dmac); in sunxi_nfc_hw_ecc_read_chunks_dma()
1039 nfc->regs + NFC_REG_CMD); in sunxi_nfc_hw_ecc_read_chunks_dma()
1041 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0); in sunxi_nfc_hw_ecc_read_chunks_dma()
1043 dmaengine_terminate_all(nfc->dmac); in sunxi_nfc_hw_ecc_read_chunks_dma()
1053 status = readl(nfc->regs + NFC_REG_ECC_ST); in sunxi_nfc_hw_ecc_read_chunks_dma()
1137 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_write_chunk() local
1149 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_hw_ecc_write_chunk()
1158 nfc->regs + NFC_REG_CMD); in sunxi_nfc_hw_ecc_write_chunk()
1160 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0); in sunxi_nfc_hw_ecc_write_chunk()
1373 struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); in sunxi_nfc_hw_ecc_write_page_dma() local
1378 ret = sunxi_nfc_wait_cmd_fifo_empty(nfc); in sunxi_nfc_hw_ecc_write_page_dma()
1400 nfc->regs + NFC_REG_WCMD_SET); in sunxi_nfc_hw_ecc_write_page_dma()
1402 dma_async_issue_pending(nfc->dmac); in sunxi_nfc_hw_ecc_write_page_dma()
1406 nfc->regs + NFC_REG_CMD); in sunxi_nfc_hw_ecc_write_page_dma()
1408 ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, false, 0); in sunxi_nfc_hw_ecc_write_page_dma()
1410 dmaengine_terminate_all(nfc->dmac); in sunxi_nfc_hw_ecc_write_page_dma()
1483 struct sunxi_nfc *nfc = to_sunxi_nfc(chip->nand.controller); in sunxi_nfc_setup_data_interface() local
1569 dev_err(nfc->dev, "unsupported tWB\n"); in sunxi_nfc_setup_data_interface()
1575 dev_err(nfc->dev, "unsupported tADL\n"); in sunxi_nfc_setup_data_interface()
1581 dev_err(nfc->dev, "unsupported tWHR\n"); in sunxi_nfc_setup_data_interface()
1588 dev_err(nfc->dev, "unsupported tRHW\n"); in sunxi_nfc_setup_data_interface()
1614 real_clk_rate = clk_round_rate(nfc->mod_clk, chip->clk_rate); in sunxi_nfc_setup_data_interface()
1616 dev_err(nfc->dev, "Unable to round clk %lu\n", chip->clk_rate); in sunxi_nfc_setup_data_interface()
1695 struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); in sunxi_nand_hw_ecc_ctrl_init() local
1756 dev_err(nfc->dev, "unsupported strength\n"); in sunxi_nand_hw_ecc_ctrl_init()
1781 if (nfc->dmac) { in sunxi_nand_hw_ecc_ctrl_init()
1860 static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, in sunxi_nand_chip_init() argument
1907 if (test_and_set_bit(tmp, &nfc->assigned_cs)) { in sunxi_nand_chip_init()
1924 nand->controller = &nfc->controller; in sunxi_nand_chip_init()
1954 list_add_tail(&chip->node, &nfc->chips); in sunxi_nand_chip_init()
1959 static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc) in sunxi_nand_chips_init() argument
1972 ret = sunxi_nand_chip_init(dev, nfc, nand_np); in sunxi_nand_chips_init()
1982 static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) in sunxi_nand_chips_cleanup() argument
1986 while (!list_empty(&nfc->chips)) { in sunxi_nand_chips_cleanup()
1987 chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, in sunxi_nand_chips_cleanup()
1999 struct sunxi_nfc *nfc; in sunxi_nfc_probe() local
2003 nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); in sunxi_nfc_probe()
2004 if (!nfc) in sunxi_nfc_probe()
2007 nfc->dev = dev; in sunxi_nfc_probe()
2008 nand_controller_init(&nfc->controller); in sunxi_nfc_probe()
2009 INIT_LIST_HEAD(&nfc->chips); in sunxi_nfc_probe()
2012 nfc->regs = devm_ioremap_resource(dev, r); in sunxi_nfc_probe()
2013 if (IS_ERR(nfc->regs)) in sunxi_nfc_probe()
2014 return PTR_ERR(nfc->regs); in sunxi_nfc_probe()
2022 nfc->ahb_clk = devm_clk_get(dev, "ahb"); in sunxi_nfc_probe()
2023 if (IS_ERR(nfc->ahb_clk)) { in sunxi_nfc_probe()
2025 return PTR_ERR(nfc->ahb_clk); in sunxi_nfc_probe()
2028 ret = clk_prepare_enable(nfc->ahb_clk); in sunxi_nfc_probe()
2032 nfc->mod_clk = devm_clk_get(dev, "mod"); in sunxi_nfc_probe()
2033 if (IS_ERR(nfc->mod_clk)) { in sunxi_nfc_probe()
2035 ret = PTR_ERR(nfc->mod_clk); in sunxi_nfc_probe()
2039 ret = clk_prepare_enable(nfc->mod_clk); in sunxi_nfc_probe()
2043 nfc->reset = devm_reset_control_get_optional_exclusive(dev, "ahb"); in sunxi_nfc_probe()
2044 if (IS_ERR(nfc->reset)) { in sunxi_nfc_probe()
2045 ret = PTR_ERR(nfc->reset); in sunxi_nfc_probe()
2049 ret = reset_control_deassert(nfc->reset); in sunxi_nfc_probe()
2055 ret = sunxi_nfc_rst(nfc); in sunxi_nfc_probe()
2059 writel(0, nfc->regs + NFC_REG_INT); in sunxi_nfc_probe()
2061 0, "sunxi-nand", nfc); in sunxi_nfc_probe()
2065 nfc->dmac = dma_request_slave_channel(dev, "rxtx"); in sunxi_nfc_probe()
2066 if (nfc->dmac) { in sunxi_nfc_probe()
2075 dmaengine_slave_config(nfc->dmac, &dmac_cfg); in sunxi_nfc_probe()
2080 platform_set_drvdata(pdev, nfc); in sunxi_nfc_probe()
2082 ret = sunxi_nand_chips_init(dev, nfc); in sunxi_nfc_probe()
2091 if (nfc->dmac) in sunxi_nfc_probe()
2092 dma_release_channel(nfc->dmac); in sunxi_nfc_probe()
2094 reset_control_assert(nfc->reset); in sunxi_nfc_probe()
2096 clk_disable_unprepare(nfc->mod_clk); in sunxi_nfc_probe()
2098 clk_disable_unprepare(nfc->ahb_clk); in sunxi_nfc_probe()
2105 struct sunxi_nfc *nfc = platform_get_drvdata(pdev); in sunxi_nfc_remove() local
2107 sunxi_nand_chips_cleanup(nfc); in sunxi_nfc_remove()
2109 reset_control_assert(nfc->reset); in sunxi_nfc_remove()
2111 if (nfc->dmac) in sunxi_nfc_remove()
2112 dma_release_channel(nfc->dmac); in sunxi_nfc_remove()
2113 clk_disable_unprepare(nfc->mod_clk); in sunxi_nfc_remove()
2114 clk_disable_unprepare(nfc->ahb_clk); in sunxi_nfc_remove()