[COMMON] iommu/exynos: add iova_to_phys
authorJanghyuck Kim <janghyuck.kim@samsung.com>
Sat, 7 May 2016 06:45:32 +0000 (15:45 +0900)
committerSangwook Ju <sw.ju@samsung.com>
Mon, 14 May 2018 10:45:19 +0000 (19:45 +0900)
iova_to_phys() is implemented to return physical address from iova.

Change-Id: I0e0d0f91231889efadb10a18b1e07d60b01ce1dc
Signed-off-by: Janghyuck Kim <janghyuck.kim@samsung.com>
drivers/iommu/exynos-iommu.c

index 13109cea161b5a56c3343412d453283ff59adf2e..e69b0cb63bcc54798f876134eb022f51c7f481e9 100644 (file)
@@ -971,7 +971,25 @@ err:
 static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *iommu_domain,
                                          dma_addr_t d_iova)
 {
-       return 0;
+       struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
+       sysmmu_iova_t iova = (sysmmu_iova_t)d_iova;
+       sysmmu_pte_t *entry;
+       phys_addr_t phys = 0;
+
+       entry = section_entry(domain->pgtable, iova);
+
+       if (lv1ent_section(entry)) {
+               phys = section_phys(entry) + section_offs(iova);
+       } else if (lv1ent_page(entry)) {
+               entry = page_entry(entry, iova);
+
+               if (lv2ent_large(entry))
+                       phys = lpage_phys(entry) + lpage_offs(iova);
+               else if (lv2ent_small(entry))
+                       phys = spage_phys(entry) + spage_offs(iova);
+       }
+
+       return phys;
 }
 
 static int exynos_iommu_of_xlate(struct device *master,