Lines Matching defs:csi2rx

144 static void csi2rx_reset(struct csi2rx_priv *csi2rx)
150 csi2rx->base + CSI2RX_SOFT_RESET_REG);
152 for (i = 0; i < csi2rx->max_streams; i++) {
154 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
160 writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
161 for (i = 0; i < csi2rx->max_streams; i++)
162 writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
165 static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
177 ret = v4l2_subdev_call_state_active(&csi2rx->subdev, pad, get_fmt,
184 link_freq = v4l2_get_link_freq(csi2rx->source_subdev->ctrl_handler,
185 fmt->bpp, 2 * csi2rx->num_lanes);
190 csi2rx->num_lanes, cfg);
194 ret = phy_power_on(csi2rx->dphy);
198 ret = phy_configure(csi2rx->dphy, &opts);
200 phy_power_off(csi2rx->dphy);
207 static int csi2rx_start(struct csi2rx_priv *csi2rx)
214 ret = clk_prepare_enable(csi2rx->p_clk);
218 reset_control_deassert(csi2rx->p_rst);
219 csi2rx_reset(csi2rx);
221 reg = csi2rx->num_lanes << 8;
222 for (i = 0; i < csi2rx->num_lanes; i++) {
223 reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);
224 set_bit(csi2rx->lanes[i], &lanes_used);
233 for (i = csi2rx->num_lanes; i < csi2rx->max_lanes; i++) {
235 csi2rx->max_lanes);
240 writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG);
243 if (csi2rx->dphy) {
245 for (i = 0; i < csi2rx->num_lanes; i++) {
246 reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
247 reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
250 writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
252 ret = csi2rx_configure_ext_dphy(csi2rx);
254 dev_err(csi2rx->dev,
270 for (i = 0; i < csi2rx->max_streams; i++) {
271 ret = clk_prepare_enable(csi2rx->pixel_clk[i]);
275 reset_control_deassert(csi2rx->pixel_rst[i]);
278 csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
285 csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));
288 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
291 ret = clk_prepare_enable(csi2rx->sys_clk);
295 reset_control_deassert(csi2rx->sys_rst);
297 ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
301 clk_disable_unprepare(csi2rx->p_clk);
306 clk_disable_unprepare(csi2rx->sys_clk);
309 reset_control_assert(csi2rx->pixel_rst[i - 1]);
310 clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
313 if (csi2rx->dphy) {
314 writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
315 phy_power_off(csi2rx->dphy);
318 clk_disable_unprepare(csi2rx->p_clk);
323 static void csi2rx_stop(struct csi2rx_priv *csi2rx)
329 clk_prepare_enable(csi2rx->p_clk);
330 reset_control_assert(csi2rx->sys_rst);
331 clk_disable_unprepare(csi2rx->sys_clk);
333 for (i = 0; i < csi2rx->max_streams; i++) {
335 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
337 ret = readl_relaxed_poll_timeout(csi2rx->base +
343 dev_warn(csi2rx->dev,
346 reset_control_assert(csi2rx->pixel_rst[i]);
347 clk_disable_unprepare(csi2rx->pixel_clk[i]);
350 reset_control_assert(csi2rx->p_rst);
351 clk_disable_unprepare(csi2rx->p_clk);
353 if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
354 dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
356 if (csi2rx->dphy) {
357 writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
359 if (phy_power_off(csi2rx->dphy))
360 dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
366 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
369 mutex_lock(&csi2rx->lock);
376 if (!csi2rx->count) {
377 ret = csi2rx_start(csi2rx);
382 csi2rx->count++;
384 csi2rx->count--;
389 if (!csi2rx->count)
390 csi2rx_stop(csi2rx);
394 mutex_unlock(&csi2rx->lock);
487 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
489 csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
492 if (csi2rx->source_pad < 0) {
493 dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n",
495 return csi2rx->source_pad;
498 csi2rx->source_subdev = s_subdev;
500 dev_dbg(csi2rx->dev, "Bound %s pad: %d\n", s_subdev->name,
501 csi2rx->source_pad);
503 return media_create_pad_link(&csi2rx->source_subdev->entity,
504 csi2rx->source_pad,
505 &csi2rx->subdev.entity, 0,
514 static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
521 csi2rx->base = devm_platform_ioremap_resource(pdev, 0);
522 if (IS_ERR(csi2rx->base))
523 return PTR_ERR(csi2rx->base);
525 csi2rx->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
526 if (IS_ERR(csi2rx->sys_clk)) {
528 return PTR_ERR(csi2rx->sys_clk);
531 csi2rx->p_clk = devm_clk_get(&pdev->dev, "p_clk");
532 if (IS_ERR(csi2rx->p_clk)) {
534 return PTR_ERR(csi2rx->p_clk);
537 csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
539 if (IS_ERR(csi2rx->sys_rst))
540 return PTR_ERR(csi2rx->sys_rst);
542 csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
544 if (IS_ERR(csi2rx->p_rst))
545 return PTR_ERR(csi2rx->p_rst);
547 csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy");
548 if (IS_ERR(csi2rx->dphy)) {
550 return PTR_ERR(csi2rx->dphy);
553 ret = clk_prepare_enable(csi2rx->p_clk);
559 dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG);
560 clk_disable_unprepare(csi2rx->p_clk);
562 csi2rx->max_lanes = dev_cfg & 7;
563 if (csi2rx->max_lanes > CSI2RX_LANES_MAX) {
565 csi2rx->max_lanes);
569 csi2rx->max_streams = (dev_cfg >> 4) & 7;
570 if (csi2rx->max_streams > CSI2RX_STREAMS_MAX) {
572 csi2rx->max_streams);
576 csi2rx->has_internal_dphy = dev_cfg & BIT(3) ? true : false;
582 if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
587 for (i = 0; i < csi2rx->max_streams; i++) {
591 csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name);
592 if (IS_ERR(csi2rx->pixel_clk[i])) {
594 return PTR_ERR(csi2rx->pixel_clk[i]);
598 csi2rx->pixel_rst[i] =
601 if (IS_ERR(csi2rx->pixel_rst[i]))
602 return PTR_ERR(csi2rx->pixel_rst[i]);
608 static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
616 ep = of_graph_get_endpoint_by_regs(csi2rx->dev->of_node, 0, 0);
623 dev_err(csi2rx->dev, "Could not parse v4l2 endpoint\n");
629 dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n",
635 memcpy(csi2rx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
636 sizeof(csi2rx->lanes));
637 csi2rx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
638 if (csi2rx->num_lanes > csi2rx->max_lanes) {
639 dev_err(csi2rx->dev, "Unsupported number of data-lanes: %d\n",
640 csi2rx->num_lanes);
645 v4l2_async_subdev_nf_init(&csi2rx->notifier, &csi2rx->subdev);
647 asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
651 v4l2_async_nf_cleanup(&csi2rx->notifier);
655 csi2rx->notifier.ops = &csi2rx_notifier_ops;
657 ret = v4l2_async_nf_register(&csi2rx->notifier);
659 v4l2_async_nf_cleanup(&csi2rx->notifier);
666 struct csi2rx_priv *csi2rx;
670 csi2rx = kzalloc(sizeof(*csi2rx), GFP_KERNEL);
671 if (!csi2rx)
673 platform_set_drvdata(pdev, csi2rx);
674 csi2rx->dev = &pdev->dev;
675 mutex_init(&csi2rx->lock);
677 ret = csi2rx_get_resources(csi2rx, pdev);
681 ret = csi2rx_parse_dt(csi2rx);
685 csi2rx->subdev.owner = THIS_MODULE;
686 csi2rx->subdev.dev = &pdev->dev;
687 v4l2_subdev_init(&csi2rx->subdev, &csi2rx_subdev_ops);
688 csi2rx->subdev.internal_ops = &csi2rx_internal_ops;
689 v4l2_set_subdevdata(&csi2rx->subdev, &pdev->dev);
690 snprintf(csi2rx->subdev.name, sizeof(csi2rx->subdev.name),
694 csi2rx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
695 csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
697 csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
698 csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
699 csi2rx->subdev.entity.ops = &csi2rx_media_ops;
701 ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
702 csi2rx->pads);
706 ret = v4l2_subdev_init_finalize(&csi2rx->subdev);
710 ret = v4l2_async_register_subdev(&csi2rx->subdev);
716 csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
717 csi2rx->dphy ? "external" :
718 csi2rx->has_internal_dphy ? "internal" : "no");
723 v4l2_subdev_cleanup(&csi2rx->subdev);
725 v4l2_async_nf_unregister(&csi2rx->notifier);
726 v4l2_async_nf_cleanup(&csi2rx->notifier);
727 media_entity_cleanup(&csi2rx->subdev.entity);
729 kfree(csi2rx);
735 struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev);
737 v4l2_async_nf_unregister(&csi2rx->notifier);
738 v4l2_async_nf_cleanup(&csi2rx->notifier);
739 v4l2_async_unregister_subdev(&csi2rx->subdev);
740 v4l2_subdev_cleanup(&csi2rx->subdev);
741 media_entity_cleanup(&csi2rx->subdev.entity);
742 kfree(csi2rx);
746 { .compatible = "starfive,jh7110-csi2rx" },
747 { .compatible = "cdns,csi2rx" },
757 .name = "cdns-csi2rx",