Lines Matching full:sp

96 #define CLK_TO_US(sp, clkcnt)		DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000)  argument
127 static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr) in mtk_nor_rmw() argument
129 u32 val = readl(sp->base + reg); in mtk_nor_rmw()
133 writel(val, sp->base + reg); in mtk_nor_rmw()
136 static inline int mtk_nor_cmd_exec(struct mtk_nor *sp, u32 cmd, ulong clk) in mtk_nor_cmd_exec() argument
138 ulong delay = CLK_TO_US(sp, clk); in mtk_nor_cmd_exec()
142 writel(cmd, sp->base + MTK_NOR_REG_CMD); in mtk_nor_cmd_exec()
143 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CMD, reg, !(reg & cmd), in mtk_nor_cmd_exec()
146 dev_err(sp->dev, "command %u timeout.\n", cmd); in mtk_nor_cmd_exec()
150 static void mtk_nor_set_addr(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_set_addr() argument
156 writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR(i)); in mtk_nor_set_addr()
160 writeb(addr & 0xff, sp->base + MTK_NOR_REG_RADR3); in mtk_nor_set_addr()
161 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, MTK_NOR_4B_ADDR, 0); in mtk_nor_set_addr()
163 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, 0, MTK_NOR_4B_ADDR); in mtk_nor_set_addr()
167 static bool need_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in need_bounce() argument
265 struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master); in mtk_nor_adjust_op_size() local
280 else if (!need_bounce(sp, op)) in mtk_nor_adjust_op_size()
327 static void mtk_nor_setup_bus(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_setup_bus() argument
336 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(4)); in mtk_nor_setup_bus()
341 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA(3)); in mtk_nor_setup_bus()
346 mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, MTK_NOR_FAST_READ, 0); in mtk_nor_setup_bus()
348 mtk_nor_rmw(sp, MTK_NOR_REG_CFG1, 0, MTK_NOR_FAST_READ); in mtk_nor_setup_bus()
350 mtk_nor_rmw(sp, MTK_NOR_REG_BUSCFG, reg, MTK_NOR_BUS_MODE_MASK); in mtk_nor_setup_bus()
353 static int mtk_nor_dma_exec(struct mtk_nor *sp, u32 from, unsigned int length, in mtk_nor_dma_exec() argument
360 writel(from, sp->base + MTK_NOR_REG_DMA_FADR); in mtk_nor_dma_exec()
361 writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR); in mtk_nor_dma_exec()
362 writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR); in mtk_nor_dma_exec()
364 if (sp->high_dma) { in mtk_nor_dma_exec()
366 sp->base + MTK_NOR_REG_DMA_DADR_HB); in mtk_nor_dma_exec()
368 sp->base + MTK_NOR_REG_DMA_END_DADR_HB); in mtk_nor_dma_exec()
371 if (sp->has_irq) { in mtk_nor_dma_exec()
372 reinit_completion(&sp->op_done); in mtk_nor_dma_exec()
373 mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0); in mtk_nor_dma_exec()
376 mtk_nor_rmw(sp, MTK_NOR_REG_DMA_CTL, MTK_NOR_DMA_START, 0); in mtk_nor_dma_exec()
378 delay = CLK_TO_US(sp, (length + 5) * BITS_PER_BYTE); in mtk_nor_dma_exec()
380 if (sp->has_irq) { in mtk_nor_dma_exec()
381 if (!wait_for_completion_timeout(&sp->op_done, in mtk_nor_dma_exec()
385 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_DMA_CTL, reg, in mtk_nor_dma_exec()
391 dev_err(sp->dev, "dma read timeout.\n"); in mtk_nor_dma_exec()
396 static int mtk_nor_read_bounce(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_bounce() argument
406 ret = mtk_nor_dma_exec(sp, op->addr.val, rdlen, sp->buffer_dma); in mtk_nor_read_bounce()
409 memcpy(op->data.buf.in, sp->buffer, op->data.nbytes); in mtk_nor_read_bounce()
414 static int mtk_nor_read_dma(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_dma() argument
419 if (need_bounce(sp, op)) in mtk_nor_read_dma()
420 return mtk_nor_read_bounce(sp, op); in mtk_nor_read_dma()
422 dma_addr = dma_map_single(sp->dev, op->data.buf.in, in mtk_nor_read_dma()
425 if (dma_mapping_error(sp->dev, dma_addr)) in mtk_nor_read_dma()
428 ret = mtk_nor_dma_exec(sp, op->addr.val, op->data.nbytes, dma_addr); in mtk_nor_read_dma()
430 dma_unmap_single(sp->dev, dma_addr, op->data.nbytes, DMA_FROM_DEVICE); in mtk_nor_read_dma()
435 static int mtk_nor_read_pio(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_read_pio() argument
440 ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_READ, 6 * BITS_PER_BYTE); in mtk_nor_read_pio()
442 buf[0] = readb(sp->base + MTK_NOR_REG_RDATA); in mtk_nor_read_pio()
446 static int mtk_nor_write_buffer_enable(struct mtk_nor *sp) in mtk_nor_write_buffer_enable() argument
451 if (sp->wbuf_en) in mtk_nor_write_buffer_enable()
454 val = readl(sp->base + MTK_NOR_REG_CFG2); in mtk_nor_write_buffer_enable()
455 writel(val | MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); in mtk_nor_write_buffer_enable()
456 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, in mtk_nor_write_buffer_enable()
459 sp->wbuf_en = true; in mtk_nor_write_buffer_enable()
463 static int mtk_nor_write_buffer_disable(struct mtk_nor *sp) in mtk_nor_write_buffer_disable() argument
468 if (!sp->wbuf_en) in mtk_nor_write_buffer_disable()
470 val = readl(sp->base + MTK_NOR_REG_CFG2); in mtk_nor_write_buffer_disable()
471 writel(val & ~MTK_NOR_WR_BUF_EN, sp->base + MTK_NOR_REG_CFG2); in mtk_nor_write_buffer_disable()
472 ret = readl_poll_timeout(sp->base + MTK_NOR_REG_CFG2, val, in mtk_nor_write_buffer_disable()
475 sp->wbuf_en = false; in mtk_nor_write_buffer_disable()
479 static int mtk_nor_pp_buffered(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_pp_buffered() argument
485 ret = mtk_nor_write_buffer_enable(sp); in mtk_nor_pp_buffered()
492 writel(val, sp->base + MTK_NOR_REG_PP_DATA); in mtk_nor_pp_buffered()
494 return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, in mtk_nor_pp_buffered()
498 static int mtk_nor_pp_unbuffered(struct mtk_nor *sp, in mtk_nor_pp_unbuffered() argument
504 ret = mtk_nor_write_buffer_disable(sp); in mtk_nor_pp_unbuffered()
507 writeb(buf[0], sp->base + MTK_NOR_REG_WDATA); in mtk_nor_pp_unbuffered()
508 return mtk_nor_cmd_exec(sp, MTK_NOR_CMD_WRITE, 6 * BITS_PER_BYTE); in mtk_nor_pp_unbuffered()
511 static int mtk_nor_spi_mem_prg(struct mtk_nor *sp, const struct spi_mem_op *op) in mtk_nor_spi_mem_prg() argument
541 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
547 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
554 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_spi_mem_prg()
559 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 writel(prg_len * BITS_PER_BYTE + sp->caps->extra_dummy_bit, in mtk_nor_spi_mem_prg()
572 sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_spi_mem_prg()
574 writel(prg_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_spi_mem_prg()
576 ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, in mtk_nor_spi_mem_prg()
585 reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); in mtk_nor_spi_mem_prg()
595 struct mtk_nor *sp = spi_controller_get_devdata(mem->spi->master); in mtk_nor_exec_op() local
600 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()
603 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
604 writeb(op->cmd.opcode, sp->base + MTK_NOR_REG_PRGDATA0); in mtk_nor_exec_op()
606 return mtk_nor_pp_buffered(sp, op); in mtk_nor_exec_op()
607 return mtk_nor_pp_unbuffered(sp, op); in mtk_nor_exec_op()
611 ret = mtk_nor_write_buffer_disable(sp); in mtk_nor_exec_op()
614 mtk_nor_setup_bus(sp, op); in mtk_nor_exec_op()
616 mtk_nor_set_addr(sp, op); in mtk_nor_exec_op()
617 return mtk_nor_read_pio(sp, op); in mtk_nor_exec_op()
619 return mtk_nor_read_dma(sp, op); in mtk_nor_exec_op()
623 return mtk_nor_spi_mem_prg(sp, op); in mtk_nor_exec_op()
628 struct mtk_nor *sp = spi_controller_get_devdata(spi->master); in mtk_nor_setup() local
630 if (spi->max_speed_hz && (spi->max_speed_hz < sp->spi_freq)) { in mtk_nor_setup()
632 sp->spi_freq); in mtk_nor_setup()
635 spi->max_speed_hz = sp->spi_freq; in mtk_nor_setup()
643 struct mtk_nor *sp = spi_controller_get_devdata(master); in mtk_nor_transfer_one_message() local
656 reg = sp->base + MTK_NOR_REG_PRGDATA(reg_offset); in mtk_nor_transfer_one_message()
665 writel(trx_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); in mtk_nor_transfer_one_message()
667 stat = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, in mtk_nor_transfer_one_message()
676 reg = sp->base + MTK_NOR_REG_SHIFT(reg_offset); in mtk_nor_transfer_one_message()
690 static void mtk_nor_disable_clk(struct mtk_nor *sp) in mtk_nor_disable_clk() argument
692 clk_disable_unprepare(sp->spi_clk); in mtk_nor_disable_clk()
693 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_disable_clk()
694 clk_disable_unprepare(sp->axi_clk); in mtk_nor_disable_clk()
695 clk_disable_unprepare(sp->axi_s_clk); in mtk_nor_disable_clk()
698 static int mtk_nor_enable_clk(struct mtk_nor *sp) in mtk_nor_enable_clk() argument
702 ret = clk_prepare_enable(sp->spi_clk); in mtk_nor_enable_clk()
706 ret = clk_prepare_enable(sp->ctlr_clk); in mtk_nor_enable_clk()
708 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
712 ret = clk_prepare_enable(sp->axi_clk); in mtk_nor_enable_clk()
714 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
715 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_enable_clk()
719 ret = clk_prepare_enable(sp->axi_s_clk); in mtk_nor_enable_clk()
721 clk_disable_unprepare(sp->spi_clk); in mtk_nor_enable_clk()
722 clk_disable_unprepare(sp->ctlr_clk); in mtk_nor_enable_clk()
723 clk_disable_unprepare(sp->axi_clk); in mtk_nor_enable_clk()
730 static void mtk_nor_init(struct mtk_nor *sp) in mtk_nor_init() argument
732 writel(0, sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_init()
733 writel(MTK_NOR_IRQ_MASK, sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_init()
735 writel(MTK_NOR_ENABLE_SF_CMD, sp->base + MTK_NOR_REG_WP); in mtk_nor_init()
736 mtk_nor_rmw(sp, MTK_NOR_REG_CFG2, MTK_NOR_WR_CUSTOM_OP_EN, 0); in mtk_nor_init()
737 mtk_nor_rmw(sp, MTK_NOR_REG_CFG3, in mtk_nor_init()
743 struct mtk_nor *sp = data; in mtk_nor_irq_handler() local
746 irq_status = readl(sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_irq_handler()
747 irq_enabled = readl(sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_irq_handler()
749 writel(irq_status, sp->base + MTK_NOR_REG_IRQ_STAT); in mtk_nor_irq_handler()
755 complete(&sp->op_done); in mtk_nor_irq_handler()
756 writel(0, sp->base + MTK_NOR_REG_IRQ_EN); in mtk_nor_irq_handler()
799 struct mtk_nor *sp; in mtk_nor_probe() local
833 ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp)); in mtk_nor_probe()
851 sp = spi_controller_get_devdata(ctlr); in mtk_nor_probe()
852 sp->base = base; in mtk_nor_probe()
853 sp->has_irq = false; in mtk_nor_probe()
854 sp->wbuf_en = false; in mtk_nor_probe()
855 sp->ctlr = ctlr; in mtk_nor_probe()
856 sp->dev = &pdev->dev; in mtk_nor_probe()
857 sp->spi_clk = spi_clk; in mtk_nor_probe()
858 sp->ctlr_clk = ctlr_clk; in mtk_nor_probe()
859 sp->axi_clk = axi_clk; in mtk_nor_probe()
860 sp->axi_s_clk = axi_s_clk; in mtk_nor_probe()
861 sp->caps = caps; in mtk_nor_probe()
862 sp->high_dma = caps->dma_bits > 32; in mtk_nor_probe()
863 sp->buffer = dmam_alloc_coherent(&pdev->dev, in mtk_nor_probe()
865 &sp->buffer_dma, GFP_KERNEL); in mtk_nor_probe()
866 if (!sp->buffer) in mtk_nor_probe()
869 if ((uintptr_t)sp->buffer & MTK_NOR_DMA_ALIGN_MASK) { in mtk_nor_probe()
870 dev_err(sp->dev, "misaligned allocation of internal buffer.\n"); in mtk_nor_probe()
874 ret = mtk_nor_enable_clk(sp); in mtk_nor_probe()
878 sp->spi_freq = clk_get_rate(sp->spi_clk); in mtk_nor_probe()
880 mtk_nor_init(sp); in mtk_nor_probe()
885 dev_warn(sp->dev, "IRQ not available."); in mtk_nor_probe()
887 ret = devm_request_irq(sp->dev, irq, mtk_nor_irq_handler, 0, in mtk_nor_probe()
888 pdev->name, sp); in mtk_nor_probe()
890 dev_warn(sp->dev, "failed to request IRQ."); in mtk_nor_probe()
892 init_completion(&sp->op_done); in mtk_nor_probe()
893 sp->has_irq = true; in mtk_nor_probe()
910 dev_info(&pdev->dev, "spi frequency: %d Hz\n", sp->spi_freq); in mtk_nor_probe()
919 mtk_nor_disable_clk(sp); in mtk_nor_probe()
927 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_remove() local
933 mtk_nor_disable_clk(sp); in mtk_nor_remove()
941 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_runtime_suspend() local
943 mtk_nor_disable_clk(sp); in mtk_nor_runtime_suspend()
951 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_runtime_resume() local
953 return mtk_nor_enable_clk(sp); in mtk_nor_runtime_resume()
964 struct mtk_nor *sp = spi_controller_get_devdata(ctlr); in mtk_nor_resume() local
971 mtk_nor_init(sp); in mtk_nor_resume()