Lines Matching full:sp

100 #define CLK_TO_US(sp, clkcnt)		DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000)  argument
131 static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr) in mtk_nor_rmw() argument
133 u32 val = readl(sp->base + reg); in mtk_nor_rmw()
137 writel(val, sp->base + reg); in mtk_nor_rmw()
140 static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk) in mtk_nor_cmd_exec() argument
142 ulong delay = CLK_TO_US(sp, clk); in mtk_nor_cmd_exec()
146 writel(cmd, sp->base + MTK_NOR_REG_CMD); in mtk_nor_cmd_exec()
147 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CMD, reg, !(reg & cmd), in mtk_nor_cmd_exec()
150 dev_err(sp->dev, "command %u timeout.\n", cmd); in mtk_nor_cmd_exec()
154 static void mtk_nor_reset(struct mtk_nor *sp) in mtk_nor_reset() argument
156 mtk_nor_rmw(sp, MTK_NOR_REG_CG_DIS, 0, MTK_NOR_SFC_SW_RST); in mtk_nor_reset()
158 mtk_nor_rmw(sp, MTK_NOR_REG_CG_DIS, MTK_NOR_SFC_SW_RST, 0); in mtk_nor_reset()
160 writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); in mtk_nor_reset()
163 static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_set_addr() argument
169 writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR(i)); in mtk_nor_set_addr()
173 writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR3); in mtk_nor_set_addr()
174 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, MTK_NOR_4B_ADDR, 0); in mtk_nor_set_addr()
176 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, 0, MTK_NOR_4B_ADDR); in mtk_nor_set_addr()
180 static bool need_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in need_bounce() argument
278 struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->controller); in mtk_nor_adjust_op_size() local
293 else if (!need_bounce(sp, op)) in mtk_nor_adjust_op_size()
340 static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_setup_bus() argument
349 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4)); in mtk_nor_setup_bus()
354 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3)); in mtk_nor_setup_bus()
359 mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, MTK_NOR_FAST_READ, 0); in mtk_nor_setup_bus()
361 mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, 0, MTK_NOR_FAST_READ); in mtk_nor_setup_bus()
363 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, reg, MTK_NOR_BUS_MODE_MASK); in mtk_nor_setup_bus()
366 static int mtk_nor_dma_exec(struct mtk_nor *sp, u32 from, unsigned int length, in mtk_nor_dma_exec() argument
373 writel(from, sp->base + MTK_NOR_REG_DMA_FADR); in mtk_nor_dma_exec()
374 writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR); in mtk_nor_dma_exec()
375 writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR); in mtk_nor_dma_exec()
377 if (sp->high_dma) { in mtk_nor_dma_exec()
379 sp->base + MTK_NOR_REG_DMA_DADR_HB); in mtk_nor_dma_exec()
381 sp->base + MTK_NOR_REG_DMA_END_DADR_HB); in mtk_nor_dma_exec()
384 if (sp->has_irq) { in mtk_nor_dma_exec()
385 reinit_completion(&sp->op_done); in mtk_nor_dma_exec()
386 mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0); in mtk_nor_dma_exec()
389 mtk_nor_rmw(sp, MTK_NOR_REG_DMA_CTL, MTK_NOR_DMA_START, 0); in mtk_nor_dma_exec()
391 delay = CLK_TO_US(sp, (length + 5) * BITS_PER_BYTE); in mtk_nor_dma_exec()
394 if (sp->has_irq) { in mtk_nor_dma_exec()
395 if (!wait_for_completion_timeout(&sp->op_done, in mtk_nor_dma_exec()
399 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_DMA_CTL, reg, in mtk_nor_dma_exec()
405 dev_err(sp->dev, "dma read timeout.\n"); in mtk_nor_dma_exec()
410 static int mtk_nor_read_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_bounce() argument
420 ret = mtk_nor_dma_exec(sp, op->addr.val, rdlen, sp->buffer_dma); in mtk_nor_read_bounce()
423 memcpy(op->data.buf.in, sp->buffer, op->data.nbytes); in mtk_nor_read_bounce()
428 static int mtk_nor_read_dma(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_dma() argument
433 if (need_bounce(sp, op)) in mtk_nor_read_dma()
434 return mtk_nor_read_bounce(sp, op); in mtk_nor_read_dma()
436 dma_addr = dma_map_single(sp->dev, op->data.buf.in, in mtk_nor_read_dma()
439 if (dma_mapping_error(sp->dev, dma_addr)) in mtk_nor_read_dma()
442 ret = mtk_nor_dma_exec(sp, op->addr.val, op->data.nbytes, dma_addr); in mtk_nor_read_dma()
444 dma_unmap_single(sp->dev, dma_addr, op->data.nbytes, DMA_FROM_DEVICE); in mtk_nor_read_dma()
449 static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_pio() argument
454 ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_READ, 6 * BITS_PER_BYTE); in mtk_nor_read_pio()
456 buf[0] = readb(sp->base + MTK_NOR_REG_RDATA); in mtk_nor_read_pio()
460 static int mtk_nor_setup_write_buffer(struct mtk_nor *sp, bool on) in mtk_nor_setup_write_buffer() argument
465 if (!(sp->wbuf_en ^ on)) in mtk_nor_setup_write_buffer()
468 val = readl(sp->base + MTK_NOR_REG_CFG2); in mtk_nor_setup_write_buffer()
470 writel(val | MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); in mtk_nor_setup_write_buffer()
471 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, in mtk_nor_setup_write_buffer()
474 writel(val & ~MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); in mtk_nor_setup_write_buffer()
475 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, in mtk_nor_setup_write_buffer()
480 sp->wbuf_en = on; in mtk_nor_setup_write_buffer()
485 static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_pp_buffered() argument
491 ret = mtk_nor_setup_write_buffer(sp, true); in mtk_nor_pp_buffered()
498 writel(val, sp->base + MTK_NOR_REG_PP_DATA); in mtk_nor_pp_buffered()
500 return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, in mtk_nor_pp_buffered()
504 static int mtk_nor_pp_unbuffered(struct mtk_nor *sp, in mtk_nor_pp_unbuffered() argument
510 ret = mtk_nor_setup_write_buffer(sp, false); in mtk_nor_pp_unbuffered()
513 writeb(buf[0], sp->base + MTK_NOR_REG_WDATA); in mtk_nor_pp_unbuffered()
514 return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE); in mtk_nor_pp_unbuffered()
517 static int mtk_nor_spi_mem_prg(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_spi_mem_prg() argument
547 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
553 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
560 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
565 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
571 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
577 writel(prg_len * BITS_PER_BYTE + sp->caps->extra_dummy_bit, in mtk_nor_spi_mem_prg()
578 sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_spi_mem_prg()
580 writel(prg_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_spi_mem_prg()
582 ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, in mtk_nor_spi_mem_prg()
591 reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); in mtk_nor_spi_mem_prg()
601 struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->controller); in mtk_nor_exec_op() local
606 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()
609 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
610 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0); in mtk_nor_exec_op()
612 return mtk_nor_pp_buffered(sp, op); in mtk_nor_exec_op()
613 return mtk_nor_pp_unbuffered(sp, op); in mtk_nor_exec_op()
617 ret = mtk_nor_setup_write_buffer(sp, false); in mtk_nor_exec_op()
620 mtk_nor_setup_bus(sp, op); in mtk_nor_exec_op()
622 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
623 return mtk_nor_read_pio(sp, op); in mtk_nor_exec_op()
625 ret = mtk_nor_read_dma(sp, op); in mtk_nor_exec_op()
628 mtk_nor_reset(sp); in mtk_nor_exec_op()
629 mtk_nor_setup_bus(sp, op); in mtk_nor_exec_op()
630 return mtk_nor_read_dma(sp, op); in mtk_nor_exec_op()
637 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()
642 struct mtk_nor *sp = spi_controller_get_devdata(spi->controller); in mtk_nor_setup() local
644 if (spi->max_speed_hz && (spi->max_speed_hz < sp->spi_freq)) { in mtk_nor_setup()
646 sp->spi_freq); in mtk_nor_setup()
649 spi->max_speed_hz = sp->spi_freq; in mtk_nor_setup()
657 struct mtk_nor *sp = spi_controller_get_devdata(host); in mtk_nor_transfer_one_message() local
670 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_transfer_one_message()
679 writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_transfer_one_message()
681 stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, in mtk_nor_transfer_one_message()
690 reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); in mtk_nor_transfer_one_message()
704 static void mtk_nor_disable_clk(struct mtk_nor *sp) in mtk_nor_disable_clk() argument
706 clk_disable_unprepare(sp->spi_clk); in mtk_nor_disable_clk()
707 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_disable_clk()
708 clk_disable_unprepare(sp->axi_clk); in mtk_nor_disable_clk()
709 clk_disable_unprepare(sp->axi_s_clk); in mtk_nor_disable_clk()
712 static int mtk_nor_enable_clk(struct mtk_nor *sp) in mtk_nor_enable_clk() argument
716 ret = clk_prepare_enable(sp->spi_clk); in mtk_nor_enable_clk()
720 ret = clk_prepare_enable(sp->ctlr_clk); in mtk_nor_enable_clk()
722 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
726 ret = clk_prepare_enable(sp->axi_clk); in mtk_nor_enable_clk()
728 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
729 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_enable_clk()
733 ret = clk_prepare_enable(sp->axi_s_clk); in mtk_nor_enable_clk()
735 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
736 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_enable_clk()
737 clk_disable_unprepare(sp->axi_clk); in mtk_nor_enable_clk()
744 static void mtk_nor_init(struct mtk_nor *sp) in mtk_nor_init() argument
746 writel(0, sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_init()
747 writel(MTK_NOR_IRQ_MASK, sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_init()
749 writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); in mtk_nor_init()
750 mtk_nor_rmw(sp, MTK_NOR_REG_CFG2, MTK_NOR_WR_CUSTOM_OP_EN, 0); in mtk_nor_init()
751 mtk_nor_rmw(sp, MTK_NOR_REG_CFG3, in mtk_nor_init()
757 struct mtk_nor *sp = data; in mtk_nor_irq_handler() local
760 irq_status = readl(sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_irq_handler()
761 irq_enabled = readl(sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_irq_handler()
763 writel(irq_status, sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_irq_handler()
769 complete(&sp->op_done); in mtk_nor_irq_handler()
770 writel(0, sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_irq_handler()
813 struct mtk_nor *sp; in mtk_nor_probe() local
847 ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*sp)); in mtk_nor_probe()
865 sp = spi_controller_get_devdata(ctlr); in mtk_nor_probe()
866 sp->base = base; in mtk_nor_probe()
867 sp->has_irq = false; in mtk_nor_probe()
868 sp->wbuf_en = false; in mtk_nor_probe()
869 sp->ctlr = ctlr; in mtk_nor_probe()
870 sp->dev = &pdev->dev; in mtk_nor_probe()
871 sp->spi_clk = spi_clk; in mtk_nor_probe()
872 sp->ctlr_clk = ctlr_clk; in mtk_nor_probe()
873 sp->axi_clk = axi_clk; in mtk_nor_probe()
874 sp->axi_s_clk = axi_s_clk; in mtk_nor_probe()
875 sp->caps = caps; in mtk_nor_probe()
876 sp->high_dma = caps->dma_bits > 32; in mtk_nor_probe()
877 sp->buffer = dmam_alloc_coherent(&pdev->dev, in mtk_nor_probe()
879 &sp->buffer_dma, GFP_KERNEL); in mtk_nor_probe()
880 if (!sp->buffer) in mtk_nor_probe()
883 if ((uintptr_t)sp->buffer & MTK_NOR_DMA_ALIGN_MASK) { in mtk_nor_probe()
884 dev_err(sp->dev, "misaligned allocation of internal buffer.\n"); in mtk_nor_probe()
888 ret = mtk_nor_enable_clk(sp); in mtk_nor_probe()
892 sp->spi_freq = clk_get_rate(sp->spi_clk); in mtk_nor_probe()
894 mtk_nor_init(sp); in mtk_nor_probe()
899 dev_warn(sp->dev, "IRQ not available."); in mtk_nor_probe()
901 ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0, in mtk_nor_probe()
902 pdev->name, sp); in mtk_nor_probe()
904 dev_warn(sp->dev, "failed to request IRQ."); in mtk_nor_probe()
906 init_completion(&sp->op_done); in mtk_nor_probe()
907 sp->has_irq = true; in mtk_nor_probe()
923 dev_info(&pdev->dev, "spi frequency: %d Hz\n", sp->spi_freq); in mtk_nor_probe()
932 mtk_nor_disable_clk(sp); in mtk_nor_probe()
940 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_remove() local
946 mtk_nor_disable_clk(sp); in mtk_nor_remove()
952 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_runtime_suspend() local
954 mtk_nor_disable_clk(sp); in mtk_nor_runtime_suspend()
962 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_runtime_resume() local
964 return mtk_nor_enable_clk(sp); in mtk_nor_runtime_resume()
975 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_resume() local
982 mtk_nor_init(sp); in mtk_nor_resume()