Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: add new SoC mt8186 support for spi-mtk-nor

Merge series from guochun.mao@mediatek.com <guochun.mao@mediatek.com>:

These patches is mainly for adding mt8186 support.
The spi nor controller of mt8186 has some differences,
it needs one more clk, axi_s, for dma feature.
And also needs one extra dummy bit when read flash registers.

+65 -10
+4
Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
··· 30 30 - mediatek,mt7622-nor 31 31 - mediatek,mt7623-nor 32 32 - mediatek,mt7629-nor 33 + - mediatek,mt8186-nor 33 34 - mediatek,mt8192-nor 34 35 - mediatek,mt8195-nor 35 36 - enum: ··· 50 49 - description: clock used for controller 51 50 - description: clock used for nor dma bus. this depends on hardware 52 51 design, so this is optional. 52 + - description: clock used for controller axi slave bus. 53 + this depends on hardware design, so it is optional. 53 54 54 55 clock-names: 55 56 minItems: 2 ··· 59 56 - const: spi 60 57 - const: sf 61 58 - const: axi 59 + - const: axi_s 62 60 63 61 required: 64 62 - compatible
+61 -10
drivers/spi/spi-mtk-nor.c
··· 95 95 96 96 #define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000) 97 97 98 + struct mtk_nor_caps { 99 + u8 dma_bits; 100 + 101 + /* extra_dummy_bit is adding for the IP of new SoCs. 102 + * Some new SoCs modify the timing of fetching registers' values 103 + * and IDs of nor flash, they need a extra_dummy_bit which can add 104 + * more clock cycles for fetching data. 105 + */ 106 + u8 extra_dummy_bit; 107 + }; 108 + 98 109 struct mtk_nor { 99 110 struct spi_controller *ctlr; 100 111 struct device *dev; ··· 115 104 struct clk *spi_clk; 116 105 struct clk *ctlr_clk; 117 106 struct clk *axi_clk; 107 + struct clk *axi_s_clk; 118 108 unsigned int spi_freq; 119 109 bool wbuf_en; 120 110 bool has_irq; 121 111 bool high_dma; 122 112 struct completion op_done; 113 + const struct mtk_nor_caps *caps; 123 114 }; 124 115 125 116 static inline void mtk_nor_rmw(struct mtk_nor *sp, u32 reg, u32 set, u32 clr) ··· 567 554 } 568 555 569 556 // trigger op 570 - writel(prg_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); 557 + if (rx_len) 558 + writel(prg_len * BITS_PER_BYTE + sp->caps->extra_dummy_bit, 559 + sp->base + MTK_NOR_REG_PRG_CNT); 560 + else 561 + writel(prg_len * BITS_PER_BYTE, sp->base + MTK_NOR_REG_PRG_CNT); 562 + 571 563 ret = mtk_nor_cmd_exec(sp, MTK_NOR_CMD_PROGRAM, 572 564 prg_len * BITS_PER_BYTE); 573 565 if (ret) ··· 692 674 clk_disable_unprepare(sp->spi_clk); 693 675 clk_disable_unprepare(sp->ctlr_clk); 694 676 clk_disable_unprepare(sp->axi_clk); 677 + clk_disable_unprepare(sp->axi_s_clk); 695 678 } 696 679 697 680 static int mtk_nor_enable_clk(struct mtk_nor *sp) ··· 713 694 if (ret) { 714 695 clk_disable_unprepare(sp->spi_clk); 715 696 clk_disable_unprepare(sp->ctlr_clk); 697 + return ret; 698 + } 699 + 700 + ret = clk_prepare_enable(sp->axi_s_clk); 701 + if (ret) { 702 + clk_disable_unprepare(sp->spi_clk); 703 + clk_disable_unprepare(sp->ctlr_clk); 704 + clk_disable_unprepare(sp->axi_clk); 716 705 return ret; 717 706 } 718 707 ··· 770 743 .exec_op = mtk_nor_exec_op 771 744 }; 772 745 746 + const struct mtk_nor_caps mtk_nor_caps_mt8173 = { 747 + .dma_bits = 32, 748 + .extra_dummy_bit = 0, 749 + }; 750 + 751 + const struct mtk_nor_caps mtk_nor_caps_mt8186 = { 752 + .dma_bits = 32, 753 + .extra_dummy_bit = 1, 754 + }; 755 + 756 + const struct mtk_nor_caps mtk_nor_caps_mt8192 = { 757 + .dma_bits = 36, 758 + .extra_dummy_bit = 0, 759 + }; 760 + 773 761 static const struct of_device_id mtk_nor_match[] = { 774 - { .compatible = "mediatek,mt8192-nor", .data = (void *)36 }, 775 - { .compatible = "mediatek,mt8173-nor", .data = (void *)32 }, 762 + { .compatible = "mediatek,mt8173-nor", .data = &mtk_nor_caps_mt8173 }, 763 + { .compatible = "mediatek,mt8186-nor", .data = &mtk_nor_caps_mt8186 }, 764 + { .compatible = "mediatek,mt8192-nor", .data = &mtk_nor_caps_mt8192 }, 776 765 { /* sentinel */ } 777 766 }; 778 767 MODULE_DEVICE_TABLE(of, mtk_nor_match); ··· 797 754 { 798 755 struct spi_controller *ctlr; 799 756 struct mtk_nor *sp; 757 + struct mtk_nor_caps *caps; 800 758 void __iomem *base; 801 - struct clk *spi_clk, *ctlr_clk, *axi_clk; 759 + struct clk *spi_clk, *ctlr_clk, *axi_clk, *axi_s_clk; 802 760 int ret, irq; 803 - unsigned long dma_bits; 804 761 805 762 base = devm_platform_ioremap_resource(pdev, 0); 806 763 if (IS_ERR(base)) ··· 818 775 if (IS_ERR(axi_clk)) 819 776 return PTR_ERR(axi_clk); 820 777 821 - dma_bits = (unsigned long)of_device_get_match_data(&pdev->dev); 822 - if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_bits))) { 823 - dev_err(&pdev->dev, "failed to set dma mask(%lu)\n", dma_bits); 824 - return -EINVAL; 778 + axi_s_clk = devm_clk_get_optional(&pdev->dev, "axi_s"); 779 + if (IS_ERR(axi_s_clk)) 780 + return PTR_ERR(axi_s_clk); 781 + 782 + caps = (struct mtk_nor_caps *)of_device_get_match_data(&pdev->dev); 783 + 784 + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(caps->dma_bits)); 785 + if (ret) { 786 + dev_err(&pdev->dev, "failed to set dma mask(%u)\n", caps->dma_bits); 787 + return ret; 825 788 } 826 789 827 790 ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp)); ··· 857 808 sp->spi_clk = spi_clk; 858 809 sp->ctlr_clk = ctlr_clk; 859 810 sp->axi_clk = axi_clk; 860 - sp->high_dma = (dma_bits > 32); 811 + sp->axi_s_clk = axi_s_clk; 812 + sp->caps = caps; 813 + sp->high_dma = caps->dma_bits > 32; 861 814 sp->buffer = dmam_alloc_coherent(&pdev->dev, 862 815 MTK_NOR_BOUNCE_BUF_SIZE + MTK_NOR_DMA_ALIGN, 863 816 &sp->buffer_dma, GFP_KERNEL);