Lines Matching full:csi2

214 static u32 rzg2l_csi2_read(struct rzg2l_csi2 *csi2, unsigned int reg)  in rzg2l_csi2_read()  argument
216 return ioread32(csi2->base + reg); in rzg2l_csi2_read()
219 static void rzg2l_csi2_write(struct rzg2l_csi2 *csi2, unsigned int reg, in rzg2l_csi2_write() argument
222 iowrite32(data, csi2->base + reg); in rzg2l_csi2_write()
225 static void rzg2l_csi2_set(struct rzg2l_csi2 *csi2, unsigned int reg, u32 set) in rzg2l_csi2_set() argument
227 rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) | set); in rzg2l_csi2_set()
230 static void rzg2l_csi2_clr(struct rzg2l_csi2 *csi2, unsigned int reg, u32 clr) in rzg2l_csi2_clr() argument
232 rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) & ~clr); in rzg2l_csi2_clr()
235 static int rzg2l_csi2_calc_mbps(struct rzg2l_csi2 *csi2) in rzg2l_csi2_calc_mbps() argument
237 struct v4l2_subdev *source = csi2->remote_source; in rzg2l_csi2_calc_mbps()
247 dev_err(csi2->dev, "no pixel rate control in subdev %s\n", in rzg2l_csi2_calc_mbps()
252 state = v4l2_subdev_lock_and_get_active_state(&csi2->subdev); in rzg2l_csi2_calc_mbps()
253 fmt = v4l2_subdev_get_pad_format(&csi2->subdev, state, RZG2L_CSI2_SINK); in rzg2l_csi2_calc_mbps()
262 do_div(mbps, csi2->lanes * 1000000); in rzg2l_csi2_calc_mbps()
271 static int rzg2l_csi2_dphy_disable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_dphy_disable() argument
276 ret = reset_control_assert(csi2->cmn_rstb); in rzg2l_csi2_dphy_disable()
281 clk_disable_unprepare(csi2->sysclk); in rzg2l_csi2_dphy_disable()
284 rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); in rzg2l_csi2_dphy_disable()
287 rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); in rzg2l_csi2_dphy_disable()
289 csi2->dphy_enabled = false; in rzg2l_csi2_dphy_disable()
294 static int rzg2l_csi2_dphy_enable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_dphy_enable() argument
302 mbps = rzg2l_csi2_calc_mbps(csi2); in rzg2l_csi2_dphy_enable()
306 csi2->hsfreq = mbps; in rzg2l_csi2_dphy_enable()
312 if (csi2->hsfreq <= dphy_timing->max_hsfreq) in rzg2l_csi2_dphy_enable()
326 rzg2l_csi2_write(csi2, CSIDPHYTIM0, dphytim0); in rzg2l_csi2_dphy_enable()
327 rzg2l_csi2_write(csi2, CSIDPHYTIM1, dphytim1); in rzg2l_csi2_dphy_enable()
330 rzg2l_csi2_write(csi2, CSIDPHYSKW0, CSIDPHYSKW0_DEFAULT_SKW); in rzg2l_csi2_dphy_enable()
333 rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); in rzg2l_csi2_dphy_enable()
339 rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); in rzg2l_csi2_dphy_enable()
345 ret = clk_prepare_enable(csi2->sysclk); in rzg2l_csi2_dphy_enable()
347 rzg2l_csi2_dphy_disable(csi2); in rzg2l_csi2_dphy_enable()
349 csi2->dphy_enabled = true; in rzg2l_csi2_dphy_enable()
356 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_dphy_setting() local
359 return rzg2l_csi2_dphy_enable(csi2); in rzg2l_csi2_dphy_setting()
361 return rzg2l_csi2_dphy_disable(csi2); in rzg2l_csi2_dphy_setting()
364 static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_mipi_link_enable() argument
366 unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ; in rzg2l_csi2_mipi_link_enable()
370 rzg2l_csi2_write(csi2, CSI2nMCT0, CSI2nMCT0_VDLN(csi2->lanes)); in rzg2l_csi2_mipi_link_enable()
374 frrskw = DIV_ROUND_UP(frrskw_coeff, csi2->hsfreq); in rzg2l_csi2_mipi_link_enable()
375 frrclk = DIV_ROUND_UP(frrclk_coeff, csi2->hsfreq); in rzg2l_csi2_mipi_link_enable()
376 rzg2l_csi2_write(csi2, CSI2nMCT2, CSI2nMCT2_FRRSKW(frrskw) | in rzg2l_csi2_mipi_link_enable()
386 rzg2l_csi2_write(csi2, CSI2nDTEL, 0xf778ff0f); in rzg2l_csi2_mipi_link_enable()
387 rzg2l_csi2_write(csi2, CSI2nDTEH, 0x00ffff1f); in rzg2l_csi2_mipi_link_enable()
390 rzg2l_csi2_write(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); in rzg2l_csi2_mipi_link_enable()
393 static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_mipi_link_disable() argument
398 rzg2l_csi2_clr(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); in rzg2l_csi2_mipi_link_disable()
401 rzg2l_csi2_write(csi2, CSI2nRTCT, CSI2nRTCT_VSRST); in rzg2l_csi2_mipi_link_disable()
405 if (!(rzg2l_csi2_read(csi2, CSI2nRTST) & CSI2nRTST_VSRSTS)) in rzg2l_csi2_mipi_link_disable()
411 dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n"); in rzg2l_csi2_mipi_link_disable()
416 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_mipi_link_setting() local
419 rzg2l_csi2_mipi_link_enable(csi2); in rzg2l_csi2_mipi_link_setting()
421 rzg2l_csi2_mipi_link_disable(csi2); in rzg2l_csi2_mipi_link_setting()
428 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_s_stream() local
433 ret = pm_runtime_resume_and_get(csi2->dev); in rzg2l_csi2_s_stream()
441 ret = reset_control_deassert(csi2->cmn_rstb); in rzg2l_csi2_s_stream()
446 ret = v4l2_subdev_call(csi2->remote_source, video, s_stream, enable); in rzg2l_csi2_s_stream()
461 pm_runtime_put_sync(csi2->dev); in rzg2l_csi2_s_stream()
467 reset_control_assert(csi2->cmn_rstb); in rzg2l_csi2_s_stream()
471 pm_runtime_put_sync(csi2->dev); in rzg2l_csi2_s_stream()
482 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_post_streamoff() local
490 if (csi2->dphy_enabled) in rzg2l_csi2_post_streamoff()
604 struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); in rzg2l_csi2_notify_bound() local
606 csi2->remote_source = subdev; in rzg2l_csi2_notify_bound()
608 dev_dbg(csi2->dev, "Bound subdev: %s pad\n", subdev->name); in rzg2l_csi2_notify_bound()
611 &csi2->subdev.entity, 0, in rzg2l_csi2_notify_bound()
620 struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); in rzg2l_csi2_notify_unbind() local
622 csi2->remote_source = NULL; in rzg2l_csi2_notify_unbind()
624 dev_dbg(csi2->dev, "Unbind subdev %s\n", subdev->name); in rzg2l_csi2_notify_unbind()
632 static int rzg2l_csi2_parse_v4l2(struct rzg2l_csi2 *csi2, in rzg2l_csi2_parse_v4l2() argument
639 csi2->lanes = vep->bus.mipi_csi2.num_data_lanes; in rzg2l_csi2_parse_v4l2()
644 static int rzg2l_csi2_parse_dt(struct rzg2l_csi2 *csi2) in rzg2l_csi2_parse_dt() argument
654 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, 0); in rzg2l_csi2_parse_dt()
656 dev_err(csi2->dev, "Not connected to subdevice\n"); in rzg2l_csi2_parse_dt()
662 dev_err(csi2->dev, "Could not parse v4l2 endpoint\n"); in rzg2l_csi2_parse_dt()
667 ret = rzg2l_csi2_parse_v4l2(csi2, &v4l2_ep); in rzg2l_csi2_parse_dt()
676 v4l2_async_subdev_nf_init(&csi2->notifier, &csi2->subdev); in rzg2l_csi2_parse_dt()
677 csi2->notifier.ops = &rzg2l_csi2_notify_ops; in rzg2l_csi2_parse_dt()
679 asd = v4l2_async_nf_add_fwnode(&csi2->notifier, fwnode, in rzg2l_csi2_parse_dt()
685 ret = v4l2_async_nf_register(&csi2->notifier); in rzg2l_csi2_parse_dt()
687 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_parse_dt()
692 static int rzg2l_validate_csi2_lanes(struct rzg2l_csi2 *csi2) in rzg2l_validate_csi2_lanes() argument
697 if (csi2->lanes != 1 && csi2->lanes != 2 && csi2->lanes != 4) { in rzg2l_validate_csi2_lanes()
698 dev_err(csi2->dev, "Unsupported number of data-lanes: %u\n", in rzg2l_validate_csi2_lanes()
699 csi2->lanes); in rzg2l_validate_csi2_lanes()
703 ret = pm_runtime_resume_and_get(csi2->dev); in rzg2l_validate_csi2_lanes()
708 lanes = (rzg2l_csi2_read(csi2, CSI2nMCG) & CSI2nMCG_SDLN) >> 8; in rzg2l_validate_csi2_lanes()
709 if (lanes < csi2->lanes) { in rzg2l_validate_csi2_lanes()
710 dev_err(csi2->dev, in rzg2l_validate_csi2_lanes()
711 "Failed to support %d data lanes\n", csi2->lanes); in rzg2l_validate_csi2_lanes()
715 pm_runtime_put_sync(csi2->dev); in rzg2l_validate_csi2_lanes()
730 struct rzg2l_csi2 *csi2; in rzg2l_csi2_probe() local
734 csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL); in rzg2l_csi2_probe()
735 if (!csi2) in rzg2l_csi2_probe()
738 csi2->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_csi2_probe()
739 if (IS_ERR(csi2->base)) in rzg2l_csi2_probe()
740 return PTR_ERR(csi2->base); in rzg2l_csi2_probe()
742 csi2->cmn_rstb = devm_reset_control_get_exclusive(&pdev->dev, "cmn-rstb"); in rzg2l_csi2_probe()
743 if (IS_ERR(csi2->cmn_rstb)) in rzg2l_csi2_probe()
744 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->cmn_rstb), in rzg2l_csi2_probe()
747 csi2->presetn = devm_reset_control_get_shared(&pdev->dev, "presetn"); in rzg2l_csi2_probe()
748 if (IS_ERR(csi2->presetn)) in rzg2l_csi2_probe()
749 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->presetn), in rzg2l_csi2_probe()
752 csi2->sysclk = devm_clk_get(&pdev->dev, "system"); in rzg2l_csi2_probe()
753 if (IS_ERR(csi2->sysclk)) in rzg2l_csi2_probe()
754 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->sysclk), in rzg2l_csi2_probe()
761 csi2->vclk_rate = clk_get_rate(vclk); in rzg2l_csi2_probe()
764 csi2->dev = &pdev->dev; in rzg2l_csi2_probe()
766 platform_set_drvdata(pdev, csi2); in rzg2l_csi2_probe()
768 ret = rzg2l_csi2_parse_dt(csi2); in rzg2l_csi2_probe()
774 ret = rzg2l_validate_csi2_lanes(csi2); in rzg2l_csi2_probe()
778 csi2->subdev.dev = &pdev->dev; in rzg2l_csi2_probe()
779 v4l2_subdev_init(&csi2->subdev, &rzg2l_csi2_subdev_ops); in rzg2l_csi2_probe()
780 v4l2_set_subdevdata(&csi2->subdev, &pdev->dev); in rzg2l_csi2_probe()
781 snprintf(csi2->subdev.name, sizeof(csi2->subdev.name), in rzg2l_csi2_probe()
783 csi2->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in rzg2l_csi2_probe()
785 csi2->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in rzg2l_csi2_probe()
786 csi2->subdev.entity.ops = &rzg2l_csi2_entity_ops; in rzg2l_csi2_probe()
788 csi2->pads[RZG2L_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; in rzg2l_csi2_probe()
790 * TODO: RZ/G2L CSI2 supports 4 virtual channels, as virtual in rzg2l_csi2_probe()
794 csi2->pads[RZG2L_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in rzg2l_csi2_probe()
795 ret = media_entity_pads_init(&csi2->subdev.entity, 2, csi2->pads); in rzg2l_csi2_probe()
799 ret = v4l2_subdev_init_finalize(&csi2->subdev); in rzg2l_csi2_probe()
803 ret = v4l2_async_register_subdev(&csi2->subdev); in rzg2l_csi2_probe()
810 v4l2_subdev_cleanup(&csi2->subdev); in rzg2l_csi2_probe()
812 v4l2_async_nf_unregister(&csi2->notifier); in rzg2l_csi2_probe()
813 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_probe()
814 media_entity_cleanup(&csi2->subdev.entity); in rzg2l_csi2_probe()
823 struct rzg2l_csi2 *csi2 = platform_get_drvdata(pdev); in rzg2l_csi2_remove() local
825 v4l2_async_nf_unregister(&csi2->notifier); in rzg2l_csi2_remove()
826 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_remove()
827 v4l2_async_unregister_subdev(&csi2->subdev); in rzg2l_csi2_remove()
828 v4l2_subdev_cleanup(&csi2->subdev); in rzg2l_csi2_remove()
829 media_entity_cleanup(&csi2->subdev.entity); in rzg2l_csi2_remove()
835 struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); in rzg2l_csi2_pm_runtime_suspend() local
837 reset_control_assert(csi2->presetn); in rzg2l_csi2_pm_runtime_suspend()
844 struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); in rzg2l_csi2_pm_runtime_resume() local
846 return reset_control_deassert(csi2->presetn); in rzg2l_csi2_pm_runtime_resume()
854 { .compatible = "renesas,rzg2l-csi2", },
863 .name = "rzg2l-csi2",
872 MODULE_DESCRIPTION("Renesas RZ/G2L MIPI CSI2 receiver driver");