Lines Matching +full:r9a07g044 +full:- +full:du
1 // SPDX-License-Identifier: GPL-2.0+
3 * vsp1_drv.c -- R-Car VSP1 Driver
5 * Copyright (C) 2013-2015 Renesas Electronics Corporation
21 #include <media/rcar-fcp.h>
22 #include <media/v4l2-subdev.h>
41 /* -----------------------------------------------------------------------------
54 for (i = 0; i < vsp1->info->wpf_count; ++i) { in vsp1_irq_handler()
55 struct vsp1_rwpf *wpf = vsp1->wpf[i]; in vsp1_irq_handler()
63 if ((status & VI6_WPF_IRQ_STA_UND) && wpf->entity.pipe) { in vsp1_irq_handler()
64 wpf->entity.pipe->underrun_count++; in vsp1_irq_handler()
66 dev_warn_ratelimited(vsp1->dev, in vsp1_irq_handler()
68 i, wpf->entity.pipe->underrun_count); in vsp1_irq_handler()
72 vsp1_pipeline_frame_end(wpf->entity.pipe); in vsp1_irq_handler()
80 /* -----------------------------------------------------------------------------
85 * vsp1_create_sink_links - Create links from all sources to the given sink
91 * - from a UDS to a UDS (UDS entities can't be chained)
92 * - from an entity to itself (no loops are allowed)
101 struct media_entity *entity = &sink->subdev.entity; in vsp1_create_sink_links()
106 list_for_each_entry(source, &vsp1->entities, list_dev) { in vsp1_create_sink_links()
109 if (source->type == sink->type) in vsp1_create_sink_links()
112 if (source->type == VSP1_ENTITY_HGO || in vsp1_create_sink_links()
113 source->type == VSP1_ENTITY_HGT || in vsp1_create_sink_links()
114 source->type == VSP1_ENTITY_LIF || in vsp1_create_sink_links()
115 source->type == VSP1_ENTITY_WPF) in vsp1_create_sink_links()
118 flags = source->type == VSP1_ENTITY_RPF && in vsp1_create_sink_links()
119 sink->type == VSP1_ENTITY_WPF && in vsp1_create_sink_links()
120 source->index == sink->index in vsp1_create_sink_links()
123 for (pad = 0; pad < entity->num_pads; ++pad) { in vsp1_create_sink_links()
124 if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) in vsp1_create_sink_links()
127 ret = media_create_pad_link(&source->subdev.entity, in vsp1_create_sink_links()
128 source->source_pad, in vsp1_create_sink_links()
134 source->sink = sink; in vsp1_create_sink_links()
147 list_for_each_entry(entity, &vsp1->entities, list_dev) { in vsp1_uapi_create_links()
148 if (entity->type == VSP1_ENTITY_LIF || in vsp1_uapi_create_links()
149 entity->type == VSP1_ENTITY_RPF) in vsp1_uapi_create_links()
157 if (vsp1->hgo) { in vsp1_uapi_create_links()
158 ret = media_create_pad_link(&vsp1->hgo->histo.entity.subdev.entity, in vsp1_uapi_create_links()
160 &vsp1->hgo->histo.video.entity, 0, in vsp1_uapi_create_links()
167 if (vsp1->hgt) { in vsp1_uapi_create_links()
168 ret = media_create_pad_link(&vsp1->hgt->histo.entity.subdev.entity, in vsp1_uapi_create_links()
170 &vsp1->hgt->histo.video.entity, 0, in vsp1_uapi_create_links()
177 for (i = 0; i < vsp1->info->lif_count; ++i) { in vsp1_uapi_create_links()
178 if (!vsp1->lif[i]) in vsp1_uapi_create_links()
181 ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity, in vsp1_uapi_create_links()
183 &vsp1->lif[i]->entity.subdev.entity, in vsp1_uapi_create_links()
189 for (i = 0; i < vsp1->info->rpf_count; ++i) { in vsp1_uapi_create_links()
190 struct vsp1_rwpf *rpf = vsp1->rpf[i]; in vsp1_uapi_create_links()
192 ret = media_create_pad_link(&rpf->video->video.entity, 0, in vsp1_uapi_create_links()
193 &rpf->entity.subdev.entity, in vsp1_uapi_create_links()
201 for (i = 0; i < vsp1->info->wpf_count; ++i) { in vsp1_uapi_create_links()
206 struct vsp1_rwpf *wpf = vsp1->wpf[i]; in vsp1_uapi_create_links()
208 ret = media_create_pad_link(&wpf->entity.subdev.entity, in vsp1_uapi_create_links()
210 &wpf->video->video.entity, 0, in vsp1_uapi_create_links()
225 list_for_each_entry_safe(entity, _entity, &vsp1->entities, list_dev) { in vsp1_destroy_entities()
226 list_del(&entity->list_dev); in vsp1_destroy_entities()
230 list_for_each_entry_safe(video, _video, &vsp1->videos, list) { in vsp1_destroy_entities()
231 list_del(&video->list); in vsp1_destroy_entities()
235 v4l2_device_unregister(&vsp1->v4l2_dev); in vsp1_destroy_entities()
236 if (vsp1->info->uapi) in vsp1_destroy_entities()
237 media_device_unregister(&vsp1->media_dev); in vsp1_destroy_entities()
238 media_device_cleanup(&vsp1->media_dev); in vsp1_destroy_entities()
240 if (!vsp1->info->uapi) in vsp1_destroy_entities()
246 struct media_device *mdev = &vsp1->media_dev; in vsp1_create_entities()
247 struct v4l2_device *vdev = &vsp1->v4l2_dev; in vsp1_create_entities()
252 mdev->dev = vsp1->dev; in vsp1_create_entities()
253 mdev->hw_revision = vsp1->version; in vsp1_create_entities()
254 strscpy(mdev->model, vsp1->info->model, sizeof(mdev->model)); in vsp1_create_entities()
257 vsp1->media_ops.link_setup = vsp1_entity_link_setup; in vsp1_create_entities()
263 if (vsp1->info->uapi) in vsp1_create_entities()
264 vsp1->media_ops.link_validate = v4l2_subdev_link_validate; in vsp1_create_entities()
266 vdev->mdev = mdev; in vsp1_create_entities()
267 ret = v4l2_device_register(vsp1->dev, vdev); in vsp1_create_entities()
269 dev_err(vsp1->dev, "V4L2 device registration failed (%d)\n", in vsp1_create_entities()
276 vsp1->brs = vsp1_brx_create(vsp1, VSP1_ENTITY_BRS); in vsp1_create_entities()
277 if (IS_ERR(vsp1->brs)) { in vsp1_create_entities()
278 ret = PTR_ERR(vsp1->brs); in vsp1_create_entities()
282 list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
286 vsp1->bru = vsp1_brx_create(vsp1, VSP1_ENTITY_BRU); in vsp1_create_entities()
287 if (IS_ERR(vsp1->bru)) { in vsp1_create_entities()
288 ret = PTR_ERR(vsp1->bru); in vsp1_create_entities()
292 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
296 vsp1->clu = vsp1_clu_create(vsp1); in vsp1_create_entities()
297 if (IS_ERR(vsp1->clu)) { in vsp1_create_entities()
298 ret = PTR_ERR(vsp1->clu); in vsp1_create_entities()
302 list_add_tail(&vsp1->clu->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
305 vsp1->hsi = vsp1_hsit_create(vsp1, true); in vsp1_create_entities()
306 if (IS_ERR(vsp1->hsi)) { in vsp1_create_entities()
307 ret = PTR_ERR(vsp1->hsi); in vsp1_create_entities()
311 list_add_tail(&vsp1->hsi->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
313 vsp1->hst = vsp1_hsit_create(vsp1, false); in vsp1_create_entities()
314 if (IS_ERR(vsp1->hst)) { in vsp1_create_entities()
315 ret = PTR_ERR(vsp1->hst); in vsp1_create_entities()
319 list_add_tail(&vsp1->hst->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
321 if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) { in vsp1_create_entities()
322 vsp1->hgo = vsp1_hgo_create(vsp1); in vsp1_create_entities()
323 if (IS_ERR(vsp1->hgo)) { in vsp1_create_entities()
324 ret = PTR_ERR(vsp1->hgo); in vsp1_create_entities()
328 list_add_tail(&vsp1->hgo->histo.entity.list_dev, in vsp1_create_entities()
329 &vsp1->entities); in vsp1_create_entities()
332 if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) { in vsp1_create_entities()
333 vsp1->hgt = vsp1_hgt_create(vsp1); in vsp1_create_entities()
334 if (IS_ERR(vsp1->hgt)) { in vsp1_create_entities()
335 ret = PTR_ERR(vsp1->hgt); in vsp1_create_entities()
339 list_add_tail(&vsp1->hgt->histo.entity.list_dev, in vsp1_create_entities()
340 &vsp1->entities); in vsp1_create_entities()
344 * The LIFs are only supported when used in conjunction with the DU, in in vsp1_create_entities()
348 if (!vsp1->info->uapi) { in vsp1_create_entities()
349 for (i = 0; i < vsp1->info->lif_count; ++i) { in vsp1_create_entities()
358 vsp1->lif[i] = lif; in vsp1_create_entities()
359 list_add_tail(&lif->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
364 vsp1->lut = vsp1_lut_create(vsp1); in vsp1_create_entities()
365 if (IS_ERR(vsp1->lut)) { in vsp1_create_entities()
366 ret = PTR_ERR(vsp1->lut); in vsp1_create_entities()
370 list_add_tail(&vsp1->lut->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
373 for (i = 0; i < vsp1->info->rpf_count; ++i) { in vsp1_create_entities()
382 vsp1->rpf[i] = rpf; in vsp1_create_entities()
383 list_add_tail(&rpf->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
385 if (vsp1->info->uapi) { in vsp1_create_entities()
393 list_add_tail(&video->list, &vsp1->videos); in vsp1_create_entities()
398 vsp1->sru = vsp1_sru_create(vsp1); in vsp1_create_entities()
399 if (IS_ERR(vsp1->sru)) { in vsp1_create_entities()
400 ret = PTR_ERR(vsp1->sru); in vsp1_create_entities()
404 list_add_tail(&vsp1->sru->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
407 for (i = 0; i < vsp1->info->uds_count; ++i) { in vsp1_create_entities()
416 vsp1->uds[i] = uds; in vsp1_create_entities()
417 list_add_tail(&uds->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
420 for (i = 0; i < vsp1->info->uif_count; ++i) { in vsp1_create_entities()
429 vsp1->uif[i] = uif; in vsp1_create_entities()
430 list_add_tail(&uif->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
433 for (i = 0; i < vsp1->info->wpf_count; ++i) { in vsp1_create_entities()
442 vsp1->wpf[i] = wpf; in vsp1_create_entities()
443 list_add_tail(&wpf->entity.list_dev, &vsp1->entities); in vsp1_create_entities()
445 if (vsp1->info->uapi) { in vsp1_create_entities()
453 list_add_tail(&video->list, &vsp1->videos); in vsp1_create_entities()
458 list_for_each_entry(entity, &vsp1->entities, list_dev) { in vsp1_create_entities()
459 ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, in vsp1_create_entities()
460 &entity->subdev); in vsp1_create_entities()
469 if (vsp1->info->uapi) { in vsp1_create_entities()
474 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); in vsp1_create_entities()
500 for (timeout = 10; timeout > 0; --timeout) { in vsp1_reset_wpf()
509 dev_err(vsp1->dev, "failed to reset wpf.%u\n", index); in vsp1_reset_wpf()
510 return -ETIMEDOUT; in vsp1_reset_wpf()
522 for (i = 0; i < vsp1->info->wpf_count; ++i) { in vsp1_device_init()
531 for (i = 0; i < vsp1->info->rpf_count; ++i) in vsp1_device_init()
534 for (i = 0; i < vsp1->info->uds_count; ++i) in vsp1_device_init()
537 for (i = 0; i < vsp1->info->uif_count; ++i) in vsp1_device_init()
564 for (i = 0; i < vsp1->info->lif_count; ++i) in vsp1_mask_all_interrupts()
566 for (i = 0; i < vsp1->info->wpf_count; ++i) in vsp1_mask_all_interrupts()
571 * vsp1_device_get - Acquire the VSP1 device
579 return pm_runtime_resume_and_get(vsp1->dev); in vsp1_device_get()
583 * vsp1_device_put - Release the VSP1 device
590 pm_runtime_put_sync(vsp1->dev); in vsp1_device_put()
593 /* -----------------------------------------------------------------------------
603 * restarted explicitly by the DU. in vsp1_pm_suspend()
605 if (!vsp1->drm) in vsp1_pm_suspend()
608 pm_runtime_force_suspend(vsp1->dev); in vsp1_pm_suspend()
617 pm_runtime_force_resume(vsp1->dev); in vsp1_pm_resume()
621 * restarted explicitly by the DU. in vsp1_pm_resume()
623 if (!vsp1->drm) in vsp1_pm_resume()
633 rcar_fcp_disable(vsp1->fcp); in vsp1_pm_runtime_suspend()
634 reset_control_assert(vsp1->rstc); in vsp1_pm_runtime_suspend()
644 ret = reset_control_deassert(vsp1->rstc); in vsp1_pm_runtime_resume()
648 if (vsp1->info) { in vsp1_pm_runtime_resume()
650 * On R-Car Gen2 and RZ/G1, vsp1 register access after deassert in vsp1_pm_runtime_resume()
651 * can cause lock-up. It is a special case and needs some delay in vsp1_pm_runtime_resume()
652 * to avoid this lock-up. in vsp1_pm_runtime_resume()
654 if (vsp1->info->gen == 2) in vsp1_pm_runtime_resume()
662 ret = rcar_fcp_enable(vsp1->fcp); in vsp1_pm_runtime_resume()
666 reset_control_assert(vsp1->rstc); in vsp1_pm_runtime_resume()
676 /* -----------------------------------------------------------------------------
683 .model = "VSP1-S",
695 .model = "VSP1-R",
705 .model = "VSP1-D",
716 .model = "VSP1-S",
728 .model = "VSP1V-S",
739 .model = "VSP1V-D",
750 .model = "VSP2-I",
761 .model = "VSP2-BD",
770 .model = "VSP2-BC",
780 .model = "VSP2-BS",
788 .model = "VSP2-D",
798 .model = "VSP2-D",
809 .model = "VSP2-D",
820 .model = "VSP2-DL",
830 .model = "VSP2-D",
843 .model = "VSP2-D",
864 info = of_device_get_match_data(vsp1->dev); in vsp1_lookup_info()
866 vsp1->version = VI6_IP_VERSION_VSP_SW | info->version | info->soc; in vsp1_lookup_info()
870 vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION); in vsp1_lookup_info()
871 model = vsp1->version & VI6_IP_VERSION_MODEL_MASK; in vsp1_lookup_info()
872 soc = vsp1->version & VI6_IP_VERSION_SOC_MASK; in vsp1_lookup_info()
877 if (model == info->version && (!info->soc || soc == info->soc)) in vsp1_lookup_info()
881 dev_err(vsp1->dev, "unsupported IP version 0x%08x\n", vsp1->version); in vsp1_lookup_info()
893 vsp1 = devm_kzalloc(&pdev->dev, sizeof(*vsp1), GFP_KERNEL); in vsp1_probe()
895 return -ENOMEM; in vsp1_probe()
897 vsp1->dev = &pdev->dev; in vsp1_probe()
898 INIT_LIST_HEAD(&vsp1->entities); in vsp1_probe()
899 INIT_LIST_HEAD(&vsp1->videos); in vsp1_probe()
904 vsp1->mmio = devm_platform_ioremap_resource(pdev, 0); in vsp1_probe()
905 if (IS_ERR(vsp1->mmio)) in vsp1_probe()
906 return PTR_ERR(vsp1->mmio); in vsp1_probe()
912 vsp1->rstc = devm_reset_control_get_shared(&pdev->dev, NULL); in vsp1_probe()
913 if (IS_ERR(vsp1->rstc)) in vsp1_probe()
914 return dev_err_probe(&pdev->dev, PTR_ERR(vsp1->rstc), in vsp1_probe()
918 fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0); in vsp1_probe()
920 vsp1->fcp = rcar_fcp_get(fcp_node); in vsp1_probe()
922 if (IS_ERR(vsp1->fcp)) { in vsp1_probe()
923 dev_dbg(&pdev->dev, "FCP not found (%ld)\n", in vsp1_probe()
924 PTR_ERR(vsp1->fcp)); in vsp1_probe()
925 return PTR_ERR(vsp1->fcp); in vsp1_probe()
933 vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp); in vsp1_probe()
935 vsp1->bus_master = vsp1->dev; in vsp1_probe()
939 pm_runtime_enable(&pdev->dev); in vsp1_probe()
945 vsp1->info = vsp1_lookup_info(vsp1); in vsp1_probe()
946 if (!vsp1->info) { in vsp1_probe()
948 ret = -ENXIO; in vsp1_probe()
952 dev_dbg(&pdev->dev, "IP version 0x%08x\n", vsp1->version); in vsp1_probe()
965 ret = devm_request_irq(&pdev->dev, irq, vsp1_irq_handler, in vsp1_probe()
966 IRQF_SHARED, dev_name(&pdev->dev), vsp1); in vsp1_probe()
968 dev_err(&pdev->dev, "failed to request IRQ\n"); in vsp1_probe()
975 dev_err(&pdev->dev, "failed to create entities\n"); in vsp1_probe()
981 pm_runtime_disable(&pdev->dev); in vsp1_probe()
982 rcar_fcp_put(vsp1->fcp); in vsp1_probe()
993 rcar_fcp_put(vsp1->fcp); in vsp1_remove()
995 pm_runtime_disable(&pdev->dev); in vsp1_remove()
1001 { .compatible = "renesas,r9a07g044-vsp2", .data = &rzg2l_vsp2_device_info },