msm-camera: add SMMU code for use with videobuf2 framework
Signed-off-by: Ankit Premrajka <ankitp@codeaurora.org>
Signed-off-by: Mingcheng Zhu <mingchen@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index c7ec849..434f95c 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -23,6 +23,7 @@
#include <mach/board.h>
#include <media/msm_camera.h>
+#include <mach/msm_subsystem_map.h>
#define CONFIG_MSM_CAMERA_DEBUG
#ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -454,6 +455,8 @@
unsigned long len;
struct file *file;
struct msm_pmem_info info;
+ struct msm_mapped_buffer *msm_buffer;
+ int subsys_id;
};
struct axidata {
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index b887f1e..8ce0f40 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -26,6 +26,7 @@
#include <media/v4l2-device.h>
#include <linux/android_pmem.h>
+#include <mach/msm_subsystem_map.h>
#include "msm.h"
#include "msm_vfe31.h"
@@ -128,6 +129,7 @@
{
struct file *file;
unsigned long paddr;
+ unsigned int flags;
#ifdef CONFIG_ANDROID_PMEM
unsigned long kvstart;
int rc;
@@ -167,8 +169,17 @@
return -ENOMEM;
INIT_HLIST_NODE(®ion->list);
-
- region->paddr = paddr;
+ flags = MSM_SUBSYSTEM_MAP_IOVA;
+ region->subsys_id = MSM_SUBSYSTEM_CAMERA;
+ region->msm_buffer = msm_subsystem_map_buffer(paddr, len,
+ flags, &(region->subsys_id), 1);
+ if (IS_ERR((void *)region->msm_buffer)) {
+ pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+ kfree(region);
+ put_pmem_file(file);
+ return PTR_ERR((void *)region->msm_buffer);
+ }
+ region->paddr = region->msm_buffer->iova[0];
region->len = len;
region->file = file;
memcpy(®ion->info, info, sizeof(region->info));
@@ -221,6 +232,11 @@
if (pinfo->type == region->info.type &&
pinfo->vaddr == region->info.vaddr &&
pinfo->fd == region->info.fd) {
+ if (msm_subsystem_unmap_buffer
+ (region->msm_buffer) < 0)
+ pr_err(
+ "%s: unmapped stat memory\n",
+ __func__);
hlist_del(node);
#ifdef CONFIG_ANDROID_PMEM
put_pmem_file(region->file);
@@ -316,7 +332,7 @@
pr_err("%s mem is null. Return ", __func__);
break;
}
- reg->paddr = mem->phyaddr;
+ reg->paddr = mem->msm_buffer->iova[0];
D("%s paddr for buf %d is 0x%p\n", __func__,
i,
(void *)reg->paddr);
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 13fbd1f..3b460ef 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -29,7 +29,7 @@
#include <media/videobuf2-msm-mem.h>
#include <media/msm_camera.h>
#include <mach/memory.h>
-
+#include <mach/msm_subsystem_map.h>
#include <media/videobuf2-core.h>
#define MAGIC_PMEM 0x0733ac64
@@ -82,6 +82,8 @@
static void *msm_vb2_mem_ops_alloc(void *alloc_ctx, unsigned long size)
{
struct videobuf2_contig_pmem *mem;
+ unsigned int flags = 0;
+ long rc;
mem = kzalloc(sizeof(*mem), GFP_KERNEL);
if (!mem)
return ERR_PTR(-ENOMEM);
@@ -96,13 +98,28 @@
kfree(mem);
return ERR_PTR(-ENOMEM);
}
+ flags = MSM_SUBSYSTEM_MAP_IOVA;
+ mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
+ mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, mem->size,
+ flags, &(mem->subsys_id), 1);
+ if (IS_ERR((void *)mem->msm_buffer)) {
+ pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+ rc = PTR_ERR((void *)mem->msm_buffer);
+ msm_mem_free(mem->phyaddr);
+ kfree(mem);
+ return ERR_PTR(-ENOMEM);
+ }
return mem;
}
static void msm_vb2_mem_ops_put(void *buf_priv)
{
struct videobuf2_contig_pmem *mem = buf_priv;
- if (!mem->is_userptr)
+ if (!mem->is_userptr) {
+ D("%s Freeing memory ", __func__);
+ if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
+ D("%s unmapped memory\n", __func__);
msm_mem_free(mem->phyaddr);
+ }
kfree(mem);
}
int videobuf2_pmem_contig_mmap_get(struct videobuf2_contig_pmem *mem,
@@ -133,6 +150,7 @@
unsigned long kvstart;
unsigned long len;
int rc;
+ unsigned int flags = 0;
if (mem->phyaddr != 0)
return 0;
@@ -148,12 +166,23 @@
mem->y_off = yoffset;
mem->cbcr_off = cbcroffset;
mem->buffer_type = path;
+ flags = MSM_SUBSYSTEM_MAP_IOVA;
+ mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
+ mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, mem->size,
+ flags, &(mem->subsys_id), 1);
+ if (IS_ERR((void *)mem->msm_buffer)) {
+ pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+ put_pmem_file(mem->file);
+ return PTR_ERR((void *)mem->msm_buffer);
+ }
return rc;
}
EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem)
{
+ if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
+ D("%s unmapped memory\n", __func__);
if (mem->is_userptr)
put_pmem_file(mem->file);
mem->is_userptr = 0;
@@ -206,7 +235,6 @@
D("mem = 0x%x\n", (u32)mem);
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_PMEM);
-
/* Try to remap memory */
size = vma->vm_end - vma->vm_start;
size = (size < mem->size) ? size : mem->size;
@@ -261,13 +289,14 @@
}
EXPORT_SYMBOL_GPL(videobuf2_queue_pmem_contig_init);
-int videobuf2_to_pmem_contig(struct vb2_buffer *vb, unsigned int plane_no)
+unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *vb,
+ unsigned int plane_no)
{
struct videobuf2_contig_pmem *mem;
mem = vb2_plane_cookie(vb, plane_no);
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_PMEM);
- return mem->phyaddr;
+ return mem->msm_buffer->iova[0];
}
EXPORT_SYMBOL_GPL(videobuf2_to_pmem_contig);
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 047d20f..24eaf13 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -16,6 +16,7 @@
#define _VIDEOBUF2_PMEM_CONTIG_H
#include <media/videobuf2-core.h>
+#include <mach/msm_subsystem_map.h>
struct videobuf2_mapping {
unsigned int count;
@@ -35,6 +36,8 @@
int dirty;
unsigned int count;
void *alloc_ctx;
+ struct msm_mapped_buffer *msm_buffer;
+ int subsys_id;
};
void videobuf2_queue_pmem_contig_init(struct vb2_queue *q,
enum v4l2_buf_type type,
@@ -48,6 +51,7 @@
uint32_t yoffset, uint32_t cbcroffset,
uint32_t addr_offset, int path);
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem);
-int videobuf2_to_pmem_contig(struct vb2_buffer *buf, unsigned int plane_no);
+unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *buf,
+ unsigned int plane_no);
#endif /* _VIDEOBUF2_PMEM_CONTIG_H */