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: Ikjoon Jang <ikjn@chromium.org>
Link: https://lore.kernel.org/r/20201006155010.v5.3.Id1cb208392928afc7ceed4de06924243c7858cd0@changeid
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Ikjoon Jang 2020-10-06 15:54:04 +08:00 коммит произвёл Mark Brown
Родитель a1daaa991e
Коммит e836d4cf61
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 24D68B725D5487D0
1 изменённых файлов: 20 добавлений и 1 удалений

Просмотреть файл

@ -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);