Unverified Commit e836d4cf authored by Ikjoon Jang's avatar Ikjoon Jang Committed by Mark Brown
Browse files

spi: spi-mtk-nor: support 36bit dma addressing



This patch enables 36bit dma address support to spi-mtk-nor.
Currently this is enabled only for mt8192-nor.

Signed-off-by: default avatarIkjoon Jang <ikjn@chromium.org>
Link: https://lore.kernel.org/r/20201006155010.v5.3.Id1cb208392928afc7ceed4de06924243c7858cd0@changeid


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent a1daaa99
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@
#define MTK_NOR_REG_DMA_FADR		0x71c
#define MTK_NOR_REG_DMA_DADR		0x720
#define MTK_NOR_REG_DMA_END_DADR	0x724
#define MTK_NOR_REG_DMA_DADR_HB		0x738
#define MTK_NOR_REG_DMA_END_DADR_HB	0x73c

#define MTK_NOR_PRG_MAX_SIZE		6
// Reading DMA src/dst addresses have to be 16-byte aligned
@@ -103,6 +105,7 @@ struct mtk_nor {
	unsigned int spi_freq;
	bool wbuf_en;
	bool has_irq;
	bool high_dma;
	struct completion op_done;
};

@@ -343,6 +346,13 @@ static int mtk_nor_dma_exec(struct mtk_nor *sp, u32 from, unsigned int length,
	writel(dma_addr, sp->base + MTK_NOR_REG_DMA_DADR);
	writel(dma_addr + length, sp->base + MTK_NOR_REG_DMA_END_DADR);

	if (sp->high_dma) {
		writel(upper_32_bits(dma_addr),
		       sp->base + MTK_NOR_REG_DMA_DADR_HB);
		writel(upper_32_bits(dma_addr + length),
		       sp->base + MTK_NOR_REG_DMA_END_DADR_HB);
	}

	if (sp->has_irq) {
		reinit_completion(&sp->op_done);
		mtk_nor_rmw(sp, MTK_NOR_REG_IRQ_EN, MTK_NOR_IRQ_DMA, 0);
@@ -731,7 +741,8 @@ static const struct spi_controller_mem_ops mtk_nor_mem_ops = {
};

static const struct of_device_id mtk_nor_match[] = {
	{ .compatible = "mediatek,mt8173-nor" },
	{ .compatible = "mediatek,mt8192-nor", .data = (void *)36 },
	{ .compatible = "mediatek,mt8173-nor", .data = (void *)32 },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mtk_nor_match);
@@ -743,6 +754,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
	void __iomem *base;
	struct clk *spi_clk, *ctlr_clk;
	int ret, irq;
	unsigned long dma_bits;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
@@ -756,6 +768,12 @@ static int mtk_nor_probe(struct platform_device *pdev)
	if (IS_ERR(ctlr_clk))
		return PTR_ERR(ctlr_clk);

	dma_bits = (unsigned long)of_device_get_match_data(&pdev->dev);
	if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(dma_bits))) {
		dev_err(&pdev->dev, "failed to set dma mask(%lu)\n", dma_bits);
		return -EINVAL;
	}

	ctlr = spi_alloc_master(&pdev->dev, sizeof(*sp));
	if (!ctlr) {
		dev_err(&pdev->dev, "failed to allocate spi controller\n");
@@ -781,6 +799,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
	sp->dev = &pdev->dev;
	sp->spi_clk = spi_clk;
	sp->ctlr_clk = ctlr_clk;
	sp->high_dma = (dma_bits > 32);
	sp->buffer = dmam_alloc_coherent(&pdev->dev,
				MTK_NOR_BOUNCE_BUF_SIZE + MTK_NOR_DMA_ALIGN,
				&sp->buffer_dma, GFP_KERNEL);