Lines Matching defs:csi2rx
104 static void csi2rx_reset(struct csi2rx_priv *csi2rx)
107 csi2rx->base + CSI2RX_SOFT_RESET_REG);
111 writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
114 static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
119 ret = phy_power_on(csi2rx->dphy);
123 ret = phy_configure(csi2rx->dphy, &opts);
125 phy_power_off(csi2rx->dphy);
132 static int csi2rx_start(struct csi2rx_priv *csi2rx)
139 ret = clk_prepare_enable(csi2rx->p_clk);
143 reset_control_deassert(csi2rx->p_rst);
144 csi2rx_reset(csi2rx);
146 reg = csi2rx->num_lanes << 8;
147 for (i = 0; i < csi2rx->num_lanes; i++) {
148 reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]);
149 set_bit(csi2rx->lanes[i], &lanes_used);
158 for (i = csi2rx->num_lanes; i < csi2rx->max_lanes; i++) {
160 csi2rx->max_lanes);
165 writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG);
167 ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
172 if (csi2rx->dphy) {
174 for (i = 0; i < csi2rx->num_lanes; i++) {
175 reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
176 reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
179 writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
192 for (i = 0; i < csi2rx->max_streams; i++) {
193 ret = clk_prepare_enable(csi2rx->pixel_clk[i]);
197 reset_control_deassert(csi2rx->pixel_rst[i]);
200 csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
204 csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));
207 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
210 ret = clk_prepare_enable(csi2rx->sys_clk);
214 reset_control_deassert(csi2rx->sys_rst);
216 if (csi2rx->dphy) {
217 ret = csi2rx_configure_ext_dphy(csi2rx);
219 dev_err(csi2rx->dev,
225 clk_disable_unprepare(csi2rx->p_clk);
230 clk_disable_unprepare(csi2rx->sys_clk);
233 reset_control_assert(csi2rx->pixel_rst[i - 1]);
234 clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
238 clk_disable_unprepare(csi2rx->p_clk);
243 static void csi2rx_stop(struct csi2rx_priv *csi2rx)
247 clk_prepare_enable(csi2rx->p_clk);
248 reset_control_assert(csi2rx->sys_rst);
249 clk_disable_unprepare(csi2rx->sys_clk);
251 for (i = 0; i < csi2rx->max_streams; i++) {
252 writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
254 reset_control_assert(csi2rx->pixel_rst[i]);
255 clk_disable_unprepare(csi2rx->pixel_clk[i]);
258 reset_control_assert(csi2rx->p_rst);
259 clk_disable_unprepare(csi2rx->p_clk);
261 if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
262 dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
264 if (csi2rx->dphy) {
265 writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
267 if (phy_power_off(csi2rx->dphy))
268 dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
274 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
277 mutex_lock(&csi2rx->lock);
284 if (!csi2rx->count) {
285 ret = csi2rx_start(csi2rx);
290 csi2rx->count++;
292 csi2rx->count--;
297 if (!csi2rx->count)
298 csi2rx_stop(csi2rx);
302 mutex_unlock(&csi2rx->lock);
319 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
321 csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
324 if (csi2rx->source_pad < 0) {
325 dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n",
327 return csi2rx->source_pad;
330 csi2rx->source_subdev = s_subdev;
332 dev_dbg(csi2rx->dev, "Bound %s pad: %d\n", s_subdev->name,
333 csi2rx->source_pad);
335 return media_create_pad_link(&csi2rx->source_subdev->entity,
336 csi2rx->source_pad,
337 &csi2rx->subdev.entity, 0,
346 static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
353 csi2rx->base = devm_platform_ioremap_resource(pdev, 0);
354 if (IS_ERR(csi2rx->base))
355 return PTR_ERR(csi2rx->base);
357 csi2rx->sys_clk = devm_clk_get(&pdev->dev, "sys_clk");
358 if (IS_ERR(csi2rx->sys_clk)) {
360 return PTR_ERR(csi2rx->sys_clk);
363 csi2rx->p_clk = devm_clk_get(&pdev->dev, "p_clk");
364 if (IS_ERR(csi2rx->p_clk)) {
366 return PTR_ERR(csi2rx->p_clk);
369 csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
371 if (IS_ERR(csi2rx->sys_rst))
372 return PTR_ERR(csi2rx->sys_rst);
374 csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
376 if (IS_ERR(csi2rx->p_rst))
377 return PTR_ERR(csi2rx->p_rst);
379 csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy");
380 if (IS_ERR(csi2rx->dphy)) {
382 return PTR_ERR(csi2rx->dphy);
385 ret = clk_prepare_enable(csi2rx->p_clk);
391 dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG);
392 clk_disable_unprepare(csi2rx->p_clk);
394 csi2rx->max_lanes = dev_cfg & 7;
395 if (csi2rx->max_lanes > CSI2RX_LANES_MAX) {
397 csi2rx->max_lanes);
401 csi2rx->max_streams = (dev_cfg >> 4) & 7;
402 if (csi2rx->max_streams > CSI2RX_STREAMS_MAX) {
404 csi2rx->max_streams);
408 csi2rx->has_internal_dphy = dev_cfg & BIT(3) ? true : false;
414 if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
419 for (i = 0; i < csi2rx->max_streams; i++) {
423 csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name);
424 if (IS_ERR(csi2rx->pixel_clk[i])) {
426 return PTR_ERR(csi2rx->pixel_clk[i]);
430 csi2rx->pixel_rst[i] =
433 if (IS_ERR(csi2rx->pixel_rst[i]))
434 return PTR_ERR(csi2rx->pixel_rst[i]);
440 static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx)
448 ep = of_graph_get_endpoint_by_regs(csi2rx->dev->of_node, 0, 0);
455 dev_err(csi2rx->dev, "Could not parse v4l2 endpoint\n");
461 dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n",
467 memcpy(csi2rx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
468 sizeof(csi2rx->lanes));
469 csi2rx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
470 if (csi2rx->num_lanes > csi2rx->max_lanes) {
471 dev_err(csi2rx->dev, "Unsupported number of data-lanes: %d\n",
472 csi2rx->num_lanes);
477 v4l2_async_subdev_nf_init(&csi2rx->notifier, &csi2rx->subdev);
479 asd = v4l2_async_nf_add_fwnode_remote(&csi2rx->notifier, fwh,
483 v4l2_async_nf_cleanup(&csi2rx->notifier);
487 csi2rx->notifier.ops = &csi2rx_notifier_ops;
489 ret = v4l2_async_nf_register(&csi2rx->notifier);
491 v4l2_async_nf_cleanup(&csi2rx->notifier);
498 struct csi2rx_priv *csi2rx;
502 csi2rx = kzalloc(sizeof(*csi2rx), GFP_KERNEL);
503 if (!csi2rx)
505 platform_set_drvdata(pdev, csi2rx);
506 csi2rx->dev = &pdev->dev;
507 mutex_init(&csi2rx->lock);
509 ret = csi2rx_get_resources(csi2rx, pdev);
513 ret = csi2rx_parse_dt(csi2rx);
517 csi2rx->subdev.owner = THIS_MODULE;
518 csi2rx->subdev.dev = &pdev->dev;
519 v4l2_subdev_init(&csi2rx->subdev, &csi2rx_subdev_ops);
520 v4l2_set_subdevdata(&csi2rx->subdev, &pdev->dev);
521 snprintf(csi2rx->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.%s",
525 csi2rx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
526 csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
528 csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
530 ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
531 csi2rx->pads);
535 ret = v4l2_async_register_subdev(&csi2rx->subdev);
541 csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
542 csi2rx->dphy ? "external" :
543 csi2rx->has_internal_dphy ? "internal" : "no");
548 v4l2_async_nf_unregister(&csi2rx->notifier);
549 v4l2_async_nf_cleanup(&csi2rx->notifier);
551 kfree(csi2rx);
557 struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev);
559 v4l2_async_nf_unregister(&csi2rx->notifier);
560 v4l2_async_nf_cleanup(&csi2rx->notifier);
561 v4l2_async_unregister_subdev(&csi2rx->subdev);
562 kfree(csi2rx);
566 { .compatible = "starfive,jh7110-csi2rx" },
567 { .compatible = "cdns,csi2rx" },
577 .name = "cdns-csi2rx",