Lines Matching +full:dphy +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0
26 #include <media/ipu-bridge.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-event.h>
30 #include <media/v4l2-fwnode.h>
31 #include <media/v4l2-ioctl.h>
32 #include <media/videobuf2-dma-sg.h>
34 #include "ipu3-cio2.h"
79 * cio2_find_format - lookup color format by fourcc or/and media bus code
113 struct device *dev = &cio2->pci_dev->dev; in cio2_fbpt_exit_dummy()
115 if (cio2->dummy_lop) { in cio2_fbpt_exit_dummy()
116 dma_free_coherent(dev, PAGE_SIZE, cio2->dummy_lop, in cio2_fbpt_exit_dummy()
117 cio2->dummy_lop_bus_addr); in cio2_fbpt_exit_dummy()
118 cio2->dummy_lop = NULL; in cio2_fbpt_exit_dummy()
120 if (cio2->dummy_page) { in cio2_fbpt_exit_dummy()
121 dma_free_coherent(dev, PAGE_SIZE, cio2->dummy_page, in cio2_fbpt_exit_dummy()
122 cio2->dummy_page_bus_addr); in cio2_fbpt_exit_dummy()
123 cio2->dummy_page = NULL; in cio2_fbpt_exit_dummy()
129 struct device *dev = &cio2->pci_dev->dev; in cio2_fbpt_init_dummy()
132 cio2->dummy_page = dma_alloc_coherent(dev, PAGE_SIZE, in cio2_fbpt_init_dummy()
133 &cio2->dummy_page_bus_addr, in cio2_fbpt_init_dummy()
135 cio2->dummy_lop = dma_alloc_coherent(dev, PAGE_SIZE, in cio2_fbpt_init_dummy()
136 &cio2->dummy_lop_bus_addr, in cio2_fbpt_init_dummy()
138 if (!cio2->dummy_page || !cio2->dummy_lop) { in cio2_fbpt_init_dummy()
140 return -ENOMEM; in cio2_fbpt_init_dummy()
147 cio2->dummy_lop[i] = PFN_DOWN(cio2->dummy_page_bus_addr); in cio2_fbpt_init_dummy()
180 entry[1].second_entry.last_page_available_bytes = PAGE_SIZE - 1; in cio2_fbpt_entry_init_dummy()
183 entry[i].lop_page_addr = PFN_DOWN(cio2->dummy_lop_bus_addr); in cio2_fbpt_entry_init_dummy()
194 struct vb2_buffer *vb = &b->vbb.vb2_buf; in cio2_fbpt_entry_init_buf()
195 unsigned int length = vb->planes[0].length; in cio2_fbpt_entry_init_buf()
198 entry[0].first_entry.first_page_offset = b->offset; in cio2_fbpt_entry_init_buf()
206 * 4095 (PAGE_SIZE - 1) means every single byte in the last page in cio2_fbpt_entry_init_buf()
210 entry[1].second_entry.last_page_available_bytes = remaining - 1; in cio2_fbpt_entry_init_buf()
215 entry->lop_page_addr = PFN_DOWN(b->lop_bus_addr[i]); in cio2_fbpt_entry_init_buf()
216 remaining -= CIO2_LOP_ENTRIES * PAGE_SIZE; in cio2_fbpt_entry_init_buf()
224 entry->lop_page_addr = PFN_DOWN(cio2->dummy_lop_bus_addr); in cio2_fbpt_entry_init_buf()
231 struct device *dev = &cio2->pci_dev->dev; in cio2_fbpt_init()
233 q->fbpt = dma_alloc_coherent(dev, CIO2_FBPT_SIZE, &q->fbpt_bus_addr, in cio2_fbpt_init()
235 if (!q->fbpt) in cio2_fbpt_init()
236 return -ENOMEM; in cio2_fbpt_init()
243 dma_free_coherent(dev, CIO2_FBPT_SIZE, q->fbpt, q->fbpt_bus_addr); in cio2_fbpt_exit()
264 * reg_rx_csi_dly_cnt_settle_clane 95 -8 300 -16
267 * reg_rx_csi_dly_cnt_settle_dlane0 85 -2 145 -6
269 * reg_rx_csi_dly_cnt_settle_dlane1 85 -2 145 -6
271 * reg_rx_csi_dly_cnt_settle_dlane2 85 -2 145 -6
273 * reg_rx_csi_dly_cnt_settle_dlane3 85 -2 145 -6
279 * shift for keeping value range suitable for 32-bit integer arithmetic
294 * b could be 0, -2 or -8, so |accinv * b| is always in cio2_rx_timing()
310 struct device *dev = &cio2->pci_dev->dev; in cio2_csi2_calc_timing()
313 if (!q->sensor) in cio2_csi2_calc_timing()
314 return -ENODEV; in cio2_csi2_calc_timing()
316 freq = v4l2_get_link_freq(q->sensor->ctrl_handler, bpp, lanes * 2); in cio2_csi2_calc_timing()
322 timing->clk_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A, in cio2_csi2_calc_timing()
326 timing->clk_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_A, in cio2_csi2_calc_timing()
330 timing->dat_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_A, in cio2_csi2_calc_timing()
334 timing->dat_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_A, in cio2_csi2_calc_timing()
339 dev_dbg(dev, "freq ct value is %d\n", timing->clk_termen); in cio2_csi2_calc_timing()
340 dev_dbg(dev, "freq cs value is %d\n", timing->clk_settle); in cio2_csi2_calc_timing()
341 dev_dbg(dev, "freq dt value is %d\n", timing->dat_termen); in cio2_csi2_calc_timing()
342 dev_dbg(dev, "freq ds value is %d\n", timing->dat_settle); in cio2_csi2_calc_timing()
354 const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1; in cio2_hw_init()
356 void __iomem *const base = cio2->base; in cio2_hw_init()
357 u8 lanes, csi2bus = q->csi2.port; in cio2_hw_init()
362 fmt = cio2_find_format(NULL, &q->subdev_fmt.code); in cio2_hw_init()
364 return -EINVAL; in cio2_hw_init()
366 lanes = q->csi2.lanes; in cio2_hw_init()
368 r = cio2_csi2_calc_timing(cio2, q, &timing, fmt->bpp, lanes); in cio2_hw_init()
372 writel(timing.clk_termen, q->csi_rx_base + in cio2_hw_init()
374 writel(timing.clk_settle, q->csi_rx_base + in cio2_hw_init()
378 writel(timing.dat_termen, q->csi_rx_base + in cio2_hw_init()
380 writel(timing.dat_settle, q->csi_rx_base + in cio2_hw_init()
402 q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_HS); in cio2_hw_init()
404 q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_LP); in cio2_hw_init()
411 writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_SP_LUT_ENTRY(i)); in cio2_hw_init()
416 q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(i)); in cio2_hw_init()
418 q->csi_rx_base + CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD); in cio2_hw_init()
421 writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_MASK); in cio2_hw_init()
422 writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_ENABLE); in cio2_hw_init()
423 writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_EDGE); in cio2_hw_init()
424 writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_LEVEL_NOT_PULSE); in cio2_hw_init()
436 fmt->mipicode << CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT, in cio2_hw_init()
437 q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(ENTRY)); in cio2_hw_init()
438 writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_COMP_FORMAT(sensor_vc)); in cio2_hw_init()
439 writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_FORCE_RAW8); in cio2_hw_init()
442 writel(lanes, q->csi_rx_base + CIO2_REG_CSIRX_NOF_ENABLED_LANES); in cio2_hw_init()
475 writel(PFN_DOWN(q->fbpt_bus_addr), base + CIO2_REG_CDMABA(CIO2_DMA_CHAN)); in cio2_hw_init()
494 base + CIO2_REG_PXM_FRF_CFG(q->csi2.port)); in cio2_hw_init()
497 writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_CLEAR); in cio2_hw_init()
503 writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE); in cio2_hw_init()
504 writel(1, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE); in cio2_hw_init()
511 struct device *dev = &cio2->pci_dev->dev; in cio2_hw_exit()
512 void __iomem *const base = cio2->base; in cio2_hw_exit()
518 writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_MASK); in cio2_hw_exit()
519 writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_ENABLE); in cio2_hw_exit()
520 writel(0, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE); in cio2_hw_exit()
521 writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE); in cio2_hw_exit()
541 struct device *dev = &cio2->pci_dev->dev; in cio2_buffer_done()
542 struct cio2_queue *q = cio2->cur_queue; in cio2_buffer_done()
551 entry = &q->fbpt[q->bufs_first * CIO2_MAX_LOPS]; in cio2_buffer_done()
552 if (entry->first_entry.ctrl & CIO2_FBPT_CTRL_VALID) { in cio2_buffer_done()
562 b = q->bufs[q->bufs_first]; in cio2_buffer_done()
566 vb2_get_plane_payload(&b->vbb.vb2_buf, 0); in cio2_buffer_done()
568 q->bufs[q->bufs_first] = NULL; in cio2_buffer_done()
569 atomic_dec(&q->bufs_queued); in cio2_buffer_done()
570 dev_dbg(dev, "buffer %i done\n", b->vbb.vb2_buf.index); in cio2_buffer_done()
572 b->vbb.vb2_buf.timestamp = ns; in cio2_buffer_done()
573 b->vbb.field = V4L2_FIELD_NONE; in cio2_buffer_done()
574 b->vbb.sequence = atomic_read(&q->frame_sequence); in cio2_buffer_done()
579 vb2_buffer_done(&b->vbb.vb2_buf, VB2_BUF_STATE_DONE); in cio2_buffer_done()
581 atomic_inc(&q->frame_sequence); in cio2_buffer_done()
583 q->bufs_first = (q->bufs_first + 1) % CIO2_MAX_BUFFERS; in cio2_buffer_done()
584 entry = &q->fbpt[q->bufs_first * CIO2_MAX_LOPS]; in cio2_buffer_done()
585 } while (!(entry->first_entry.ctrl & CIO2_FBPT_CTRL_VALID)); in cio2_buffer_done()
597 .u.frame_sync.frame_sequence = atomic_read(&q->frame_sequence), in cio2_queue_event_sof()
600 v4l2_event_queue(q->subdev.devnode, &event); in cio2_queue_event_sof()
613 "DPHY start of transmission error",
614 "DPHY synchronization error",
617 "escape mode ultra-low power state for data lane(s)",
618 "escape mode ultra-low power state exit for clock lane",
619 "inter-frame short packet discarded",
620 "inter-frame long packet discarded",
621 "non-matching Long Packet stalled",
630 dev_err(dev, "CSI-2 receiver port %i: %s\n", in cio2_irq_log_irq_errs()
640 "DPHY not recoverable",
659 struct device *dev = &cio2->pci_dev->dev; in cio2_irq_handle_once()
660 void __iomem *const base = cio2->base; in cio2_irq_handle_once()
693 /* DMA IO done -- frame ready */ in cio2_irq_handle_once()
715 cio2->cur_queue); in cio2_irq_handle_once()
759 void __iomem *const base = cio2->base; in cio2_irq()
760 struct device *dev = &cio2->pci_dev->dev; in cio2_irq()
764 dev_dbg(dev, "isr enter - interrupt status 0x%x\n", int_status); in cio2_irq()
787 if (q->bufs[i]) { in cio2_vb2_return_all_buffers()
788 atomic_dec(&q->bufs_queued); in cio2_vb2_return_all_buffers()
789 vb2_buffer_done(&q->bufs[i]->vbb.vb2_buf, in cio2_vb2_return_all_buffers()
791 q->bufs[i] = NULL; in cio2_vb2_return_all_buffers()
803 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_queue_setup()
807 if (*num_planes && *num_planes < q->format.num_planes) in cio2_vb2_queue_setup()
808 return -EINVAL; in cio2_vb2_queue_setup()
810 for (i = 0; i < q->format.num_planes; ++i) { in cio2_vb2_queue_setup()
811 if (*num_planes && sizes[i] < q->format.plane_fmt[i].sizeimage) in cio2_vb2_queue_setup()
812 return -EINVAL; in cio2_vb2_queue_setup()
813 sizes[i] = q->format.plane_fmt[i].sizeimage; in cio2_vb2_queue_setup()
817 *num_planes = q->format.num_planes; in cio2_vb2_queue_setup()
822 q->bufs[i] = NULL; in cio2_vb2_queue_setup()
823 cio2_fbpt_entry_init_dummy(cio2, &q->fbpt[i * CIO2_MAX_LOPS]); in cio2_vb2_queue_setup()
825 atomic_set(&q->bufs_queued, 0); in cio2_vb2_queue_setup()
826 q->bufs_first = 0; in cio2_vb2_queue_setup()
827 q->bufs_next = 0; in cio2_vb2_queue_setup()
835 struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue); in cio2_vb2_buf_init()
836 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_buf_init()
838 unsigned int pages = PFN_UP(vb->planes[0].length); in cio2_vb2_buf_init()
846 vb->planes[0].length); in cio2_vb2_buf_init()
847 return -ENOSPC; /* Should never happen */ in cio2_vb2_buf_init()
850 memset(b->lop, 0, sizeof(b->lop)); in cio2_vb2_buf_init()
853 b->lop[i] = dma_alloc_coherent(dev, PAGE_SIZE, in cio2_vb2_buf_init()
854 &b->lop_bus_addr[i], GFP_KERNEL); in cio2_vb2_buf_init()
855 if (!b->lop[i]) in cio2_vb2_buf_init()
862 return -ENOMEM; in cio2_vb2_buf_init()
864 if (sg->nents && sg->sgl) in cio2_vb2_buf_init()
865 b->offset = sg->sgl->offset; in cio2_vb2_buf_init()
868 for_each_sg_dma_page(sg->sgl, &sg_iter, sg->nents, 0) { in cio2_vb2_buf_init()
869 if (!pages--) in cio2_vb2_buf_init()
871 b->lop[i][j] = PFN_DOWN(sg_page_iter_dma_address(&sg_iter)); in cio2_vb2_buf_init()
879 b->lop[i][j] = PFN_DOWN(cio2->dummy_page_bus_addr); in cio2_vb2_buf_init()
882 while (i--) in cio2_vb2_buf_init()
883 dma_free_coherent(dev, PAGE_SIZE, b->lop[i], b->lop_bus_addr[i]); in cio2_vb2_buf_init()
884 return -ENOMEM; in cio2_vb2_buf_init()
890 struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue); in cio2_vb2_buf_queue()
891 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_buf_queue()
893 container_of(vb->vb2_queue, struct cio2_queue, vbq); in cio2_vb2_buf_queue()
897 unsigned int i, j, next = q->bufs_next; in cio2_vb2_buf_queue()
898 int bufs_queued = atomic_inc_return(&q->bufs_queued); in cio2_vb2_buf_queue()
901 dev_dbg(dev, "queue buffer %d\n", vb->index); in cio2_vb2_buf_queue()
906 * gets pre-empted due to increased CPU load. Upon this, the driver in cio2_vb2_buf_queue()
918 fbpt_rp = (readl(cio2->base + CIO2_REG_CDMARI(CIO2_DMA_CHAN)) in cio2_vb2_buf_queue()
940 if (!q->bufs[next]) { in cio2_vb2_buf_queue()
941 q->bufs[next] = b; in cio2_vb2_buf_queue()
942 entry = &q->fbpt[next * CIO2_MAX_LOPS]; in cio2_vb2_buf_queue()
945 q->bufs_next = (next + 1) % CIO2_MAX_BUFFERS; in cio2_vb2_buf_queue()
946 for (j = 0; j < vb->num_planes; j++) in cio2_vb2_buf_queue()
948 q->format.plane_fmt[j].sizeimage); in cio2_vb2_buf_queue()
958 atomic_dec(&q->bufs_queued); in cio2_vb2_buf_queue()
965 struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue); in cio2_vb2_buf_cleanup()
966 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_buf_cleanup()
972 if (b->lop[i]) in cio2_vb2_buf_cleanup()
974 b->lop[i], b->lop_bus_addr[i]); in cio2_vb2_buf_cleanup()
982 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_start_streaming()
985 cio2->cur_queue = q; in cio2_vb2_start_streaming()
986 atomic_set(&q->frame_sequence, 0); in cio2_vb2_start_streaming()
994 r = video_device_pipeline_start(&q->vdev, &q->pipe); in cio2_vb2_start_streaming()
1003 r = v4l2_subdev_call(q->sensor, video, s_stream, 1); in cio2_vb2_start_streaming()
1007 cio2->streaming = true; in cio2_vb2_start_streaming()
1014 video_device_pipeline_stop(&q->vdev); in cio2_vb2_start_streaming()
1027 struct device *dev = &cio2->pci_dev->dev; in cio2_vb2_stop_streaming()
1029 if (v4l2_subdev_call(q->sensor, video, s_stream, 0)) in cio2_vb2_stop_streaming()
1033 synchronize_irq(cio2->pci_dev->irq); in cio2_vb2_stop_streaming()
1035 video_device_pipeline_stop(&q->vdev); in cio2_vb2_stop_streaming()
1037 cio2->streaming = false; in cio2_vb2_stop_streaming()
1056 strscpy(cap->driver, CIO2_NAME, sizeof(cap->driver)); in cio2_v4l2_querycap()
1057 strscpy(cap->card, CIO2_DEVICE_NAME, sizeof(cap->card)); in cio2_v4l2_querycap()
1065 if (f->index >= ARRAY_SIZE(formats)) in cio2_v4l2_enum_fmt()
1066 return -EINVAL; in cio2_v4l2_enum_fmt()
1068 f->pixelformat = formats[f->index].fourcc; in cio2_v4l2_enum_fmt()
1078 f->fmt.pix_mp = q->format; in cio2_v4l2_g_fmt()
1086 struct v4l2_pix_format_mplane *mpix = &f->fmt.pix_mp; in cio2_v4l2_try_fmt()
1088 fmt = cio2_find_format(&mpix->pixelformat, NULL); in cio2_v4l2_try_fmt()
1093 if (mpix->width > CIO2_IMAGE_MAX_WIDTH) in cio2_v4l2_try_fmt()
1094 mpix->width = CIO2_IMAGE_MAX_WIDTH; in cio2_v4l2_try_fmt()
1095 if (mpix->height > CIO2_IMAGE_MAX_HEIGHT) in cio2_v4l2_try_fmt()
1096 mpix->height = CIO2_IMAGE_MAX_HEIGHT; in cio2_v4l2_try_fmt()
1098 mpix->num_planes = 1; in cio2_v4l2_try_fmt()
1099 mpix->pixelformat = fmt->fourcc; in cio2_v4l2_try_fmt()
1100 mpix->colorspace = V4L2_COLORSPACE_RAW; in cio2_v4l2_try_fmt()
1101 mpix->field = V4L2_FIELD_NONE; in cio2_v4l2_try_fmt()
1102 mpix->plane_fmt[0].bytesperline = cio2_bytesperline(mpix->width); in cio2_v4l2_try_fmt()
1103 mpix->plane_fmt[0].sizeimage = mpix->plane_fmt[0].bytesperline * in cio2_v4l2_try_fmt()
1104 mpix->height; in cio2_v4l2_try_fmt()
1107 mpix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in cio2_v4l2_try_fmt()
1108 mpix->quantization = V4L2_QUANTIZATION_DEFAULT; in cio2_v4l2_try_fmt()
1109 mpix->xfer_func = V4L2_XFER_FUNC_DEFAULT; in cio2_v4l2_try_fmt()
1119 q->format = f->fmt.pix_mp; in cio2_v4l2_s_fmt()
1127 if (input->index > 0) in cio2_video_enum_input()
1128 return -EINVAL; in cio2_video_enum_input()
1130 strscpy(input->name, "camera", sizeof(input->name)); in cio2_video_enum_input()
1131 input->type = V4L2_INPUT_TYPE_CAMERA; in cio2_video_enum_input()
1147 return input == 0 ? 0 : -EINVAL; in cio2_video_s_input()
1183 if (sub->type != V4L2_EVENT_FRAME_SYNC) in cio2_subdev_subscribe_event()
1184 return -EINVAL; in cio2_subdev_subscribe_event()
1187 if (sub->id != 0) in cio2_subdev_subscribe_event()
1188 return -EINVAL; in cio2_subdev_subscribe_event()
1208 format = v4l2_subdev_get_try_format(sd, fh->state, CIO2_PAD_SINK); in cio2_subdev_open()
1212 format = v4l2_subdev_get_try_format(sd, fh->state, CIO2_PAD_SOURCE); in cio2_subdev_open()
1219 * cio2_subdev_get_fmt - Handle get format by pads subdev method
1221 * @cfg: V4L2 subdev pad config
1223 * return -EINVAL or zero on success
1231 mutex_lock(&q->subdev_lock); in cio2_subdev_get_fmt()
1233 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) in cio2_subdev_get_fmt()
1234 fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, in cio2_subdev_get_fmt()
1235 fmt->pad); in cio2_subdev_get_fmt()
1237 fmt->format = q->subdev_fmt; in cio2_subdev_get_fmt()
1239 mutex_unlock(&q->subdev_lock); in cio2_subdev_get_fmt()
1245 * cio2_subdev_set_fmt - Handle set format by pads subdev method
1247 * @cfg: V4L2 subdev pad config
1249 * return -EINVAL or zero on success
1257 u32 mbus_code = fmt->format.code; in cio2_subdev_set_fmt()
1264 if (fmt->pad == CIO2_PAD_SOURCE) in cio2_subdev_set_fmt()
1267 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) in cio2_subdev_set_fmt()
1268 mbus = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); in cio2_subdev_set_fmt()
1270 mbus = &q->subdev_fmt; in cio2_subdev_set_fmt()
1272 fmt->format.code = formats[0].mbus_code; in cio2_subdev_set_fmt()
1276 fmt->format.code = mbus_code; in cio2_subdev_set_fmt()
1281 fmt->format.width = min(fmt->format.width, CIO2_IMAGE_MAX_WIDTH); in cio2_subdev_set_fmt()
1282 fmt->format.height = min(fmt->format.height, CIO2_IMAGE_MAX_HEIGHT); in cio2_subdev_set_fmt()
1283 fmt->format.field = V4L2_FIELD_NONE; in cio2_subdev_set_fmt()
1285 mutex_lock(&q->subdev_lock); in cio2_subdev_set_fmt()
1286 *mbus = fmt->format; in cio2_subdev_set_fmt()
1287 mutex_unlock(&q->subdev_lock); in cio2_subdev_set_fmt()
1296 if (code->index >= ARRAY_SIZE(formats)) in cio2_subdev_enum_mbus_code()
1297 return -EINVAL; in cio2_subdev_enum_mbus_code()
1299 code->code = formats[code->index].mbus_code; in cio2_subdev_enum_mbus_code()
1306 if (is_media_entity_v4l2_subdev(pad->entity)) { in cio2_subdev_link_validate_get_format()
1308 media_entity_to_v4l2_subdev(pad->entity); in cio2_subdev_link_validate_get_format()
1311 fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; in cio2_subdev_link_validate_get_format()
1312 fmt->pad = pad->index; in cio2_subdev_link_validate_get_format()
1316 return -EINVAL; in cio2_subdev_link_validate_get_format()
1321 struct media_entity *entity = link->sink->entity; in cio2_video_link_validate()
1325 struct device *dev = &cio2->pci_dev->dev; in cio2_video_link_validate()
1329 if (!media_pad_remote_pad_first(entity->pads)) { in cio2_video_link_validate()
1330 dev_info(dev, "video node %s pad not connected\n", vd->name); in cio2_video_link_validate()
1331 return -ENOTCONN; in cio2_video_link_validate()
1334 ret = cio2_subdev_link_validate_get_format(link->source, &source_fmt); in cio2_video_link_validate()
1338 if (source_fmt.format.width != q->format.width || in cio2_video_link_validate()
1339 source_fmt.format.height != q->format.height) { in cio2_video_link_validate()
1341 q->format.width, q->format.height, in cio2_video_link_validate()
1343 return -EINVAL; in cio2_video_link_validate()
1346 if (!cio2_find_format(&q->format.pixelformat, &source_fmt.format.code)) in cio2_video_link_validate()
1347 return -EINVAL; in cio2_video_link_validate()
1373 /******* V4L2 sub-device asynchronous registration callbacks***********/
1393 if (cio2->queue[s_asd->csi2.port].sensor) in cio2_notifier_bound()
1394 return -EBUSY; in cio2_notifier_bound()
1396 ret = ipu_bridge_instantiate_vcm(sd->dev); in cio2_notifier_bound()
1400 q = &cio2->queue[s_asd->csi2.port]; in cio2_notifier_bound()
1402 q->csi2 = s_asd->csi2; in cio2_notifier_bound()
1403 q->sensor = sd; in cio2_notifier_bound()
1404 q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port); in cio2_notifier_bound()
1417 cio2->queue[s_asd->csi2.port].sensor = NULL; in cio2_notifier_unbind()
1424 struct device *dev = &cio2->pci_dev->dev; in cio2_notifier_complete()
1430 list_for_each_entry(asd, &cio2->notifier.done_list, asc_entry) { in cio2_notifier_complete()
1432 q = &cio2->queue[s_asd->csi2.port]; in cio2_notifier_complete()
1434 ret = media_entity_get_fwnode_pad(&q->sensor->entity, in cio2_notifier_complete()
1435 s_asd->asd.match.fwnode, in cio2_notifier_complete()
1439 s_asd->asd.match.fwnode, ret); in cio2_notifier_complete()
1443 ret = media_create_pad_link(&q->sensor->entity, ret, in cio2_notifier_complete()
1444 &q->subdev.entity, CIO2_PAD_SINK, in cio2_notifier_complete()
1448 q->sensor->name, s_asd->asd.match.fwnode, ret); in cio2_notifier_complete()
1453 return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev); in cio2_notifier_complete()
1464 struct device *dev = &cio2->pci_dev->dev; in cio2_parse_firmware()
1484 s_asd = v4l2_async_nf_add_fwnode_remote(&cio2->notifier, ep, in cio2_parse_firmware()
1492 s_asd->csi2.port = vep.base.port; in cio2_parse_firmware()
1493 s_asd->csi2.lanes = vep.bus.mipi_csi2.num_data_lanes; in cio2_parse_firmware()
1508 cio2->notifier.ops = &cio2_async_ops; in cio2_parse_firmware()
1509 ret = v4l2_async_nf_register(&cio2->notifier); in cio2_parse_firmware()
1530 struct device *dev = &cio2->pci_dev->dev; in cio2_queue_init()
1531 struct video_device *vdev = &q->vdev; in cio2_queue_init()
1532 struct vb2_queue *vbq = &q->vbq; in cio2_queue_init()
1533 struct v4l2_subdev *subdev = &q->subdev; in cio2_queue_init()
1538 mutex_init(&q->lock); in cio2_queue_init()
1539 mutex_init(&q->subdev_lock); in cio2_queue_init()
1542 fmt = &q->subdev_fmt; in cio2_queue_init()
1543 fmt->width = default_width; in cio2_queue_init()
1544 fmt->height = default_height; in cio2_queue_init()
1545 fmt->code = dflt_fmt.mbus_code; in cio2_queue_init()
1546 fmt->field = V4L2_FIELD_NONE; in cio2_queue_init()
1548 q->format.width = default_width; in cio2_queue_init()
1549 q->format.height = default_height; in cio2_queue_init()
1550 q->format.pixelformat = dflt_fmt.fourcc; in cio2_queue_init()
1551 q->format.colorspace = V4L2_COLORSPACE_RAW; in cio2_queue_init()
1552 q->format.field = V4L2_FIELD_NONE; in cio2_queue_init()
1553 q->format.num_planes = 1; in cio2_queue_init()
1554 q->format.plane_fmt[0].bytesperline = in cio2_queue_init()
1555 cio2_bytesperline(q->format.width); in cio2_queue_init()
1556 q->format.plane_fmt[0].sizeimage = q->format.plane_fmt[0].bytesperline * in cio2_queue_init()
1557 q->format.height; in cio2_queue_init()
1565 q->subdev_pads[CIO2_PAD_SINK].flags = MEDIA_PAD_FL_SINK | in cio2_queue_init()
1567 q->subdev_pads[CIO2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in cio2_queue_init()
1568 subdev->entity.ops = &cio2_media_ops; in cio2_queue_init()
1569 subdev->internal_ops = &cio2_subdev_internal_ops; in cio2_queue_init()
1570 r = media_entity_pads_init(&subdev->entity, CIO2_PADS, q->subdev_pads); in cio2_queue_init()
1576 q->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; in cio2_queue_init()
1577 vdev->entity.ops = &cio2_video_entity_ops; in cio2_queue_init()
1578 r = media_entity_pads_init(&vdev->entity, 1, &q->vdev_pad); in cio2_queue_init()
1587 subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; in cio2_queue_init()
1588 subdev->owner = THIS_MODULE; in cio2_queue_init()
1589 snprintf(subdev->name, sizeof(subdev->name), in cio2_queue_init()
1590 CIO2_ENTITY_NAME " %td", q - cio2->queue); in cio2_queue_init()
1591 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in cio2_queue_init()
1593 r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev); in cio2_queue_init()
1600 vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; in cio2_queue_init()
1601 vbq->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF; in cio2_queue_init()
1602 vbq->ops = &cio2_vb2_ops; in cio2_queue_init()
1603 vbq->mem_ops = &vb2_dma_sg_memops; in cio2_queue_init()
1604 vbq->buf_struct_size = sizeof(struct cio2_buffer); in cio2_queue_init()
1605 vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in cio2_queue_init()
1606 vbq->min_buffers_needed = 1; in cio2_queue_init()
1607 vbq->drv_priv = cio2; in cio2_queue_init()
1608 vbq->lock = &q->lock; in cio2_queue_init()
1616 snprintf(vdev->name, sizeof(vdev->name), in cio2_queue_init()
1617 "%s %td", CIO2_NAME, q - cio2->queue); in cio2_queue_init()
1618 vdev->release = video_device_release_empty; in cio2_queue_init()
1619 vdev->fops = &cio2_v4l2_fops; in cio2_queue_init()
1620 vdev->ioctl_ops = &cio2_v4l2_ioctl_ops; in cio2_queue_init()
1621 vdev->lock = &cio2->lock; in cio2_queue_init()
1622 vdev->v4l2_dev = &cio2->v4l2_dev; in cio2_queue_init()
1623 vdev->queue = &q->vbq; in cio2_queue_init()
1624 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING; in cio2_queue_init()
1626 r = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in cio2_queue_init()
1634 &subdev->entity, CIO2_PAD_SOURCE, &vdev->entity, 0, in cio2_queue_init()
1642 vb2_video_unregister_device(&q->vdev); in cio2_queue_init()
1646 media_entity_cleanup(&vdev->entity); in cio2_queue_init()
1648 media_entity_cleanup(&subdev->entity); in cio2_queue_init()
1652 mutex_destroy(&q->subdev_lock); in cio2_queue_init()
1653 mutex_destroy(&q->lock); in cio2_queue_init()
1660 vb2_video_unregister_device(&q->vdev); in cio2_queue_exit()
1661 media_entity_cleanup(&q->vdev.entity); in cio2_queue_exit()
1662 v4l2_device_unregister_subdev(&q->subdev); in cio2_queue_exit()
1663 media_entity_cleanup(&q->subdev.entity); in cio2_queue_exit()
1664 cio2_fbpt_exit(q, &cio2->pci_dev->dev); in cio2_queue_exit()
1665 mutex_destroy(&q->subdev_lock); in cio2_queue_exit()
1666 mutex_destroy(&q->lock); in cio2_queue_exit()
1674 r = cio2_queue_init(cio2, &cio2->queue[i]); in cio2_queues_init()
1682 for (i--; i >= 0; i--) in cio2_queues_init()
1683 cio2_queue_exit(cio2, &cio2->queue[i]); in cio2_queues_init()
1693 cio2_queue_exit(cio2, &cio2->queue[i]); in cio2_queues_exit()
1701 return -EINVAL; in cio2_check_fwnode_graph()
1709 return cio2_check_fwnode_graph(fwnode->secondary); in cio2_check_fwnode_graph()
1717 struct device *dev = &pci_dev->dev; in cio2_pci_probe()
1729 if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) { in cio2_pci_probe()
1731 return -EINVAL; in cio2_pci_probe()
1741 return -ENOMEM; in cio2_pci_probe()
1742 cio2->pci_dev = pci_dev; in cio2_pci_probe()
1751 pci_dev->device, pci_dev->revision); in cio2_pci_probe()
1756 return -ENODEV; in cio2_pci_probe()
1759 cio2->base = pcim_iomap_table(pci_dev)[CIO2_PCI_BAR]; in cio2_pci_probe()
1765 r = dma_set_mask(&pci_dev->dev, CIO2_DMA_MASK); in cio2_pci_probe()
1768 return -ENODEV; in cio2_pci_probe()
1781 mutex_init(&cio2->lock); in cio2_pci_probe()
1783 cio2->media_dev.dev = dev; in cio2_pci_probe()
1784 strscpy(cio2->media_dev.model, CIO2_DEVICE_NAME, in cio2_pci_probe()
1785 sizeof(cio2->media_dev.model)); in cio2_pci_probe()
1786 cio2->media_dev.hw_revision = 0; in cio2_pci_probe()
1788 media_device_init(&cio2->media_dev); in cio2_pci_probe()
1789 r = media_device_register(&cio2->media_dev); in cio2_pci_probe()
1793 cio2->v4l2_dev.mdev = &cio2->media_dev; in cio2_pci_probe()
1794 r = v4l2_device_register(dev, &cio2->v4l2_dev); in cio2_pci_probe()
1804 v4l2_async_nf_init(&cio2->notifier, &cio2->v4l2_dev); in cio2_pci_probe()
1806 r = devm_request_irq(dev, pci_dev->irq, cio2_irq, IRQF_SHARED, in cio2_pci_probe()
1824 v4l2_async_nf_unregister(&cio2->notifier); in cio2_pci_probe()
1825 v4l2_async_nf_cleanup(&cio2->notifier); in cio2_pci_probe()
1828 v4l2_device_unregister(&cio2->v4l2_dev); in cio2_pci_probe()
1830 media_device_unregister(&cio2->media_dev); in cio2_pci_probe()
1831 media_device_cleanup(&cio2->media_dev); in cio2_pci_probe()
1833 mutex_destroy(&cio2->lock); in cio2_pci_probe()
1843 media_device_unregister(&cio2->media_dev); in cio2_pci_remove()
1844 v4l2_async_nf_unregister(&cio2->notifier); in cio2_pci_remove()
1845 v4l2_async_nf_cleanup(&cio2->notifier); in cio2_pci_remove()
1848 v4l2_device_unregister(&cio2->v4l2_dev); in cio2_pci_remove()
1849 media_device_cleanup(&cio2->media_dev); in cio2_pci_remove()
1850 mutex_destroy(&cio2->lock); in cio2_pci_remove()
1852 pm_runtime_forbid(&pci_dev->dev); in cio2_pci_remove()
1853 pm_runtime_get_noresume(&pci_dev->dev); in cio2_pci_remove()
1860 void __iomem *const base = cio2->base; in cio2_runtime_suspend()
1866 pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm); in cio2_runtime_suspend()
1869 pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm); in cio2_runtime_suspend()
1878 void __iomem *const base = cio2->base; in cio2_runtime_resume()
1884 pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm); in cio2_runtime_resume()
1886 pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm); in cio2_runtime_resume()
1900 { 0, start - 1 }, in arrange()
1901 { start, elems - 1 }, in arrange()
1904 #define CHUNK_SIZE(a) ((a)->end - (a)->begin + 1) in arrange()
1906 /* Loop as long as we have out-of-place entries */ in arrange()
1935 arr[0].end = arr[1].begin + size0 - 1; in arrange()
1945 for (i = 0, j = q->bufs_first; i < CIO2_MAX_BUFFERS; in cio2_fbpt_rearrange()
1947 if (q->bufs[j]) in cio2_fbpt_rearrange()
1954 arrange(q->fbpt, sizeof(struct cio2_fbpt_entry) * CIO2_MAX_LOPS, in cio2_fbpt_rearrange()
1956 arrange(q->bufs, sizeof(struct cio2_buffer *), in cio2_fbpt_rearrange()
1968 cio2_fbpt_entry_enable(cio2, q->fbpt + i * CIO2_MAX_LOPS); in cio2_fbpt_rearrange()
1975 struct cio2_queue *q = cio2->cur_queue; in cio2_suspend()
1979 if (!cio2->streaming) in cio2_suspend()
1983 r = v4l2_subdev_call(q->sensor, video, s_stream, 0); in cio2_suspend()
1990 synchronize_irq(pci_dev->irq); in cio2_suspend()
1999 q->bufs_first = 0; in cio2_suspend()
2000 q->bufs_next = 0; in cio2_suspend()
2008 struct cio2_queue *q = cio2->cur_queue; in cio2_resume()
2012 if (!cio2->streaming) in cio2_resume()
2027 r = v4l2_subdev_call(q->sensor, video, s_stream, 1); in cio2_resume()