diff -drupN a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
--- a/arch/arm/mm/dma-mapping.c	2018-08-06 17:23:04.000000000 +0300
+++ b/arch/arm/mm/dma-mapping.c	2022-06-12 05:28:14.000000000 +0300
@@ -519,7 +519,7 @@ static int __dma_update_pte(pte_t *pte,
 	return 0;
 }
 
-static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
+static void __maybe_unused __dma_remap(struct page *page, size_t size, pgprot_t prot)
 {
 	unsigned long start = (unsigned long) page_address(page);
 	unsigned end = start + size;
@@ -617,8 +617,8 @@ static void *__alloc_from_contiguous(str
 			return NULL;
 		}
 	} else {
-		__dma_remap(page, size, prot);
-		ptr = page_address(page);
+		ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
+						   prot, caller);
 	}
 
  out:
@@ -633,7 +633,7 @@ static void __free_from_contiguous(struc
 		if (PageHighMem(page))
 			__dma_free_remap(cpu_addr, size);
 		else
-			__dma_remap(page, size, PAGE_KERNEL);
+			dma_common_free_remap(cpu_addr, size, VM_USERMAP);
 	}
 	dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 }
@@ -1720,43 +1720,33 @@ static int __map_sg_chunk(struct device
 			  bool is_coherent)
 {
 	struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
-	dma_addr_t iova, iova_base;
+	dma_addr_t iova;
 	int ret = 0;
-	unsigned int count;
-	struct scatterlist *s;
-	int prot;
+	int prot = __dma_direction_to_prot(dir);
 
 	size = PAGE_ALIGN(size);
 	*handle = DMA_ERROR_CODE;
 
-	iova_base = iova = __alloc_iova(mapping, size);
+	iova = __alloc_iova(mapping, size);
 	if (iova == DMA_ERROR_CODE)
 		return -ENOMEM;
 
-	for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
-		phys_addr_t phys = page_to_phys(sg_page(s));
-		unsigned int len = PAGE_ALIGN(s->offset + s->length);
-
-		if (!is_coherent && (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
-			__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
-
-		prot = __dma_direction_to_prot(dir);
-
-		ret = iommu_map(mapping->domain, iova, phys, len, prot);
-		if (ret < 0)
-			goto fail;
-		count += len >> PAGE_SHIFT;
-		iova += len;
+	if (iommu_map_sg(mapping->domain, iova, sg, size, prot) < size) {
+		pr_err("%s, %d, iommu_map_sg failed\n", __func__, __LINE__);
+		ret = -ENOMEM;
+		goto fail;
 	}
-	*handle = iova_base;
+	*handle = iova;
 
 	return 0;
 fail:
-	iommu_unmap(mapping->domain, iova_base, count * PAGE_SIZE);
-	__free_iova(mapping, iova_base, size);
+	__free_iova(mapping, iova, size);
 	return ret;
 }
 
+void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir);
+
 static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 		     enum dma_data_direction dir, unsigned long attrs,
 		     bool is_coherent)
@@ -1767,6 +1757,9 @@ static int __iommu_map_sg(struct device
 	unsigned int size = s->offset + s->length;
 	unsigned int max = dma_get_max_seg_size(dev);
 
+	if (!is_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC))
+		arm_iommu_sync_sg_for_device(dev, sg, nents, dir);
+
 	for (i = 1; i < nents; i++) {
 		s = sg_next(s);
 
@@ -2342,6 +2335,7 @@ static struct dma_map_ops *arm_get_iommu
 	return coherent ? &iommu_coherent_ops : &iommu_ops;
 }
 
+static struct dma_iommu_mapping *sunxi_mapping;
 static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
 				    const struct iommu_ops *iommu)
 {
@@ -2350,12 +2344,16 @@ static bool arm_setup_iommu_dma_ops(stru
 	if (!iommu)
 		return false;
 
-	mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
-	if (IS_ERR(mapping)) {
-		pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
-				size, dev_name(dev));
-		return false;
-	}
+	if (!sunxi_mapping) {
+		mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
+		if (IS_ERR(mapping)) {
+			pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
+					size, dev_name(dev));
+			return false;
+		}
+		sunxi_mapping = mapping;
+	} else
+		mapping = sunxi_mapping;
 
 	if (__arm_iommu_attach_device(dev, mapping)) {
 		pr_warn("Failed to attached device %s to IOMMU_mapping\n",
@@ -2415,3 +2413,4 @@ void arch_teardown_dma_ops(struct device
 {
 	arm_teardown_iommu_dma_ops(dev);
 }
+EXPORT_SYMBOL(v7_dma_flush_range);