Lines Matching refs:csi

36 /* csi control reg 1 */
91 /* csi status reg */
111 /* csi image parameter reg */
115 /* csi control reg 18 */
269 static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
271 return readl(csi->regbase + offset);
274 static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value,
277 writel(value, csi->regbase + offset);
280 static u32 imx7_csi_irq_clear(struct imx7_csi *csi)
284 isr = imx7_csi_reg_read(csi, CSI_CSISR);
285 imx7_csi_reg_write(csi, isr, CSI_CSISR);
290 static void imx7_csi_init_default(struct imx7_csi *csi)
292 imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE |
295 imx7_csi_reg_write(csi, 0, CSI_CSICR2);
296 imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3);
298 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(IMX7_CSI_DEF_PIX_WIDTH) |
302 imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3);
305 static void imx7_csi_hw_enable_irq(struct imx7_csi *csi)
307 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
313 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
316 static void imx7_csi_hw_disable_irq(struct imx7_csi *csi)
318 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
324 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
327 static void imx7_csi_hw_enable(struct imx7_csi *csi)
329 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
333 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
336 static void imx7_csi_hw_disable(struct imx7_csi *csi)
338 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
342 imx7_csi_reg_write(csi, cr, CSI_CSICR18);
345 static void imx7_csi_dma_reflash(struct imx7_csi *csi)
349 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
351 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
354 static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi)
356 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC;
358 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
359 imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
360 imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1);
363 static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi)
365 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
372 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
375 static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi)
377 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
381 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
384 static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t dma_addr,
388 imx7_csi_reg_write(csi, dma_addr, CSI_CSIDMASA_FB2);
390 imx7_csi_reg_write(csi, dma_addr, CSI_CSIDMASA_FB1);
393 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi);
395 static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi)
404 buf = imx7_csi_video_next_buf(csi);
406 csi->active_vb2_buf[i] = buf;
410 csi->active_vb2_buf[i] = NULL;
411 dma_addr = csi->underrun_buf.dma_addr;
414 imx7_csi_update_buf(csi, dma_addr, i);
418 static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
426 buf = csi->active_vb2_buf[i];
432 csi->active_vb2_buf[i] = NULL;
437 static void imx7_csi_free_dma_buf(struct imx7_csi *csi,
441 dma_free_coherent(csi->dev, buf->len, buf->virt, buf->dma_addr);
447 static int imx7_csi_alloc_dma_buf(struct imx7_csi *csi,
450 imx7_csi_free_dma_buf(csi, buf);
453 buf->virt = dma_alloc_coherent(csi->dev, buf->len, &buf->dma_addr,
461 static int imx7_csi_dma_setup(struct imx7_csi *csi)
465 ret = imx7_csi_alloc_dma_buf(csi, &csi->underrun_buf,
466 csi->vdev_fmt.sizeimage);
468 v4l2_warn(&csi->sd, "consider increasing the CMA area\n");
472 csi->frame_sequence = 0;
473 csi->last_eof = false;
474 init_completion(&csi->last_eof_completion);
476 imx7_csi_setup_vb2_buf(csi);
481 static void imx7_csi_dma_cleanup(struct imx7_csi *csi,
484 imx7_csi_dma_unsetup_vb2_buf(csi, return_status);
485 imx7_csi_free_dma_buf(csi, &csi->underrun_buf);
488 static void imx7_csi_dma_stop(struct imx7_csi *csi)
495 spin_lock_irqsave(&csi->irqlock, flags);
496 csi->last_eof = true;
497 spin_unlock_irqrestore(&csi->irqlock, flags);
503 ret = wait_for_completion_timeout(&csi->last_eof_completion,
506 v4l2_warn(&csi->sd, "wait last EOF timeout\n");
508 imx7_csi_hw_disable_irq(csi);
511 static void imx7_csi_configure(struct imx7_csi *csi,
514 struct v4l2_pix_format *out_pix = &csi->vdev_fmt;
520 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
532 if (!csi->is_csi2) {
545 sink_fmt = v4l2_subdev_get_pad_format(&csi->sd, sd_state,
622 imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
623 imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2);
624 imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
625 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
627 imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT);
628 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) |
631 imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA);
634 static int imx7_csi_init(struct imx7_csi *csi,
639 ret = clk_prepare_enable(csi->mclk);
643 imx7_csi_configure(csi, sd_state);
645 ret = imx7_csi_dma_setup(csi);
647 clk_disable_unprepare(csi->mclk);
654 static void imx7_csi_deinit(struct imx7_csi *csi,
657 imx7_csi_dma_cleanup(csi, return_status);
658 imx7_csi_init_default(csi);
659 imx7_csi_dmareq_rff_disable(csi);
660 clk_disable_unprepare(csi->mclk);
663 static void imx7_csi_baseaddr_switch_on_second_frame(struct imx7_csi *csi)
665 u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
670 imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
673 static void imx7_csi_enable(struct imx7_csi *csi)
676 imx7_csi_rx_fifo_clear(csi);
677 imx7_csi_dma_reflash(csi);
682 imx7_csi_irq_clear(csi);
683 imx7_csi_hw_enable_irq(csi);
686 imx7_csi_dmareq_rff_enable(csi);
687 imx7_csi_hw_enable(csi);
689 if (csi->model == IMX7_CSI_IMX8MQ)
690 imx7_csi_baseaddr_switch_on_second_frame(csi);
693 static void imx7_csi_disable(struct imx7_csi *csi)
695 imx7_csi_dma_stop(csi);
697 imx7_csi_dmareq_rff_disable(csi);
699 imx7_csi_hw_disable_irq(csi);
701 imx7_csi_hw_disable(csi);
708 static void imx7_csi_error_recovery(struct imx7_csi *csi)
710 imx7_csi_hw_disable(csi);
712 imx7_csi_rx_fifo_clear(csi);
714 imx7_csi_dma_reflash(csi);
716 imx7_csi_hw_enable(csi);
719 static void imx7_csi_vb2_buf_done(struct imx7_csi *csi)
725 done = csi->active_vb2_buf[csi->buf_num];
727 done->vbuf.field = csi->vdev_fmt.field;
728 done->vbuf.sequence = csi->frame_sequence;
733 csi->frame_sequence++;
736 next = imx7_csi_video_next_buf(csi);
739 csi->active_vb2_buf[csi->buf_num] = next;
741 dma_addr = csi->underrun_buf.dma_addr;
742 csi->active_vb2_buf[csi->buf_num] = NULL;
745 imx7_csi_update_buf(csi, dma_addr, csi->buf_num);
750 struct imx7_csi *csi = data;
753 spin_lock(&csi->irqlock);
755 status = imx7_csi_irq_clear(csi);
758 dev_warn(csi->dev, "Rx fifo overflow\n");
759 imx7_csi_error_recovery(csi);
763 dev_warn(csi->dev, "Hresponse error detected\n");
764 imx7_csi_error_recovery(csi);
768 imx7_csi_hw_disable(csi);
770 imx7_csi_dma_reflash(csi);
772 imx7_csi_hw_enable(csi);
782 * when csi work in field0 and field1 will write to
786 csi->buf_num = 0;
788 csi->buf_num = 1;
793 imx7_csi_vb2_buf_done(csi);
795 if (csi->last_eof) {
796 complete(&csi->last_eof_completion);
797 csi->last_eof = false;
801 spin_unlock(&csi->irqlock);
1026 struct imx7_csi *csi = video_drvdata(file);
1031 "platform:%s", dev_name(csi->dev));
1108 struct imx7_csi *csi = video_drvdata(file);
1110 f->fmt.pix = csi->vdev_fmt;
1165 struct imx7_csi *csi = video_drvdata(file);
1168 if (vb2_is_busy(&csi->q)) {
1169 dev_err(csi->dev, "%s queue busy\n", __func__);
1173 cc = __imx7_csi_video_try_fmt(&f->fmt.pix, &csi->vdev_compose);
1175 csi->vdev_cc = cc;
1176 csi->vdev_fmt = f->fmt.pix;
1184 struct imx7_csi *csi = video_drvdata(file);
1194 s->r = csi->vdev_compose;
1204 s->r.width = csi->vdev_fmt.width;
1205 s->r.height = csi->vdev_fmt.height;
1247 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1248 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1285 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1286 struct v4l2_pix_format *pix = &csi->vdev_fmt;
1289 dev_err(csi->dev,
1300 static bool imx7_csi_fast_track_buffer(struct imx7_csi *csi,
1308 if (!csi->is_streaming)
1342 spin_lock_irqsave(&csi->irqlock, flags);
1344 buf_num = csi->buf_num;
1345 if (csi->active_vb2_buf[buf_num]) {
1346 spin_unlock_irqrestore(&csi->irqlock, flags);
1350 imx7_csi_update_buf(csi, dma_addr, buf_num);
1352 isr = imx7_csi_reg_read(csi, CSI_CSISR);
1363 spin_unlock_irqrestore(&csi->irqlock, flags);
1367 csi->active_vb2_buf[buf_num] = buf;
1369 spin_unlock_irqrestore(&csi->irqlock, flags);
1375 struct imx7_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
1379 if (imx7_csi_fast_track_buffer(csi, buf))
1382 spin_lock_irqsave(&csi->q_lock, flags);
1384 list_add_tail(&buf->list, &csi->ready_q);
1386 spin_unlock_irqrestore(&csi->q_lock, flags);
1389 static int imx7_csi_video_validate_fmt(struct imx7_csi *csi)
1399 ret = v4l2_subdev_call_state_active(&csi->sd, pad, get_fmt, &fmt_src);
1410 if (csi->vdev_compose.width != fmt_src.format.width ||
1411 csi->vdev_compose.height != fmt_src.format.height)
1419 if (!cc || csi->vdev_cc->yuv != cc->yuv)
1428 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1433 ret = imx7_csi_video_validate_fmt(csi);
1435 dev_err(csi->dev, "capture format not valid\n");
1439 mutex_lock(&csi->mdev.graph_mutex);
1441 ret = __video_device_pipeline_start(csi->vdev, &csi->pipe);
1445 ret = v4l2_subdev_call(&csi->sd, video, s_stream, 1);
1449 mutex_unlock(&csi->mdev.graph_mutex);
1454 __video_device_pipeline_stop(csi->vdev);
1456 mutex_unlock(&csi->mdev.graph_mutex);
1457 dev_err(csi->dev, "pipeline start failed with %d\n", ret);
1459 spin_lock_irqsave(&csi->q_lock, flags);
1460 list_for_each_entry_safe(buf, tmp, &csi->ready_q, list) {
1464 spin_unlock_irqrestore(&csi->q_lock, flags);
1470 struct imx7_csi *csi = vb2_get_drv_priv(vq);
1475 mutex_lock(&csi->mdev.graph_mutex);
1476 v4l2_subdev_call(&csi->sd, video, s_stream, 0);
1477 __video_device_pipeline_stop(csi->vdev);
1478 mutex_unlock(&csi->mdev.graph_mutex);
1481 spin_lock_irqsave(&csi->q_lock, flags);
1482 list_for_each_entry_safe(frame, tmp, &csi->ready_q, list) {
1486 spin_unlock_irqrestore(&csi->q_lock, flags);
1506 struct imx7_csi *csi = video_drvdata(file);
1509 if (mutex_lock_interruptible(&csi->vdev_mutex))
1514 dev_err(csi->dev, "v4l2_fh_open failed\n");
1518 ret = v4l2_pipeline_pm_get(&csi->vdev->entity);
1523 mutex_unlock(&csi->vdev_mutex);
1529 struct imx7_csi *csi = video_drvdata(file);
1530 struct vb2_queue *vq = &csi->q;
1532 mutex_lock(&csi->vdev_mutex);
1539 v4l2_pipeline_pm_put(&csi->vdev->entity);
1542 mutex_unlock(&csi->vdev_mutex);
1559 static struct imx7_csi_vb2_buffer *imx7_csi_video_next_buf(struct imx7_csi *csi)
1564 spin_lock_irqsave(&csi->q_lock, flags);
1567 if (!list_empty(&csi->ready_q)) {
1568 buf = list_entry(csi->ready_q.next, struct imx7_csi_vb2_buffer,
1573 spin_unlock_irqrestore(&csi->q_lock, flags);
1578 static void imx7_csi_video_init_format(struct imx7_csi *csi)
1580 struct v4l2_pix_format *pixfmt = &csi->vdev_fmt;
1585 csi->vdev_cc = __imx7_csi_video_try_fmt(pixfmt, &csi->vdev_compose);
1588 static int imx7_csi_video_register(struct imx7_csi *csi)
1590 struct v4l2_subdev *sd = &csi->sd;
1592 struct video_device *vdev = csi->vdev;
1598 imx7_csi_video_init_format(csi);
1603 dev_err(csi->dev, "Failed to register video device\n");
1607 dev_info(csi->dev, "Registered %s as /dev/%s\n", vdev->name,
1615 dev_err(csi->dev, "failed to create link to device node\n");
1623 static void imx7_csi_video_unregister(struct imx7_csi *csi)
1625 media_entity_cleanup(&csi->vdev->entity);
1626 video_unregister_device(csi->vdev);
1629 static int imx7_csi_video_init(struct imx7_csi *csi)
1635 mutex_init(&csi->vdev_mutex);
1636 INIT_LIST_HEAD(&csi->ready_q);
1637 spin_lock_init(&csi->q_lock);
1652 vdev->lock = &csi->vdev_mutex;
1653 vdev->queue = &csi->q;
1655 snprintf(vdev->name, sizeof(vdev->name), "%s capture", csi->sd.name);
1657 video_set_drvdata(vdev, csi);
1658 csi->vdev = vdev;
1661 csi->vdev_pad.flags = MEDIA_PAD_FL_SINK;
1662 ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad);
1669 vq = &csi->q;
1672 vq->drv_priv = csi;
1677 vq->lock = &csi->vdev_mutex;
1679 vq->dev = csi->dev;
1683 dev_err(csi->dev, "vb2_queue_init failed\n");
1697 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1704 ret = imx7_csi_init(csi, sd_state);
1708 ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
1710 imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED);
1714 imx7_csi_enable(csi);
1716 imx7_csi_disable(csi);
1718 v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
1720 imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR);
1723 csi->is_streaming = !!enable;
1882 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1889 if (csi->is_streaming)
1918 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1931 switch (csi->src_sd->entity.function) {
1934 csi->is_csi2 = true;
1939 for (i = 0; i < csi->src_sd->entity.num_pads; i++) {
1940 struct media_pad *spad = &csi->src_sd->entity.pads[i];
1953 csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE;
1961 csi->is_csi2 = false;
1970 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1973 ret = imx7_csi_video_init(csi);
1977 ret = imx7_csi_video_register(csi);
1981 ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
1985 ret = media_device_register(&csi->mdev);
1992 imx7_csi_video_unregister(csi);
1998 struct imx7_csi *csi = v4l2_get_subdevdata(sd);
2000 imx7_csi_video_unregister(csi);
2042 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2043 struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
2045 csi->src_sd = sd;
2053 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
2055 return v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
2063 static int imx7_csi_async_register(struct imx7_csi *csi)
2069 v4l2_async_nf_init(&csi->notifier, &csi->v4l2_dev);
2071 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
2074 ret = dev_err_probe(csi->dev, -ENOTCONN,
2079 asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep,
2085 ret = dev_err_probe(csi->dev, PTR_ERR(asd),
2090 csi->notifier.ops = &imx7_csi_notify_ops;
2092 ret = v4l2_async_nf_register(&csi->notifier);
2099 v4l2_async_nf_cleanup(&csi->notifier);
2103 static void imx7_csi_media_cleanup(struct imx7_csi *csi)
2105 v4l2_device_unregister(&csi->v4l2_dev);
2106 media_device_unregister(&csi->mdev);
2107 v4l2_subdev_cleanup(&csi->sd);
2108 media_device_cleanup(&csi->mdev);
2115 static int imx7_csi_media_dev_init(struct imx7_csi *csi)
2119 strscpy(csi->mdev.model, "imx-media", sizeof(csi->mdev.model));
2120 csi->mdev.ops = &imx7_csi_media_ops;
2121 csi->mdev.dev = csi->dev;
2123 csi->v4l2_dev.mdev = &csi->mdev;
2124 strscpy(csi->v4l2_dev.name, "imx-media",
2125 sizeof(csi->v4l2_dev.name));
2126 snprintf(csi->mdev.bus_info, sizeof(csi->mdev.bus_info),
2127 "platform:%s", dev_name(csi->mdev.dev));
2129 media_device_init(&csi->mdev);
2131 ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
2133 v4l2_err(&csi->v4l2_dev,
2141 media_device_cleanup(&csi->mdev);
2146 static int imx7_csi_media_init(struct imx7_csi *csi)
2152 ret = imx7_csi_media_dev_init(csi);
2156 v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops);
2157 v4l2_set_subdevdata(&csi->sd, csi);
2158 csi->sd.internal_ops = &imx7_csi_internal_ops;
2159 csi->sd.entity.ops = &imx7_csi_entity_ops;
2160 csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
2161 csi->sd.dev = csi->dev;
2162 csi->sd.owner = THIS_MODULE;
2163 csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
2164 snprintf(csi->sd.name, sizeof(csi->sd.name), "csi");
2167 csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ?
2170 ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM,
2171 csi->pad);
2175 ret = v4l2_subdev_init_finalize(&csi->sd);
2179 ret = v4l2_device_register_subdev(&csi->v4l2_dev, &csi->sd);
2186 imx7_csi_media_cleanup(csi);
2193 struct imx7_csi *csi;
2196 csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
2197 if (!csi)
2200 csi->dev = dev;
2201 platform_set_drvdata(pdev, csi);
2203 spin_lock_init(&csi->irqlock);
2206 csi->mclk = devm_clk_get(&pdev->dev, "mclk");
2207 if (IS_ERR(csi->mclk)) {
2208 ret = PTR_ERR(csi->mclk);
2213 csi->irq = platform_get_irq(pdev, 0);
2214 if (csi->irq < 0)
2215 return csi->irq;
2217 csi->regbase = devm_platform_ioremap_resource(pdev, 0);
2218 if (IS_ERR(csi->regbase))
2219 return PTR_ERR(csi->regbase);
2221 csi->model = (enum imx_csi_model)(uintptr_t)of_device_get_match_data(&pdev->dev);
2223 ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi",
2224 (void *)csi);
2231 ret = imx7_csi_media_init(csi);
2235 ret = imx7_csi_async_register(csi);
2242 imx7_csi_media_cleanup(csi);
2249 struct imx7_csi *csi = platform_get_drvdata(pdev);
2251 imx7_csi_media_cleanup(csi);
2253 v4l2_async_nf_unregister(&csi->notifier);
2254 v4l2_async_nf_cleanup(&csi->notifier);
2255 v4l2_async_unregister_subdev(&csi->sd);
2259 { .compatible = "fsl,imx8mq-csi", .data = (void *)IMX7_CSI_IMX8MQ },
2260 { .compatible = "fsl,imx7-csi", .data = (void *)IMX7_CSI_IMX7 },
2261 { .compatible = "fsl,imx6ul-csi", .data = (void *)IMX7_CSI_IMX7 },
2271 .name = "imx7-csi",
2279 MODULE_ALIAS("platform:imx7-csi");