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) {