Merge "msm: mpq8064: Allow client to select num bufs for VC to hold onto" into msm-3.4
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 407bf2e..cb33550 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -503,7 +503,7 @@
unsigned int *nplanes, unsigned int sizes[],
void *alloc_ctxs[])
{
- *nbuffers += 2;
+ *nbuffers += vcap_ctrl->vc_tot_buf;
if (*nbuffers > VIDEO_MAX_FRAME)
return -EINVAL;
*nplanes = 1;
@@ -524,17 +524,16 @@
{
struct vcap_client_data *c_data = vb2_get_drv_priv(vb->vb2_queue);
struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
- struct vcap_action *vid_vc_action = &c_data->vid_vc_action;
+ struct vc_action *vc_action = &c_data->vc_action;
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags = 0;
spin_lock_irqsave(&c_data->cap_slock, flags);
- list_add_tail(&buf->list, &vid_vc_action->active);
+ list_add_tail(&buf->list, &vc_action->active);
spin_unlock_irqrestore(&c_data->cap_slock, flags);
if (atomic_read(&c_data->dev->vc_enabled) == 0) {
-
- if (atomic_read(&q->queued_count) > 1)
+ if (atomic_read(&q->queued_count) >= c_data->vc_action.tot_buf)
if (vc_hw_kick_off(c_data) == 0)
atomic_set(&c_data->dev->vc_enabled, 1);
}
@@ -554,9 +553,9 @@
vc_stop_capture(c_data);
- while (!list_empty(&c_data->vid_vc_action.active)) {
+ while (!list_empty(&c_data->vc_action.active)) {
struct vcap_buffer *buf;
- buf = list_entry(c_data->vid_vc_action.active.next,
+ buf = list_entry(c_data->vc_action.active.next,
struct vcap_buffer, list);
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
@@ -617,7 +616,7 @@
{
struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
- struct vp_action *vp_act = &cd->vid_vp_action;
+ struct vp_action *vp_act = &cd->vp_action;
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags = 0;
@@ -626,7 +625,7 @@
spin_unlock_irqrestore(&cd->cap_slock, flags);
if (atomic_read(&cd->dev->vp_enabled) == 0) {
- if (cd->vid_vp_action.vp_state == VP_FRAME1) {
+ if (cd->vp_action.vp_state == VP_FRAME1) {
if (atomic_read(&q->queued_count) > 1 &&
atomic_read(&cd->vp_out_vidq.queued_count) > 0)
/* Valid code flow for VC-VP mode */
@@ -651,9 +650,9 @@
dprintk(2, "VP stop streaming\n");
- while (!list_empty(&c_data->vid_vp_action.in_active)) {
+ while (!list_empty(&c_data->vp_action.in_active)) {
struct vcap_buffer *buf;
- buf = list_entry(c_data->vid_vp_action.in_active.next,
+ buf = list_entry(c_data->vp_action.in_active.next,
struct vcap_buffer, list);
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
@@ -715,7 +714,7 @@
{
struct vcap_client_data *cd = vb2_get_drv_priv(vb->vb2_queue);
struct vcap_buffer *buf = container_of(vb, struct vcap_buffer, vb);
- struct vp_action *vp_act = &cd->vid_vp_action;
+ struct vp_action *vp_act = &cd->vp_action;
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags = 0;
@@ -724,7 +723,7 @@
spin_unlock_irqrestore(&cd->cap_slock, flags);
if (atomic_read(&cd->dev->vp_enabled) == 0) {
- if (cd->vid_vp_action.vp_state == VP_FRAME1) {
+ if (cd->vp_action.vp_state == VP_FRAME1) {
if (atomic_read(&q->queued_count) > 0 &&
atomic_read(&
cd->vp_in_vidq.queued_count) > 1)
@@ -749,9 +748,9 @@
dprintk(2, "VP out q stop streaming\n");
vp_stop_capture(c_data);
- while (!list_empty(&c_data->vid_vp_action.out_active)) {
+ while (!list_empty(&c_data->vp_action.out_active)) {
struct vcap_buffer *buf;
- buf = list_entry(c_data->vid_vp_action.out_active.next,
+ buf = list_entry(c_data->vp_action.out_active.next,
struct vcap_buffer, list);
list_del(&buf->list);
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
@@ -884,6 +883,7 @@
struct v4l2_requestbuffers *rb)
{
struct vcap_client_data *c_data = to_client_data(file->private_data);
+ struct vcap_dev *dev = c_data->dev;
int rc;
dprintk(3, "In Req Buf %08x\n", (unsigned int)rb->type);
@@ -905,7 +905,7 @@
pr_err("VCAP Err: VP No prog support\n");
return -ENOTRECOVERABLE;
}
- if (rb->count < 6) {
+ if (rb->count <= VCAP_VP_MIN_BUF) {
pr_err("VCAP Err: Not enough buf for VC_VP\n");
return -EINVAL;
}
@@ -924,10 +924,13 @@
rb->type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
rc = vb2_reqbufs(&c_data->vp_in_vidq, rb);
rb->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ c_data->vc_action.tot_buf = dev->vc_tot_buf;
return rc;
} else {
- return vb2_reqbufs(&c_data->vc_vidq, rb);
+ rc = vb2_reqbufs(&c_data->vc_vidq, rb);
+ c_data->vc_action.tot_buf = dev->vc_tot_buf;
+ return rc;
}
case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
return vb2_reqbufs(&c_data->vp_in_vidq, rb);
@@ -1219,13 +1222,13 @@
rc = init_motion_buf(c_data);
if (rc < 0)
goto free_res;
- if (c_data->vid_vp_action.nr_param.mode) {
+ if (c_data->vp_action.nr_param.mode) {
rc = init_nr_buf(c_data);
if (rc < 0)
goto s_on_deinit_m_buf;
}
- c_data->vid_vp_action.vp_state = VP_FRAME1;
+ c_data->vp_action.vp_state = VP_FRAME1;
c_data->streaming = 1;
rc = vb2_streamon(&c_data->vp_in_vidq,
@@ -1308,14 +1311,14 @@
if (rc < 0)
goto free_res;
- if (c_data->vid_vp_action.nr_param.mode) {
+ if (c_data->vp_action.nr_param.mode) {
rc = init_nr_buf(c_data);
if (rc < 0)
goto s_on_deinit_m_buf;
}
c_data->dev->vc_to_vp_work.cd = c_data;
- c_data->vid_vp_action.vp_state = VP_FRAME1;
+ c_data->vp_action.vp_state = VP_FRAME1;
c_data->streaming = 1;
/* These stream on calls should not fail */
@@ -1341,7 +1344,7 @@
return 0;
s_on_deinit_nr_buf:
- if (c_data->vid_vp_action.nr_param.mode)
+ if (c_data->vp_action.nr_param.mode)
deinit_nr_buf(c_data);
s_on_deinit_m_buf:
deinit_motion_buf(c_data);
@@ -1436,7 +1439,7 @@
return rc;
deinit_motion_buf(c_data);
- if (c_data->vid_vp_action.nr_param.mode)
+ if (c_data->vp_action.nr_param.mode)
deinit_nr_buf(c_data);
atomic_set(&c_data->dev->vp_enabled, 0);
return rc;
@@ -1484,7 +1487,7 @@
return rc;
deinit_motion_buf(c_data);
- if (c_data->vid_vp_action.nr_param.mode)
+ if (c_data->vp_action.nr_param.mode)
deinit_nr_buf(c_data);
atomic_set(&c_data->dev->vc_enabled, 0);
atomic_set(&c_data->dev->vp_enabled, 0);
@@ -1535,7 +1538,9 @@
int cmd, void *arg)
{
struct vcap_client_data *c_data = to_client_data(file->private_data);
+ struct vcap_dev *dev = c_data->dev;
struct nr_param *param;
+ int val;
unsigned long flags = 0;
int ret;
@@ -1544,7 +1549,7 @@
if (c_data->streaming != 0 &&
(!(!((struct nr_param *) arg)->mode) !=
- !(!(c_data->vid_vp_action.nr_param.mode)))) {
+ !(!(c_data->vp_action.nr_param.mode)))) {
pr_err("ERR: Trying to toggle on/off while VP is already running");
return -EBUSY;
}
@@ -1557,22 +1562,28 @@
return ret;
}
param = (struct nr_param *) arg;
- c_data->vid_vp_action.nr_param = *param;
+ c_data->vp_action.nr_param = *param;
if (param->mode == NR_AUTO)
- s_default_nr_val(&c_data->vid_vp_action.nr_param);
- c_data->vid_vp_action.nr_update = true;
+ s_default_nr_val(&c_data->vp_action.nr_param);
+ c_data->vp_action.nr_update = true;
spin_unlock_irqrestore(&c_data->cap_slock, flags);
break;
case VCAPIOC_NR_G_PARAMS:
- *((struct nr_param *)arg) = c_data->vid_vp_action.nr_param;
- if (c_data->vid_vp_action.nr_param.mode != NR_DISABLE) {
+ *((struct nr_param *)arg) = c_data->vp_action.nr_param;
+ if (c_data->vp_action.nr_param.mode != NR_DISABLE) {
if (c_data->streaming)
nr_g_param(c_data, (struct nr_param *) arg);
else
(*(struct nr_param *) arg) =
- c_data->vid_vp_action.nr_param;
+ c_data->vp_action.nr_param;
}
break;
+ case VCAPIOC_S_NUM_VC_BUF:
+ val = (*(int *) arg);
+ if (val < VCAP_VC_MIN_BUF || val > VCAP_VC_MAX_BUF)
+ return -EINVAL;
+ dev->vc_tot_buf = (uint8_t) val;
+ break;
default:
return -EINVAL;
}
@@ -1658,9 +1669,9 @@
if (ret < 0)
goto vp_out_q_failed;
- INIT_LIST_HEAD(&c_data->vid_vc_action.active);
- INIT_LIST_HEAD(&c_data->vid_vp_action.in_active);
- INIT_LIST_HEAD(&c_data->vid_vp_action.out_active);
+ INIT_LIST_HEAD(&c_data->vc_action.active);
+ INIT_LIST_HEAD(&c_data->vp_action.in_active);
+ INIT_LIST_HEAD(&c_data->vp_action.out_active);
v4l2_fh_init(&c_data->vfh, dev->vfd);
v4l2_fh_add(&c_data->vfh);
@@ -1722,6 +1733,7 @@
mutex_unlock(&dev->dev_mutex);
if (ret == 0) {
vcap_disable(dev);
+ dev->vc_tot_buf = 2;
dev->vp_dummy_complete = false;
}
v4l2_fh_del(&c_data->vfh);
@@ -1963,6 +1975,7 @@
goto rel_vcap_wq;
}
+ dev->vc_tot_buf = 2;
atomic_set(&dev->vc_enabled, 0);
atomic_set(&dev->vp_enabled, 0);
atomic_set(&dev->open_clients, 0);
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 966fa4b..1825352 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -107,14 +107,30 @@
}
}
+static uint8_t correct_buf_num(uint32_t reg)
+{
+ int i;
+ bool block_found = false;
+ for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
+ if (reg & (0x2 << i)) {
+ block_found = true;
+ continue;
+ }
+ if (block_found)
+ return i;
+ }
+ return 0;
+}
+
irqreturn_t vc_handler(struct vcap_dev *dev)
{
uint32_t irq, timestamp;
- enum rdy_buf vc_buf_status, buf_ind;
struct vcap_buffer *buf;
struct vb2_buffer *vb = NULL;
struct vcap_client_data *c_data;
struct v4l2_event v4l2_evt;
+ uint8_t i, idx, buf_num, tot, done_count = 0;
+ bool work_todo = false;
irq = readl_relaxed(VCAP_VC_INT_STATUS);
@@ -154,106 +170,75 @@
v4l2_event_queue(dev->vfd, &v4l2_evt);
}
- vc_buf_status = irq & VC_BUFFER_WRITTEN;
- dprintk(1, "Done buf status = %d\n", vc_buf_status);
-
- if (vc_buf_status == VC_NO_BUF) {
+ if (!(irq & VC_BUFFER_MASK)) {
writel_relaxed(irq, VCAP_VC_INT_CLEAR);
pr_err("VC IRQ shows some error\n");
return IRQ_HANDLED;
}
if (dev->vc_client == NULL) {
+ /* This should never happen */
writel_relaxed(irq, VCAP_VC_INT_CLEAR);
pr_err("VC: There is no active vc client\n");
return IRQ_HANDLED;
}
+ c_data = dev->vc_client;
- spin_lock(&dev->vc_client->cap_slock);
- if (list_empty(&dev->vc_client->vid_vc_action.active)) {
- /* Just leave we have no new queued buffers */
- spin_unlock(&dev->vc_client->cap_slock);
- writel_relaxed(irq, VCAP_VC_INT_CLEAR);
- v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
- VCAP_VC_BUF_OVERWRITE_EVENT;
- v4l2_event_queue(dev->vfd, &v4l2_evt);
- dprintk(1, "We have no more avilable buffers\n");
- return IRQ_HANDLED;
+ for (i = 0; i < VCAP_VC_MAX_BUF; i++) {
+ if (0x2 & (irq >> i))
+ done_count++;
}
- spin_unlock(&dev->vc_client->cap_slock);
+ /* Double check expected buffers are done */
+ buf_num = c_data->vc_action.buf_num;
+ tot = c_data->vc_action.tot_buf;
+ for (i = 0; i < done_count; i++) {
+ if (!(irq & (0x1 << (((buf_num + i) % tot) + 1)))) {
+ v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+ VCAP_VC_UNEXPECT_BUF_DONE;
+ v4l2_event_queue(dev->vfd, &v4l2_evt);
+ pr_debug("Unexpected buffer done\n");
+ c_data->vc_action.buf_num =
+ correct_buf_num(irq) % tot;
+ writel_relaxed(irq, VCAP_VC_INT_CLEAR);
+ return IRQ_HANDLED;
+ }
+ }
+
+ /* If here we know which buffers are done */
timestamp = readl_relaxed(VCAP_VC_TIMESTAMP);
- buf_ind = dev->vc_client->vid_vc_action.buf_ind;
-
- if (vc_buf_status == VC_BUF1N2) {
- /* There are 2 buffer ready */
- writel_relaxed(irq, VCAP_VC_INT_CLEAR);
- return IRQ_HANDLED;
- } else if (buf_ind != vc_buf_status) {
- /* buffer is out of sync */
- writel_relaxed(irq, VCAP_VC_INT_CLEAR);
- return IRQ_HANDLED;
- }
-
- if (buf_ind == VC_BUF1) {
- dprintk(1, "Got BUF1\n");
- vb = &dev->vc_client->vid_vc_action.buf1->vb;
- spin_lock(&dev->vc_client->cap_slock);
- if (list_empty(&dev->vc_client->vid_vc_action.active)) {
- spin_unlock(&dev->vc_client->cap_slock);
+ c_data->vc_action.buf_num = (buf_num + done_count) % tot;
+ for (i = 0; i < done_count; i++) {
+ idx = (buf_num + i) % tot;
+ vb = &c_data->vc_action.buf[idx]->vb;
+ spin_lock(&c_data->cap_slock);
+ if (list_empty(&c_data->vc_action.active)) {
+ spin_unlock(&c_data->cap_slock);
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
VCAP_VC_BUF_OVERWRITE_EVENT;
v4l2_event_queue(dev->vfd, &v4l2_evt);
- writel_relaxed(irq, VCAP_VC_INT_CLEAR);
- return IRQ_HANDLED;
+ continue;
}
- buf = list_entry(dev->vc_client->vid_vc_action.active.next,
+ buf = list_entry(c_data->vc_action.active.next,
struct vcap_buffer, list);
list_del(&buf->list);
- spin_unlock(&dev->vc_client->cap_slock);
+ spin_unlock(&c_data->cap_slock);
/* Config vc with this new buffer */
- config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1,
- VCAP_VC_C_ADDR_1);
-
- vb->v4l2_buf.timestamp.tv_usec = timestamp;
+ config_buffer(c_data, buf, VCAP_VC_Y_ADDR_1 + 0x8 * idx,
+ VCAP_VC_C_ADDR_1 + 0x8 * idx);
+ vb->v4l2_buf.timestamp.tv_usec = timestamp -
+ 1000000 / c_data->vc_format.frame_rate *
+ (done_count - 1 - i);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
- dev->vc_client->vid_vc_action.buf1 = buf;
- dev->vc_client->vid_vc_action.buf_ind = VC_BUF2;
- irq = VC_BUF1;
- } else {
- dprintk(1, "Got BUF2\n");
- spin_lock(&dev->vc_client->cap_slock);
- vb = &dev->vc_client->vid_vc_action.buf2->vb;
- if (list_empty(&dev->vc_client->vid_vc_action.active)) {
- spin_unlock(&dev->vc_client->cap_slock);
- writel_relaxed(irq, VCAP_VC_INT_CLEAR);
- v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
- VCAP_VC_BUF_OVERWRITE_EVENT;
- v4l2_event_queue(dev->vfd, &v4l2_evt);
- return IRQ_HANDLED;
- }
- buf = list_entry(dev->vc_client->vid_vc_action.active.next,
- struct vcap_buffer, list);
- list_del(&buf->list);
- spin_unlock(&dev->vc_client->cap_slock);
- /* Config vc with this new buffer */
- config_buffer(c_data, buf, VCAP_VC_Y_ADDR_2,
- VCAP_VC_C_ADDR_2);
-
- vb->v4l2_buf.timestamp.tv_usec = timestamp;
- vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
-
- dev->vc_client->vid_vc_action.buf2 = buf;
- dev->vc_client->vid_vc_action.buf_ind = VC_BUF1;
- irq = VC_BUF2;
+ work_todo = true;
+ c_data->vc_action.buf[idx] = buf;
}
- if (c_data->op_mode == VC_AND_VP_VCAP_OP)
+ if (work_todo && c_data->op_mode == VC_AND_VP_VCAP_OP)
queue_work(dev->vcap_wq, &dev->vc_to_vp_work.work);
writel_relaxed(irq, VCAP_VC_INT_CLEAR);
-
return IRQ_HANDLED;
}
@@ -264,58 +249,59 @@
int vc_hw_kick_off(struct vcap_client_data *c_data)
{
- struct vcap_action *vid_vc_action = &c_data->vid_vc_action;
+ struct vc_action *vc_action = &c_data->vc_action;
struct vcap_dev *dev;
unsigned long flags = 0;
- int rc, counter = 0;
+ int rc, i, counter = 0;
struct vcap_buffer *buf;
dev = c_data->dev;
- vid_vc_action->buf_ind = VC_BUF1;
dprintk(2, "Start Kickoff\n");
if (dev->vc_client == NULL) {
pr_err("No active vc client\n");
return -ENODEV;
}
+ c_data->vc_action.buf_num = 0;
spin_lock_irqsave(&dev->vc_client->cap_slock, flags);
- if (list_empty(&dev->vc_client->vid_vc_action.active)) {
+ if (list_empty(&dev->vc_client->vc_action.active)) {
spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
pr_err("%s: VC We have no more avilable buffers\n",
__func__);
return -EINVAL;
}
- list_for_each_entry(buf, &vid_vc_action->active, list)
+ list_for_each_entry(buf, &vc_action->active, list)
counter++;
- if (counter < 2) {
+ if (counter < c_data->vc_action.tot_buf) {
/* not enough buffers have been queued */
spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
return -EINVAL;
}
- vid_vc_action->buf1 = list_entry(vid_vc_action->active.next,
+ for (i = 0; i < c_data->vc_action.tot_buf; i++) {
+ vc_action->buf[i] = list_entry(vc_action->active.next,
struct vcap_buffer, list);
- list_del(&vid_vc_action->buf1->list);
-
- vid_vc_action->buf2 = list_entry(vid_vc_action->active.next,
- struct vcap_buffer, list);
- list_del(&vid_vc_action->buf2->list);
-
+ list_del(&vc_action->buf[i]->list);
+ }
spin_unlock_irqrestore(&dev->vc_client->cap_slock, flags);
- config_buffer(c_data, vid_vc_action->buf1, VCAP_VC_Y_ADDR_1,
- VCAP_VC_C_ADDR_1);
- config_buffer(c_data, vid_vc_action->buf2, VCAP_VC_Y_ADDR_2,
- VCAP_VC_C_ADDR_2);
+ for (i = 0; i < c_data->vc_action.tot_buf; i++) {
+ config_buffer(c_data, vc_action->buf[i],
+ VCAP_VC_Y_ADDR_1 + i * 8,
+ VCAP_VC_C_ADDR_1 + i * 8);
+ }
+ rc = 0;
+ for (i = 0; i < c_data->vc_action.tot_buf; i++)
+ rc = rc << 1 | 0x2;
+ writel_relaxed(rc, VCAP_VC_INT_MASK);
+
+ enable_irq(dev->vcirq->start);
rc = readl_relaxed(VCAP_VC_CTRL);
writel_iowmb(rc | 0x1, VCAP_VC_CTRL);
- writel_relaxed(0x6, VCAP_VC_INT_MASK);
-
- enable_irq(dev->vcirq->start);
return 0;
}
@@ -383,7 +369,9 @@
writel_iowmb(0x00000002, VCAP_VC_NPL_CTRL);
writel_iowmb(0x00000004 | vc_format->color_space << 1 |
vc_format->mode << 3 |
- vc_format->mode << 10, VCAP_VC_CTRL);
+ (c_data->vc_action.tot_buf - 2) << 4 |
+ vc_format->mode << 10,
+ VCAP_VC_CTRL);
writel_relaxed(vc_format->h_polar << 4 |
vc_format->v_polar << 0, VCAP_VC_POLARITY);
diff --git a/drivers/media/video/vcap_vc.h b/drivers/media/video/vcap_vc.h
index 76693bb..7f42c7f 100644
--- a/drivers/media/video/vcap_vc.h
+++ b/drivers/media/video/vcap_vc.h
@@ -62,6 +62,7 @@
#define VCAP_VC_TIMESTAMP (VCAP_BASE + 0x0034)
#define VC_BUFFER_WRITTEN (0x3 << 1)
+#define VC_BUFFER_MASK 0x7E
int vc_start_capture(struct vcap_client_data *c_data);
int vc_hw_kick_off(struct vcap_client_data *c_data);
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index f8f27d4..12b3208 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -81,7 +81,7 @@
}
/* No need to verify vp_client is not NULL caller does so */
- vp_act = &dev->vp_client->vid_vp_action;
+ vp_act = &dev->vp_client->vp_action;
spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
if (list_empty(&vp_act->in_active)) {
@@ -173,7 +173,7 @@
{
struct vcap_dev *dev = c_data->dev;
struct nr_param *par;
- par = &c_data->vid_vp_action.nr_param;
+ par = &c_data->vp_action.nr_param;
if (par->mode == NR_MANUAL) {
writel_relaxed(par->window << 24 | par->decay_ratio << 20,
VCAP_VP_NR_CONFIG);
@@ -190,7 +190,7 @@
par->chroma.blend_limit_ratio << 0,
VCAP_VP_NR_CHROMA_CONFIG);
}
- c_data->vid_vp_action.nr_update = false;
+ c_data->vp_action.nr_update = false;
}
static void vp_wq_fnc(struct work_struct *work)
@@ -210,7 +210,7 @@
else
return;
- vp_act = &dev->vp_client->vid_vp_action;
+ vp_act = &dev->vp_client->vp_action;
rc = readl_relaxed(VCAP_OFFSET(0x048));
while (!(rc & 0x00000100))
@@ -244,7 +244,7 @@
#endif
/* Cycle Buffers*/
- if (vp_work->cd->vid_vp_action.nr_param.mode) {
+ if (vp_work->cd->vp_action.nr_param.mode) {
if (vp_act->bufNR.nr_pos == TM1_BUF)
vp_act->bufNR.nr_pos = BUF_NOT_IN_USE;
@@ -340,7 +340,7 @@
return IRQ_HANDLED;
}
- vp_act = &dev->vp_client->vid_vp_action;
+ vp_act = &dev->vp_client->vp_action;
c_data = dev->vp_client;
if (vp_act->vp_state == VP_UNKNOWN) {
@@ -467,7 +467,7 @@
size_t size = ((c_data->vp_out_fmt.width + 63) >> 6) *
((c_data->vp_out_fmt.height + 7) >> 3) * 16;
- if (c_data->vid_vp_action.motionHandle) {
+ if (c_data->vp_action.motionHandle) {
pr_err("Motion buffer has already been created");
return -ENOEXEC;
}
@@ -501,7 +501,7 @@
}
memset(vaddr, 0, size);
- c_data->vid_vp_action.motionHandle = handle;
+ c_data->vp_action.motionHandle = handle;
vaddr = NULL;
ion_unmap_kernel(dev->ion_client, handle);
@@ -513,14 +513,14 @@
void deinit_motion_buf(struct vcap_client_data *c_data)
{
struct vcap_dev *dev = c_data->dev;
- if (!c_data->vid_vp_action.motionHandle) {
+ if (!c_data->vp_action.motionHandle) {
pr_err("Motion buffer has not been created");
return;
}
writel_iowmb(0x00000000, VCAP_VP_MOTION_EST_ADDR);
- ion_free(dev->ion_client, c_data->vid_vp_action.motionHandle);
- c_data->vid_vp_action.motionHandle = NULL;
+ ion_free(dev->ion_client, c_data->vp_action.motionHandle);
+ c_data->vp_action.motionHandle = NULL;
return;
}
@@ -532,7 +532,7 @@
unsigned long paddr;
int rc;
- if (c_data->vid_vp_action.bufNR.nr_handle) {
+ if (c_data->vp_action.bufNR.nr_handle) {
pr_err("NR buffer has already been created");
return -ENOEXEC;
}
@@ -557,16 +557,16 @@
return rc;
}
- c_data->vid_vp_action.bufNR.nr_handle = handle;
+ c_data->vp_action.bufNR.nr_handle = handle;
update_nr_value(c_data);
- c_data->vid_vp_action.bufNR.paddr = paddr;
+ c_data->vp_action.bufNR.paddr = paddr;
rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
rc |= (((c_data->vp_out_fmt.width / 16) << 20) | 0x1);
writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
writel_relaxed(paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
writel_relaxed(paddr + frame_size, VCAP_VP_NR_T2_C_BASE_ADDR);
- c_data->vid_vp_action.bufNR.nr_pos = NRT2_BUF;
+ c_data->vp_action.bufNR.nr_pos = NRT2_BUF;
return 0;
}
@@ -576,11 +576,11 @@
struct nr_buffer *buf;
uint32_t rc;
- if (!c_data->vid_vp_action.bufNR.nr_handle) {
+ if (!c_data->vp_action.bufNR.nr_handle) {
pr_err("NR buffer has not been created");
return;
}
- buf = &c_data->vid_vp_action.bufNR;
+ buf = &c_data->vp_action.bufNR;
rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
rc &= !(0x0FF00001);
@@ -757,7 +757,7 @@
pr_err("No active vp client\n");
return -ENODEV;
}
- vp_act = &dev->vp_client->vid_vp_action;
+ vp_act = &dev->vp_client->vp_action;
spin_lock_irqsave(&dev->vp_client->cap_slock, flags);
if (list_empty(&vp_act->in_active)) {
@@ -854,7 +854,7 @@
pr_err("No active vp client\n");
return -ENODEV;
}
- vp_act = &dev->vp_client->vid_vp_action;
+ vp_act = &dev->vp_client->vp_action;
if (vp_act->vp_state == VP_UNKNOWN) {
pr_err("%s: VP is in an unknown state\n",
diff --git a/include/media/vcap_fmt.h b/include/media/vcap_fmt.h
index 00e0375..2641720 100644
--- a/include/media/vcap_fmt.h
+++ b/include/media/vcap_fmt.h
@@ -27,7 +27,8 @@
#define VCAP_VP_REG_W_ERR_EVENT 8
#define VCAP_VP_IN_HEIGHT_ERR_EVENT 9
#define VCAP_VP_IN_WIDTH_ERR_EVENT 10
-#define VCAP_MAX_NOTIFY_EVENT 11
+#define VCAP_VC_UNEXPECT_BUF_DONE 11
+#define VCAP_MAX_NOTIFY_EVENT 12
enum hal_vcap_mode {
HAL_VCAP_MODE_PRO = 0,
@@ -80,6 +81,7 @@
#define VCAPIOC_NR_S_PARAMS _IOWR('V', (BASE_VIDIOC_PRIVATE+0), struct nr_param)
#define VCAPIOC_NR_G_PARAMS _IOWR('V', (BASE_VIDIOC_PRIVATE+1), struct nr_param)
+#define VCAPIOC_S_NUM_VC_BUF _IOWR('V', (BASE_VIDIOC_PRIVATE+2), int)
struct v4l2_format_vc_ext {
enum hal_vcap_mode mode;
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index d56e534..81f7922 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -44,15 +44,11 @@
#define VCAP_SW_RESET_REQ (VCAP_BASE + 0x024)
#define VCAP_SW_RESET_STATUS (VCAP_BASE + 0x028)
+#define VCAP_VP_MIN_BUF 4
+#define VCAP_VC_MAX_BUF 6
+#define VCAP_VC_MIN_BUF 2
struct vcap_client_data;
-enum rdy_buf {
- VC_NO_BUF = 0,
- VC_BUF1 = 1 << 1,
- VC_BUF2 = 1 << 2,
- VC_BUF1N2 = 0x11 << 1,
-};
-
enum vp_state {
VP_UNKNOWN = 0,
VP_FRAME1,
@@ -81,23 +77,18 @@
VC_AND_VP_VCAP_OP,
};
-struct vcap_action {
+struct vc_action {
struct list_head active;
/* thread for generating video stream*/
- struct task_struct *kthread;
wait_queue_head_t wq;
/* Buffer index */
- enum rdy_buf buf_ind;
+ uint8_t tot_buf;
+ uint8_t buf_num;
/* Buffers inside vc */
- struct vcap_buffer *buf1;
- struct vcap_buffer *buf2;
-
- /* Counters to control fps rate */
- int frame;
- int ini_jiffies;
+ struct vcap_buffer *buf[6];
};
struct nr_buffer {
@@ -176,6 +167,8 @@
bool vp_shutdown;
wait_queue_head_t vp_dummy_waitq;
+ uint8_t vc_tot_buf;
+
struct workqueue_struct *vcap_wq;
struct vp_work_t vp_work;
struct vp_work_t vc_to_vp_work;
@@ -211,8 +204,8 @@
struct vp_format_data vp_in_fmt;
struct vp_format_data vp_out_fmt;
- struct vcap_action vid_vc_action;
- struct vp_action vid_vp_action;
+ struct vc_action vc_action;
+ struct vp_action vp_action;
struct workqueue_struct *vcap_work_q;
struct ion_handle *vc_ion_handle;