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