Lines Matching +full:bl +full:- +full:name

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013--2024 Intel Corporation
14 #include <media/media-entity.h>
15 #include <media/v4l2-subdev.h>
16 #include <media/videobuf2-dma-sg.h>
17 #include <media/videobuf2-v4l2.h>
19 #include "ipu6-bus.h"
20 #include "ipu6-dma.h"
21 #include "ipu6-fw-isys.h"
22 #include "ipu6-isys.h"
23 #include "ipu6-isys-video.h"
27 struct ipu6_isys *isys = vb2_get_drv_priv(vb->vb2_queue); in ipu6_isys_buf_init()
34 ret = ipu6_dma_map_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0); in ipu6_isys_buf_init()
38 ivb->dma_addr = sg_dma_address(sg->sgl); in ipu6_isys_buf_init()
45 struct ipu6_isys *isys = vb2_get_drv_priv(vb->vb2_queue); in ipu6_isys_buf_cleanup()
51 ivb->dma_addr = 0; in ipu6_isys_buf_cleanup()
52 ipu6_dma_unmap_sgtable(isys->adev, sg, DMA_TO_DEVICE, 0); in ipu6_isys_buf_cleanup()
61 struct device *dev = &av->isys->adev->auxdev.dev; in ipu6_isys_queue_setup()
69 av->vdev.name, sizes[0], size); in ipu6_isys_queue_setup()
70 return -EINVAL; in ipu6_isys_queue_setup()
80 struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); in ipu6_isys_buf_prepare()
82 struct device *dev = &av->isys->adev->auxdev.dev; in ipu6_isys_buf_prepare()
88 av->vdev.name, size, vb2_plane_size(vb, 0)); in ipu6_isys_buf_prepare()
91 return -EINVAL; in ipu6_isys_buf_prepare()
102 void ipu6_isys_buffer_list_queue(struct ipu6_isys_buffer_list *bl, in ipu6_isys_buffer_list_queue() argument
110 if (!bl) in ipu6_isys_buffer_list_queue()
113 WARN_ON_ONCE(!bl->nbufs); in ipu6_isys_buffer_list_queue()
117 list_for_each_entry_safe(ib, ib_safe, &bl->head, head) { in ipu6_isys_buffer_list_queue()
121 vb2_queue_to_isys_queue(vb->vb2_queue); in ipu6_isys_buffer_list_queue()
125 dev = &av->isys->adev->auxdev.dev; in ipu6_isys_buffer_list_queue()
126 spin_lock_irqsave(&aq->lock, flags); in ipu6_isys_buffer_list_queue()
127 list_del(&ib->head); in ipu6_isys_buffer_list_queue()
129 list_add(&ib->head, &aq->active); in ipu6_isys_buffer_list_queue()
131 list_add_tail(&ib->head, &aq->incoming); in ipu6_isys_buffer_list_queue()
132 spin_unlock_irqrestore(&aq->lock, flags); in ipu6_isys_buffer_list_queue()
140 bl, op_flags, state, bl->nbufs); in ipu6_isys_buffer_list_queue()
144 bl->nbufs--; in ipu6_isys_buffer_list_queue()
147 WARN_ON(bl->nbufs); in ipu6_isys_buffer_list_queue()
151 * flush_firmware_streamon_fail() - Flush in cases where requests may
157 struct device *dev = &stream->isys->adev->auxdev.dev; in flush_firmware_streamon_fail()
161 lockdep_assert_held(&stream->mutex); in flush_firmware_streamon_fail()
163 list_for_each_entry(aq, &stream->queues, node) { in flush_firmware_streamon_fail()
167 spin_lock_irqsave(&aq->lock, flags); in flush_firmware_streamon_fail()
168 list_for_each_entry_safe(ib, ib_safe, &aq->active, head) { in flush_firmware_streamon_fail()
172 list_del(&ib->head); in flush_firmware_streamon_fail()
173 if (av->streaming) { in flush_firmware_streamon_fail()
176 av->vdev.name, vb->index); in flush_firmware_streamon_fail()
178 list_add(&ib->head, &aq->incoming); in flush_firmware_streamon_fail()
183 av->vdev.name, vb->index); in flush_firmware_streamon_fail()
187 spin_unlock_irqrestore(&aq->lock, flags); in flush_firmware_streamon_fail()
197 struct ipu6_isys_buffer_list *bl) in buffer_list_get() argument
199 struct device *dev = &stream->isys->adev->auxdev.dev; in buffer_list_get()
204 bl->nbufs = 0; in buffer_list_get()
205 INIT_LIST_HEAD(&bl->head); in buffer_list_get()
207 list_for_each_entry(aq, &stream->queues, node) { in buffer_list_get()
210 spin_lock_irqsave(&aq->lock, flags); in buffer_list_get()
211 if (list_empty(&aq->incoming)) { in buffer_list_get()
212 spin_unlock_irqrestore(&aq->lock, flags); in buffer_list_get()
213 if (!list_empty(&bl->head)) in buffer_list_get()
214 ipu6_isys_buffer_list_queue(bl, buf_flag, 0); in buffer_list_get()
215 return -ENODATA; in buffer_list_get()
218 ib = list_last_entry(&aq->incoming, in buffer_list_get()
222 ipu6_isys_queue_to_video(aq)->vdev.name, in buffer_list_get()
223 ipu6_isys_buffer_to_vb2_buffer(ib)->index); in buffer_list_get()
224 list_del(&ib->head); in buffer_list_get()
225 list_add(&ib->head, &bl->head); in buffer_list_get()
226 spin_unlock_irqrestore(&aq->lock, flags); in buffer_list_get()
228 bl->nbufs++; in buffer_list_get()
231 dev_dbg(dev, "get buffer list %p, %u buffers\n", bl, bl->nbufs); in buffer_list_get()
240 struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); in ipu6_isys_buf_to_fw_frame_buf_pin()
245 set->output_pins[aq->fw_output].addr = ivb->dma_addr; in ipu6_isys_buf_to_fw_frame_buf_pin()
246 set->output_pins[aq->fw_output].out_buf_id = vb->index + 1; in ipu6_isys_buf_to_fw_frame_buf_pin()
257 struct ipu6_isys_buffer_list *bl) in ipu6_isys_buf_to_fw_frame_buf() argument
261 WARN_ON(!bl->nbufs); in ipu6_isys_buf_to_fw_frame_buf()
263 set->send_irq_sof = 1; in ipu6_isys_buf_to_fw_frame_buf()
264 set->send_resp_sof = 1; in ipu6_isys_buf_to_fw_frame_buf()
265 set->send_irq_eof = 0; in ipu6_isys_buf_to_fw_frame_buf()
266 set->send_resp_eof = 0; in ipu6_isys_buf_to_fw_frame_buf()
268 if (stream->streaming) in ipu6_isys_buf_to_fw_frame_buf()
269 set->send_irq_capture_ack = 0; in ipu6_isys_buf_to_fw_frame_buf()
271 set->send_irq_capture_ack = 1; in ipu6_isys_buf_to_fw_frame_buf()
272 set->send_irq_capture_done = 0; in ipu6_isys_buf_to_fw_frame_buf()
274 set->send_resp_capture_ack = 1; in ipu6_isys_buf_to_fw_frame_buf()
275 set->send_resp_capture_done = 1; in ipu6_isys_buf_to_fw_frame_buf()
276 if (atomic_read(&stream->sequence) >= IPU6_ISYS_FRAME_NUM_THRESHOLD) { in ipu6_isys_buf_to_fw_frame_buf()
277 set->send_resp_capture_ack = 0; in ipu6_isys_buf_to_fw_frame_buf()
278 set->send_resp_capture_done = 0; in ipu6_isys_buf_to_fw_frame_buf()
281 list_for_each_entry(ib, &bl->head, head) { in ipu6_isys_buf_to_fw_frame_buf()
290 struct ipu6_isys_buffer_list *bl, bool error) in ipu6_isys_stream_start() argument
292 struct ipu6_isys_stream *stream = av->stream; in ipu6_isys_stream_start()
293 struct device *dev = &stream->isys->adev->auxdev.dev; in ipu6_isys_stream_start()
297 mutex_lock(&stream->isys->stream_mutex); in ipu6_isys_stream_start()
298 ret = ipu6_isys_video_set_streaming(av, 1, bl); in ipu6_isys_stream_start()
299 mutex_unlock(&stream->isys->stream_mutex); in ipu6_isys_stream_start()
303 stream->streaming = 1; in ipu6_isys_stream_start()
305 bl = &__bl; in ipu6_isys_stream_start()
312 ret = buffer_list_get(stream, bl); in ipu6_isys_stream_start()
318 return -ENOMEM; in ipu6_isys_stream_start()
320 buf = &msg->fw_msg.frame; in ipu6_isys_stream_start()
321 ipu6_isys_buf_to_fw_frame_buf(buf, stream, bl); in ipu6_isys_stream_start()
323 stream->nr_output_pins); in ipu6_isys_stream_start()
324 ipu6_isys_buffer_list_queue(bl, IPU6_ISYS_BUFFER_LIST_FL_ACTIVE, in ipu6_isys_stream_start()
326 ret = ipu6_fw_isys_complex_cmd(stream->isys, in ipu6_isys_stream_start()
327 stream->stream_handle, buf, in ipu6_isys_stream_start()
328 msg->dma_addr, sizeof(*buf), in ipu6_isys_stream_start()
335 if (bl && bl->nbufs) in ipu6_isys_stream_start()
336 ipu6_isys_buffer_list_queue(bl, in ipu6_isys_stream_start()
349 struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); in buf_queue()
354 struct ipu6_isys_buffer *ib = &ivb->ib; in buf_queue()
355 struct device *dev = &av->isys->adev->auxdev.dev; in buf_queue()
357 media_entity_pipeline(&av->vdev.entity); in buf_queue()
359 struct ipu6_isys_stream *stream = av->stream; in buf_queue()
360 struct ipu6_isys_buffer_list bl; in buf_queue() local
366 dev_dbg(dev, "queue buffer %u for %s\n", vb->index, av->vdev.name); in buf_queue()
368 dma = ivb->dma_addr; in buf_queue()
371 spin_lock_irqsave(&aq->lock, flags); in buf_queue()
372 list_add(&ib->head, &aq->incoming); in buf_queue()
373 spin_unlock_irqrestore(&aq->lock, flags); in buf_queue()
375 if (!media_pipe || !vb->vb2_queue->start_streaming_called) { in buf_queue()
377 av->vdev.name); in buf_queue()
381 mutex_lock(&stream->mutex); in buf_queue()
383 if (stream->nr_streaming != stream->nr_queues) { in buf_queue()
393 ret = buffer_list_get(stream, &bl); in buf_queue()
401 ret = -ENOMEM; in buf_queue()
405 buf = &msg->fw_msg.frame; in buf_queue()
406 ipu6_isys_buf_to_fw_frame_buf(buf, stream, &bl); in buf_queue()
407 ipu6_fw_isys_dump_frame_buff_set(dev, buf, stream->nr_output_pins); in buf_queue()
409 if (!stream->streaming) { in buf_queue()
410 ret = ipu6_isys_stream_start(av, &bl, true); in buf_queue()
422 ipu6_isys_buffer_list_queue(&bl, IPU6_ISYS_BUFFER_LIST_FL_ACTIVE, 0); in buf_queue()
424 ret = ipu6_fw_isys_complex_cmd(stream->isys, stream->stream_handle, in buf_queue()
425 buf, msg->dma_addr, sizeof(*buf), in buf_queue()
431 mutex_unlock(&stream->mutex); in buf_queue()
438 struct device *dev = &av->isys->adev->auxdev.dev; in ipu6_isys_link_fmt_validate()
440 media_pad_remote_pad_first(av->vdev.entity.pads); in ipu6_isys_link_fmt_validate()
446 return -ENOTCONN; in ipu6_isys_link_fmt_validate()
448 sd = media_entity_to_v4l2_subdev(remote_pad->entity); in ipu6_isys_link_fmt_validate()
449 r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, remote_pad->index); in ipu6_isys_link_fmt_validate()
451 ret = ipu6_isys_get_stream_pad_fmt(sd, remote_pad->index, r_stream, in ipu6_isys_link_fmt_validate()
456 sd->entity.name, remote_pad->index, r_stream); in ipu6_isys_link_fmt_validate()
466 return -EINVAL; in ipu6_isys_link_fmt_validate()
469 code = ipu6_isys_get_isys_format(ipu6_isys_get_format(av), 0)->code; in ipu6_isys_link_fmt_validate()
473 return -EINVAL; in ipu6_isys_link_fmt_validate()
487 spin_lock_irqsave(&aq->lock, flags); in return_buffers()
488 while (!list_empty(&aq->incoming)) { in return_buffers()
491 ib = list_first_entry(&aq->incoming, struct ipu6_isys_buffer, in return_buffers()
494 list_del(&ib->head); in return_buffers()
495 spin_unlock_irqrestore(&aq->lock, flags); in return_buffers()
499 spin_lock_irqsave(&aq->lock, flags); in return_buffers()
507 while (!list_empty(&aq->active)) { in return_buffers()
510 ib = list_first_entry(&aq->active, struct ipu6_isys_buffer, in return_buffers()
514 list_del(&ib->head); in return_buffers()
515 spin_unlock_irqrestore(&aq->lock, flags); in return_buffers()
519 spin_lock_irqsave(&aq->lock, flags); in return_buffers()
523 spin_unlock_irqrestore(&aq->lock, flags); in return_buffers()
526 mutex_lock(&av->isys->mutex); in return_buffers()
527 av->isys->need_reset = true; in return_buffers()
528 mutex_unlock(&av->isys->mutex); in return_buffers()
534 video_device_pipeline_stop(&av->vdev); in ipu6_isys_stream_cleanup()
535 ipu6_isys_put_stream(av->stream); in ipu6_isys_stream_cleanup()
536 av->stream = NULL; in ipu6_isys_stream_cleanup()
543 struct device *dev = &av->isys->adev->auxdev.dev; in start_streaming()
546 struct ipu6_isys_buffer_list __bl, *bl = NULL; in start_streaming() local
552 av->vdev.name, ipu6_isys_get_frame_width(av), in start_streaming()
553 ipu6_isys_get_frame_height(av), pfmt->css_pixelformat); in start_streaming()
565 av->vdev.name, ret); in start_streaming()
569 ret = ipu6_isys_fw_open(av->isys); in start_streaming()
573 stream = av->stream; in start_streaming()
574 mutex_lock(&stream->mutex); in start_streaming()
575 if (!stream->nr_streaming) { in start_streaming()
582 stream->nr_streaming++; in start_streaming()
583 dev_dbg(dev, "queue %u of %u\n", stream->nr_streaming, in start_streaming()
584 stream->nr_queues); in start_streaming()
586 list_add(&aq->node, &stream->queues); in start_streaming()
590 if (stream->nr_streaming != stream->nr_queues) in start_streaming()
593 bl = &__bl; in start_streaming()
594 ret = buffer_list_get(stream, bl); in start_streaming()
600 ret = ipu6_isys_stream_start(av, bl, false); in start_streaming()
605 mutex_unlock(&stream->mutex); in start_streaming()
611 list_del(&aq->node); in start_streaming()
612 stream->nr_streaming--; in start_streaming()
615 mutex_unlock(&stream->mutex); in start_streaming()
616 ipu6_isys_fw_close(av->isys); in start_streaming()
631 struct ipu6_isys_stream *stream = av->stream; in stop_streaming()
633 mutex_lock(&stream->mutex); in stop_streaming()
637 mutex_lock(&av->isys->stream_mutex); in stop_streaming()
638 if (stream->nr_streaming == stream->nr_queues && stream->streaming) in stop_streaming()
640 mutex_unlock(&av->isys->stream_mutex); in stop_streaming()
642 stream->nr_streaming--; in stop_streaming()
643 list_del(&aq->node); in stop_streaming()
644 stream->streaming = 0; in stop_streaming()
645 mutex_unlock(&stream->mutex); in stop_streaming()
651 ipu6_isys_fw_close(av->isys); in stop_streaming()
658 u64 time = (u64)info->timestamp[1] << 32 | info->timestamp[0]; in get_sof_sequence_by_timestamp()
659 struct ipu6_isys *isys = stream->isys; in get_sof_sequence_by_timestamp()
660 struct device *dev = &isys->adev->auxdev.dev; in get_sof_sequence_by_timestamp()
668 return atomic_read(&stream->sequence) - 1; in get_sof_sequence_by_timestamp()
671 if (time == stream->seq[i].timestamp) { in get_sof_sequence_by_timestamp()
673 stream->seq[i].sequence, time); in get_sof_sequence_by_timestamp()
674 return stream->seq[i].sequence; in get_sof_sequence_by_timestamp()
679 stream->seq[i].sequence, stream->seq[i].timestamp); in get_sof_sequence_by_timestamp()
687 struct ipu6_bus_device *adev = av->isys->adev; in get_sof_ns_delta()
688 struct ipu6_device *isp = adev->isp; in get_sof_ns_delta()
695 delta = tsc_now - ((u64)info->timestamp[1] << 32 | info->timestamp[0]); in get_sof_ns_delta()
705 struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); in ipu6_isys_buf_calc_sequence_time()
707 struct device *dev = &av->isys->adev->auxdev.dev; in ipu6_isys_buf_calc_sequence_time()
708 struct ipu6_isys_stream *stream = av->stream; in ipu6_isys_buf_calc_sequence_time()
712 ns = ktime_get_ns() - get_sof_ns_delta(av, info); in ipu6_isys_buf_calc_sequence_time()
715 vbuf->vb2_buf.timestamp = ns; in ipu6_isys_buf_calc_sequence_time()
716 vbuf->sequence = sequence; in ipu6_isys_buf_calc_sequence_time()
718 dev_dbg(dev, "buf: %s: buffer done, CPU-timestamp:%lld, sequence:%d\n", in ipu6_isys_buf_calc_sequence_time()
719 av->vdev.name, ktime_get_ns(), sequence); in ipu6_isys_buf_calc_sequence_time()
720 dev_dbg(dev, "index:%d, vbuf timestamp:%lld\n", vb->index, in ipu6_isys_buf_calc_sequence_time()
721 vbuf->vb2_buf.timestamp); in ipu6_isys_buf_calc_sequence_time()
728 if (atomic_read(&ib->str2mmio_flag)) { in ipu6_isys_queue_buf_done()
732 * to the userspace when it is de-queued in ipu6_isys_queue_buf_done()
734 atomic_set(&ib->str2mmio_flag, 0); in ipu6_isys_queue_buf_done()
743 struct ipu6_isys_queue *aq = stream->output_pins[info->pin_id].aq; in ipu6_isys_queue_buf_ready()
744 struct ipu6_isys *isys = stream->isys; in ipu6_isys_queue_buf_ready()
745 struct device *dev = &isys->adev->auxdev.dev; in ipu6_isys_queue_buf_ready()
752 spin_lock_irqsave(&aq->lock, flags); in ipu6_isys_queue_buf_ready()
753 if (list_empty(&aq->active)) { in ipu6_isys_queue_buf_ready()
754 spin_unlock_irqrestore(&aq->lock, flags); in ipu6_isys_queue_buf_ready()
759 list_for_each_entry_reverse(ib, &aq->active, head) { in ipu6_isys_queue_buf_ready()
767 addr = ivb->dma_addr; in ipu6_isys_queue_buf_ready()
769 if (info->pin.addr != addr) { in ipu6_isys_queue_buf_ready()
777 if (info->error_info.error == in ipu6_isys_queue_buf_ready()
783 atomic_set(&ib->str2mmio_flag, 1); in ipu6_isys_queue_buf_ready()
788 buf->field = V4L2_FIELD_NONE; in ipu6_isys_queue_buf_ready()
790 list_del(&ib->head); in ipu6_isys_queue_buf_ready()
791 spin_unlock_irqrestore(&aq->lock, flags); in ipu6_isys_queue_buf_ready()
802 spin_unlock_irqrestore(&aq->lock, flags); in ipu6_isys_queue_buf_ready()
819 struct ipu6_isys *isys = ipu6_isys_queue_to_video(aq)->isys; in ipu6_isys_queue_init()
821 struct ipu6_bus_device *adev = isys->adev; in ipu6_isys_queue_init()
825 if (!aq->vbq.io_modes) in ipu6_isys_queue_init()
826 aq->vbq.io_modes = VB2_MMAP | VB2_DMABUF; in ipu6_isys_queue_init()
828 aq->vbq.drv_priv = isys; in ipu6_isys_queue_init()
829 aq->vbq.ops = &ipu6_isys_queue_ops; in ipu6_isys_queue_init()
830 aq->vbq.lock = &av->mutex; in ipu6_isys_queue_init()
831 aq->vbq.mem_ops = &vb2_dma_sg_memops; in ipu6_isys_queue_init()
832 aq->vbq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in ipu6_isys_queue_init()
833 aq->vbq.min_queued_buffers = 1; in ipu6_isys_queue_init()
834 aq->vbq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in ipu6_isys_queue_init()
836 ret = vb2_queue_init(&aq->vbq); in ipu6_isys_queue_init()
840 aq->dev = &adev->auxdev.dev; in ipu6_isys_queue_init()
841 aq->vbq.dev = &adev->isp->pdev->dev; in ipu6_isys_queue_init()
842 spin_lock_init(&aq->lock); in ipu6_isys_queue_init()
843 INIT_LIST_HEAD(&aq->active); in ipu6_isys_queue_init()
844 INIT_LIST_HEAD(&aq->incoming); in ipu6_isys_queue_init()