From 4ad515d1220a9067833416464338e4c4e494ce3a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 22 Jul 2020 17:59:31 +0100 Subject: [PATCH] bcm2835-dma: Advertise the full DMA range Unless the DMA mask is set wider than 32 bits, DMA mapping will use a bounce buffer. Signed-off-by: Phil Elwell --- drivers/dma/bcm2835-dma.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -41,6 +41,7 @@ #define BCM2711_DMA_MEMCPY_CHAN 14 struct bcm2835_dma_cfg_data { + u64 dma_mask; u32 chan_40bit_mask; }; @@ -300,10 +301,12 @@ DEFINE_SPINLOCK(memcpy_lock); static const struct bcm2835_dma_cfg_data bcm2835_dma_cfg = { .chan_40bit_mask = 0, + .dma_mask = DMA_BIT_MASK(32), }; static const struct bcm2835_dma_cfg_data bcm2711_dma_cfg = { .chan_40bit_mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), + .dma_mask = DMA_BIT_MASK(36), }; static inline size_t bcm2835_dma_max_frame_length(struct bcm2835_chan *c) @@ -1180,6 +1183,8 @@ static struct dma_chan *bcm2835_dma_xlat static int bcm2835_dma_probe(struct platform_device *pdev) { + const struct bcm2835_dma_cfg_data *cfg_data; + const struct of_device_id *of_id; struct bcm2835_dmadev *od; struct resource *res; void __iomem *base; @@ -1189,13 +1194,20 @@ static int bcm2835_dma_probe(struct plat int irq_flags; uint32_t chans_available; char chan_name[BCM2835_DMA_CHAN_NAME_SIZE]; - const struct of_device_id *of_id; int chan_count, chan_start, chan_end; + of_id = of_match_node(bcm2835_dma_of_match, pdev->dev.of_node); + if (!of_id) { + dev_err(&pdev->dev, "Failed to match compatible string\n"); + return -EINVAL; + } + + cfg_data = of_id->data; + if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + rc = dma_set_mask_and_coherent(&pdev->dev, cfg_data->dma_mask); if (rc) { dev_err(&pdev->dev, "Unable to set DMA mask\n"); return rc; @@ -1260,7 +1272,7 @@ static int bcm2835_dma_probe(struct plat return -EINVAL; } - od->cfg_data = of_id->data; + od->cfg_data = cfg_data; /* Request DMA channel mask from device tree */ if (of_property_read_u32(pdev->dev.of_node,