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

spi: mediatek: support large PA

Add spi large PA(max=64G) support for DMA transfer.

Signed-off-by: luhua.xu <luhua.xu@mediatek.com>
Link: https://lore.kernel.org/r/1568195731-3239-4-git-send-email-luhua.xu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

luhua.xu and committed by
Mark Brown
fdeae8f5 2c231e0a

+39 -5
+39 -5
drivers/spi/spi-mt65xx.c
··· 17 17 #include <linux/platform_data/spi-mt65xx.h> 18 18 #include <linux/pm_runtime.h> 19 19 #include <linux/spi/spi.h> 20 + #include <linux/dma-mapping.h> 20 21 21 22 #define SPI_CFG0_REG 0x0000 22 23 #define SPI_CFG1_REG 0x0004 ··· 29 28 #define SPI_STATUS0_REG 0x001c 30 29 #define SPI_PAD_SEL_REG 0x0024 31 30 #define SPI_CFG2_REG 0x0028 31 + #define SPI_TX_SRC_REG_64 0x002c 32 + #define SPI_RX_DST_REG_64 0x0030 32 33 33 34 #define SPI_CFG0_SCK_HIGH_OFFSET 0 34 35 #define SPI_CFG0_SCK_LOW_OFFSET 8 ··· 76 73 77 74 #define MTK_SPI_MAX_FIFO_SIZE 32U 78 75 #define MTK_SPI_PACKET_SIZE 1024 76 + #define MTK_SPI_32BITS_MASK (0xffffffff) 77 + 78 + #define DMA_ADDR_EXT_BITS (36) 79 + #define DMA_ADDR_DEF_BITS (32) 79 80 80 81 struct mtk_spi_compatible { 81 82 bool need_pad_sel; ··· 87 80 bool must_tx; 88 81 /* some IC design adjust cfg register to enhance time accuracy */ 89 82 bool enhance_timing; 83 + /* some IC support DMA addr extension */ 84 + bool dma_ext; 90 85 }; 91 86 92 87 struct mtk_spi { ··· 115 106 .need_pad_sel = true, 116 107 .must_tx = true, 117 108 .enhance_timing = true, 109 + .dma_ext = true, 118 110 }; 119 111 120 112 static const struct mtk_spi_compatible mt7622_compat = { ··· 390 380 { 391 381 struct mtk_spi *mdata = spi_master_get_devdata(master); 392 382 393 - if (mdata->tx_sgl) 394 - writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG); 395 - if (mdata->rx_sgl) 396 - writel(xfer->rx_dma, mdata->base + SPI_RX_DST_REG); 383 + if (mdata->tx_sgl) { 384 + writel((u32)(xfer->tx_dma & MTK_SPI_32BITS_MASK), 385 + mdata->base + SPI_TX_SRC_REG); 386 + #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 387 + if (mdata->dev_comp->dma_ext) 388 + writel((u32)(xfer->tx_dma >> 32), 389 + mdata->base + SPI_TX_SRC_REG_64); 390 + #endif 391 + } 392 + 393 + if (mdata->rx_sgl) { 394 + writel((u32)(xfer->rx_dma & MTK_SPI_32BITS_MASK), 395 + mdata->base + SPI_RX_DST_REG); 396 + #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 397 + if (mdata->dev_comp->dma_ext) 398 + writel((u32)(xfer->rx_dma >> 32), 399 + mdata->base + SPI_RX_DST_REG_64); 400 + #endif 401 + } 397 402 } 398 403 399 404 static int mtk_spi_fifo_transfer(struct spi_master *master, ··· 620 595 struct mtk_spi *mdata; 621 596 const struct of_device_id *of_id; 622 597 struct resource *res; 623 - int i, irq, ret; 598 + int i, irq, ret, addr_bits; 624 599 625 600 master = spi_alloc_master(&pdev->dev, sizeof(*mdata)); 626 601 if (!master) { ··· 785 760 } 786 761 } 787 762 } 763 + 764 + if (mdata->dev_comp->dma_ext) 765 + addr_bits = DMA_ADDR_EXT_BITS; 766 + else 767 + addr_bits = DMA_ADDR_DEF_BITS; 768 + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(addr_bits)); 769 + if (ret) 770 + dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n", 771 + addr_bits, ret); 788 772 789 773 return 0; 790 774