Lines Matching +full:s +full:- +full:ahb

1 // SPDX-License-Identifier: GPL-2.0
5 * Qualcomm MSM Camera Subsystem - Core
8 * Copyright (C) 2015-2018 Linaro Ltd.
11 #include <linux/media-bus-format.h>
22 #include <media/media-device.h>
23 #include <media/v4l2-async.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-mc.h>
26 #include <media/v4l2-fwnode.h>
37 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
49 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
63 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
80 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
97 .clock = { "top_ahb", "ahb", "ispif_ahb",
111 "vfe_ahb", "vfe_axi", "ahb" },
132 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
144 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
156 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" },
170 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
187 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
204 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
221 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
238 .clock = { "top_ahb", "ahb", "ispif_ahb",
252 .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb",
270 .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb",
287 * camss_add_clock_margin - Add margin to clock frequency rate
300 * camss_enable_clocks - Enable multiple clocks
324 for (i--; i >= 0; i--) in camss_enable_clocks()
331 * camss_disable_clocks - Disable multiple clocks
339 for (i = nclocks - 1; i >= 0; i--) in camss_disable_clocks()
344 * camss_find_sensor - Find a linked media entity which represents a sensor
354 pad = &entity->pads[0]; in camss_find_sensor()
355 if (!(pad->flags & MEDIA_PAD_FL_SINK)) in camss_find_sensor()
359 if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) in camss_find_sensor()
362 entity = pad->entity; in camss_find_sensor()
364 if (entity->function == MEDIA_ENT_F_CAM_SENSOR) in camss_find_sensor()
370 * camss_get_pixel_clock - Get pixel clock rate from sensor
384 return -ENODEV; in camss_get_pixel_clock()
388 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); in camss_get_pixel_clock()
391 return -EINVAL; in camss_get_pixel_clock()
400 if (camss->version == CAMSS_8x96) { in camss_pm_domain_on()
401 camss->genpd_link[id] = device_link_add(camss->dev, in camss_pm_domain_on()
402 camss->genpd[id], DL_FLAG_STATELESS | in camss_pm_domain_on()
405 if (!camss->genpd_link[id]) in camss_pm_domain_on()
406 return -EINVAL; in camss_pm_domain_on()
414 if (camss->version == CAMSS_8x96) in camss_pm_domain_off()
415 device_link_del(camss->genpd_link[id]); in camss_pm_domain_off()
419 * camss_of_parse_endpoint_node - Parse port endpoint node
430 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; in camss_of_parse_endpoint_node()
437 csd->interface.csiphy_id = vep.base.port; in camss_of_parse_endpoint_node()
440 lncfg->clk.pos = mipi_csi2->clock_lane; in camss_of_parse_endpoint_node()
441 lncfg->clk.pol = mipi_csi2->lane_polarities[0]; in camss_of_parse_endpoint_node()
442 lncfg->num_data = mipi_csi2->num_data_lanes; in camss_of_parse_endpoint_node()
444 lncfg->data = devm_kcalloc(dev, in camss_of_parse_endpoint_node()
445 lncfg->num_data, sizeof(*lncfg->data), in camss_of_parse_endpoint_node()
447 if (!lncfg->data) in camss_of_parse_endpoint_node()
448 return -ENOMEM; in camss_of_parse_endpoint_node()
450 for (i = 0; i < lncfg->num_data; i++) { in camss_of_parse_endpoint_node()
451 lncfg->data[i].pos = mipi_csi2->data_lanes[i]; in camss_of_parse_endpoint_node()
452 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; in camss_of_parse_endpoint_node()
459 * camss_of_parse_ports - Parse ports node
467 struct device *dev = camss->dev; in camss_of_parse_ports()
472 for_each_endpoint_of_node(dev->of_node, node) { in camss_of_parse_ports()
482 ret = -EINVAL; in camss_of_parse_ports()
487 &camss->notifier, of_fwnode_handle(remote), in camss_of_parse_ports()
512 * camss_init_subdevices - Initialize subdev structures and resources
526 if (camss->version == CAMSS_8x16) { in camss_init_subdevices()
531 } else if (camss->version == CAMSS_8x96) { in camss_init_subdevices()
537 return -EINVAL; in camss_init_subdevices()
540 for (i = 0; i < camss->csiphy_num; i++) { in camss_init_subdevices()
541 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], in camss_init_subdevices()
544 dev_err(camss->dev, in camss_init_subdevices()
545 "Failed to init csiphy%d sub-device: %d\n", in camss_init_subdevices()
551 for (i = 0; i < camss->csid_num; i++) { in camss_init_subdevices()
552 ret = msm_csid_subdev_init(camss, &camss->csid[i], in camss_init_subdevices()
555 dev_err(camss->dev, in camss_init_subdevices()
556 "Failed to init csid%d sub-device: %d\n", in camss_init_subdevices()
562 ret = msm_ispif_subdev_init(&camss->ispif, ispif_res); in camss_init_subdevices()
564 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", in camss_init_subdevices()
569 for (i = 0; i < camss->vfe_num; i++) { in camss_init_subdevices()
570 ret = msm_vfe_subdev_init(camss, &camss->vfe[i], in camss_init_subdevices()
573 dev_err(camss->dev, in camss_init_subdevices()
574 "Fail to init vfe%d sub-device: %d\n", i, ret); in camss_init_subdevices()
583 * camss_register_entities - Register subdev nodes and create links
593 for (i = 0; i < camss->csiphy_num; i++) { in camss_register_entities()
594 ret = msm_csiphy_register_entity(&camss->csiphy[i], in camss_register_entities()
595 &camss->v4l2_dev); in camss_register_entities()
597 dev_err(camss->dev, in camss_register_entities()
604 for (i = 0; i < camss->csid_num; i++) { in camss_register_entities()
605 ret = msm_csid_register_entity(&camss->csid[i], in camss_register_entities()
606 &camss->v4l2_dev); in camss_register_entities()
608 dev_err(camss->dev, in camss_register_entities()
615 ret = msm_ispif_register_entities(&camss->ispif, &camss->v4l2_dev); in camss_register_entities()
617 dev_err(camss->dev, "Failed to register ispif entities: %d\n", in camss_register_entities()
622 for (i = 0; i < camss->vfe_num; i++) { in camss_register_entities()
623 ret = msm_vfe_register_entities(&camss->vfe[i], in camss_register_entities()
624 &camss->v4l2_dev); in camss_register_entities()
626 dev_err(camss->dev, in camss_register_entities()
633 for (i = 0; i < camss->csiphy_num; i++) { in camss_register_entities()
634 for (j = 0; j < camss->csid_num; j++) { in camss_register_entities()
636 &camss->csiphy[i].subdev.entity, in camss_register_entities()
638 &camss->csid[j].subdev.entity, in camss_register_entities()
642 dev_err(camss->dev, in camss_register_entities()
643 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
644 camss->csiphy[i].subdev.entity.name, in camss_register_entities()
645 camss->csid[j].subdev.entity.name, in camss_register_entities()
652 for (i = 0; i < camss->csid_num; i++) { in camss_register_entities()
653 for (j = 0; j < camss->ispif.line_num; j++) { in camss_register_entities()
655 &camss->csid[i].subdev.entity, in camss_register_entities()
657 &camss->ispif.line[j].subdev.entity, in camss_register_entities()
661 dev_err(camss->dev, in camss_register_entities()
662 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
663 camss->csid[i].subdev.entity.name, in camss_register_entities()
664 camss->ispif.line[j].subdev.entity.name, in camss_register_entities()
671 for (i = 0; i < camss->ispif.line_num; i++) in camss_register_entities()
672 for (k = 0; k < camss->vfe_num; k++) in camss_register_entities()
673 for (j = 0; j < ARRAY_SIZE(camss->vfe[k].line); j++) { in camss_register_entities()
675 &camss->ispif.line[i].subdev.entity, in camss_register_entities()
677 &camss->vfe[k].line[j].subdev.entity, in camss_register_entities()
681 dev_err(camss->dev, in camss_register_entities()
682 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
683 camss->ispif.line[i].subdev.entity.name, in camss_register_entities()
684 camss->vfe[k].line[j].subdev.entity.name, in camss_register_entities()
693 i = camss->vfe_num; in camss_register_entities()
695 for (i--; i >= 0; i--) in camss_register_entities()
696 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_register_entities()
698 msm_ispif_unregister_entities(&camss->ispif); in camss_register_entities()
701 i = camss->csid_num; in camss_register_entities()
703 for (i--; i >= 0; i--) in camss_register_entities()
704 msm_csid_unregister_entity(&camss->csid[i]); in camss_register_entities()
706 i = camss->csiphy_num; in camss_register_entities()
708 for (i--; i >= 0; i--) in camss_register_entities()
709 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_register_entities()
715 * camss_unregister_entities - Unregister subdev nodes
724 for (i = 0; i < camss->csiphy_num; i++) in camss_unregister_entities()
725 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_unregister_entities()
727 for (i = 0; i < camss->csid_num; i++) in camss_unregister_entities()
728 msm_csid_unregister_entity(&camss->csid[i]); in camss_unregister_entities()
730 msm_ispif_unregister_entities(&camss->ispif); in camss_unregister_entities()
732 for (i = 0; i < camss->vfe_num; i++) in camss_unregister_entities()
733 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_unregister_entities()
743 u8 id = csd->interface.csiphy_id; in camss_subdev_notifier_bound()
744 struct csiphy_device *csiphy = &camss->csiphy[id]; in camss_subdev_notifier_bound()
746 csiphy->cfg.csi2 = &csd->interface.csi2; in camss_subdev_notifier_bound()
747 subdev->host_priv = csiphy; in camss_subdev_notifier_bound()
755 struct v4l2_device *v4l2_dev = &camss->v4l2_dev; in camss_subdev_notifier_complete()
759 list_for_each_entry(sd, &v4l2_dev->subdevs, list) { in camss_subdev_notifier_complete()
760 if (sd->host_priv) { in camss_subdev_notifier_complete()
761 struct media_entity *sensor = &sd->entity; in camss_subdev_notifier_complete()
763 (struct csiphy_device *) sd->host_priv; in camss_subdev_notifier_complete()
764 struct media_entity *input = &csiphy->subdev.entity; in camss_subdev_notifier_complete()
767 for (i = 0; i < sensor->num_pads; i++) { in camss_subdev_notifier_complete()
768 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) in camss_subdev_notifier_complete()
771 if (i == sensor->num_pads) { in camss_subdev_notifier_complete()
772 dev_err(camss->dev, in camss_subdev_notifier_complete()
774 return -EINVAL; in camss_subdev_notifier_complete()
781 dev_err(camss->dev, in camss_subdev_notifier_complete()
782 "Failed to link %s->%s entities: %d\n", in camss_subdev_notifier_complete()
783 sensor->name, input->name, ret); in camss_subdev_notifier_complete()
789 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_subdev_notifier_complete()
793 return media_device_register(&camss->media_dev); in camss_subdev_notifier_complete()
806 * camss_probe - Probe CAMSS platform device
813 struct device *dev = &pdev->dev; in camss_probe()
819 return -ENOMEM; in camss_probe()
821 atomic_set(&camss->ref_count, 0); in camss_probe()
822 camss->dev = dev; in camss_probe()
825 if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) { in camss_probe()
826 camss->version = CAMSS_8x16; in camss_probe()
827 camss->csiphy_num = 2; in camss_probe()
828 camss->csid_num = 2; in camss_probe()
829 camss->vfe_num = 1; in camss_probe()
830 } else if (of_device_is_compatible(dev->of_node, in camss_probe()
831 "qcom,msm8996-camss")) { in camss_probe()
832 camss->version = CAMSS_8x96; in camss_probe()
833 camss->csiphy_num = 3; in camss_probe()
834 camss->csid_num = 4; in camss_probe()
835 camss->vfe_num = 2; in camss_probe()
837 ret = -EINVAL; in camss_probe()
841 camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, in camss_probe()
842 sizeof(*camss->csiphy), GFP_KERNEL); in camss_probe()
843 if (!camss->csiphy) { in camss_probe()
844 ret = -ENOMEM; in camss_probe()
848 camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), in camss_probe()
850 if (!camss->csid) { in camss_probe()
851 ret = -ENOMEM; in camss_probe()
855 camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), in camss_probe()
857 if (!camss->vfe) { in camss_probe()
858 ret = -ENOMEM; in camss_probe()
862 v4l2_async_notifier_init(&camss->notifier); in camss_probe()
878 camss->media_dev.dev = camss->dev; in camss_probe()
879 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", in camss_probe()
880 sizeof(camss->media_dev.model)); in camss_probe()
881 camss->media_dev.ops = &camss_media_ops; in camss_probe()
882 media_device_init(&camss->media_dev); in camss_probe()
884 camss->v4l2_dev.mdev = &camss->media_dev; in camss_probe()
885 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); in camss_probe()
896 camss->notifier.ops = &camss_subdev_notifier_ops; in camss_probe()
898 ret = v4l2_async_notifier_register(&camss->v4l2_dev, in camss_probe()
899 &camss->notifier); in camss_probe()
907 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_probe()
914 ret = media_device_register(&camss->media_dev); in camss_probe()
922 if (camss->version == CAMSS_8x96) { in camss_probe()
923 camss->genpd[PM_DOMAIN_VFE0] = dev_pm_domain_attach_by_id( in camss_probe()
924 camss->dev, PM_DOMAIN_VFE0); in camss_probe()
925 if (IS_ERR(camss->genpd[PM_DOMAIN_VFE0])) in camss_probe()
926 return PTR_ERR(camss->genpd[PM_DOMAIN_VFE0]); in camss_probe()
928 camss->genpd[PM_DOMAIN_VFE1] = dev_pm_domain_attach_by_id( in camss_probe()
929 camss->dev, PM_DOMAIN_VFE1); in camss_probe()
930 if (IS_ERR(camss->genpd[PM_DOMAIN_VFE1])) { in camss_probe()
931 dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], in camss_probe()
933 return PTR_ERR(camss->genpd[PM_DOMAIN_VFE1]); in camss_probe()
944 v4l2_device_unregister(&camss->v4l2_dev); in camss_probe()
946 v4l2_async_notifier_cleanup(&camss->notifier); in camss_probe()
955 v4l2_device_unregister(&camss->v4l2_dev); in camss_delete()
956 media_device_unregister(&camss->media_dev); in camss_delete()
957 media_device_cleanup(&camss->media_dev); in camss_delete()
959 pm_runtime_disable(camss->dev); in camss_delete()
961 if (camss->version == CAMSS_8x96) { in camss_delete()
962 dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE0], true); in camss_delete()
963 dev_pm_domain_detach(camss->genpd[PM_DOMAIN_VFE1], true); in camss_delete()
970 * camss_remove - Remove CAMSS platform device
979 v4l2_async_notifier_unregister(&camss->notifier); in camss_remove()
980 v4l2_async_notifier_cleanup(&camss->notifier); in camss_remove()
983 if (atomic_read(&camss->ref_count) == 0) in camss_remove()
990 { .compatible = "qcom,msm8916-camss" },
991 { .compatible = "qcom,msm8996-camss" },
1017 .name = "qcom-camss",
1025 MODULE_ALIAS("platform:qcom-camss");