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)
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,
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);
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);