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:
Родитель
a1daaa991e
Коммит
e836d4cf61
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче