aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkyoungheon <kyoungheon@samsung.com>2010-11-22 17:36:18 -0800
committerArve Hjønnevåg <arve@android.com>2011-11-17 17:52:56 -0800
commit5f4b037e6ebb18d65a3ac896032eb559d7fe2baf (patch)
treefb5cd04c3446e21d270070906032fc3156ec70f2
parente5cc05ef38659db41d529f202b1daf2f7a4b4ab2 (diff)
downloadkernel_samsung_crespo-5f4b037e6ebb18d65a3ac896032eb559d7fe2baf.zip
kernel_samsung_crespo-5f4b037e6ebb18d65a3ac896032eb559d7fe2baf.tar.gz
kernel_samsung_crespo-5f4b037e6ebb18d65a3ac896032eb559d7fe2baf.tar.bz2
S5PC11X : FIMC apply v4l2 standard for asynchronous dequeue/queue
To make framedrop in camera HAL layer, FIMC should support v4l2 standard Signed-off-by: Song Youngmok <ym.song@samsung.com>
-rw-r--r--drivers/media/video/samsung/fimc/fimc.h3
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture.c79
2 files changed, 45 insertions, 37 deletions
diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h
index 8b33814..3e61a98 100644
--- a/drivers/media/video/samsung/fimc/fimc.h
+++ b/drivers/media/video/samsung/fimc/fimc.h
@@ -65,10 +65,7 @@
#define FIMC_SCLK 1
#define FIMC_OVLY_MODE FIMC_OVLY_DMA_AUTO
-#define PINGPONG_2ADDR_MODE
-#if defined(PINGPONG_2ADDR_MODE)
#define FIMC_PINGPONG 2
-#endif
/*
* ENUMERATIONS
diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c
index b7df637..a7bc6be 100644
--- a/drivers/media/video/samsung/fimc/fimc_capture.c
+++ b/drivers/media/video/samsung/fimc/fimc_capture.c
@@ -389,19 +389,34 @@ static int fimc_add_outqueue(struct fimc_control *ctrl, int i)
struct fimc_capinfo *cap = ctrl->cap;
struct fimc_buf_set *buf;
- if (cap->nr_bufs > FIMC_PHYBUFS) {
- if (list_empty(&cap->inq))
- return -ENOENT;
+ unsigned int mask = 0x2;
- buf = list_first_entry(&cap->inq, struct fimc_buf_set, list);
- list_del(&buf->list);
- } else {
- buf = &cap->bufs[i];
+ /* PINGPONG_2ADDR_MODE Only */
+ /* pair_buf_index stands for pair index of i. (0<->2) (1<->3) */
+
+ int pair_buf_index = (i^mask);
+
+ /* FIMC have 4 h/w registers */
+ if (i < 0 || i >= FIMC_PHYBUFS) {
+ fimc_err("%s: invalid queue index : %d\n", __func__, i);
+ return -ENOENT;
}
+ if (list_empty(&cap->inq))
+ return -ENOENT;
+
+ buf = list_first_entry(&cap->inq, struct fimc_buf_set, list);
+
+ /* pair index buffer should be allocated first */
+ cap->outq[pair_buf_index] = buf->id;
+ fimc_hwset_output_address(ctrl, buf, pair_buf_index);
+
cap->outq[i] = buf->id;
fimc_hwset_output_address(ctrl, buf, i);
+ if (cap->nr_bufs != 1)
+ list_del(&buf->list);
+
return 0;
}
@@ -409,7 +424,7 @@ static int fimc_update_hwaddr(struct fimc_control *ctrl)
{
int i;
- for (i = 0; i < FIMC_PHYBUFS; i++)
+ for (i = 0; i < FIMC_PINGPONG; i++)
fimc_add_outqueue(ctrl, i);
return 0;
@@ -690,7 +705,6 @@ int fimc_enum_fmt_vid_capture(struct file *file, void *fh,
return ret;
}
- memset(f, 0, sizeof(*f));
memcpy(f, &capture_fmts[i], sizeof(*f));
return 0;
@@ -709,7 +723,6 @@ int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
mutex_lock(&ctrl->v4l2_lock);
- memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix));
mutex_unlock(&ctrl->v4l2_lock);
@@ -794,7 +807,7 @@ static int fimc_fmt_depth(struct fimc_control *ctrl, struct v4l2_format *f)
int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
{
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
- struct fimc_capinfo *cap = ctrl->cap;
+ struct fimc_capinfo *cap;
int ret = 0;
int depth;
@@ -809,23 +822,20 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
* released at the file close.
* Anyone has better idea to do this?
*/
- if (!cap) {
- cap = kzalloc(sizeof(*cap), GFP_KERNEL);
- if (!cap) {
+ mutex_lock(&ctrl->v4l2_lock);
+
+ if (!ctrl->cap) {
+ ctrl->cap = kmalloc(sizeof(*cap), GFP_KERNEL);
+ if (!ctrl->cap) {
+ mutex_unlock(&ctrl->v4l2_lock);
fimc_err("%s: no memory for "
"capture device info\n", __func__);
return -ENOMEM;
}
- /* assign to ctrl */
- ctrl->cap = cap;
- } else {
- memset(cap, 0, sizeof(*cap));
}
-
- mutex_lock(&ctrl->v4l2_lock);
-
- memset(&cap->fmt, 0, sizeof(cap->fmt));
+ cap = ctrl->cap;
+ memset(cap, 0, sizeof(*cap));
memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
/*
@@ -922,7 +932,7 @@ static void fimc_free_buffers(struct fimc_control *ctrl)
return;
- for (i = 0; i < FIMC_PHYBUFS; i++) {
+ for (i = 0; i < cap->nr_bufs; i++) {
memset(&cap->bufs[i], 0, sizeof(cap->bufs[i]));
cap->bufs[i].state = VIDEOBUF_NEEDS_INIT;
}
@@ -1498,7 +1508,7 @@ static void fimc_reset_capture(struct fimc_control *ctrl)
fimc_stop_capture(ctrl);
- for (i = 0; i < FIMC_PHYBUFS; i++)
+ for (i = 0; i < FIMC_PINGPONG; i++)
fimc_add_inqueue(ctrl, ctrl->cap->outq[i]);
fimc_hwset_reset(ctrl);
@@ -1643,16 +1653,19 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
{
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
+ if (!ctrl->cap || !ctrl->cap->nr_bufs) {
+ fimc_err("%s: Invalid capture setting.\n", __func__);
+ return -EINVAL;
+ }
+
if (b->memory != V4L2_MEMORY_MMAP) {
fimc_err("%s: invalid memory type\n", __func__);
return -EINVAL;
}
- if (ctrl->cap->nr_bufs > FIMC_PHYBUFS) {
- mutex_lock(&ctrl->v4l2_lock);
- fimc_add_inqueue(ctrl, b->index);
- mutex_unlock(&ctrl->v4l2_lock);
- }
+ mutex_lock(&ctrl->v4l2_lock);
+ fimc_add_inqueue(ctrl, b->index);
+ mutex_unlock(&ctrl->v4l2_lock);
return 0;
}
@@ -1684,7 +1697,7 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b)
}
/* find out the real index */
- pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4) % cap->nr_bufs;
+ pp = ((fimc_hwget_frame_count(ctrl) + 2) % 4);
/* We have read the latest frame, hence should reset availability
* flag
@@ -1695,16 +1708,14 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b)
if (cap->fmt.field == V4L2_FIELD_INTERLACED_TB)
pp &= ~0x1;
- if (cap->nr_bufs > FIMC_PHYBUFS) {
b->index = cap->outq[pp];
+ fimc_dbg("%s: buffer(%d) outq[%d]\n", __func__, b->index, pp);
+
ret = fimc_add_outqueue(ctrl, pp);
if (ret) {
b->index = -1;
fimc_err("%s: no inqueue buffer\n", __func__);
}
- } else {
- b->index = pp;
- }
mutex_unlock(&ctrl->v4l2_lock);