Lines Matching refs:csi

51 /* csi control reg 1 */
106 /* csi status reg */
126 /* csi image parameter reg */
130 /* csi control reg 18 */
284 static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
286 return readl(csi->regbase + offset);
289 static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value,
292 writel(value, csi->regbase + offset);
295 static u32 imx7_csi_irq_clear(struct imx7_csi *csi)
299 isr = imx7_csi_reg_read(csi, CSI_CSISR);
300 imx7_csi_reg_write(csi, isr, CSI_CSISR);
305 static void imx7_csi_init_default(struct imx7_csi *csi)
307 imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE |
310 imx7_csi_reg_write(csi, 0, CSI_CSICR2);
311 imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3);
313 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(IMX7_CSI_DEF_PIX_WIDTH) |
317 imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3);
320 static void imx7_csi_hw_enable_irq(struct imx7_csi *csi)
322 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
328 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
331 static void imx7_csi_hw_disable_irq(struct imx7_csi *csi)
333 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
339 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
342 static void imx7_csi_hw_enable(struct imx7_csi *csi)
344 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
348 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
351 static void imx7_csi_hw_disable(struct imx7_csi *csi)
353 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
357 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
360 static void imx7_csi_dma_reflash(struct imx7_csi *csi)
364 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
366 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
369 static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi)
371 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC;
373 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
374 imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
375 imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1);
378 static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi)
380 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
387 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
390 static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi)
392 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
396 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
399 static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t dma_addr,
403 imx7_csi_reg_write(csi, dma_addr, CSI_CSIDMASA_FB2);
405 imx7_csi_reg_write(csi, dma_addr, CSI_CSIDMASA_FB1);
408 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi);
410 static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi)
419 buf = imx7_csi_video_next_buf(csi);
421 csi->active_vb2_buf[i] = buf;
425 csi->active_vb2_buf[i] = NULL;
426 dma_addr = csi->underrun_buf.dma_addr;
429 imx7_csi_update_buf(csi, dma_addr, i);
433 static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
441 buf = csi->active_vb2_buf[i];
447 csi->active_vb2_buf[i] = NULL;
452 static void imx7_csi_free_dma_buf(struct imx7_csi *csi,
456 dma_free_coherent(csi->dev, buf->len, buf->virt, buf->dma_addr);
462 static int imx7_csi_alloc_dma_buf(struct imx7_csi *csi,
465 imx7_csi_free_dma_buf(csi, buf);
468 buf->virt = dma_alloc_coherent(csi->dev, buf->len, &buf->dma_addr,
476 static int imx7_csi_dma_setup(struct imx7_csi *csi)
480 ret = imx7_csi_alloc_dma_buf(csi, &csi->underrun_buf,
481 csi->vdev_fmt.sizeimage);
483 v4l2_warn(&csi->sd, "consider increasing the CMA area\n");
487 csi->frame_sequence = 0;
488 csi->last_eof = false;
489 init_completion(&csi->last_eof_completion);
491 imx7_csi_setup_vb2_buf(csi);
496 static void imx7_csi_dma_cleanup(struct imx7_csi *csi,
499 imx7_csi_dma_unsetup_vb2_buf(csi, return_status);
500 imx7_csi_free_dma_buf(csi, &csi->underrun_buf);
503 static void imx7_csi_dma_stop(struct imx7_csi *csi)
510 spin_lock_irqsave(&csi->irqlock, flags);
511 csi->last_eof = true;
512 spin_unlock_irqrestore(&csi->irqlock, flags);
518 ret = wait_for_completion_timeout(&csi->last_eof_completion,
521 v4l2_warn(&csi->sd, "wait last EOF timeout\n");
523 imx7_csi_hw_disable_irq(csi);
526 static void imx7_csi_configure(struct imx7_csi *csi,
529 struct v4l2_pix_format *out_pix = &csi->vdev_fmt;
535 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
547 if (!csi->is_csi2) {
637 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
638 imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2);
639 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
640 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
642 imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT);
643 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) |
646 imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA);
649 static int imx7_csi_init(struct imx7_csi *csi,
654 ret = clk_prepare_enable(csi->mclk);
658 imx7_csi_configure(csi, sd_state);
660 ret = imx7_csi_dma_setup(csi);
662 clk_disable_unprepare(csi->mclk);
669 static void imx7_csi_deinit(struct imx7_csi *csi,
672 imx7_csi_dma_cleanup(csi, return_status);
673 imx7_csi_init_default(csi);
674 imx7_csi_dmareq_rff_disable(csi);
675 clk_disable_unprepare(csi->mclk);
678 static void imx7_csi_baseaddr_switch_on_second_frame(struct imx7_csi *csi)
680 u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
685 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
688 static void imx7_csi_enable(struct imx7_csi *csi)
691 imx7_csi_rx_fifo_clear(csi);
692 imx7_csi_dma_reflash(csi);
697 imx7_csi_irq_clear(csi);
698 imx7_csi_hw_enable_irq(csi);
701 imx7_csi_dmareq_rff_enable(csi);
702 imx7_csi_hw_enable(csi);
704 if (csi->model == IMX7_CSI_IMX8MQ)
705 imx7_csi_baseaddr_switch_on_second_frame(csi);
708 static void imx7_csi_disable(struct imx7_csi *csi)
710 imx7_csi_dma_stop(csi);
712 imx7_csi_dmareq_rff_disable(csi);
714 imx7_csi_hw_disable_irq(csi);
716 imx7_csi_hw_disable(csi);
723 static void imx7_csi_error_recovery(struct imx7_csi *csi)
725 imx7_csi_hw_disable(csi);
727 imx7_csi_rx_fifo_clear(csi);
729 imx7_csi_dma_reflash(csi);
731 imx7_csi_hw_enable(csi);
734 static void imx7_csi_vb2_buf_done(struct imx7_csi *csi)
740 done = csi->active_vb2_buf[csi->buf_num];
742 done->vbuf.field = csi->vdev_fmt.field;
743 done->vbuf.sequence = csi->frame_sequence;
748 csi->frame_sequence++;
751 next = imx7_csi_video_next_buf(csi);
754 csi->active_vb2_buf[csi->buf_num] = next;
756 dma_addr = csi->underrun_buf.dma_addr;
757 csi->active_vb2_buf[csi->buf_num] = NULL;
760 imx7_csi_update_buf(csi, dma_addr, csi->buf_num);
765 struct imx7_csi *csi = data;
768 spin_lock(&csi->irqlock);
770 status = imx7_csi_irq_clear(csi);
773 dev_warn(csi->dev, "Rx fifo overflow\n");
774 imx7_csi_error_recovery(csi);
778 dev_warn(csi->dev, "Hresponse error detected\n");
779 imx7_csi_error_recovery(csi);
783 imx7_csi_hw_disable(csi);
785 imx7_csi_dma_reflash(csi);
787 imx7_csi_hw_enable(csi);
797 * when csi work in field0 and field1 will write to
801 csi->buf_num = 0;
803 csi->buf_num = 1;
808 imx7_csi_vb2_buf_done(csi);
810 if (csi->last_eof) {
811 complete(&csi->last_eof_completion);
812 csi->last_eof = false;
816 spin_unlock(&csi->irqlock);
1041 struct imx7_csi *csi = video_drvdata(file);
1046 "platform:%s", dev_name(csi->dev));
1123 struct imx7_csi *csi = video_drvdata(file);
1125 f->fmt.pix = csi->vdev_fmt;
1180 struct imx7_csi *csi = video_drvdata(file);
1183 if (vb2_is_busy(&csi->q)) {
1184 dev_err(csi->dev, "%s queue busy\n", __func__);
1188 cc = __imx7_csi_video_try_fmt(&f->fmt.pix, &csi->vdev_compose);
1190 csi->vdev_cc = cc;
1191 csi->vdev_fmt = f->fmt.pix;
1199 struct imx7_csi *csi = video_drvdata(file);
1209 s->r = csi->vdev_compose;
1219 s->r.width = csi->vdev_fmt.width;
1220 s->r.height = csi->vdev_fmt.height;
1262 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1264 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1301 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1302 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1305 dev_err(csi->dev,
1316 static bool imx7_csi_fast_track_buffer(struct imx7_csi *csi,
1324 if (!csi->is_streaming)
1358 spin_lock_irqsave(&csi->irqlock, flags);
1360 buf_num = csi->buf_num;
1361 if (csi->active_vb2_buf[buf_num]) {
1362 spin_unlock_irqrestore(&csi->irqlock, flags);
1366 imx7_csi_update_buf(csi, dma_addr, buf_num);
1368 isr = imx7_csi_reg_read(csi, CSI_CSISR);
1379 spin_unlock_irqrestore(&csi->irqlock, flags);
1383 csi->active_vb2_buf[buf_num] = buf;
1385 spin_unlock_irqrestore(&csi->irqlock, flags);
1391 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1395 if (imx7_csi_fast_track_buffer(csi, buf))
1398 spin_lock_irqsave(&csi->q_lock, flags);
1400 list_add_tail(&buf->list, &csi->ready_q);
1402 spin_unlock_irqrestore(&csi->q_lock, flags);
1405 static int imx7_csi_video_validate_fmt(struct imx7_csi *csi)
1415 ret = v4l2_subdev_call_state_active(&csi->sd, pad, get_fmt, &fmt_src);
1426 if (csi->vdev_compose.width != fmt_src.format.width ||
1427 csi->vdev_compose.height != fmt_src.format.height)
1435 if (!cc || csi->vdev_cc->yuv != cc->yuv)
1444 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1449 ret = imx7_csi_video_validate_fmt(csi);
1451 dev_err(csi->dev, "capture format not valid\n");
1455 mutex_lock(&csi->mdev.graph_mutex);
1457 ret = __video_device_pipeline_start(csi->vdev, &csi->pipe);
1461 ret = v4l2_subdev_call(&csi->sd, video, s_stream, 1);
1465 mutex_unlock(&csi->mdev.graph_mutex);
1470 __video_device_pipeline_stop(csi->vdev);
1472 mutex_unlock(&csi->mdev.graph_mutex);
1473 dev_err(csi->dev, "pipeline start failed with %d\n", ret);
1475 spin_lock_irqsave(&csi->q_lock, flags);
1476 list_for_each_entry_safe(buf, tmp, &csi->ready_q, list) {
1480 spin_unlock_irqrestore(&csi->q_lock, flags);
1486 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1491 mutex_lock(&csi->mdev.graph_mutex);
1492 v4l2_subdev_call(&csi->sd, video, s_stream, 0);
1493 __video_device_pipeline_stop(csi->vdev);
1494 mutex_unlock(&csi->mdev.graph_mutex);
1497 spin_lock_irqsave(&csi->q_lock, flags);
1498 list_for_each_entry_safe(frame, tmp, &csi->ready_q, list) {
1502 spin_unlock_irqrestore(&csi->q_lock, flags);
1522 struct imx7_csi *csi = video_drvdata(file);
1525 if (mutex_lock_interruptible(&csi->vdev_mutex))
1530 dev_err(csi->dev, "v4l2_fh_open failed\n");
1534 ret = v4l2_pipeline_pm_get(&csi->vdev->entity);
1539 mutex_unlock(&csi->vdev_mutex);
1545 struct imx7_csi *csi = video_drvdata(file);
1546 struct vb2_queue *vq = &csi->q;
1548 mutex_lock(&csi->vdev_mutex);
1555 v4l2_pipeline_pm_put(&csi->vdev->entity);
1558 mutex_unlock(&csi->vdev_mutex);
1575 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi)
1580 spin_lock_irqsave(&csi->q_lock, flags);
1583 if (!list_empty(&csi->ready_q)) {
1584 buf = list_entry(csi->ready_q.next, struct imx7_csi_vb2_buffer,
1589 spin_unlock_irqrestore(&csi->q_lock, flags);
1594 static void imx7_csi_video_init_format(struct imx7_csi *csi)
1596 struct v4l2_pix_format *pixfmt = &csi->vdev_fmt;
1601 csi->vdev_cc = __imx7_csi_video_try_fmt(pixfmt, &csi->vdev_compose);
1604 static int imx7_csi_video_register(struct imx7_csi *csi)
1606 struct v4l2_subdev *sd = &csi->sd;
1608 struct video_device *vdev = csi->vdev;
1614 imx7_csi_video_init_format(csi);
1619 dev_err(csi->dev, "Failed to register video device\n");
1623 dev_info(csi->dev, "Registered %s as /dev/%s\n", vdev->name,
1631 dev_err(csi->dev, "failed to create link to device node\n");
1639 static void imx7_csi_video_unregister(struct imx7_csi *csi)
1641 media_entity_cleanup(&csi->vdev->entity);
1642 video_unregister_device(csi->vdev);
1645 static int imx7_csi_video_init(struct imx7_csi *csi)
1651 mutex_init(&csi->vdev_mutex);
1652 INIT_LIST_HEAD(&csi->ready_q);
1653 spin_lock_init(&csi->q_lock);
1668 vdev->lock = &csi->vdev_mutex;
1669 vdev->queue = &csi->q;
1671 snprintf(vdev->name, sizeof(vdev->name), "%s capture", csi->sd.name);
1673 video_set_drvdata(vdev, csi);
1674 csi->vdev = vdev;
1677 csi->vdev_pad.flags = MEDIA_PAD_FL_SINK;
1678 ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad);
1685 vq = &csi->q;
1688 vq->drv_priv = csi;
1693 vq->lock = &csi->vdev_mutex;
1695 vq->dev = csi->dev;
1699 dev_err(csi->dev, "vb2_queue_init failed\n");
1713 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1720 ret = imx7_csi_init(csi, sd_state);
1724 ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
1726 imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED);
1730 imx7_csi_enable(csi);
1732 imx7_csi_disable(csi);
1734 v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
1736 imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR);
1739 csi->is_streaming = !!enable;
1898 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1905 if (csi->is_streaming)
1934 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1947 switch (csi->src_sd->entity.function) {
1950 csi->is_csi2 = true;
1955 for (i = 0; i < csi->src_sd->entity.num_pads; i++) {
1956 struct media_pad *spad = &csi->src_sd->entity.pads[i];
1969 csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE;
1977 csi->is_csi2 = false;
1986 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1989 ret = imx7_csi_video_init(csi);
1993 ret = imx7_csi_video_register(csi);
1997 ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
2001 ret = media_device_register(&csi->mdev);
2008 imx7_csi_video_unregister(csi);
2014 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
2016 imx7_csi_video_unregister(csi);
2058 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2059 struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
2061 csi->src_sd = sd;
2069 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2071 return v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
2079 static int imx7_csi_async_register(struct imx7_csi *csi)
2085 v4l2_async_nf_init(&csi->notifier, &csi->v4l2_dev);
2087 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
2090 ret = dev_err_probe(csi->dev, -ENOTCONN,
2095 asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
2101 ret = dev_err_probe(csi->dev, PTR_ERR(asd),
2106 csi->notifier.ops = &imx7_csi_notify_ops;
2108 ret = v4l2_async_nf_register(&csi->notifier);
2115 v4l2_async_nf_cleanup(&csi->notifier);
2119 static void imx7_csi_media_cleanup(struct imx7_csi *csi)
2121 v4l2_device_unregister(&csi->v4l2_dev);
2122 media_device_unregister(&csi->mdev);
2123 v4l2_subdev_cleanup(&csi->sd);
2124 media_device_cleanup(&csi->mdev);
2131 static int imx7_csi_media_dev_init(struct imx7_csi *csi)
2135 strscpy(csi->mdev.model, "imx-media", sizeof(csi->mdev.model));
2136 csi->mdev.ops = &imx7_csi_media_ops;
2137 csi->mdev.dev = csi->dev;
2139 csi->v4l2_dev.mdev = &csi->mdev;
2140 strscpy(csi->v4l2_dev.name, "imx-media",
2141 sizeof(csi->v4l2_dev.name));
2142 snprintf(csi->mdev.bus_info, sizeof(csi->mdev.bus_info),
2143 "platform:%s", dev_name(csi->mdev.dev));
2145 media_device_init(&csi->mdev);
2147 ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
2149 v4l2_err(&csi->v4l2_dev,
2157 media_device_cleanup(&csi->mdev);
2162 static int imx7_csi_media_init(struct imx7_csi *csi)
2168 ret = imx7_csi_media_dev_init(csi);
2172 v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops);
2173 v4l2_set_subdevdata(&csi->sd, csi);
2174 csi->sd.internal_ops = &imx7_csi_internal_ops;
2175 csi->sd.entity.ops = &imx7_csi_entity_ops;
2176 csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
2177 csi->sd.dev = csi->dev;
2178 csi->sd.owner = THIS_MODULE;
2179 csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
2180 snprintf(csi->sd.name, sizeof(csi->sd.name), "csi");
2183 csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ?
2186 ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM,
2187 csi->pad);
2191 ret = v4l2_subdev_init_finalize(&csi->sd);
2195 ret = v4l2_device_register_subdev(&csi->v4l2_dev, &csi->sd);
2202 imx7_csi_media_cleanup(csi);
2209 struct imx7_csi *csi;
2212 csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
2213 if (!csi)
2216 csi->dev = dev;
2217 platform_set_drvdata(pdev, csi);
2219 spin_lock_init(&csi->irqlock);
2222 csi->mclk = devm_clk_get(&pdev->dev, "mclk");
2223 if (IS_ERR(csi->mclk)) {
2224 ret = PTR_ERR(csi->mclk);
2229 csi->irq = platform_get_irq(pdev, 0);
2230 if (csi->irq < 0)
2231 return csi->irq;
2233 csi->regbase = devm_platform_ioremap_resource(pdev, 0);
2234 if (IS_ERR(csi->regbase))
2235 return PTR_ERR(csi->regbase);
2237 csi->model = (enum imx_csi_model)(uintptr_t)of_device_get_match_data(&pdev->dev);
2239 ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi",
2240 (void *)csi);
2247 ret = imx7_csi_media_init(csi);
2251 ret = imx7_csi_async_register(csi);
2258 imx7_csi_media_cleanup(csi);
2265 struct imx7_csi *csi = platform_get_drvdata(pdev);
2267 imx7_csi_media_cleanup(csi);
2269 v4l2_async_nf_unregister(&csi->notifier);
2270 v4l2_async_nf_cleanup(&csi->notifier);
2271 v4l2_async_unregister_subdev(&csi->sd);
2275 { .compatible = "fsl,imx8mq-csi", .data = (void *)IMX7_CSI_IMX8MQ },
2276 { .compatible = "fsl,imx7-csi", .data = (void *)IMX7_CSI_IMX7 },
2277 { .compatible = "fsl,imx6ul-csi", .data = (void *)IMX7_CSI_IMX7 },
2287 .name = "imx7-csi",
2295 MODULE_ALIAS("platform:imx7-csi");