msm_fb: display: Add IOMMU support to MDP and rotator driver

Add IOMMU support to MDP and rotator driver for operating with
virtual addresses instead of physical addresses

Change-Id: Ia5afcf33220e0e75e92948649c2bd4d7ef32917d
Signed-off-by: Ravishangar Kalyanam <rkalya@codeaurora.org>
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 3d9c9d1..59013e3 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -33,6 +33,8 @@
 #include <mach/msm_bus.h>
 #include <mach/msm_bus_board.h>
 #endif
+#include <mach/msm_subsystem_map.h>
+#include <mach/iommu_domains.h>
 
 #define DRIVER_NAME "msm_rotator"
 
@@ -146,6 +148,33 @@
 	CLK_SUSPEND,
 };
 
+int msm_rotator_iommu_map_buf(int mem_id, unsigned char src,
+	unsigned long *start, unsigned long *len,
+	struct ion_handle **pihdl)
+{
+	if (!msm_rotator_dev->client)
+		return -EINVAL;
+
+	*pihdl = ion_import_fd(msm_rotator_dev->client, mem_id);
+	if (IS_ERR_OR_NULL(*pihdl)) {
+		pr_err("ion_import_fd() failed\n");
+		return PTR_ERR(*pihdl);
+	}
+	pr_debug("%s(): ion_hdl %p, ion_buf %p\n", __func__, *pihdl,
+		ion_share(msm_rotator_dev->client, *pihdl));
+
+	if (ion_map_iommu(msm_rotator_dev->client,
+		*pihdl,	ROTATOR_DOMAIN, GEN_POOL,
+		SZ_4K, 0, start, len, 0, ION_IOMMU_UNMAP_DELAYED)) {
+		pr_err("ion_map_iommu() failed\n");
+		return -EINVAL;
+	}
+
+	pr_debug("%s(): mem_id %d, start 0x%lx, len 0x%lx\n",
+		__func__, mem_id, *start, *len);
+	return 0;
+}
+
 int msm_rotator_imem_allocate(int requestor)
 {
 	int rc = 0;
@@ -748,9 +777,9 @@
 	return 0;
 }
 
-static int get_img(struct msmfb_data *fbd, unsigned long *start,
-	unsigned long *len, struct file **p_file, int *p_need,
-	struct ion_handle **p_ihdl)
+static int get_img(struct msmfb_data *fbd, unsigned char src,
+	unsigned long *start, unsigned long *len, struct file **p_file,
+	int *p_need, struct ion_handle **p_ihdl)
 {
 	int ret = 0;
 #ifdef CONFIG_FB
@@ -766,19 +795,25 @@
 #ifdef CONFIG_FB
 	if (fbd->flags & MDP_MEMORY_ID_TYPE_FB) {
 		file = fget_light(fbd->memory_id, &put_needed);
-		if (file == NULL)
+		if (file == NULL) {
+			pr_err("fget_light returned NULL\n");
 			return -EINVAL;
+		}
 
 		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
 			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
-			if (get_fb_phys_info(start, len, fb_num))
+			if (get_fb_phys_info(start, len, fb_num,
+				ROTATOR_SUBSYSTEM_ID)) {
+				pr_err("get_fb_phys_info() failed\n");
 				ret = -1;
-			else {
+			} else {
 				*p_file = file;
 				*p_need = put_needed;
 			}
-		} else
+		} else {
+			pr_err("invalid FB_MAJOR failed\n");
 			ret = -1;
+		}
 		if (ret)
 			fput_light(file, put_needed);
 		return ret;
@@ -786,15 +821,8 @@
 #endif
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	*p_ihdl = ion_import_fd(msm_rotator_dev->client,
-		fbd->memory_id);
-	if (IS_ERR_OR_NULL(*p_ihdl))
-		return PTR_ERR(*p_ihdl);
-	if (!ion_phys(msm_rotator_dev->client, *p_ihdl, start,
-		(size_t *) len))
-		return 0;
-	else
-		return -ENOMEM;
+	return msm_rotator_iommu_map_buf(fbd->memory_id, src, start,
+		len, p_ihdl);
 #endif
 #ifdef CONFIG_ANDROID_PMEM
 	if (!get_pmem_file(fbd->memory_id, start, &vstart, len, p_file))
@@ -812,8 +840,13 @@
 		put_pmem_file(p_file);
 #endif
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	if (!IS_ERR_OR_NULL(p_ihdl))
+	if (!IS_ERR_OR_NULL(p_ihdl)) {
+		pr_debug("%s(): p_ihdl %p\n", __func__, p_ihdl);
+		ion_unmap_iommu(msm_rotator_dev->client,
+			p_ihdl, ROTATOR_DOMAIN, GEN_POOL);
+
 		ion_free(msm_rotator_dev->client, p_ihdl);
+	}
 #endif
 }
 static int msm_rotator_do_rotate(unsigned long arg)
@@ -878,17 +911,18 @@
 		goto do_rotate_unlock_mutex;
 	}
 
-
-	rc = get_img(&info.src, (unsigned long *)&in_paddr,
-		(unsigned long *)&src_len, &srcp0_file, &ps0_need, &srcp0_ihdl);
+	rc = get_img(&info.src, 1, (unsigned long *)&in_paddr,
+			(unsigned long *)&src_len, &srcp0_file, &ps0_need,
+			&srcp0_ihdl);
 	if (rc) {
 		pr_err("%s: in get_img() failed id=0x%08x\n",
 			DRIVER_NAME, info.src.memory_id);
 		goto do_rotate_unlock_mutex;
 	}
 
-	rc = get_img(&info.dst, (unsigned long *)&out_paddr,
-		(unsigned long *)&dst_len, &dstp0_file, &p_need, &dstp0_ihdl);
+	rc = get_img(&info.dst, 0, (unsigned long *)&out_paddr,
+			(unsigned long *)&dst_len, &dstp0_file, &p_need,
+			&dstp0_ihdl);
 	if (rc) {
 		pr_err("%s: out get_img() failed id=0x%08x\n",
 		       DRIVER_NAME, info.dst.memory_id);
@@ -916,7 +950,7 @@
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(&info.src_chroma,
+		rc = get_img(&info.src_chroma, 1,
 				(unsigned long *)&in_chroma_paddr,
 				(unsigned long *)&src_len, &srcp1_file, &p_need,
 				&srcp1_ihdl);
@@ -926,7 +960,7 @@
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(&info.dst_chroma,
+		rc = get_img(&info.dst_chroma, 0,
 				(unsigned long *)&out_chroma_paddr,
 				(unsigned long *)&dst_len, &dstp1_file, &p_need,
 				&dstp1_ihdl);
@@ -1514,7 +1548,8 @@
 		clk_disable(msm_rotator_dev->imem_clk);
 #endif
 	if (ver != pdata->hardware_version_number)
-		pr_info("%s: invalid HW version\n", DRIVER_NAME);
+		pr_info("%s: invalid HW version ver 0x%x\n",
+			DRIVER_NAME, ver);
 
 	msm_rotator_dev->irq = platform_get_irq(pdev, 0);
 	if (msm_rotator_dev->irq < 0) {