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",
290 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
304 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
318 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
334 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
354 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
374 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
394 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
414 .clock = { "top_ahb", "ahb", "ispif_ahb",
428 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
449 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
545 .regulator = { "vdda-csi0" },
565 .regulator = { "vdda-csi1" },
585 .regulator = { "vdda-csi2" },
645 /* VFE-lite */
666 * camss_add_clock_margin - Add margin to clock frequency rate
679 * camss_enable_clocks - Enable multiple clocks
703 for (i--; i >= 0; i--) in camss_enable_clocks()
710 * camss_disable_clocks - Disable multiple clocks
718 for (i = nclocks - 1; i >= 0; i--) in camss_disable_clocks()
723 * camss_find_sensor - Find a linked media entity which represents a sensor
733 pad = &entity->pads[0]; in camss_find_sensor()
734 if (!(pad->flags & MEDIA_PAD_FL_SINK)) in camss_find_sensor()
738 if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) in camss_find_sensor()
741 entity = pad->entity; in camss_find_sensor()
743 if (entity->function == MEDIA_ENT_F_CAM_SENSOR) in camss_find_sensor()
749 * camss_get_link_freq - Get link frequency from sensor
764 return -ENODEV; in camss_get_link_freq()
768 return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes); in camss_get_link_freq()
772 * camss_get_pixel_clock - Get pixel clock rate from sensor
786 return -ENODEV; in camss_get_pixel_clock()
790 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); in camss_get_pixel_clock()
793 return -EINVAL; in camss_get_pixel_clock()
804 if (id < camss->vfe_num) { in camss_pm_domain_on()
805 struct vfe_device *vfe = &camss->vfe[id]; in camss_pm_domain_on()
807 ret = vfe->ops->pm_domain_on(vfe); in camss_pm_domain_on()
815 if (id < camss->vfe_num) { in camss_pm_domain_off()
816 struct vfe_device *vfe = &camss->vfe[id]; in camss_pm_domain_off()
818 vfe->ops->pm_domain_off(vfe); in camss_pm_domain_off()
823 * camss_of_parse_endpoint_node - Parse port endpoint node
834 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; in camss_of_parse_endpoint_node()
841 csd->interface.csiphy_id = vep.base.port; in camss_of_parse_endpoint_node()
844 lncfg->clk.pos = mipi_csi2->clock_lane; in camss_of_parse_endpoint_node()
845 lncfg->clk.pol = mipi_csi2->lane_polarities[0]; in camss_of_parse_endpoint_node()
846 lncfg->num_data = mipi_csi2->num_data_lanes; in camss_of_parse_endpoint_node()
848 lncfg->data = devm_kcalloc(dev, in camss_of_parse_endpoint_node()
849 lncfg->num_data, sizeof(*lncfg->data), in camss_of_parse_endpoint_node()
851 if (!lncfg->data) in camss_of_parse_endpoint_node()
852 return -ENOMEM; in camss_of_parse_endpoint_node()
854 for (i = 0; i < lncfg->num_data; i++) { in camss_of_parse_endpoint_node()
855 lncfg->data[i].pos = mipi_csi2->data_lanes[i]; in camss_of_parse_endpoint_node()
856 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; in camss_of_parse_endpoint_node()
863 * camss_of_parse_ports - Parse ports node
871 struct device *dev = camss->dev; in camss_of_parse_ports()
876 for_each_endpoint_of_node(dev->of_node, node) { in camss_of_parse_ports()
885 ret = -EINVAL; in camss_of_parse_ports()
890 &camss->notifier, of_fwnode_handle(remote), in camss_of_parse_ports()
913 * camss_init_subdevices - Initialize subdev structures and resources
927 if (camss->version == CAMSS_8x16) { in camss_init_subdevices()
932 } else if (camss->version == CAMSS_8x96) { in camss_init_subdevices()
937 } else if (camss->version == CAMSS_660) { in camss_init_subdevices()
942 } else if (camss->version == CAMSS_845) { in camss_init_subdevices()
949 return -EINVAL; in camss_init_subdevices()
952 for (i = 0; i < camss->csiphy_num; i++) { in camss_init_subdevices()
953 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], in camss_init_subdevices()
956 dev_err(camss->dev, in camss_init_subdevices()
957 "Failed to init csiphy%d sub-device: %d\n", in camss_init_subdevices()
963 for (i = 0; i < camss->csid_num; i++) { in camss_init_subdevices()
964 ret = msm_csid_subdev_init(camss, &camss->csid[i], in camss_init_subdevices()
967 dev_err(camss->dev, in camss_init_subdevices()
968 "Failed to init csid%d sub-device: %d\n", in camss_init_subdevices()
976 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", in camss_init_subdevices()
981 for (i = 0; i < camss->vfe_num; i++) { in camss_init_subdevices()
982 ret = msm_vfe_subdev_init(camss, &camss->vfe[i], in camss_init_subdevices()
985 dev_err(camss->dev, in camss_init_subdevices()
986 "Fail to init vfe%d sub-device: %d\n", i, ret); in camss_init_subdevices()
995 * camss_register_entities - Register subdev nodes and create links
1005 for (i = 0; i < camss->csiphy_num; i++) { in camss_register_entities()
1006 ret = msm_csiphy_register_entity(&camss->csiphy[i], in camss_register_entities()
1007 &camss->v4l2_dev); in camss_register_entities()
1009 dev_err(camss->dev, in camss_register_entities()
1016 for (i = 0; i < camss->csid_num; i++) { in camss_register_entities()
1017 ret = msm_csid_register_entity(&camss->csid[i], in camss_register_entities()
1018 &camss->v4l2_dev); in camss_register_entities()
1020 dev_err(camss->dev, in camss_register_entities()
1027 ret = msm_ispif_register_entities(camss->ispif, in camss_register_entities()
1028 &camss->v4l2_dev); in camss_register_entities()
1030 dev_err(camss->dev, "Failed to register ispif entities: %d\n", in camss_register_entities()
1035 for (i = 0; i < camss->vfe_num; i++) { in camss_register_entities()
1036 ret = msm_vfe_register_entities(&camss->vfe[i], in camss_register_entities()
1037 &camss->v4l2_dev); in camss_register_entities()
1039 dev_err(camss->dev, in camss_register_entities()
1046 for (i = 0; i < camss->csiphy_num; i++) { in camss_register_entities()
1047 for (j = 0; j < camss->csid_num; j++) { in camss_register_entities()
1049 &camss->csiphy[i].subdev.entity, in camss_register_entities()
1051 &camss->csid[j].subdev.entity, in camss_register_entities()
1055 dev_err(camss->dev, in camss_register_entities()
1056 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1057 camss->csiphy[i].subdev.entity.name, in camss_register_entities()
1058 camss->csid[j].subdev.entity.name, in camss_register_entities()
1065 if (camss->ispif) { in camss_register_entities()
1066 for (i = 0; i < camss->csid_num; i++) { in camss_register_entities()
1067 for (j = 0; j < camss->ispif->line_num; j++) { in camss_register_entities()
1069 &camss->csid[i].subdev.entity, in camss_register_entities()
1071 &camss->ispif->line[j].subdev.entity, in camss_register_entities()
1075 dev_err(camss->dev, in camss_register_entities()
1076 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1077 camss->csid[i].subdev.entity.name, in camss_register_entities()
1078 camss->ispif->line[j].subdev.entity.name, in camss_register_entities()
1085 for (i = 0; i < camss->ispif->line_num; i++) in camss_register_entities()
1086 for (k = 0; k < camss->vfe_num; k++) in camss_register_entities()
1087 for (j = 0; j < camss->vfe[k].line_num; j++) { in camss_register_entities()
1088 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; in camss_register_entities()
1089 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; in camss_register_entities()
1091 ret = media_create_pad_link(&ispif->entity, in camss_register_entities()
1093 &vfe->entity, in camss_register_entities()
1097 dev_err(camss->dev, in camss_register_entities()
1098 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1099 ispif->entity.name, in camss_register_entities()
1100 vfe->entity.name, in camss_register_entities()
1106 for (i = 0; i < camss->csid_num; i++) in camss_register_entities()
1107 for (k = 0; k < camss->vfe_num; k++) in camss_register_entities()
1108 for (j = 0; j < camss->vfe[k].line_num; j++) { in camss_register_entities()
1109 struct v4l2_subdev *csid = &camss->csid[i].subdev; in camss_register_entities()
1110 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; in camss_register_entities()
1112 ret = media_create_pad_link(&csid->entity, in camss_register_entities()
1114 &vfe->entity, in camss_register_entities()
1118 dev_err(camss->dev, in camss_register_entities()
1119 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1120 csid->entity.name, in camss_register_entities()
1121 vfe->entity.name, in camss_register_entities()
1131 i = camss->vfe_num; in camss_register_entities()
1133 for (i--; i >= 0; i--) in camss_register_entities()
1134 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_register_entities()
1137 msm_ispif_unregister_entities(camss->ispif); in camss_register_entities()
1139 i = camss->csid_num; in camss_register_entities()
1141 for (i--; i >= 0; i--) in camss_register_entities()
1142 msm_csid_unregister_entity(&camss->csid[i]); in camss_register_entities()
1144 i = camss->csiphy_num; in camss_register_entities()
1146 for (i--; i >= 0; i--) in camss_register_entities()
1147 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_register_entities()
1153 * camss_unregister_entities - Unregister subdev nodes
1162 for (i = 0; i < camss->csiphy_num; i++) in camss_unregister_entities()
1163 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_unregister_entities()
1165 for (i = 0; i < camss->csid_num; i++) in camss_unregister_entities()
1166 msm_csid_unregister_entity(&camss->csid[i]); in camss_unregister_entities()
1168 msm_ispif_unregister_entities(camss->ispif); in camss_unregister_entities()
1170 for (i = 0; i < camss->vfe_num; i++) in camss_unregister_entities()
1171 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_unregister_entities()
1181 u8 id = csd->interface.csiphy_id; in camss_subdev_notifier_bound()
1182 struct csiphy_device *csiphy = &camss->csiphy[id]; in camss_subdev_notifier_bound()
1184 csiphy->cfg.csi2 = &csd->interface.csi2; in camss_subdev_notifier_bound()
1185 subdev->host_priv = csiphy; in camss_subdev_notifier_bound()
1193 struct v4l2_device *v4l2_dev = &camss->v4l2_dev; in camss_subdev_notifier_complete()
1197 list_for_each_entry(sd, &v4l2_dev->subdevs, list) { in camss_subdev_notifier_complete()
1198 if (sd->host_priv) { in camss_subdev_notifier_complete()
1199 struct media_entity *sensor = &sd->entity; in camss_subdev_notifier_complete()
1201 (struct csiphy_device *) sd->host_priv; in camss_subdev_notifier_complete()
1202 struct media_entity *input = &csiphy->subdev.entity; in camss_subdev_notifier_complete()
1205 for (i = 0; i < sensor->num_pads; i++) { in camss_subdev_notifier_complete()
1206 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) in camss_subdev_notifier_complete()
1209 if (i == sensor->num_pads) { in camss_subdev_notifier_complete()
1210 dev_err(camss->dev, in camss_subdev_notifier_complete()
1212 return -EINVAL; in camss_subdev_notifier_complete()
1219 dev_err(camss->dev, in camss_subdev_notifier_complete()
1220 "Failed to link %s->%s entities: %d\n", in camss_subdev_notifier_complete()
1221 sensor->name, input->name, ret); in camss_subdev_notifier_complete()
1227 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_subdev_notifier_complete()
1231 return media_device_register(&camss->media_dev); in camss_subdev_notifier_complete()
1250 if (camss->version == CAMSS_8x96 || in camss_configure_pd()
1251 camss->version == CAMSS_660) in camss_configure_pd()
1253 else if (camss->version == CAMSS_845) in camss_configure_pd()
1257 camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); in camss_configure_pd()
1258 if (IS_ERR(camss->genpd[i])) { in camss_configure_pd()
1259 ret = PTR_ERR(camss->genpd[i]); in camss_configure_pd()
1263 camss->genpd_link[i] = device_link_add(camss->dev, camss->genpd[i], in camss_configure_pd()
1266 if (!camss->genpd_link[i]) { in camss_configure_pd()
1267 dev_pm_domain_detach(camss->genpd[i], true); in camss_configure_pd()
1268 ret = -EINVAL; in camss_configure_pd()
1279 device_link_del(camss->genpd_link[i]); in camss_configure_pd()
1280 dev_pm_domain_detach(camss->genpd[i], true); in camss_configure_pd()
1287 * camss_probe - Probe CAMSS platform device
1294 struct device *dev = &pdev->dev; in camss_probe()
1300 return -ENOMEM; in camss_probe()
1302 atomic_set(&camss->ref_count, 0); in camss_probe()
1303 camss->dev = dev; in camss_probe()
1306 if (of_device_is_compatible(dev->of_node, "qcom,msm8916-camss")) { in camss_probe()
1307 camss->version = CAMSS_8x16; in camss_probe()
1308 camss->csiphy_num = 2; in camss_probe()
1309 camss->csid_num = 2; in camss_probe()
1310 camss->vfe_num = 1; in camss_probe()
1311 } else if (of_device_is_compatible(dev->of_node, in camss_probe()
1312 "qcom,msm8996-camss")) { in camss_probe()
1313 camss->version = CAMSS_8x96; in camss_probe()
1314 camss->csiphy_num = 3; in camss_probe()
1315 camss->csid_num = 4; in camss_probe()
1316 camss->vfe_num = 2; in camss_probe()
1317 } else if (of_device_is_compatible(dev->of_node, in camss_probe()
1318 "qcom,sdm660-camss")) { in camss_probe()
1319 camss->version = CAMSS_660; in camss_probe()
1320 camss->csiphy_num = 3; in camss_probe()
1321 camss->csid_num = 4; in camss_probe()
1322 camss->vfe_num = 2; in camss_probe()
1323 } else if (of_device_is_compatible(dev->of_node, in camss_probe()
1324 "qcom,sdm845-camss")) { in camss_probe()
1325 camss->version = CAMSS_845; in camss_probe()
1326 camss->csiphy_num = 4; in camss_probe()
1327 camss->csid_num = 3; in camss_probe()
1328 camss->vfe_num = 3; in camss_probe()
1330 ret = -EINVAL; in camss_probe()
1334 camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, in camss_probe()
1335 sizeof(*camss->csiphy), GFP_KERNEL); in camss_probe()
1336 if (!camss->csiphy) { in camss_probe()
1337 ret = -ENOMEM; in camss_probe()
1341 camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), in camss_probe()
1343 if (!camss->csid) { in camss_probe()
1344 ret = -ENOMEM; in camss_probe()
1348 if (camss->version == CAMSS_8x16 || in camss_probe()
1349 camss->version == CAMSS_8x96) { in camss_probe()
1350 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); in camss_probe()
1351 if (!camss->ispif) { in camss_probe()
1352 ret = -ENOMEM; in camss_probe()
1357 camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), in camss_probe()
1359 if (!camss->vfe) { in camss_probe()
1360 ret = -ENOMEM; in camss_probe()
1364 v4l2_async_notifier_init(&camss->notifier); in camss_probe()
1380 camss->media_dev.dev = camss->dev; in camss_probe()
1381 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", in camss_probe()
1382 sizeof(camss->media_dev.model)); in camss_probe()
1383 camss->media_dev.ops = &camss_media_ops; in camss_probe()
1384 media_device_init(&camss->media_dev); in camss_probe()
1386 camss->v4l2_dev.mdev = &camss->media_dev; in camss_probe()
1387 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); in camss_probe()
1398 camss->notifier.ops = &camss_subdev_notifier_ops; in camss_probe()
1400 ret = v4l2_async_notifier_register(&camss->v4l2_dev, in camss_probe()
1401 &camss->notifier); in camss_probe()
1409 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_probe()
1416 ret = media_device_register(&camss->media_dev); in camss_probe()
1437 v4l2_device_unregister(&camss->v4l2_dev); in camss_probe()
1439 v4l2_async_notifier_cleanup(&camss->notifier); in camss_probe()
1451 v4l2_device_unregister(&camss->v4l2_dev); in camss_delete()
1452 media_device_unregister(&camss->media_dev); in camss_delete()
1453 media_device_cleanup(&camss->media_dev); in camss_delete()
1455 pm_runtime_disable(camss->dev); in camss_delete()
1457 if (camss->version == CAMSS_8x96 || in camss_delete()
1458 camss->version == CAMSS_660) in camss_delete()
1460 else if (camss->version == CAMSS_845) in camss_delete()
1464 device_link_del(camss->genpd_link[i]); in camss_delete()
1465 dev_pm_domain_detach(camss->genpd[i], true); in camss_delete()
1472 * camss_remove - Remove CAMSS platform device
1481 v4l2_async_notifier_unregister(&camss->notifier); in camss_remove()
1482 v4l2_async_notifier_cleanup(&camss->notifier); in camss_remove()
1485 if (atomic_read(&camss->ref_count) == 0) in camss_remove()
1492 { .compatible = "qcom,msm8916-camss" },
1493 { .compatible = "qcom,msm8996-camss" },
1494 { .compatible = "qcom,sdm660-camss" },
1495 { .compatible = "qcom,sdm845-camss" },
1521 .name = "qcom-camss",
1529 MODULE_ALIAS("platform:qcom-camss");