diff options
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/media/ipu3/ipu3-css.c | 5 | ||||
-rw-r--r-- | drivers/staging/media/ipu3/ipu3-v4l2.c | 46 | ||||
-rw-r--r-- | drivers/staging/media/ipu3/ipu3.c | 30 |
3 files changed, 46 insertions, 35 deletions
diff --git a/drivers/staging/media/ipu3/ipu3-css.c b/drivers/staging/media/ipu3/ipu3-css.c index e7f1898874fd..23cf5b2cfe8b 100644 --- a/drivers/staging/media/ipu3/ipu3-css.c +++ b/drivers/staging/media/ipu3/ipu3-css.c @@ -2171,11 +2171,6 @@ int imgu_css_set_parameters(struct imgu_css *css, unsigned int pipe, obgrid_size = imgu_css_fw_obgrid_size(bi); stripes = bi->info.isp.sp.iterator.num_stripes ? : 1; - /* - * TODO(b/118782861): If userspace queues more than 4 buffers, the - * parameters from previous buffers will be overwritten. Fix the driver - * not to allow this. - */ imgu_css_pool_get(&css_pipe->pool.parameter_set_info); param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, 0)->vaddr; diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index c34b433539c4..be818c29620f 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -341,8 +341,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) struct imgu_video_device *node = container_of(vb->vb2_queue, struct imgu_video_device, vbq); unsigned int queue = imgu_node_to_queue(node->id); + struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, + vid_buf.vbb.vb2_buf); unsigned long need_bytes; - unsigned int pipe = node->pipe; + unsigned long payload = vb2_get_plane_payload(vb, 0); if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE || vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT) @@ -350,42 +352,26 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) else need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - if (queue == IPU3_CSS_QUEUE_PARAMS) { - unsigned long payload = vb2_get_plane_payload(vb, 0); - struct vb2_v4l2_buffer *buf = - container_of(vb, struct vb2_v4l2_buffer, vb2_buf); - int r = -EINVAL; - - if (payload == 0) { - payload = need_bytes; - vb2_set_plane_payload(vb, 0, payload); - } - if (payload >= need_bytes) - r = imgu_css_set_parameters(&imgu->css, pipe, - vb2_plane_vaddr(vb, 0)); - buf->flags = V4L2_BUF_FLAG_DONE; - vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE - : VB2_BUF_STATE_ERROR); - - } else { - struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, - vid_buf.vbb.vb2_buf); + if (queue == IPU3_CSS_QUEUE_PARAMS && payload && payload < need_bytes) { + dev_err(&imgu->pci_dev->dev, "invalid data size for params."); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + return; + } - mutex_lock(&imgu->lock); + mutex_lock(&imgu->lock); + if (queue != IPU3_CSS_QUEUE_PARAMS) imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr); - list_add_tail(&buf->vid_buf.list, - &node->buffers); - mutex_unlock(&imgu->lock); - vb2_set_plane_payload(&buf->vid_buf.vbb.vb2_buf, 0, need_bytes); + list_add_tail(&buf->vid_buf.list, &node->buffers); + mutex_unlock(&imgu->lock); - if (imgu->streaming) - imgu_queue_buffers(imgu, false, pipe); - } + vb2_set_plane_payload(vb, 0, need_bytes); + + if (imgu->streaming) + imgu_queue_buffers(imgu, false, node->pipe); dev_dbg(&imgu->pci_dev->dev, "%s for pipe %d node %d", __func__, node->pipe, node->id); - } static int imgu_vb2_queue_setup(struct vb2_queue *vq, diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c index d00d26264c37..17fe2cb4127d 100644 --- a/drivers/staging/media/ipu3/ipu3.c +++ b/drivers/staging/media/ipu3/ipu3.c @@ -236,6 +236,11 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe); mutex_lock(&imgu->lock); + if (!imgu_css_pipe_queue_empty(&imgu->css, pipe)) { + mutex_unlock(&imgu->lock); + return 0; + } + /* Buffer set is queued to FW only when input buffer is ready */ for (node = IMGU_NODE_NUM - 1; imgu_queue_getbuf(imgu, IMGU_NODE_IN, pipe); @@ -246,6 +251,31 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe dev_warn(&imgu->pci_dev->dev, "Vf not enabled, ignore queue"); continue; + } else if (node == IMGU_NODE_PARAMS && + imgu_pipe->nodes[node].enabled) { + struct vb2_buffer *vb; + struct imgu_vb2_buffer *ivb; + + /* No parameters for this frame */ + if (list_empty(&imgu_pipe->nodes[node].buffers)) + continue; + + ivb = list_first_entry(&imgu_pipe->nodes[node].buffers, + struct imgu_vb2_buffer, list); + vb = &ivb->vbb.vb2_buf; + r = imgu_css_set_parameters(&imgu->css, pipe, + vb2_plane_vaddr(vb, 0)); + if (r) { + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + dev_warn(&imgu->pci_dev->dev, + "set parameters failed."); + continue; + } + + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + dev_dbg(&imgu->pci_dev->dev, + "queue user parameters %d to css.", vb->index); + list_del(&ivb->list); } else if (imgu_pipe->queue_enabled[node]) { struct imgu_css_buffer *buf = imgu_queue_getbuf(imgu, node, pipe); |