Lines Matching +full:timing +full:- +full:adjustment

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Renesas RZ/G2L MIPI CSI-2 Receiver
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-device.h>
23 #include <media/v4l2-fwnode.h>
24 #include <media/v4l2-mc.h>
25 #include <media/v4l2-subdev.h>
60 /* D-PHY Control Register 0 */
65 /* D-PHY Timing Register 0 */
70 /* D-PHY Timing Register 1 */
77 /* D-PHY Skew Adjustment Function */
272 return ioread32(csi2->base + reg);
278 iowrite32(data, csi2->base + reg);
293 struct v4l2_subdev *source = csi2->remote_source;
301 if (!csi2->remote_source)
302 return -ENODEV;
304 remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
306 dev_err(csi2->dev, "can't get source pad of %s (%ld)\n",
307 csi2->remote_source->name, PTR_ERR(remote_pad));
311 state = v4l2_subdev_lock_and_get_active_state(&csi2->subdev);
313 format = rzg2l_csi2_code_to_fmt(fmt->code);
317 ret = v4l2_get_link_freq(remote_pad, format->bpp, csi2->lanes * 2);
319 dev_err(csi2->dev, "can't retrieve link freq from subdev %s\n",
320 source->name);
321 return -EINVAL;
330 /* -----------------------------------------------------------------------------
338 /* Reset the CRU (D-PHY) */
339 ret = reset_control_assert(csi2->cmn_rstb);
343 /* Stop the D-PHY clock */
344 clk_disable_unprepare(csi2->sysclk);
352 csi2->dphy_enabled = false;
369 csi2->hsfreq = mbps;
371 /* Set DPHY timing parameters */
375 if (csi2->hsfreq <= dphy_timing->max_hsfreq)
380 return -EINVAL;
382 /* Set D-PHY timing parameters */
383 dphytim0 = CSIDPHYTIM0_TCLK_MISS(dphy_timing->tclk_miss) |
384 CSIDPHYTIM0_T_INIT(dphy_timing->t_init);
385 dphytim1 = CSIDPHYTIM1_THS_PREPARE(dphy_timing->ths_prepare) |
386 CSIDPHYTIM1_TCLK_PREPARE(dphy_timing->tclk_prepare) |
387 CSIDPHYTIM1_THS_SETTLE(dphy_timing->ths_settle) |
388 CSIDPHYTIM1_TCLK_SETTLE(dphy_timing->tclk_settle);
392 /* Enable D-PHY power control 0 */
401 /* Enable D-PHY power control 1 */
407 /* Start supplying the internal clock for the D-PHY block */
408 ret = clk_prepare_enable(csi2->sysclk);
412 csi2->dphy_enabled = true;
428 return csi2->info->dphy_enable(csi2);
430 return csi2->info->dphy_disable(csi2);
435 unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ;
439 rzg2l_csi2_write(csi2, CSI2nMCT0, CSI2nMCT0_VDLN(csi2->lanes));
443 frrskw = DIV_ROUND_UP(frrskw_coeff, csi2->hsfreq);
444 frrclk = DIV_ROUND_UP(frrclk_coeff, csi2->hsfreq);
451 * Generic Long Packet Data Types 1 to 4 YUV422 8-bit,
452 * RGB565, RGB888, RAW8 to RAW20, User-defined 8-bit
458 clk_disable_unprepare(csi2->vclk);
463 return clk_prepare_enable(csi2->vclk);
477 while (--timeout) {
484 dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n");
493 /* Reset the CRU (D-PHY) */
494 ret = reset_control_assert(csi2->cmn_rstb);
498 csi2->dphy_enabled = false;
513 csi2->hsfreq = mbps;
516 if (csi2->hsfreq <= rzv2h_s_hssettlectl[i].hsfreq)
521 return -EINVAL;
529 if (csi2->hsfreq > 1500)
536 csi2->dphy_enabled = true;
567 ret = pm_runtime_resume_and_get(csi2->dev);
575 ret = reset_control_deassert(csi2->cmn_rstb);
580 ret = v4l2_subdev_call(csi2->remote_source, video, s_stream, enable);
595 pm_runtime_put_sync(csi2->dev);
601 reset_control_assert(csi2->cmn_rstb);
605 pm_runtime_put_sync(csi2->dev);
619 * In ideal case D-PHY will be disabled in s_stream(0) callback
624 if (csi2->dphy_enabled)
638 if (fmt->pad == RZG2L_CSI2_SOURCE) {
639 fmt->format = *src_format;
645 if (!rzg2l_csi2_code_to_fmt(fmt->format.code))
646 sink_format->code = rzg2l_csi2_formats[0].code;
648 sink_format->code = fmt->format.code;
650 sink_format->field = V4L2_FIELD_NONE;
651 sink_format->colorspace = fmt->format.colorspace;
652 sink_format->xfer_func = fmt->format.xfer_func;
653 sink_format->ycbcr_enc = fmt->format.ycbcr_enc;
654 sink_format->quantization = fmt->format.quantization;
655 sink_format->width = clamp_t(u32, fmt->format.width,
657 sink_format->height = clamp_t(u32, fmt->format.height,
659 fmt->format = *sink_format;
688 if (code->index >= ARRAY_SIZE(rzg2l_csi2_formats))
689 return -EINVAL;
691 code->code = rzg2l_csi2_formats[code->index].code;
700 if (fse->index != 0)
701 return -EINVAL;
703 if (!rzg2l_csi2_code_to_fmt(fse->code))
704 return -EINVAL;
706 fse->min_width = RZG2L_CSI2_MIN_WIDTH;
707 fse->min_height = RZG2L_CSI2_MIN_HEIGHT;
708 fse->max_width = RZG2L_CSI2_MAX_WIDTH;
709 fse->max_height = RZG2L_CSI2_MAX_HEIGHT;
720 if (!csi2->remote_source)
721 return -ENODEV;
723 remote_pad = media_pad_remote_pad_unique(&csi2->pads[RZG2L_CSI2_SINK]);
725 dev_err(csi2->dev, "can't get source pad of %s (%ld)\n",
726 csi2->remote_source->name, PTR_ERR(remote_pad));
729 return v4l2_subdev_call(csi2->remote_source, pad, get_frame_desc,
730 remote_pad->index, fd);
756 /* -----------------------------------------------------------------------------
766 csi2->remote_source = subdev;
768 dev_dbg(csi2->dev, "Bound subdev: %s pad\n", subdev->name);
770 return media_create_pad_link(&subdev->entity, RZG2L_CSI2_SINK,
771 &csi2->subdev.entity, 0,
782 csi2->remote_source = NULL;
784 dev_dbg(csi2->dev, "Unbind subdev %s\n", subdev->name);
796 if (vep->base.port || vep->base.id)
797 return -ENOTCONN;
799 csi2->lanes = vep->bus.mipi_csi2.num_data_lanes;
814 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, 0);
816 dev_err(csi2->dev, "Not connected to subdevice\n");
817 return -EINVAL;
822 dev_err(csi2->dev, "Could not parse v4l2 endpoint\n");
824 return -EINVAL;
836 v4l2_async_subdev_nf_init(&csi2->notifier, &csi2->subdev);
837 csi2->notifier.ops = &rzg2l_csi2_notify_ops;
839 asd = v4l2_async_nf_add_fwnode(&csi2->notifier, fwnode,
845 ret = v4l2_async_nf_register(&csi2->notifier);
847 v4l2_async_nf_cleanup(&csi2->notifier);
857 if (csi2->lanes != 1 && csi2->lanes != 2 && csi2->lanes != 4) {
858 dev_err(csi2->dev, "Unsupported number of data-lanes: %u\n",
859 csi2->lanes);
860 return -EINVAL;
863 ret = pm_runtime_resume_and_get(csi2->dev);
867 /* Checking the maximum lanes support for CSI-2 module */
869 if (lanes < csi2->lanes) {
870 dev_err(csi2->dev,
871 "Failed to support %d data lanes\n", csi2->lanes);
872 ret = -EINVAL;
875 pm_runtime_put_sync(csi2->dev);
880 /* -----------------------------------------------------------------------------
890 struct device *dev = &pdev->dev;
896 return -ENOMEM;
898 csi2->info = of_device_get_match_data(dev);
899 if (!csi2->info)
900 return dev_err_probe(dev, -EINVAL, "Failed to get OF match data\n");
902 csi2->base = devm_platform_ioremap_resource(pdev, 0);
903 if (IS_ERR(csi2->base))
904 return PTR_ERR(csi2->base);
906 csi2->cmn_rstb = devm_reset_control_get_exclusive(dev, "cmn-rstb");
907 if (IS_ERR(csi2->cmn_rstb))
908 return dev_err_probe(dev, PTR_ERR(csi2->cmn_rstb),
909 "Failed to get cpg cmn-rstb\n");
911 csi2->presetn = devm_reset_control_get_shared(dev, "presetn");
912 if (IS_ERR(csi2->presetn))
913 return dev_err_probe(dev, PTR_ERR(csi2->presetn),
916 if (csi2->info->has_system_clk) {
917 csi2->sysclk = devm_clk_get(dev, "system");
918 if (IS_ERR(csi2->sysclk))
919 return dev_err_probe(dev, PTR_ERR(csi2->sysclk),
923 csi2->vclk = devm_clk_get(dev, "video");
924 if (IS_ERR(csi2->vclk))
925 return dev_err_probe(dev, PTR_ERR(csi2->vclk),
927 csi2->vclk_rate = clk_get_rate(csi2->vclk);
929 csi2->dev = dev;
945 csi2->subdev.dev = dev;
946 v4l2_subdev_init(&csi2->subdev, &rzg2l_csi2_subdev_ops);
947 csi2->subdev.internal_ops = &rzg2l_csi2_internal_ops;
948 v4l2_set_subdevdata(&csi2->subdev, dev);
949 snprintf(csi2->subdev.name, sizeof(csi2->subdev.name),
950 "csi-%s", dev_name(dev));
951 csi2->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
953 csi2->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
954 csi2->subdev.entity.ops = &rzg2l_csi2_entity_ops;
956 csi2->pads[RZG2L_CSI2_SINK].flags = MEDIA_PAD_FL_SINK |
963 csi2->pads[RZG2L_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
965 ret = media_entity_pads_init(&csi2->subdev.entity, ARRAY_SIZE(csi2->pads),
966 csi2->pads);
970 ret = v4l2_subdev_init_finalize(&csi2->subdev);
974 ret = v4l2_async_register_subdev(&csi2->subdev);
981 v4l2_subdev_cleanup(&csi2->subdev);
983 v4l2_async_nf_unregister(&csi2->notifier);
984 v4l2_async_nf_cleanup(&csi2->notifier);
985 media_entity_cleanup(&csi2->subdev.entity);
994 v4l2_async_nf_unregister(&csi2->notifier);
995 v4l2_async_nf_cleanup(&csi2->notifier);
996 v4l2_async_unregister_subdev(&csi2->subdev);
997 v4l2_subdev_cleanup(&csi2->subdev);
998 media_entity_cleanup(&csi2->subdev.entity);
1005 reset_control_assert(csi2->presetn);
1014 return reset_control_deassert(csi2->presetn);
1024 .compatible = "renesas,r9a09g057-csi2",
1028 .compatible = "renesas,rzg2l-csi2",
1039 .name = "rzg2l-csi2",
1047 MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");