camera: Store the data offsets for each planes.
- When the user queues a buffer, store the data offset
along with the address offset which is already stored.
data offset indicates the offset of the data in the
buffer.
- Use this offset when the physical address of the
buffer is configured to VFE.
- Depending on the number of planes present in the
buffer, store either the y, cbr offset or the
offset of each plane.
Signed-off-by: Kiran Kumar H N <hurlisal@codeaurora.org>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index e3b97c9..2f83234 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -770,25 +770,26 @@
}
if (!pb->count) {
/* Deallocation. free buf_offset array */
- D("%s freeing buf_offset information ", __func__);
+ D("%s freeing buffer offsets array ", __func__);
for (j = 0 ; j < pcam_inst->buf_count ; j++)
kfree(pcam_inst->buf_offset[j]);
kfree(pcam_inst->buf_offset);
} else {
/* Allocation. allocate buf_offset array */
- pcam_inst->buf_offset = (uint32_t **)
- kzalloc(pb->count * sizeof(uint32_t *),
+ pcam_inst->buf_offset = (struct msm_cam_buf_offset **)
+ kzalloc(pb->count * sizeof(struct msm_cam_buf_offset *),
GFP_KERNEL);
if (!pcam_inst->buf_offset) {
pr_err("%s out of memory ", __func__);
return -ENOMEM;
}
for (i = 0; i < pb->count; i++) {
- pcam_inst->buf_offset[i] = kzalloc(sizeof(uint32_t) *
+ pcam_inst->buf_offset[i] =
+ kzalloc(sizeof(struct msm_cam_buf_offset) *
pcam_inst->plane_info.num_planes, GFP_KERNEL);
if (!pcam_inst->buf_offset[i]) {
pr_err("%s out of memory ", __func__);
- for (j = i ; j >= 0; j--)
+ for (j = i-1 ; j >= 0; j--)
kfree(pcam_inst->buf_offset[j]);
kfree(pcam_inst->buf_offset);
return -ENOMEM;
@@ -825,14 +826,18 @@
WARN_ON(pctx != f->private_data);
if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
- D("%s storing buf_offset for plane %d as %d",
- __func__, i, pb->m.planes[i].reserved[0]);
- pcam_inst->buf_offset[pb->index][i] =
+ D("%s stored offsets for plane %d as"
+ "addr offset %d, data offset %d",
+ __func__, i, pb->m.planes[i].reserved[0],
+ pb->m.planes[i].data_offset);
+ pcam_inst->buf_offset[pb->index][i].data_offset =
+ pb->m.planes[i].data_offset;
+ pcam_inst->buf_offset[pb->index][i].addr_offset =
pb->m.planes[i].reserved[0];
}
} else {
D("%s stored reserved info %d", __func__, pb->reserved);
- pcam_inst->buf_offset[pb->index][0] = pb->reserved;
+ pcam_inst->buf_offset[pb->index][0].addr_offset = pb->reserved;
}
rc = vb2_qbuf(&pcam_inst->vid_bufq, pb);
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 001ca4b..01ca3e0 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -240,6 +240,10 @@
unsigned long buffer;
int fd;
};
+struct msm_cam_buf_offset {
+ uint32_t addr_offset;
+ uint32_t data_offset;
+};
#define MSM_DEV_INST_MAX 16
struct msm_cam_v4l2_dev_inst {
@@ -255,8 +259,8 @@
int image_mode;
int path;
int buf_count;
- /* buffer offset, if any */
- uint32_t **buf_offset;
+ /* buffer offsets, if any */
+ struct msm_cam_buf_offset **buf_offset;
struct v4l2_crop crop;
int streamon;
struct msm_mem_map_info mem_map;
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 617c8b4..a83fa00 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -77,9 +77,11 @@
struct msm_cam_v4l2_device *pcam;
struct videobuf2_contig_pmem *mem;
struct vb2_queue *vq;
- uint32_t offset;
+ uint32_t buf_idx;
struct msm_frame_buffer *buf;
int rc = 0, i;
+ enum videobuf2_buffer_type buf_type;
+ struct videobuf2_msm_offset offset;
vq = vb->vb2_queue;
pcam_inst = vb2_get_drv_priv(vq);
pcam = pcam_inst->pcam;
@@ -95,17 +97,28 @@
if (buf->state == MSM_BUFFER_STATE_INITIALIZED)
return rc;
+ buf_type = (vb->num_planes == 1) ? VIDEOBUF2_SINGLE_PLANE
+ : VIDEOBUF2_MULTIPLE_PLANES;
+ if (buf_type == VIDEOBUF2_SINGLE_PLANE) {
+ offset.sp_off.y_off = 0;
+ offset.sp_off.cbcr_off =
+ pcam_inst->plane_info.plane[0].offset;
+ }
+ buf_idx = vb->v4l2_buf.index;
for (i = 0; i < vb->num_planes; i++) {
mem = vb2_plane_cookie(vb, i);
- offset = pcam_inst->plane_info.plane[i].offset;
+ if (buf_type == VIDEOBUF2_MULTIPLE_PLANES)
+ offset.data_offset =
+ pcam_inst->plane_info.plane[i].offset;
if (vb->v4l2_buf.memory == V4L2_MEMORY_USERPTR)
- rc = videobuf2_pmem_contig_user_get(mem, offset,
- pcam_inst->buf_offset[vb->v4l2_buf.index][i],
+ rc = videobuf2_pmem_contig_user_get(mem, &offset,
+ buf_type,
+ pcam_inst->buf_offset[buf_idx][i].addr_offset,
pcam_inst->path);
else
- rc = videobuf2_pmem_contig_mmap_get(mem, offset,
- pcam_inst->path);
+ rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
+ buf_type, pcam_inst->path);
if (rc < 0) {
pr_err("%s error initializing buffer ",
__func__);
@@ -393,13 +406,23 @@
struct msm_frame_buffer *buf = NULL, *tmp;
uint32_t buf_phyaddr = 0;
unsigned long flags = 0;
+ uint32_t buf_idx, offset = 0;
+ struct videobuf2_contig_pmem *mem;
/* we actually need a list, not a queue */
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
list_for_each_entry_safe(buf, tmp,
&pcam_inst->free_vq, list) {
+ buf_idx = buf->vidbuf.v4l2_buf.index;
+ mem = vb2_plane_cookie(&buf->vidbuf, 0);
+ if (mem->buffer_type == VIDEOBUF2_MULTIPLE_PLANES)
+ offset = mem->offset.data_offset +
+ pcam_inst->buf_offset[buf_idx][0].data_offset;
+ else
+ offset = mem->offset.sp_off.y_off;
buf_phyaddr = (unsigned long)
- videobuf2_to_pmem_contig(&buf->vidbuf, 0);
+ videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
+ offset;
D("%s vb_idx=%d,vb_paddr=0x%x ch0=0x%x\n",
__func__, buf->vidbuf.v4l2_buf.index,
buf_phyaddr, fbuf->ch_paddr[0]);
@@ -483,6 +506,7 @@
struct videobuf2_contig_pmem *mem;
struct msm_frame_buffer *buf = NULL;
int rc = -EINVAL, idx, i;
+ uint32_t buf_idx, plane_offset = 0;
if (!free_buf) {
pr_err("%s: free_buf= null\n", __func__);
@@ -498,33 +522,45 @@
}
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
list_for_each_entry(buf, &pcam_inst->free_vq, list) {
- if (buf->state == MSM_BUFFER_STATE_QUEUED) {
- if (pcam_inst->vid_fmt.type ==
+ if (buf->state != MSM_BUFFER_STATE_QUEUED)
+ continue;
+
+ buf_idx = buf->vidbuf.v4l2_buf.index;
+ if (pcam_inst->vid_fmt.type ==
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- free_buf->num_planes =
- pcam_inst->plane_info.num_planes;
- for (i = 0; i < free_buf->num_planes; i++)
- free_buf->ch_paddr[i] = (uint32_t)
- videobuf2_to_pmem_contig(
- &buf->vidbuf, i);
- } else {
- mem = vb2_plane_cookie(&buf->vidbuf, 0);
- free_buf->ch_paddr[0] = (uint32_t)
- videobuf2_to_pmem_contig(&buf->vidbuf, 0);
- free_buf->ch_paddr[1] =
- free_buf->ch_paddr[0] + mem->offset;
+ free_buf->num_planes =
+ pcam_inst->plane_info.num_planes;
+ for (i = 0; i < free_buf->num_planes; i++) {
+ mem = vb2_plane_cookie(&buf->vidbuf, i);
+ if (mem->buffer_type ==
+ VIDEOBUF2_MULTIPLE_PLANES)
+ plane_offset =
+ mem->offset.data_offset;
+ else
+ plane_offset =
+ mem->offset.sp_off.cbcr_off;
+
+ free_buf->ch_paddr[i] = (uint32_t)
+ videobuf2_to_pmem_contig(&buf->vidbuf, i) +
+ pcam_inst->buf_offset[buf_idx][i].data_offset +
+ plane_offset;
}
- free_buf->vb = (uint32_t)buf;
- buf->state = MSM_BUFFER_STATE_RESERVED;
- D("%s idx=%d,inst=0x%p,idx=%d,paddr=0x%x, "
- "ch1 addr=0x%x\n", __func__,
- idx, pcam_inst,
- buf->vidbuf.v4l2_buf.index,
- free_buf->ch_paddr[0],
- free_buf->ch_paddr[1]);
- rc = 0;
- break;
+ } else {
+ mem = vb2_plane_cookie(&buf->vidbuf, 0);
+ free_buf->ch_paddr[0] = (uint32_t)
+ videobuf2_to_pmem_contig(&buf->vidbuf, 0) +
+ mem->offset.sp_off.y_off;
+ free_buf->ch_paddr[1] = free_buf->ch_paddr[0] +
+ mem->offset.sp_off.cbcr_off;
}
+ free_buf->vb = (uint32_t)buf;
+ buf->state = MSM_BUFFER_STATE_RESERVED;
+ D("%s idx=%d,inst=0x%p,idx=%d,paddr=0x%x, "
+ "ch1 addr=0x%x\n", __func__,
+ idx, pcam_inst, buf->vidbuf.v4l2_buf.index,
+ free_buf->ch_paddr[0], free_buf->ch_paddr[1]);
+ rc = 0;
+ break;
}
if (rc != 0)
D("%s:No free buffer available: inst = 0x%p ",
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index 167e721..f0c1bfa 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -134,7 +134,7 @@
videobuf2_to_pmem_contig(&vb->vidbuf, 0);
div.phy_offset = mem->addr_offset;
div.y_off = 0;
- div.cbcr_off = mem->offset;
+ div.cbcr_off = mem->offset.sp_off.cbcr_off;
div.fd = (int)mem->vaddr;
div.vb = (uint32_t)vb;
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
@@ -142,7 +142,7 @@
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
div.frame_id =
p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
- div.path = mem->buffer_type;
+ div.path = mem->path;
div.length = mem->size;
msm_mctl_gettimeofday(&div.timestamp);
vb->vidbuf.v4l2_buf.timestamp = div.timestamp;
@@ -167,14 +167,14 @@
memset(pp_frame, 0, sizeof(struct msm_pp_frame));
pp_frame->handle = (uint32_t)vb;
pp_frame->frame_id = vb->vidbuf.v4l2_buf.sequence;
- pp_frame->image_type = (unsigned short)mem->buffer_type;
+ pp_frame->image_type = (unsigned short)mem->path;
pp_frame->timestamp = vb->vidbuf.v4l2_buf.timestamp;
/* hard coded for now. Will need to expand to MP case */
pp_frame->num_planes = 1;
pp_frame->sp.addr_offset = mem->addr_offset;
pp_frame->sp.phy_addr = videobuf2_to_pmem_contig(&vb->vidbuf, 0);
pp_frame->sp.y_off = 0;
- pp_frame->sp.cbcr_off = mem->offset;
+ pp_frame->sp.cbcr_off = mem->offset.sp_off.cbcr_off;
pp_frame->sp.length = mem->size;
pp_frame->sp.fd = (int)mem->vaddr;
return 0;
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index 74debe1..d765244 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -124,10 +124,16 @@
kfree(mem);
}
int videobuf2_pmem_contig_mmap_get(struct videobuf2_contig_pmem *mem,
- uint32_t offset, int path)
+ struct videobuf2_msm_offset *offset,
+ enum videobuf2_buffer_type buffer_type,
+ int path)
{
- mem->offset = offset;
- mem->buffer_type = path;
+ if (offset)
+ mem->offset = *offset;
+ else
+ memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
+ mem->buffer_type = buffer_type;
+ mem->path = path;
return 0;
}
EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_mmap_get);
@@ -143,7 +149,8 @@
* Returns 0 if successful.
*/
int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
- uint32_t offset,
+ struct videobuf2_msm_offset *offset,
+ enum videobuf2_buffer_type buffer_type,
uint32_t addr_offset, int path)
{
unsigned long kvstart;
@@ -161,8 +168,12 @@
__func__, (int)mem->vaddr, rc);
return rc;
}
- mem->offset = offset;
- mem->buffer_type = path;
+ if (offset)
+ mem->offset = *offset;
+ else
+ memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
+ mem->path = path;
+ mem->buffer_type = buffer_type;
flags = MSM_SUBSYSTEM_MAP_IOVA;
mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, len,
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 1cb2fbc..ac1575b 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -22,18 +22,35 @@
unsigned int count;
};
+enum videobuf2_buffer_type {
+ VIDEOBUF2_SINGLE_PLANE,
+ VIDEOBUF2_MULTIPLE_PLANES
+};
+
+struct videobuf2_sp_offset {
+ uint32_t y_off;
+ uint32_t cbcr_off;
+};
+
+struct videobuf2_msm_offset {
+ union {
+ struct videobuf2_sp_offset sp_off;
+ uint32_t data_offset;
+ };
+};
+
struct videobuf2_contig_pmem {
u32 magic;
void *vaddr;
int phyaddr;
unsigned long size;
int is_userptr;
- /* Single plane - CbCr offset
- * Multi plane - plane offset
- */
- uint32_t offset;
- int buffer_type;
+ /* Offset of the plane inside the buffer */
+ struct videobuf2_msm_offset offset;
+ enum videobuf2_buffer_type buffer_type;
+ int path;
struct file *file;
+ /* Offset of the buffer */
uint32_t addr_offset;
int dirty;
unsigned int count;
@@ -48,9 +65,11 @@
unsigned int size,
void *priv);
int videobuf2_pmem_contig_mmap_get(struct videobuf2_contig_pmem *mem,
- uint32_t offset, int path);
+ struct videobuf2_msm_offset *offset,
+ enum videobuf2_buffer_type, int path);
int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
- uint32_t offset,
+ struct videobuf2_msm_offset *offset,
+ enum videobuf2_buffer_type,
uint32_t addr_offset, int path);
void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem);
unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *buf,