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>
This commit is contained in:
Родитель
2c231e0ab6
Коммит
fdeae8f5a2
|
@ -17,6 +17,7 @@
|
|||
#include <linux/platform_data/spi-mt65xx.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#define SPI_CFG0_REG 0x0000
|
||||
#define SPI_CFG1_REG 0x0004
|
||||
|
@ -28,6 +29,8 @@
|
|||
#define SPI_STATUS0_REG 0x001c
|
||||
#define SPI_PAD_SEL_REG 0x0024
|
||||
#define SPI_CFG2_REG 0x0028
|
||||
#define SPI_TX_SRC_REG_64 0x002c
|
||||
#define SPI_RX_DST_REG_64 0x0030
|
||||
|
||||
#define SPI_CFG0_SCK_HIGH_OFFSET 0
|
||||
#define SPI_CFG0_SCK_LOW_OFFSET 8
|
||||
|
@ -73,6 +76,10 @@
|
|||
|
||||
#define MTK_SPI_MAX_FIFO_SIZE 32U
|
||||
#define MTK_SPI_PACKET_SIZE 1024
|
||||
#define MTK_SPI_32BITS_MASK (0xffffffff)
|
||||
|
||||
#define DMA_ADDR_EXT_BITS (36)
|
||||
#define DMA_ADDR_DEF_BITS (32)
|
||||
|
||||
struct mtk_spi_compatible {
|
||||
bool need_pad_sel;
|
||||
|
@ -80,6 +87,8 @@ struct mtk_spi_compatible {
|
|||
bool must_tx;
|
||||
/* some IC design adjust cfg register to enhance time accuracy */
|
||||
bool enhance_timing;
|
||||
/* some IC support DMA addr extension */
|
||||
bool dma_ext;
|
||||
};
|
||||
|
||||
struct mtk_spi {
|
||||
|
@ -106,6 +115,7 @@ static const struct mtk_spi_compatible mt6765_compat = {
|
|||
.need_pad_sel = true,
|
||||
.must_tx = true,
|
||||
.enhance_timing = true,
|
||||
.dma_ext = true,
|
||||
};
|
||||
|
||||
static const struct mtk_spi_compatible mt7622_compat = {
|
||||
|
@ -380,10 +390,25 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
|
|||
{
|
||||
struct mtk_spi *mdata = spi_master_get_devdata(master);
|
||||
|
||||
if (mdata->tx_sgl)
|
||||
writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG);
|
||||
if (mdata->rx_sgl)
|
||||
writel(xfer->rx_dma, mdata->base + SPI_RX_DST_REG);
|
||||
if (mdata->tx_sgl) {
|
||||
writel((u32)(xfer->tx_dma & MTK_SPI_32BITS_MASK),
|
||||
mdata->base + SPI_TX_SRC_REG);
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
if (mdata->dev_comp->dma_ext)
|
||||
writel((u32)(xfer->tx_dma >> 32),
|
||||
mdata->base + SPI_TX_SRC_REG_64);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mdata->rx_sgl) {
|
||||
writel((u32)(xfer->rx_dma & MTK_SPI_32BITS_MASK),
|
||||
mdata->base + SPI_RX_DST_REG);
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
if (mdata->dev_comp->dma_ext)
|
||||
writel((u32)(xfer->rx_dma >> 32),
|
||||
mdata->base + SPI_RX_DST_REG_64);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int mtk_spi_fifo_transfer(struct spi_master *master,
|
||||
|
@ -595,7 +620,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
|||
struct mtk_spi *mdata;
|
||||
const struct of_device_id *of_id;
|
||||
struct resource *res;
|
||||
int i, irq, ret;
|
||||
int i, irq, ret, addr_bits;
|
||||
|
||||
master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
|
||||
if (!master) {
|
||||
|
@ -761,6 +786,15 @@ static int mtk_spi_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
if (mdata->dev_comp->dma_ext)
|
||||
addr_bits = DMA_ADDR_EXT_BITS;
|
||||
else
|
||||
addr_bits = DMA_ADDR_DEF_BITS;
|
||||
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(addr_bits));
|
||||
if (ret)
|
||||
dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n",
|
||||
addr_bits, ret);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_runtime_pm:
|
||||
|
|
Загрузка…
Ссылка в новой задаче