From 1953b8289b51b1ebc42e8511a6b7b12de7142c1e Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Tue, 14 May 2019 16:28:15 +0800 Subject: [PATCH] MLK-15064-2 ARM64: DMA: limit the dma mask to be 32bit Limit the dma mask to be 32bit, because that the imx8 doesn't have the 64bit dma capapbility although it is 64bit soc. Signed-off-by: Richard Zhu Reviewed-by: Frank Li --- arch/arm64/mm/dma-mapping.c | 45 +++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index c389f2bef938..9f0452ad2029 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -328,7 +329,19 @@ static int __swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t addr) return 0; } -static const struct dma_map_ops arm64_swiotlb_dma_ops = { +static int __swiotlb_dma_supported_quirk(struct device *hwdev, u64 mask) +{ + if (mask > DMA_BIT_MASK(32)) { + pr_err("Can't support > 32 bit dma.\n"); + return 0; + } + + if (swiotlb) + return swiotlb_dma_supported(hwdev, mask); + return 1; +} + +static struct dma_map_ops arm64_swiotlb_dma_ops = { .alloc = __dma_alloc, .free = __dma_free, .mmap = __swiotlb_mmap, @@ -807,7 +820,7 @@ static void __iommu_unmap_sg_attrs(struct device *dev, iommu_dma_unmap_sg(dev, sgl, nelems, dir, attrs); } -static const struct dma_map_ops iommu_dma_ops = { +static struct dma_map_ops iommu_dma_ops = { .alloc = __iommu_alloc_attrs, .free = __iommu_free_attrs, .mmap = __iommu_mmap_attrs, @@ -867,6 +880,15 @@ void arch_teardown_dma_ops(struct device *dev) dev->dma_ops = NULL; } +static int iommu_dma_supported_quirk(struct device *dev, u64 mask) +{ + if (mask > DMA_BIT_MASK(32)) { + pr_err("Can't support > 32 bit dma.\n"); + return 0; + } + + return 1; +} #else static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, @@ -875,9 +897,16 @@ static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, #endif /* CONFIG_IOMMU_DMA */ +/* + * Some 64bit SoCs only support up to 32bit dma capability. + * Do quirk set here. + */ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, const struct iommu_ops *iommu, bool coherent) { + u32 mask32; + struct device_node *np; + if (!dev->dma_ops) dev->dma_ops = &arm64_swiotlb_dma_ops; @@ -890,4 +919,16 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, dev->dma_ops = xen_dma_ops; } #endif + + np = of_find_compatible_node(NULL, NULL, "dma-capability"); + if (np == NULL) + return; + if (of_property_read_u32(np, "only-dma-mask32", &mask32)) + mask32 = 0; + if (mask32) { + arm64_swiotlb_dma_ops.dma_supported = __swiotlb_dma_supported_quirk; +#ifdef CONFIG_IOMMU_DMA + iommu_dma_ops.dma_supported = iommu_dma_supported_quirk; +#endif + } } -- 2.17.1