summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/media/ipu3/ipu3-css.c5
-rw-r--r--drivers/staging/media/ipu3/ipu3-v4l2.c46
-rw-r--r--drivers/staging/media/ipu3/ipu3.c30
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);