xref: /linux/drivers/staging/media/ipu7/ipu7-isys-queue.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2013 - 2025 Intel Corporation
4  */
5 
6 #include <linux/atomic.h>
7 #include <linux/bug.h>
8 #include <linux/device.h>
9 #include <linux/list.h>
10 #include <linux/lockdep.h>
11 #include <linux/mutex.h>
12 #include <linux/spinlock.h>
13 #include <linux/types.h>
14 
15 #include <media/media-entity.h>
16 #include <media/v4l2-subdev.h>
17 #include <media/videobuf2-dma-sg.h>
18 #include <media/videobuf2-v4l2.h>
19 
20 #include "abi/ipu7_fw_isys_abi.h"
21 
22 #include "ipu7-bus.h"
23 #include "ipu7-dma.h"
24 #include "ipu7-fw-isys.h"
25 #include "ipu7-isys.h"
26 #include "ipu7-isys-csi2-regs.h"
27 #include "ipu7-isys-video.h"
28 #include "ipu7-platform-regs.h"
29 
30 #define IPU_MAX_FRAME_COUNTER	(U8_MAX + 1)
31 
32 static int ipu7_isys_buf_init(struct vb2_buffer *vb)
33 {
34 	struct ipu7_isys *isys = vb2_get_drv_priv(vb->vb2_queue);
35 	struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0);
36 	struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb);
37 	struct ipu7_isys_video_buffer *ivb =
38 		vb2_buffer_to_ipu7_isys_video_buffer(vvb);
39 	int ret;
40 
41 	ret = ipu7_dma_map_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0);
42 	if (ret)
43 		return ret;
44 
45 	ivb->dma_addr = sg_dma_address(sg->sgl);
46 
47 	return 0;
48 }
49 
50 static void ipu7_isys_buf_cleanup(struct vb2_buffer *vb)
51 {
52 	struct ipu7_isys *isys = vb2_get_drv_priv(vb->vb2_queue);
53 	struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0);
54 	struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb);
55 	struct ipu7_isys_video_buffer *ivb =
56 		vb2_buffer_to_ipu7_isys_video_buffer(vvb);
57 
58 	ivb->dma_addr = 0;
59 	ipu7_dma_unmap_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0);
60 }
61 
62 static int ipu7_isys_queue_setup(struct vb2_queue *q, unsigned int *num_buffers,
63 				 unsigned int *num_planes, unsigned int sizes[],
64 				 struct device *alloc_devs[])
65 {
66 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q);
67 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
68 	struct device *dev = &av->isys->adev->auxdev.dev;
69 	u32 size = av->pix_fmt.sizeimage;
70 
71 	/* num_planes == 0: we're being called through VIDIOC_REQBUFS */
72 	if (!*num_planes) {
73 		sizes[0] = size;
74 	} else if (sizes[0] < size) {
75 		dev_dbg(dev, "%s: queue setup: size %u < %u\n",
76 			av->vdev.name, sizes[0], size);
77 		return -EINVAL;
78 	}
79 
80 	*num_planes = 1;
81 
82 	return 0;
83 }
84 
85 static int ipu7_isys_buf_prepare(struct vb2_buffer *vb)
86 {
87 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue);
88 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
89 	struct device *dev = &av->isys->adev->auxdev.dev;
90 	u32 bytesperline = av->pix_fmt.bytesperline;
91 	u32 height = av->pix_fmt.height;
92 
93 	dev_dbg(dev, "buffer: %s: configured size %u, buffer size %lu\n",
94 		av->vdev.name, av->pix_fmt.sizeimage, vb2_plane_size(vb, 0));
95 
96 	if (av->pix_fmt.sizeimage > vb2_plane_size(vb, 0))
97 		return -EINVAL;
98 
99 	dev_dbg(dev, "buffer: %s: bytesperline %u, height %u\n",
100 		av->vdev.name, bytesperline, height);
101 	vb2_set_plane_payload(vb, 0, bytesperline * height);
102 
103 	return 0;
104 }
105 
106 /*
107  * Queue a buffer list back to incoming or active queues. The buffers
108  * are removed from the buffer list.
109  */
110 void ipu7_isys_buffer_list_queue(struct ipu7_isys_buffer_list *bl,
111 				 unsigned long op_flags,
112 				 enum vb2_buffer_state state)
113 {
114 	struct ipu7_isys_buffer *ib, *ib_safe;
115 	unsigned long flags;
116 	bool first = true;
117 
118 	if (!bl)
119 		return;
120 
121 	WARN_ON_ONCE(!bl->nbufs);
122 	WARN_ON_ONCE(op_flags & IPU_ISYS_BUFFER_LIST_FL_ACTIVE &&
123 		     op_flags & IPU_ISYS_BUFFER_LIST_FL_INCOMING);
124 
125 	list_for_each_entry_safe(ib, ib_safe, &bl->head, head) {
126 		struct ipu7_isys_video *av;
127 
128 		struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib);
129 		struct ipu7_isys_queue *aq =
130 			vb2_queue_to_isys_queue(vb->vb2_queue);
131 
132 		av = ipu7_isys_queue_to_video(aq);
133 		spin_lock_irqsave(&aq->lock, flags);
134 		list_del(&ib->head);
135 		if (op_flags & IPU_ISYS_BUFFER_LIST_FL_ACTIVE)
136 			list_add(&ib->head, &aq->active);
137 		else if (op_flags & IPU_ISYS_BUFFER_LIST_FL_INCOMING)
138 			list_add_tail(&ib->head, &aq->incoming);
139 		spin_unlock_irqrestore(&aq->lock, flags);
140 
141 		if (op_flags & IPU_ISYS_BUFFER_LIST_FL_SET_STATE)
142 			vb2_buffer_done(vb, state);
143 
144 		if (first) {
145 			dev_dbg(&av->isys->adev->auxdev.dev,
146 				"queue buf list %p flags %lx, s %d, %d bufs\n",
147 				bl, op_flags, state, bl->nbufs);
148 			first = false;
149 		}
150 
151 		bl->nbufs--;
152 	}
153 
154 	WARN_ON(bl->nbufs);
155 }
156 
157 /*
158  * flush_firmware_streamon_fail() - Flush in cases where requests may
159  * have been queued to firmware and the *firmware streamon fails for a
160  * reason or another.
161  */
162 static void flush_firmware_streamon_fail(struct ipu7_isys_stream *stream)
163 {
164 	struct ipu7_isys_queue *aq;
165 	unsigned long flags;
166 
167 	lockdep_assert_held(&stream->mutex);
168 
169 	list_for_each_entry(aq, &stream->queues, node) {
170 		struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
171 		struct device *dev = &av->isys->adev->auxdev.dev;
172 		struct ipu7_isys_buffer *ib, *ib_safe;
173 
174 		spin_lock_irqsave(&aq->lock, flags);
175 		list_for_each_entry_safe(ib, ib_safe, &aq->active, head) {
176 			struct vb2_buffer *vb =
177 				ipu7_isys_buffer_to_vb2_buffer(ib);
178 
179 			list_del(&ib->head);
180 			if (av->streaming) {
181 				dev_dbg(dev,
182 					"%s: queue buffer %u back to incoming\n",
183 					av->vdev.name, vb->index);
184 				/* Queue already streaming, return to driver. */
185 				list_add(&ib->head, &aq->incoming);
186 				continue;
187 			}
188 			/* Queue not yet streaming, return to user. */
189 			dev_dbg(dev, "%s: return %u back to videobuf2\n",
190 				av->vdev.name, vb->index);
191 			vb2_buffer_done(ipu7_isys_buffer_to_vb2_buffer(ib),
192 					VB2_BUF_STATE_QUEUED);
193 		}
194 		spin_unlock_irqrestore(&aq->lock, flags);
195 	}
196 }
197 
198 /*
199  * Attempt obtaining a buffer list from the incoming queues, a list of buffers
200  * that contains one entry from each video buffer queue. If a buffer can't be
201  * obtained from every queue, the buffers are returned back to the queue.
202  */
203 static int buffer_list_get(struct ipu7_isys_stream *stream,
204 			   struct ipu7_isys_buffer_list *bl)
205 {
206 	unsigned long buf_flag = IPU_ISYS_BUFFER_LIST_FL_INCOMING;
207 	struct device *dev = &stream->isys->adev->auxdev.dev;
208 	struct ipu7_isys_queue *aq;
209 	unsigned long flags;
210 
211 	bl->nbufs = 0;
212 	INIT_LIST_HEAD(&bl->head);
213 
214 	list_for_each_entry(aq, &stream->queues, node) {
215 		struct ipu7_isys_buffer *ib;
216 
217 		spin_lock_irqsave(&aq->lock, flags);
218 		if (list_empty(&aq->incoming)) {
219 			spin_unlock_irqrestore(&aq->lock, flags);
220 			if (!list_empty(&bl->head))
221 				ipu7_isys_buffer_list_queue(bl, buf_flag, 0);
222 			return -ENODATA;
223 		}
224 
225 		ib = list_last_entry(&aq->incoming,
226 				     struct ipu7_isys_buffer, head);
227 
228 		dev_dbg(dev, "buffer: %s: buffer %u\n",
229 			ipu7_isys_queue_to_video(aq)->vdev.name,
230 			ipu7_isys_buffer_to_vb2_buffer(ib)->index);
231 		list_del(&ib->head);
232 		list_add(&ib->head, &bl->head);
233 		spin_unlock_irqrestore(&aq->lock, flags);
234 
235 		bl->nbufs++;
236 	}
237 
238 	dev_dbg(dev, "get buffer list %p, %u buffers\n", bl, bl->nbufs);
239 
240 	return 0;
241 }
242 
243 static void ipu7_isys_buf_to_fw_frame_buf_pin(struct vb2_buffer *vb,
244 					      struct ipu7_insys_buffset *set)
245 {
246 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue);
247 	struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb);
248 	struct ipu7_isys_video_buffer *ivb =
249 		vb2_buffer_to_ipu7_isys_video_buffer(vvb);
250 
251 	set->output_pins[aq->fw_output].addr = ivb->dma_addr;
252 	set->output_pins[aq->fw_output].user_token = (uintptr_t)set;
253 }
254 
255 /*
256  * Convert a buffer list to a isys fw ABI framebuffer set. The
257  * buffer list is not modified.
258  */
259 #define IPU_ISYS_FRAME_NUM_THRESHOLD	(30)
260 void ipu7_isys_buffer_to_fw_frame_buff(struct ipu7_insys_buffset *set,
261 				       struct ipu7_isys_stream *stream,
262 				       struct ipu7_isys_buffer_list *bl)
263 {
264 	struct ipu7_isys_buffer *ib;
265 	u32 buf_id;
266 
267 	WARN_ON(!bl->nbufs);
268 
269 	set->skip_frame = 0;
270 	set->capture_msg_map = IPU_INSYS_FRAME_ENABLE_MSG_SEND_RESP |
271 			       IPU_INSYS_FRAME_ENABLE_MSG_SEND_IRQ;
272 
273 	buf_id = atomic_fetch_inc(&stream->buf_id);
274 	set->frame_id = buf_id % IPU_MAX_FRAME_COUNTER;
275 
276 	list_for_each_entry(ib, &bl->head, head) {
277 		struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib);
278 
279 		ipu7_isys_buf_to_fw_frame_buf_pin(vb, set);
280 	}
281 }
282 
283 /* Start streaming for real. The buffer list must be available. */
284 static int ipu7_isys_stream_start(struct ipu7_isys_video *av,
285 				  struct ipu7_isys_buffer_list *bl, bool error)
286 {
287 	struct ipu7_isys_stream *stream = av->stream;
288 	struct device *dev = &stream->isys->adev->auxdev.dev;
289 	struct ipu7_isys_buffer_list __bl;
290 	int ret;
291 
292 	mutex_lock(&stream->isys->stream_mutex);
293 
294 	ret = ipu7_isys_video_set_streaming(av, 1, bl);
295 	mutex_unlock(&stream->isys->stream_mutex);
296 	if (ret)
297 		goto out_requeue;
298 
299 	stream->streaming = 1;
300 
301 	bl = &__bl;
302 
303 	do {
304 		struct ipu7_insys_buffset *buf = NULL;
305 		struct isys_fw_msgs *msg;
306 		enum ipu7_insys_send_type send_type =
307 			IPU_INSYS_SEND_TYPE_STREAM_CAPTURE;
308 
309 		ret = buffer_list_get(stream, bl);
310 		if (ret < 0)
311 			break;
312 
313 		msg = ipu7_get_fw_msg_buf(stream);
314 		if (!msg)
315 			return -ENOMEM;
316 
317 		buf = &msg->fw_msg.frame;
318 
319 		ipu7_isys_buffer_to_fw_frame_buff(buf, stream, bl);
320 
321 		ipu7_fw_isys_dump_frame_buff_set(dev, buf,
322 						 stream->nr_output_pins);
323 
324 		ipu7_isys_buffer_list_queue(bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE,
325 					    0);
326 
327 		ret = ipu7_fw_isys_complex_cmd(stream->isys,
328 					       stream->stream_handle, buf,
329 					       msg->dma_addr, sizeof(*buf),
330 					       send_type);
331 	} while (!WARN_ON(ret));
332 
333 	return 0;
334 
335 out_requeue:
336 	if (bl && bl->nbufs)
337 		ipu7_isys_buffer_list_queue(bl,
338 					    IPU_ISYS_BUFFER_LIST_FL_INCOMING |
339 					    (error ?
340 					     IPU_ISYS_BUFFER_LIST_FL_SET_STATE :
341 					     0), error ? VB2_BUF_STATE_ERROR :
342 					    VB2_BUF_STATE_QUEUED);
343 	flush_firmware_streamon_fail(stream);
344 
345 	return ret;
346 }
347 
348 static void buf_queue(struct vb2_buffer *vb)
349 {
350 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue);
351 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
352 	struct vb2_v4l2_buffer *vvb = to_vb2_v4l2_buffer(vb);
353 	struct ipu7_isys_video_buffer *ivb =
354 		vb2_buffer_to_ipu7_isys_video_buffer(vvb);
355 	struct media_pipeline *media_pipe =
356 		media_entity_pipeline(&av->vdev.entity);
357 	struct device *dev = &av->isys->adev->auxdev.dev;
358 	struct ipu7_isys_stream *stream = av->stream;
359 	struct ipu7_isys_buffer *ib = &ivb->ib;
360 	struct ipu7_insys_buffset *buf = NULL;
361 	struct ipu7_isys_buffer_list bl;
362 	struct isys_fw_msgs *msg;
363 	unsigned long flags;
364 	dma_addr_t dma;
365 	int ret;
366 
367 	dev_dbg(dev, "queue buffer %u for %s\n", vb->index, av->vdev.name);
368 
369 	dma = ivb->dma_addr;
370 	dev_dbg(dev, "iova: iova %pad\n", &dma);
371 
372 	spin_lock_irqsave(&aq->lock, flags);
373 	list_add(&ib->head, &aq->incoming);
374 	spin_unlock_irqrestore(&aq->lock, flags);
375 
376 	if (!media_pipe || !vb->vb2_queue->start_streaming_called) {
377 		dev_dbg(dev, "media pipeline is not ready for %s\n",
378 			av->vdev.name);
379 		return;
380 	}
381 
382 	mutex_lock(&stream->mutex);
383 
384 	if (stream->nr_streaming != stream->nr_queues) {
385 		dev_dbg(dev, "not streaming yet, adding to incoming\n");
386 		goto out;
387 	}
388 
389 	/*
390 	 * We just put one buffer to the incoming list of this queue
391 	 * (above). Let's see whether all queues in the pipeline would
392 	 * have a buffer.
393 	 */
394 	ret = buffer_list_get(stream, &bl);
395 	if (ret < 0) {
396 		dev_dbg(dev, "No buffers available\n");
397 		goto out;
398 	}
399 
400 	msg = ipu7_get_fw_msg_buf(stream);
401 	if (!msg) {
402 		ret = -ENOMEM;
403 		goto out;
404 	}
405 
406 	buf = &msg->fw_msg.frame;
407 
408 	ipu7_isys_buffer_to_fw_frame_buff(buf, stream, &bl);
409 
410 	ipu7_fw_isys_dump_frame_buff_set(dev, buf, stream->nr_output_pins);
411 
412 	if (!stream->streaming) {
413 		ret = ipu7_isys_stream_start(av, &bl, true);
414 		if (ret)
415 			dev_err(dev, "stream start failed.\n");
416 		goto out;
417 	}
418 
419 	/*
420 	 * We must queue the buffers in the buffer list to the
421 	 * appropriate video buffer queues BEFORE passing them to the
422 	 * firmware since we could get a buffer event back before we
423 	 * have queued them ourselves to the active queue.
424 	 */
425 	ipu7_isys_buffer_list_queue(&bl, IPU_ISYS_BUFFER_LIST_FL_ACTIVE, 0);
426 
427 	ret = ipu7_fw_isys_complex_cmd(stream->isys, stream->stream_handle,
428 				       buf, msg->dma_addr, sizeof(*buf),
429 				       IPU_INSYS_SEND_TYPE_STREAM_CAPTURE);
430 	if (ret < 0)
431 		dev_err(dev, "send stream capture failed\n");
432 
433 out:
434 	mutex_unlock(&stream->mutex);
435 }
436 
437 static int ipu7_isys_link_fmt_validate(struct ipu7_isys_queue *aq)
438 {
439 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
440 	struct device *dev = &av->isys->adev->auxdev.dev;
441 	struct media_pad *remote_pad =
442 		media_pad_remote_pad_first(av->vdev.entity.pads);
443 	struct v4l2_mbus_framefmt format;
444 	struct v4l2_subdev *sd;
445 	u32 r_stream, code;
446 	int ret;
447 
448 	if (!remote_pad)
449 		return -ENOTCONN;
450 
451 	sd = media_entity_to_v4l2_subdev(remote_pad->entity);
452 	r_stream = ipu7_isys_get_src_stream_by_src_pad(sd, remote_pad->index);
453 
454 	ret = ipu7_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream,
455 					   &format);
456 	if (ret) {
457 		dev_dbg(dev, "failed to get %s: pad %d, stream:%d format\n",
458 			sd->entity.name, remote_pad->index, r_stream);
459 		return ret;
460 	}
461 
462 	if (format.width != av->pix_fmt.width ||
463 	    format.height != av->pix_fmt.height) {
464 		dev_dbg(dev, "wrong width or height %ux%u (%ux%u expected)\n",
465 			av->pix_fmt.width, av->pix_fmt.height, format.width,
466 			format.height);
467 		return -EINVAL;
468 	}
469 
470 	code = ipu7_isys_get_isys_format(av->pix_fmt.pixelformat)->code;
471 	if (format.code != code) {
472 		dev_dbg(dev, "wrong mbus code 0x%8.8x (0x%8.8x expected)\n",
473 			code, format.code);
474 		return -EINVAL;
475 	}
476 
477 	return 0;
478 }
479 
480 static void return_buffers(struct ipu7_isys_queue *aq,
481 			   enum vb2_buffer_state state)
482 {
483 	struct ipu7_isys_buffer *ib;
484 	struct vb2_buffer *vb;
485 	unsigned long flags;
486 
487 	spin_lock_irqsave(&aq->lock, flags);
488 	/*
489 	 * Something went wrong (FW crash / HW hang / not all buffers
490 	 * returned from isys) if there are still buffers queued in active
491 	 * queue. We have to clean up places a bit.
492 	 */
493 	while (!list_empty(&aq->active)) {
494 		ib = list_last_entry(&aq->active, struct ipu7_isys_buffer,
495 				     head);
496 		vb = ipu7_isys_buffer_to_vb2_buffer(ib);
497 
498 		list_del(&ib->head);
499 		spin_unlock_irqrestore(&aq->lock, flags);
500 
501 		vb2_buffer_done(vb, state);
502 
503 		spin_lock_irqsave(&aq->lock, flags);
504 	}
505 
506 	while (!list_empty(&aq->incoming)) {
507 		ib = list_last_entry(&aq->incoming, struct ipu7_isys_buffer,
508 				     head);
509 		vb = ipu7_isys_buffer_to_vb2_buffer(ib);
510 		list_del(&ib->head);
511 		spin_unlock_irqrestore(&aq->lock, flags);
512 
513 		vb2_buffer_done(vb, state);
514 
515 		spin_lock_irqsave(&aq->lock, flags);
516 	}
517 
518 	spin_unlock_irqrestore(&aq->lock, flags);
519 }
520 
521 static void ipu7_isys_stream_cleanup(struct ipu7_isys_video *av)
522 {
523 	video_device_pipeline_stop(&av->vdev);
524 	ipu7_isys_put_stream(av->stream);
525 	av->stream = NULL;
526 }
527 
528 static int start_streaming(struct vb2_queue *q, unsigned int count)
529 {
530 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q);
531 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
532 	struct device *dev = &av->isys->adev->auxdev.dev;
533 	const struct ipu7_isys_pixelformat *pfmt =
534 		ipu7_isys_get_isys_format(av->pix_fmt.pixelformat);
535 	struct ipu7_isys_buffer_list __bl, *bl = NULL;
536 	struct ipu7_isys_stream *stream;
537 	struct media_entity *source_entity = NULL;
538 	int nr_queues, ret;
539 
540 	dev_dbg(dev, "stream: %s: width %u, height %u, css pixelformat %u\n",
541 		av->vdev.name, av->pix_fmt.width, av->pix_fmt.height,
542 		pfmt->css_pixelformat);
543 
544 	ret = ipu7_isys_setup_video(av, &source_entity, &nr_queues);
545 	if (ret < 0) {
546 		dev_dbg(dev, "failed to setup video\n");
547 		goto out_return_buffers;
548 	}
549 
550 	ret = ipu7_isys_link_fmt_validate(aq);
551 	if (ret) {
552 		dev_dbg(dev,
553 			"%s: link format validation failed (%d)\n",
554 			av->vdev.name, ret);
555 		goto out_pipeline_stop;
556 	}
557 
558 	stream = av->stream;
559 	mutex_lock(&stream->mutex);
560 	if (!stream->nr_streaming) {
561 		ret = ipu7_isys_video_prepare_stream(av, source_entity,
562 						     nr_queues);
563 		if (ret) {
564 			mutex_unlock(&stream->mutex);
565 			goto out_pipeline_stop;
566 		}
567 	}
568 
569 	stream->nr_streaming++;
570 	dev_dbg(dev, "queue %u of %u\n", stream->nr_streaming,
571 		stream->nr_queues);
572 
573 	list_add(&aq->node, &stream->queues);
574 
575 	if (stream->nr_streaming != stream->nr_queues)
576 		goto out;
577 
578 	bl = &__bl;
579 	ret = buffer_list_get(stream, bl);
580 	if (ret < 0) {
581 		dev_warn(dev, "no buffer available, DRIVER BUG?\n");
582 		goto out;
583 	}
584 
585 	ret = ipu7_isys_fw_open(av->isys);
586 	if (ret)
587 		goto out_stream_start;
588 
589 	ipu7_isys_setup_hw(av->isys);
590 
591 	ret = ipu7_isys_stream_start(av, bl, false);
592 	if (ret)
593 		goto out_isys_fw_close;
594 
595 out:
596 	mutex_unlock(&stream->mutex);
597 
598 	return 0;
599 
600 out_isys_fw_close:
601 	ipu7_isys_fw_close(av->isys);
602 
603 out_stream_start:
604 	list_del(&aq->node);
605 	stream->nr_streaming--;
606 	mutex_unlock(&stream->mutex);
607 
608 out_pipeline_stop:
609 	ipu7_isys_stream_cleanup(av);
610 
611 out_return_buffers:
612 	return_buffers(aq, VB2_BUF_STATE_QUEUED);
613 
614 	return ret;
615 }
616 
617 static void stop_streaming(struct vb2_queue *q)
618 {
619 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(q);
620 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
621 	struct ipu7_isys_stream *stream = av->stream;
622 
623 	mutex_lock(&stream->mutex);
624 	mutex_lock(&av->isys->stream_mutex);
625 	if (stream->nr_streaming == stream->nr_queues && stream->streaming)
626 		ipu7_isys_video_set_streaming(av, 0, NULL);
627 	mutex_unlock(&av->isys->stream_mutex);
628 
629 	stream->nr_streaming--;
630 	list_del(&aq->node);
631 	stream->streaming = 0;
632 
633 	mutex_unlock(&stream->mutex);
634 
635 	ipu7_isys_stream_cleanup(av);
636 
637 	return_buffers(aq, VB2_BUF_STATE_ERROR);
638 
639 	ipu7_isys_fw_close(av->isys);
640 }
641 
642 static unsigned int
643 get_sof_sequence_by_timestamp(struct ipu7_isys_stream *stream, u64 time)
644 {
645 	struct ipu7_isys *isys = stream->isys;
646 	struct device *dev = &isys->adev->auxdev.dev;
647 	unsigned int i;
648 
649 	/*
650 	 * The timestamp is invalid as no TSC in some FPGA platform,
651 	 * so get the sequence from pipeline directly in this case.
652 	 */
653 	if (time == 0)
654 		return atomic_read(&stream->sequence) - 1;
655 
656 	for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++)
657 		if (time == stream->seq[i].timestamp) {
658 			dev_dbg(dev, "SOF: using seq nr %u for ts %llu\n",
659 				stream->seq[i].sequence, time);
660 			return stream->seq[i].sequence;
661 		}
662 
663 	dev_dbg(dev, "SOF: looking for %llu\n", time);
664 	for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++)
665 		dev_dbg(dev, "SOF: sequence %u, timestamp value %llu\n",
666 			stream->seq[i].sequence, stream->seq[i].timestamp);
667 	dev_dbg(dev, "SOF sequence number not found\n");
668 
669 	return atomic_read(&stream->sequence) - 1;
670 }
671 
672 static u64 get_sof_ns_delta(struct ipu7_isys_video *av, u64 time)
673 {
674 	struct ipu7_bus_device *adev = av->isys->adev;
675 	struct ipu7_device *isp = adev->isp;
676 	u64 delta, tsc_now;
677 
678 	ipu_buttress_tsc_read(isp, &tsc_now);
679 	if (!tsc_now)
680 		return 0;
681 
682 	delta = tsc_now - time;
683 
684 	return ipu_buttress_tsc_ticks_to_ns(delta, isp);
685 }
686 
687 static void ipu7_isys_buf_calc_sequence_time(struct ipu7_isys_buffer *ib,
688 					     u64 time)
689 {
690 	struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib);
691 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
692 	struct ipu7_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue);
693 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
694 	struct device *dev = &av->isys->adev->auxdev.dev;
695 	struct ipu7_isys_stream *stream = av->stream;
696 	u64 ns;
697 	u32 sequence;
698 
699 	ns = ktime_get_ns() - get_sof_ns_delta(av, time);
700 	sequence = get_sof_sequence_by_timestamp(stream, time);
701 
702 	vbuf->vb2_buf.timestamp = ns;
703 	vbuf->sequence = sequence;
704 
705 	dev_dbg(dev, "buf: %s: buffer done, CPU-timestamp:%lld, sequence:%d\n",
706 		av->vdev.name, ktime_get_ns(), sequence);
707 	dev_dbg(dev, "index:%d, vbuf timestamp:%lld\n", vb->index,
708 		vbuf->vb2_buf.timestamp);
709 }
710 
711 static void ipu7_isys_queue_buf_done(struct ipu7_isys_buffer *ib)
712 {
713 	struct vb2_buffer *vb = ipu7_isys_buffer_to_vb2_buffer(ib);
714 
715 	if (atomic_read(&ib->str2mmio_flag)) {
716 		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
717 		/*
718 		 * Operation on buffer is ended with error and will be reported
719 		 * to the userspace when it is de-queued
720 		 */
721 		atomic_set(&ib->str2mmio_flag, 0);
722 	} else {
723 		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
724 	}
725 }
726 
727 void ipu7_isys_queue_buf_ready(struct ipu7_isys_stream *stream,
728 			       struct ipu7_insys_resp *info)
729 {
730 	struct ipu7_isys_queue *aq = stream->output_pins[info->pin_id].aq;
731 	u64 time = ((u64)info->timestamp[1] << 32 | info->timestamp[0]);
732 	struct ipu7_isys *isys = stream->isys;
733 	struct device *dev = &isys->adev->auxdev.dev;
734 	struct ipu7_isys_buffer *ib;
735 	struct vb2_buffer *vb;
736 	unsigned long flags;
737 	bool first = true;
738 	struct vb2_v4l2_buffer *buf;
739 
740 	dev_dbg(dev, "buffer: %s: received buffer %8.8x %d\n",
741 		ipu7_isys_queue_to_video(aq)->vdev.name, info->pin.addr,
742 		info->frame_id);
743 
744 	spin_lock_irqsave(&aq->lock, flags);
745 	if (list_empty(&aq->active)) {
746 		spin_unlock_irqrestore(&aq->lock, flags);
747 		dev_err(dev, "active queue empty\n");
748 		return;
749 	}
750 
751 	list_for_each_entry_reverse(ib, &aq->active, head) {
752 		struct ipu7_isys_video_buffer *ivb;
753 		struct vb2_v4l2_buffer *vvb;
754 		dma_addr_t addr;
755 
756 		vb = ipu7_isys_buffer_to_vb2_buffer(ib);
757 		vvb = to_vb2_v4l2_buffer(vb);
758 		ivb = vb2_buffer_to_ipu7_isys_video_buffer(vvb);
759 		addr = ivb->dma_addr;
760 
761 		if (info->pin.addr != addr) {
762 			if (first)
763 				dev_err(dev, "Unexpected buffer address %pad\n",
764 					&addr);
765 
766 			first = false;
767 			continue;
768 		}
769 
770 		dev_dbg(dev, "buffer: found buffer %pad\n", &addr);
771 
772 		buf = to_vb2_v4l2_buffer(vb);
773 		buf->field = V4L2_FIELD_NONE;
774 
775 		list_del(&ib->head);
776 		spin_unlock_irqrestore(&aq->lock, flags);
777 
778 		ipu7_isys_buf_calc_sequence_time(ib, time);
779 
780 		ipu7_isys_queue_buf_done(ib);
781 
782 		return;
783 	}
784 
785 	dev_err(dev, "Failed to find a matching video buffer\n");
786 
787 	spin_unlock_irqrestore(&aq->lock, flags);
788 }
789 
790 static const struct vb2_ops ipu7_isys_queue_ops = {
791 	.queue_setup = ipu7_isys_queue_setup,
792 	.buf_init = ipu7_isys_buf_init,
793 	.buf_prepare = ipu7_isys_buf_prepare,
794 	.buf_cleanup = ipu7_isys_buf_cleanup,
795 	.start_streaming = start_streaming,
796 	.stop_streaming = stop_streaming,
797 	.buf_queue = buf_queue,
798 };
799 
800 int ipu7_isys_queue_init(struct ipu7_isys_queue *aq)
801 {
802 	struct ipu7_isys *isys = ipu7_isys_queue_to_video(aq)->isys;
803 	struct ipu7_isys_video *av = ipu7_isys_queue_to_video(aq);
804 	struct ipu7_bus_device *adev = isys->adev;
805 	int ret;
806 
807 	if (!aq->vbq.io_modes)
808 		aq->vbq.io_modes = VB2_MMAP | VB2_DMABUF;
809 
810 	aq->vbq.drv_priv = isys;
811 	aq->vbq.ops = &ipu7_isys_queue_ops;
812 	aq->vbq.lock = &av->mutex;
813 	aq->vbq.mem_ops = &vb2_dma_sg_memops;
814 	aq->vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
815 	aq->vbq.min_queued_buffers = 1;
816 	aq->vbq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
817 
818 	ret = vb2_queue_init(&aq->vbq);
819 	if (ret)
820 		return ret;
821 
822 	aq->dev = &adev->auxdev.dev;
823 	aq->vbq.dev = &adev->isp->pdev->dev;
824 	spin_lock_init(&aq->lock);
825 	INIT_LIST_HEAD(&aq->active);
826 	INIT_LIST_HEAD(&aq->incoming);
827 
828 	return 0;
829 }
830