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