Unverified Commit fdeae8f5 authored by luhua.xu's avatar luhua.xu Committed by Mark Brown
Browse files

spi: mediatek: support large PA



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

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


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2c231e0a
Loading
Loading
Loading
Loading
+39 −5
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/platform_data/spi-mt65xx.h>
#include <linux/platform_data/spi-mt65xx.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <linux/dma-mapping.h>


#define SPI_CFG0_REG                      0x0000
#define SPI_CFG0_REG                      0x0000
#define SPI_CFG1_REG                      0x0004
#define SPI_CFG1_REG                      0x0004
@@ -28,6 +29,8 @@
#define SPI_STATUS0_REG                   0x001c
#define SPI_STATUS0_REG                   0x001c
#define SPI_PAD_SEL_REG                   0x0024
#define SPI_PAD_SEL_REG                   0x0024
#define SPI_CFG2_REG                      0x0028
#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_HIGH_OFFSET          0
#define SPI_CFG0_SCK_LOW_OFFSET           8
#define SPI_CFG0_SCK_LOW_OFFSET           8
@@ -73,6 +76,10 @@


#define MTK_SPI_MAX_FIFO_SIZE 32U
#define MTK_SPI_MAX_FIFO_SIZE 32U
#define MTK_SPI_PACKET_SIZE 1024
#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 {
struct mtk_spi_compatible {
	bool need_pad_sel;
	bool need_pad_sel;
@@ -80,6 +87,8 @@ struct mtk_spi_compatible {
	bool must_tx;
	bool must_tx;
	/* some IC design adjust cfg register to enhance time accuracy */
	/* some IC design adjust cfg register to enhance time accuracy */
	bool enhance_timing;
	bool enhance_timing;
	/* some IC support DMA addr extension */
	bool dma_ext;
};
};


struct mtk_spi {
struct mtk_spi {
@@ -106,6 +115,7 @@ static const struct mtk_spi_compatible mt6765_compat = {
	.need_pad_sel = true,
	.need_pad_sel = true,
	.must_tx = true,
	.must_tx = true,
	.enhance_timing = true,
	.enhance_timing = true,
	.dma_ext = true,
};
};


static const struct mtk_spi_compatible mt7622_compat = {
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);
	struct mtk_spi *mdata = spi_master_get_devdata(master);


	if (mdata->tx_sgl)
	if (mdata->tx_sgl) {
		writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG);
		writel((u32)(xfer->tx_dma & MTK_SPI_32BITS_MASK),
	if (mdata->rx_sgl)
		       mdata->base + SPI_TX_SRC_REG);
		writel(xfer->rx_dma, mdata->base + SPI_RX_DST_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,
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;
	struct mtk_spi *mdata;
	const struct of_device_id *of_id;
	const struct of_device_id *of_id;
	struct resource *res;
	struct resource *res;
	int i, irq, ret;
	int i, irq, ret, addr_bits;


	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
	if (!master) {
	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;
	return 0;


err_disable_runtime_pm:
err_disable_runtime_pm: