Lines Matching refs:csi2

215 static u32 rzg2l_csi2_read(struct rzg2l_csi2 *csi2, unsigned int reg)  in rzg2l_csi2_read()  argument
217 return ioread32(csi2->base + reg); in rzg2l_csi2_read()
220 static void rzg2l_csi2_write(struct rzg2l_csi2 *csi2, unsigned int reg, in rzg2l_csi2_write() argument
223 iowrite32(data, csi2->base + reg); in rzg2l_csi2_write()
226 static void rzg2l_csi2_set(struct rzg2l_csi2 *csi2, unsigned int reg, u32 set) in rzg2l_csi2_set() argument
228 rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) | set); in rzg2l_csi2_set()
231 static void rzg2l_csi2_clr(struct rzg2l_csi2 *csi2, unsigned int reg, u32 clr) in rzg2l_csi2_clr() argument
233 rzg2l_csi2_write(csi2, reg, rzg2l_csi2_read(csi2, reg) & ~clr); in rzg2l_csi2_clr()
236 static int rzg2l_csi2_calc_mbps(struct rzg2l_csi2 *csi2) in rzg2l_csi2_calc_mbps() argument
238 struct v4l2_subdev *source = csi2->remote_source; in rzg2l_csi2_calc_mbps()
248 dev_err(csi2->dev, "no pixel rate control in subdev %s\n", in rzg2l_csi2_calc_mbps()
253 state = v4l2_subdev_lock_and_get_active_state(&csi2->subdev); in rzg2l_csi2_calc_mbps()
254 fmt = v4l2_subdev_get_pad_format(&csi2->subdev, state, RZG2L_CSI2_SINK); in rzg2l_csi2_calc_mbps()
263 do_div(mbps, csi2->lanes * 1000000); in rzg2l_csi2_calc_mbps()
272 static int rzg2l_csi2_dphy_disable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_dphy_disable() argument
277 ret = reset_control_assert(csi2->cmn_rstb); in rzg2l_csi2_dphy_disable()
282 clk_disable_unprepare(csi2->sysclk); in rzg2l_csi2_dphy_disable()
285 rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); in rzg2l_csi2_dphy_disable()
288 rzg2l_csi2_clr(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); in rzg2l_csi2_dphy_disable()
290 csi2->dphy_enabled = false; in rzg2l_csi2_dphy_disable()
295 static int rzg2l_csi2_dphy_enable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_dphy_enable() argument
303 mbps = rzg2l_csi2_calc_mbps(csi2); in rzg2l_csi2_dphy_enable()
307 csi2->hsfreq = mbps; in rzg2l_csi2_dphy_enable()
313 if (csi2->hsfreq <= dphy_timing->max_hsfreq) in rzg2l_csi2_dphy_enable()
327 rzg2l_csi2_write(csi2, CSIDPHYTIM0, dphytim0); in rzg2l_csi2_dphy_enable()
328 rzg2l_csi2_write(csi2, CSIDPHYTIM1, dphytim1); in rzg2l_csi2_dphy_enable()
331 rzg2l_csi2_write(csi2, CSIDPHYSKW0, CSIDPHYSKW0_DEFAULT_SKW); in rzg2l_csi2_dphy_enable()
334 rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_BGR); in rzg2l_csi2_dphy_enable()
340 rzg2l_csi2_set(csi2, CSIDPHYCTRL0, CSIDPHYCTRL0_EN_LDO1200); in rzg2l_csi2_dphy_enable()
346 ret = clk_prepare_enable(csi2->sysclk); in rzg2l_csi2_dphy_enable()
348 rzg2l_csi2_dphy_disable(csi2); in rzg2l_csi2_dphy_enable()
350 csi2->dphy_enabled = true; in rzg2l_csi2_dphy_enable()
357 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_dphy_setting() local
360 return rzg2l_csi2_dphy_enable(csi2); in rzg2l_csi2_dphy_setting()
362 return rzg2l_csi2_dphy_disable(csi2); in rzg2l_csi2_dphy_setting()
365 static void rzg2l_csi2_mipi_link_enable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_mipi_link_enable() argument
367 unsigned long vclk_rate = csi2->vclk_rate / HZ_PER_MHZ; in rzg2l_csi2_mipi_link_enable()
371 rzg2l_csi2_write(csi2, CSI2nMCT0, CSI2nMCT0_VDLN(csi2->lanes)); in rzg2l_csi2_mipi_link_enable()
375 frrskw = DIV_ROUND_UP(frrskw_coeff, csi2->hsfreq); in rzg2l_csi2_mipi_link_enable()
376 frrclk = DIV_ROUND_UP(frrclk_coeff, csi2->hsfreq); in rzg2l_csi2_mipi_link_enable()
377 rzg2l_csi2_write(csi2, CSI2nMCT2, CSI2nMCT2_FRRSKW(frrskw) | in rzg2l_csi2_mipi_link_enable()
387 rzg2l_csi2_write(csi2, CSI2nDTEL, 0xf778ff0f); in rzg2l_csi2_mipi_link_enable()
388 rzg2l_csi2_write(csi2, CSI2nDTEH, 0x00ffff1f); in rzg2l_csi2_mipi_link_enable()
391 rzg2l_csi2_write(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); in rzg2l_csi2_mipi_link_enable()
394 static void rzg2l_csi2_mipi_link_disable(struct rzg2l_csi2 *csi2) in rzg2l_csi2_mipi_link_disable() argument
399 rzg2l_csi2_clr(csi2, CSI2nMCT3, CSI2nMCT3_RXEN); in rzg2l_csi2_mipi_link_disable()
402 rzg2l_csi2_write(csi2, CSI2nRTCT, CSI2nRTCT_VSRST); in rzg2l_csi2_mipi_link_disable()
406 if (!(rzg2l_csi2_read(csi2, CSI2nRTST) & CSI2nRTST_VSRSTS)) in rzg2l_csi2_mipi_link_disable()
412 dev_err(csi2->dev, "Clearing CSI2nRTST.VSRSTS timed out\n"); in rzg2l_csi2_mipi_link_disable()
417 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_mipi_link_setting() local
420 rzg2l_csi2_mipi_link_enable(csi2); in rzg2l_csi2_mipi_link_setting()
422 rzg2l_csi2_mipi_link_disable(csi2); in rzg2l_csi2_mipi_link_setting()
429 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_s_stream() local
434 ret = pm_runtime_resume_and_get(csi2->dev); in rzg2l_csi2_s_stream()
442 ret = reset_control_deassert(csi2->cmn_rstb); in rzg2l_csi2_s_stream()
447 ret = v4l2_subdev_call(csi2->remote_source, video, s_stream, enable); in rzg2l_csi2_s_stream()
462 pm_runtime_put_sync(csi2->dev); in rzg2l_csi2_s_stream()
468 reset_control_assert(csi2->cmn_rstb); in rzg2l_csi2_s_stream()
472 pm_runtime_put_sync(csi2->dev); in rzg2l_csi2_s_stream()
483 struct rzg2l_csi2 *csi2 = sd_to_csi2(sd); in rzg2l_csi2_post_streamoff() local
491 if (csi2->dphy_enabled) in rzg2l_csi2_post_streamoff()
605 struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); in rzg2l_csi2_notify_bound() local
607 csi2->remote_source = subdev; in rzg2l_csi2_notify_bound()
609 dev_dbg(csi2->dev, "Bound subdev: %s pad\n", subdev->name); in rzg2l_csi2_notify_bound()
612 &csi2->subdev.entity, 0, in rzg2l_csi2_notify_bound()
621 struct rzg2l_csi2 *csi2 = notifier_to_csi2(notifier); in rzg2l_csi2_notify_unbind() local
623 csi2->remote_source = NULL; in rzg2l_csi2_notify_unbind()
625 dev_dbg(csi2->dev, "Unbind subdev %s\n", subdev->name); in rzg2l_csi2_notify_unbind()
633 static int rzg2l_csi2_parse_v4l2(struct rzg2l_csi2 *csi2, in rzg2l_csi2_parse_v4l2() argument
640 csi2->lanes = vep->bus.mipi_csi2.num_data_lanes; in rzg2l_csi2_parse_v4l2()
645 static int rzg2l_csi2_parse_dt(struct rzg2l_csi2 *csi2) in rzg2l_csi2_parse_dt() argument
655 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, 0); in rzg2l_csi2_parse_dt()
657 dev_err(csi2->dev, "Not connected to subdevice\n"); in rzg2l_csi2_parse_dt()
663 dev_err(csi2->dev, "Could not parse v4l2 endpoint\n"); in rzg2l_csi2_parse_dt()
668 ret = rzg2l_csi2_parse_v4l2(csi2, &v4l2_ep); in rzg2l_csi2_parse_dt()
677 v4l2_async_nf_init(&csi2->notifier); in rzg2l_csi2_parse_dt()
678 csi2->notifier.ops = &rzg2l_csi2_notify_ops; in rzg2l_csi2_parse_dt()
680 asd = v4l2_async_nf_add_fwnode(&csi2->notifier, fwnode, in rzg2l_csi2_parse_dt()
686 ret = v4l2_async_subdev_nf_register(&csi2->subdev, &csi2->notifier); in rzg2l_csi2_parse_dt()
688 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_parse_dt()
693 static int rzg2l_validate_csi2_lanes(struct rzg2l_csi2 *csi2) in rzg2l_validate_csi2_lanes() argument
698 if (csi2->lanes != 1 && csi2->lanes != 2 && csi2->lanes != 4) { in rzg2l_validate_csi2_lanes()
699 dev_err(csi2->dev, "Unsupported number of data-lanes: %u\n", in rzg2l_validate_csi2_lanes()
700 csi2->lanes); in rzg2l_validate_csi2_lanes()
704 ret = pm_runtime_resume_and_get(csi2->dev); in rzg2l_validate_csi2_lanes()
709 lanes = (rzg2l_csi2_read(csi2, CSI2nMCG) & CSI2nMCG_SDLN) >> 8; in rzg2l_validate_csi2_lanes()
710 if (lanes < csi2->lanes) { in rzg2l_validate_csi2_lanes()
711 dev_err(csi2->dev, in rzg2l_validate_csi2_lanes()
712 "Failed to support %d data lanes\n", csi2->lanes); in rzg2l_validate_csi2_lanes()
716 pm_runtime_put_sync(csi2->dev); in rzg2l_validate_csi2_lanes()
731 struct rzg2l_csi2 *csi2; in rzg2l_csi2_probe() local
735 csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL); in rzg2l_csi2_probe()
736 if (!csi2) in rzg2l_csi2_probe()
739 csi2->base = devm_platform_ioremap_resource(pdev, 0); in rzg2l_csi2_probe()
740 if (IS_ERR(csi2->base)) in rzg2l_csi2_probe()
741 return PTR_ERR(csi2->base); in rzg2l_csi2_probe()
743 csi2->cmn_rstb = devm_reset_control_get_exclusive(&pdev->dev, "cmn-rstb"); in rzg2l_csi2_probe()
744 if (IS_ERR(csi2->cmn_rstb)) in rzg2l_csi2_probe()
745 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->cmn_rstb), in rzg2l_csi2_probe()
748 csi2->presetn = devm_reset_control_get_shared(&pdev->dev, "presetn"); in rzg2l_csi2_probe()
749 if (IS_ERR(csi2->presetn)) in rzg2l_csi2_probe()
750 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->presetn), in rzg2l_csi2_probe()
753 csi2->sysclk = devm_clk_get(&pdev->dev, "system"); in rzg2l_csi2_probe()
754 if (IS_ERR(csi2->sysclk)) in rzg2l_csi2_probe()
755 return dev_err_probe(&pdev->dev, PTR_ERR(csi2->sysclk), in rzg2l_csi2_probe()
762 csi2->vclk_rate = clk_get_rate(vclk); in rzg2l_csi2_probe()
765 csi2->dev = &pdev->dev; in rzg2l_csi2_probe()
767 platform_set_drvdata(pdev, csi2); in rzg2l_csi2_probe()
769 ret = rzg2l_csi2_parse_dt(csi2); in rzg2l_csi2_probe()
775 ret = rzg2l_validate_csi2_lanes(csi2); in rzg2l_csi2_probe()
779 csi2->subdev.dev = &pdev->dev; in rzg2l_csi2_probe()
780 v4l2_subdev_init(&csi2->subdev, &rzg2l_csi2_subdev_ops); in rzg2l_csi2_probe()
781 v4l2_set_subdevdata(&csi2->subdev, &pdev->dev); in rzg2l_csi2_probe()
782 snprintf(csi2->subdev.name, sizeof(csi2->subdev.name), in rzg2l_csi2_probe()
784 csi2->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in rzg2l_csi2_probe()
786 csi2->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in rzg2l_csi2_probe()
787 csi2->subdev.entity.ops = &rzg2l_csi2_entity_ops; in rzg2l_csi2_probe()
789 csi2->pads[RZG2L_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; in rzg2l_csi2_probe()
795 csi2->pads[RZG2L_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in rzg2l_csi2_probe()
796 ret = media_entity_pads_init(&csi2->subdev.entity, 2, csi2->pads); in rzg2l_csi2_probe()
800 ret = v4l2_subdev_init_finalize(&csi2->subdev); in rzg2l_csi2_probe()
804 ret = v4l2_async_register_subdev(&csi2->subdev); in rzg2l_csi2_probe()
811 v4l2_subdev_cleanup(&csi2->subdev); in rzg2l_csi2_probe()
813 v4l2_async_nf_unregister(&csi2->notifier); in rzg2l_csi2_probe()
814 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_probe()
815 media_entity_cleanup(&csi2->subdev.entity); in rzg2l_csi2_probe()
824 struct rzg2l_csi2 *csi2 = platform_get_drvdata(pdev); in rzg2l_csi2_remove() local
826 v4l2_async_nf_unregister(&csi2->notifier); in rzg2l_csi2_remove()
827 v4l2_async_nf_cleanup(&csi2->notifier); in rzg2l_csi2_remove()
828 v4l2_async_unregister_subdev(&csi2->subdev); in rzg2l_csi2_remove()
829 v4l2_subdev_cleanup(&csi2->subdev); in rzg2l_csi2_remove()
830 media_entity_cleanup(&csi2->subdev.entity); in rzg2l_csi2_remove()
838 struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); in rzg2l_csi2_pm_runtime_suspend() local
840 reset_control_assert(csi2->presetn); in rzg2l_csi2_pm_runtime_suspend()
847 struct rzg2l_csi2 *csi2 = dev_get_drvdata(dev); in rzg2l_csi2_pm_runtime_resume() local
849 return reset_control_deassert(csi2->presetn); in rzg2l_csi2_pm_runtime_resume()