Lines Matching full:sfc

197 static int rockchip_sfc_reset(struct rockchip_sfc *sfc)  in rockchip_sfc_reset()  argument
202 writel_relaxed(SFC_RCVR_RESET, sfc->regbase + SFC_RCVR); in rockchip_sfc_reset()
204 err = readl_poll_timeout(sfc->regbase + SFC_RCVR, status, in rockchip_sfc_reset()
208 dev_err(sfc->dev, "SFC reset never finished\n"); in rockchip_sfc_reset()
211 writel_relaxed(0xFFFFFFFF, sfc->regbase + SFC_ICLR); in rockchip_sfc_reset()
213 dev_dbg(sfc->dev, "reset\n"); in rockchip_sfc_reset()
218 static u16 rockchip_sfc_get_version(struct rockchip_sfc *sfc) in rockchip_sfc_get_version() argument
220 return (u16)(readl(sfc->regbase + SFC_VER) & 0xffff); in rockchip_sfc_get_version()
223 static u32 rockchip_sfc_get_max_iosize(struct rockchip_sfc *sfc) in rockchip_sfc_get_max_iosize() argument
228 static u32 rockchip_sfc_get_max_dll_cells(struct rockchip_sfc *sfc) in rockchip_sfc_get_max_dll_cells() argument
230 switch (rockchip_sfc_get_version(sfc)) { in rockchip_sfc_get_max_dll_cells()
242 static void rockchip_sfc_set_delay_lines(struct rockchip_sfc *sfc, u16 cells) in rockchip_sfc_set_delay_lines() argument
244 u16 cell_max = (u16)rockchip_sfc_get_max_dll_cells(sfc); in rockchip_sfc_set_delay_lines()
253 writel(val, sfc->regbase + SFC_DLL_CTRL0); in rockchip_sfc_set_delay_lines()
256 static void rockchip_sfc_irq_unmask(struct rockchip_sfc *sfc, u32 mask) in rockchip_sfc_irq_unmask() argument
261 reg = readl(sfc->regbase + SFC_IMR); in rockchip_sfc_irq_unmask()
263 writel(reg, sfc->regbase + SFC_IMR); in rockchip_sfc_irq_unmask()
266 static void rockchip_sfc_irq_mask(struct rockchip_sfc *sfc, u32 mask) in rockchip_sfc_irq_mask() argument
271 reg = readl(sfc->regbase + SFC_IMR); in rockchip_sfc_irq_mask()
273 writel(reg, sfc->regbase + SFC_IMR); in rockchip_sfc_irq_mask()
276 static int rockchip_sfc_init(struct rockchip_sfc *sfc) in rockchip_sfc_init() argument
278 writel(0, sfc->regbase + SFC_CTRL); in rockchip_sfc_init()
279 writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR); in rockchip_sfc_init()
280 rockchip_sfc_irq_mask(sfc, 0xFFFFFFFF); in rockchip_sfc_init()
281 if (rockchip_sfc_get_version(sfc) >= SFC_VER_4) in rockchip_sfc_init()
282 writel(SFC_LEN_CTRL_TRB_SEL, sfc->regbase + SFC_LEN_CTRL); in rockchip_sfc_init()
287 static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) in rockchip_sfc_wait_txfifo_ready() argument
292 ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, in rockchip_sfc_wait_txfifo_ready()
296 dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n"); in rockchip_sfc_wait_txfifo_ready()
304 static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) in rockchip_sfc_wait_rxfifo_ready() argument
309 ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, in rockchip_sfc_wait_rxfifo_ready()
313 dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n"); in rockchip_sfc_wait_rxfifo_ready()
325 * SFC not support output DUMMY cycles right after CMD cycles, so in rockchip_sfc_adjust_op_work()
336 static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc, in rockchip_sfc_xfer_setup() argument
355 writel(op->addr.nbytes * 8 - 1, sfc->regbase + SFC_ABIT); in rockchip_sfc_xfer_setup()
372 if (sfc->version >= SFC_VER_4) /* Clear it if no data to transfer */ in rockchip_sfc_xfer_setup()
373 writel(len, sfc->regbase + SFC_LEN_EXT); in rockchip_sfc_xfer_setup()
389 dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n", in rockchip_sfc_xfer_setup()
392 dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n", in rockchip_sfc_xfer_setup()
395 writel(ctrl, sfc->regbase + SFC_CTRL); in rockchip_sfc_xfer_setup()
396 writel(cmd, sfc->regbase + SFC_CMD); in rockchip_sfc_xfer_setup()
398 writel(op->addr.val, sfc->regbase + SFC_ADDR); in rockchip_sfc_xfer_setup()
403 static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int len) in rockchip_sfc_write_fifo() argument
413 tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); in rockchip_sfc_write_fifo()
417 iowrite32_rep(sfc->regbase + SFC_DATA, buf, write_words); in rockchip_sfc_write_fifo()
424 tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); in rockchip_sfc_write_fifo()
428 writel(tmp, sfc->regbase + SFC_DATA); in rockchip_sfc_write_fifo()
434 static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len) in rockchip_sfc_read_fifo() argument
445 rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); in rockchip_sfc_read_fifo()
449 ioread32_rep(sfc->regbase + SFC_DATA, buf, read_words); in rockchip_sfc_read_fifo()
456 rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); in rockchip_sfc_read_fifo()
459 tmp = readl(sfc->regbase + SFC_DATA); in rockchip_sfc_read_fifo()
466 static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t dma_buf, size_t len) in rockchip_sfc_fifo_transfer_dma() argument
468 writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR); in rockchip_sfc_fifo_transfer_dma()
469 writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR); in rockchip_sfc_fifo_transfer_dma()
470 writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER); in rockchip_sfc_fifo_transfer_dma()
475 static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc, in rockchip_sfc_xfer_data_poll() argument
478 dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len); in rockchip_sfc_xfer_data_poll()
481 return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len); in rockchip_sfc_xfer_data_poll()
483 return rockchip_sfc_read_fifo(sfc, op->data.buf.in, len); in rockchip_sfc_xfer_data_poll()
486 static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc, in rockchip_sfc_xfer_data_dma() argument
491 dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len); in rockchip_sfc_xfer_data_dma()
494 memcpy(sfc->buffer, op->data.buf.out, len); in rockchip_sfc_xfer_data_dma()
496 ret = rockchip_sfc_fifo_transfer_dma(sfc, sfc->dma_buffer, len); in rockchip_sfc_xfer_data_dma()
497 if (!wait_for_completion_timeout(&sfc->cp, msecs_to_jiffies(2000))) { in rockchip_sfc_xfer_data_dma()
498 dev_err(sfc->dev, "DMA wait for transfer finish timeout\n"); in rockchip_sfc_xfer_data_dma()
501 rockchip_sfc_irq_mask(sfc, SFC_IMR_DMA); in rockchip_sfc_xfer_data_dma()
503 memcpy(op->data.buf.in, sfc->buffer, len); in rockchip_sfc_xfer_data_dma()
508 static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us) in rockchip_sfc_xfer_done() argument
517 ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, in rockchip_sfc_xfer_done()
523 ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, in rockchip_sfc_xfer_done()
527 dev_err(sfc->dev, "wait sfc idle timeout\n"); in rockchip_sfc_xfer_done()
528 rockchip_sfc_reset(sfc); in rockchip_sfc_xfer_done()
536 static int rockchip_sfc_exec_op_bypass(struct rockchip_sfc *sfc, in rockchip_sfc_exec_op_bypass() argument
540 u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize); in rockchip_sfc_exec_op_bypass()
544 rockchip_sfc_xfer_setup(sfc, mem, op, len); in rockchip_sfc_exec_op_bypass()
545 ret = rockchip_sfc_xfer_data_poll(sfc, op, len); in rockchip_sfc_exec_op_bypass()
547 dev_err(sfc->dev, "xfer data failed ret %d\n", ret); in rockchip_sfc_exec_op_bypass()
552 return rockchip_sfc_xfer_done(sfc, 100000); in rockchip_sfc_exec_op_bypass()
555 static void rockchip_sfc_delay_lines_tuning(struct rockchip_sfc *sfc, struct spi_mem *mem) in rockchip_sfc_delay_lines_tuning() argument
562 u16 cell_max = (u16)rockchip_sfc_get_max_dll_cells(sfc); in rockchip_sfc_delay_lines_tuning()
567 clk_set_rate(sfc->clk, SFC_DLL_THRESHOLD_RATE); in rockchip_sfc_delay_lines_tuning()
569 rockchip_sfc_exec_op_bypass(sfc, mem, &op); in rockchip_sfc_delay_lines_tuning()
572 dev_dbg(sfc->dev, "no dev, dll by pass\n"); in rockchip_sfc_delay_lines_tuning()
573 clk_set_rate(sfc->clk, mem->spi->max_speed_hz); in rockchip_sfc_delay_lines_tuning()
578 clk_set_rate(sfc->clk, mem->spi->max_speed_hz); in rockchip_sfc_delay_lines_tuning()
583 rockchip_sfc_set_delay_lines(sfc, right); in rockchip_sfc_delay_lines_tuning()
584 rockchip_sfc_exec_op_bypass(sfc, mem, &op); in rockchip_sfc_delay_lines_tuning()
585 dev_dbg(sfc->dev, "dll read flash id:%x %x %x\n", in rockchip_sfc_delay_lines_tuning()
609 sfc->dll_cells = left + (right - left) * 2 / 5; in rockchip_sfc_delay_lines_tuning()
611 sfc->dll_cells = left + (right - left) / 2; in rockchip_sfc_delay_lines_tuning()
613 sfc->dll_cells = 0; in rockchip_sfc_delay_lines_tuning()
616 if (sfc->dll_cells) { in rockchip_sfc_delay_lines_tuning()
617 dev_dbg(sfc->dev, "%d %d %d dll training success in %dMHz max_cells=%u sfc_ver=%d\n", in rockchip_sfc_delay_lines_tuning()
618 left, right, sfc->dll_cells, mem->spi->max_speed_hz, in rockchip_sfc_delay_lines_tuning()
619 rockchip_sfc_get_max_dll_cells(sfc), rockchip_sfc_get_version(sfc)); in rockchip_sfc_delay_lines_tuning()
620 rockchip_sfc_set_delay_lines(sfc, (u16)sfc->dll_cells); in rockchip_sfc_delay_lines_tuning()
622 dev_err(sfc->dev, "%d %d dll training failed in %dMHz, reduce the frequency\n", in rockchip_sfc_delay_lines_tuning()
624 rockchip_sfc_set_delay_lines(sfc, 0); in rockchip_sfc_delay_lines_tuning()
625 clk_set_rate(sfc->clk, SFC_DLL_THRESHOLD_RATE); in rockchip_sfc_delay_lines_tuning()
626 mem->spi->max_speed_hz = clk_get_rate(sfc->clk); in rockchip_sfc_delay_lines_tuning()
632 struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master); in rockchip_sfc_exec_mem_op() local
636 ret = pm_runtime_get_sync(sfc->dev); in rockchip_sfc_exec_mem_op()
638 pm_runtime_put_noidle(sfc->dev); in rockchip_sfc_exec_mem_op()
642 if (unlikely(mem->spi->max_speed_hz != sfc->frequency) && !has_acpi_companion(sfc->dev)) { in rockchip_sfc_exec_mem_op()
643 ret = clk_set_rate(sfc->clk, mem->spi->max_speed_hz); in rockchip_sfc_exec_mem_op()
646 sfc->frequency = mem->spi->max_speed_hz; in rockchip_sfc_exec_mem_op()
647 if (rockchip_sfc_get_version(sfc) >= SFC_VER_4) { in rockchip_sfc_exec_mem_op()
648 if (clk_get_rate(sfc->clk) > SFC_DLL_THRESHOLD_RATE) in rockchip_sfc_exec_mem_op()
649 rockchip_sfc_delay_lines_tuning(sfc, mem); in rockchip_sfc_exec_mem_op()
651 rockchip_sfc_set_delay_lines(sfc, 0); in rockchip_sfc_exec_mem_op()
654 dev_dbg(sfc->dev, "set_freq=%dHz real_freq=%ldHz\n", in rockchip_sfc_exec_mem_op()
655 sfc->frequency, clk_get_rate(sfc->clk)); in rockchip_sfc_exec_mem_op()
659 rockchip_sfc_xfer_setup(sfc, mem, op, len); in rockchip_sfc_exec_mem_op()
661 if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD && !(len & 0x3)) { in rockchip_sfc_exec_mem_op()
662 init_completion(&sfc->cp); in rockchip_sfc_exec_mem_op()
663 rockchip_sfc_irq_unmask(sfc, SFC_IMR_DMA); in rockchip_sfc_exec_mem_op()
664 ret = rockchip_sfc_xfer_data_dma(sfc, op, len); in rockchip_sfc_exec_mem_op()
666 ret = rockchip_sfc_xfer_data_poll(sfc, op, len); in rockchip_sfc_exec_mem_op()
670 dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir); in rockchip_sfc_exec_mem_op()
677 ret = rockchip_sfc_xfer_done(sfc, 100000); in rockchip_sfc_exec_mem_op()
679 pm_runtime_mark_last_busy(sfc->dev); in rockchip_sfc_exec_mem_op()
680 pm_runtime_put_autosuspend(sfc->dev); in rockchip_sfc_exec_mem_op()
687 struct rockchip_sfc *sfc = spi_master_get_devdata(mem->spi->master); in rockchip_sfc_adjust_op_size() local
689 op->data.nbytes = min(op->data.nbytes, sfc->max_iosize); in rockchip_sfc_adjust_op_size()
701 struct rockchip_sfc *sfc = dev_id; in rockchip_sfc_irq_handler() local
704 reg = readl(sfc->regbase + SFC_RISR); in rockchip_sfc_irq_handler()
707 writel_relaxed(reg, sfc->regbase + SFC_ICLR); in rockchip_sfc_irq_handler()
710 complete(&sfc->cp); in rockchip_sfc_irq_handler()
723 struct rockchip_sfc *sfc; in rockchip_sfc_probe() local
726 master = devm_spi_alloc_master(&pdev->dev, sizeof(*sfc)); in rockchip_sfc_probe()
737 sfc = spi_master_get_devdata(master); in rockchip_sfc_probe()
738 sfc->dev = dev; in rockchip_sfc_probe()
741 sfc->regbase = devm_ioremap_resource(dev, res); in rockchip_sfc_probe()
742 if (IS_ERR(sfc->regbase)) in rockchip_sfc_probe()
743 return PTR_ERR(sfc->regbase); in rockchip_sfc_probe()
746 sfc->clk = devm_clk_get(&pdev->dev, "clk_sfc"); in rockchip_sfc_probe()
747 if (IS_ERR(sfc->clk)) { in rockchip_sfc_probe()
748 dev_err(&pdev->dev, "Failed to get sfc interface clk\n"); in rockchip_sfc_probe()
749 return PTR_ERR(sfc->clk); in rockchip_sfc_probe()
753 sfc->hclk = devm_clk_get(&pdev->dev, "hclk_sfc"); in rockchip_sfc_probe()
754 if (IS_ERR(sfc->hclk)) { in rockchip_sfc_probe()
755 dev_err(&pdev->dev, "Failed to get sfc ahb clk\n"); in rockchip_sfc_probe()
756 return PTR_ERR(sfc->hclk); in rockchip_sfc_probe()
760 ret = device_property_read_u32(&pdev->dev, "clock-frequency", &sfc->frequency); in rockchip_sfc_probe()
767 sfc->use_dma = !of_property_read_bool(sfc->dev->of_node, in rockchip_sfc_probe()
768 "rockchip,sfc-no-dma"); in rockchip_sfc_probe()
770 if (sfc->use_dma) { in rockchip_sfc_probe()
777 sfc->buffer = dmam_alloc_coherent(dev, SFC_MAX_IOSIZE_VER3, in rockchip_sfc_probe()
778 &sfc->dma_buffer, in rockchip_sfc_probe()
780 if (!sfc->buffer) in rockchip_sfc_probe()
784 ret = clk_prepare_enable(sfc->hclk); in rockchip_sfc_probe()
790 ret = clk_prepare_enable(sfc->clk); in rockchip_sfc_probe()
804 0, pdev->name, sfc); in rockchip_sfc_probe()
811 platform_set_drvdata(pdev, sfc); in rockchip_sfc_probe()
816 if (readl_poll_timeout(sfc->regbase + SFC_SR, status, in rockchip_sfc_probe()
819 dev_err(dev, "Wait for SFC idle timeout!\n"); in rockchip_sfc_probe()
822 ret = rockchip_sfc_init(sfc); in rockchip_sfc_probe()
826 sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc); in rockchip_sfc_probe()
827 sfc->version = rockchip_sfc_get_version(sfc); in rockchip_sfc_probe()
845 pm_runtime_disable(sfc->dev); in rockchip_sfc_probe()
846 pm_runtime_set_suspended(sfc->dev); in rockchip_sfc_probe()
847 pm_runtime_dont_use_autosuspend(sfc->dev); in rockchip_sfc_probe()
849 clk_disable_unprepare(sfc->clk); in rockchip_sfc_probe()
851 clk_disable_unprepare(sfc->hclk); in rockchip_sfc_probe()
859 struct rockchip_sfc *sfc = platform_get_drvdata(pdev); in rockchip_sfc_remove() local
863 clk_disable_unprepare(sfc->clk); in rockchip_sfc_remove()
864 clk_disable_unprepare(sfc->hclk); in rockchip_sfc_remove()
871 struct rockchip_sfc *sfc = dev_get_drvdata(dev); in rockchip_sfc_runtime_suspend() local
873 clk_disable_unprepare(sfc->clk); in rockchip_sfc_runtime_suspend()
874 clk_disable_unprepare(sfc->hclk); in rockchip_sfc_runtime_suspend()
881 struct rockchip_sfc *sfc = dev_get_drvdata(dev); in rockchip_sfc_runtime_resume() local
884 ret = clk_prepare_enable(sfc->hclk); in rockchip_sfc_runtime_resume()
888 ret = clk_prepare_enable(sfc->clk); in rockchip_sfc_runtime_resume()
890 clk_disable_unprepare(sfc->hclk); in rockchip_sfc_runtime_resume()
904 struct rockchip_sfc *sfc = dev_get_drvdata(dev); in rockchip_sfc_resume() local
919 rockchip_sfc_init(sfc); in rockchip_sfc_resume()
920 if (sfc->dll_cells) in rockchip_sfc_resume()
921 rockchip_sfc_set_delay_lines(sfc, (u16)sfc->dll_cells); in rockchip_sfc_resume()
936 { .compatible = "rockchip,sfc"},
943 .name = "rockchip-sfc",