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.
12 #include <linux/media-bus-format.h>
24 #include <media/media-device.h>
25 #include <media/v4l2-async.h>
26 #include <media/v4l2-device.h>
27 #include <media/v4l2-mc.h>
28 #include <media/v4l2-fwnode.h>
39 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
52 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
67 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
85 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
103 .clock = { "top_ahb", "ahb", "ispif_ahb",
117 "vfe_ahb", "vfe_axi", "ahb" },
140 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" },
153 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" },
166 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer" },
181 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
199 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
217 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
235 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
253 .clock = { "top_ahb", "ahb", "ispif_ahb",
267 .clock = { "top_ahb", "ahb", "vfe0", "csi_vfe0", "vfe_ahb",
288 .clock = { "top_ahb", "ahb", "vfe1", "csi_vfe1", "vfe_ahb",
311 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer",
326 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer",
341 .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy2_timer",
358 .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb",
379 .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb",
400 .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb",
421 .clock = { "top_ahb", "ispif_ahb", "csi3_ahb", "ahb",
442 .clock = { "top_ahb", "ahb", "ispif_ahb",
456 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe0",
480 .clock = { "throttle_axi", "top_ahb", "ahb", "vfe1",
583 .regulators = { "vdda-phy", "vdda-pll" },
604 .regulators = { "vdda-phy", "vdda-pll" },
625 .regulators = { "vdda-phy", "vdda-pll" },
693 /* VFE-lite */
782 .regulators = { "vdda-phy", "vdda-pll" },
795 .regulators = { "vdda-phy", "vdda-pll" },
808 .regulators = { "vdda-phy", "vdda-pll" },
821 .regulators = { "vdda-phy", "vdda-pll" },
945 * camss_add_clock_margin - Add margin to clock frequency rate
958 * camss_enable_clocks - Enable multiple clocks
982 for (i--; i >= 0; i--) in camss_enable_clocks()
989 * camss_disable_clocks - Disable multiple clocks
997 for (i = nclocks - 1; i >= 0; i--) in camss_disable_clocks()
1002 * camss_find_sensor - Find a linked media entity which represents a sensor
1012 pad = &entity->pads[0]; in camss_find_sensor()
1013 if (!(pad->flags & MEDIA_PAD_FL_SINK)) in camss_find_sensor()
1017 if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) in camss_find_sensor()
1020 entity = pad->entity; in camss_find_sensor()
1022 if (entity->function == MEDIA_ENT_F_CAM_SENSOR) in camss_find_sensor()
1028 * camss_get_link_freq - Get link frequency from sensor
1043 return -ENODEV; in camss_get_link_freq()
1047 return v4l2_get_link_freq(subdev->ctrl_handler, bpp, 2 * lanes); in camss_get_link_freq()
1051 * camss_get_pixel_clock - Get pixel clock rate from sensor
1065 return -ENODEV; in camss_get_pixel_clock()
1069 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); in camss_get_pixel_clock()
1072 return -EINVAL; in camss_get_pixel_clock()
1083 if (id < camss->res->vfe_num) { in camss_pm_domain_on()
1084 struct vfe_device *vfe = &camss->vfe[id]; in camss_pm_domain_on()
1086 ret = vfe->ops->pm_domain_on(vfe); in camss_pm_domain_on()
1094 if (id < camss->res->vfe_num) { in camss_pm_domain_off()
1095 struct vfe_device *vfe = &camss->vfe[id]; in camss_pm_domain_off()
1097 vfe->ops->pm_domain_off(vfe); in camss_pm_domain_off()
1102 * camss_of_parse_endpoint_node - Parse port endpoint node
1113 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; in camss_of_parse_endpoint_node()
1120 csd->interface.csiphy_id = vep.base.port; in camss_of_parse_endpoint_node()
1123 lncfg->clk.pos = mipi_csi2->clock_lane; in camss_of_parse_endpoint_node()
1124 lncfg->clk.pol = mipi_csi2->lane_polarities[0]; in camss_of_parse_endpoint_node()
1125 lncfg->num_data = mipi_csi2->num_data_lanes; in camss_of_parse_endpoint_node()
1127 lncfg->data = devm_kcalloc(dev, in camss_of_parse_endpoint_node()
1128 lncfg->num_data, sizeof(*lncfg->data), in camss_of_parse_endpoint_node()
1130 if (!lncfg->data) in camss_of_parse_endpoint_node()
1131 return -ENOMEM; in camss_of_parse_endpoint_node()
1133 for (i = 0; i < lncfg->num_data; i++) { in camss_of_parse_endpoint_node()
1134 lncfg->data[i].pos = mipi_csi2->data_lanes[i]; in camss_of_parse_endpoint_node()
1135 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1]; in camss_of_parse_endpoint_node()
1142 * camss_of_parse_ports - Parse ports node
1150 struct device *dev = camss->dev; in camss_of_parse_ports()
1155 for_each_endpoint_of_node(dev->of_node, node) { in camss_of_parse_ports()
1164 ret = -EINVAL; in camss_of_parse_ports()
1168 csd = v4l2_async_nf_add_fwnode(&camss->notifier, in camss_of_parse_ports()
1192 * camss_init_subdevices - Initialize subdev structures and resources
1199 const struct camss_resources *res = camss->res; in camss_init_subdevices()
1203 for (i = 0; i < camss->res->csiphy_num; i++) { in camss_init_subdevices()
1204 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i], in camss_init_subdevices()
1205 &res->csiphy_res[i], i); in camss_init_subdevices()
1207 dev_err(camss->dev, in camss_init_subdevices()
1208 "Failed to init csiphy%d sub-device: %d\n", in camss_init_subdevices()
1215 for (i = 0; i < camss->res->vfe_num; i++) { in camss_init_subdevices()
1216 ret = msm_vfe_subdev_init(camss, &camss->vfe[i], in camss_init_subdevices()
1217 &res->vfe_res[i], i); in camss_init_subdevices()
1219 dev_err(camss->dev, in camss_init_subdevices()
1220 "Fail to init vfe%d sub-device: %d\n", i, ret); in camss_init_subdevices()
1225 for (i = 0; i < camss->res->csid_num; i++) { in camss_init_subdevices()
1226 ret = msm_csid_subdev_init(camss, &camss->csid[i], in camss_init_subdevices()
1227 &res->csid_res[i], i); in camss_init_subdevices()
1229 dev_err(camss->dev, in camss_init_subdevices()
1230 "Failed to init csid%d sub-device: %d\n", in camss_init_subdevices()
1236 ret = msm_ispif_subdev_init(camss, res->ispif_res); in camss_init_subdevices()
1238 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n", in camss_init_subdevices()
1247 * camss_register_entities - Register subdev nodes and create links
1257 for (i = 0; i < camss->res->csiphy_num; i++) { in camss_register_entities()
1258 ret = msm_csiphy_register_entity(&camss->csiphy[i], in camss_register_entities()
1259 &camss->v4l2_dev); in camss_register_entities()
1261 dev_err(camss->dev, in camss_register_entities()
1268 for (i = 0; i < camss->res->csid_num; i++) { in camss_register_entities()
1269 ret = msm_csid_register_entity(&camss->csid[i], in camss_register_entities()
1270 &camss->v4l2_dev); in camss_register_entities()
1272 dev_err(camss->dev, in camss_register_entities()
1279 ret = msm_ispif_register_entities(camss->ispif, in camss_register_entities()
1280 &camss->v4l2_dev); in camss_register_entities()
1282 dev_err(camss->dev, "Failed to register ispif entities: %d\n", in camss_register_entities()
1287 for (i = 0; i < camss->res->vfe_num; i++) { in camss_register_entities()
1288 ret = msm_vfe_register_entities(&camss->vfe[i], in camss_register_entities()
1289 &camss->v4l2_dev); in camss_register_entities()
1291 dev_err(camss->dev, in camss_register_entities()
1298 for (i = 0; i < camss->res->csiphy_num; i++) { in camss_register_entities()
1299 for (j = 0; j < camss->res->csid_num; j++) { in camss_register_entities()
1301 &camss->csiphy[i].subdev.entity, in camss_register_entities()
1303 &camss->csid[j].subdev.entity, in camss_register_entities()
1307 dev_err(camss->dev, in camss_register_entities()
1308 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1309 camss->csiphy[i].subdev.entity.name, in camss_register_entities()
1310 camss->csid[j].subdev.entity.name, in camss_register_entities()
1317 if (camss->ispif) { in camss_register_entities()
1318 for (i = 0; i < camss->res->csid_num; i++) { in camss_register_entities()
1319 for (j = 0; j < camss->ispif->line_num; j++) { in camss_register_entities()
1321 &camss->csid[i].subdev.entity, in camss_register_entities()
1323 &camss->ispif->line[j].subdev.entity, in camss_register_entities()
1327 dev_err(camss->dev, in camss_register_entities()
1328 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1329 camss->csid[i].subdev.entity.name, in camss_register_entities()
1330 camss->ispif->line[j].subdev.entity.name, in camss_register_entities()
1337 for (i = 0; i < camss->ispif->line_num; i++) in camss_register_entities()
1338 for (k = 0; k < camss->res->vfe_num; k++) in camss_register_entities()
1339 for (j = 0; j < camss->vfe[k].line_num; j++) { in camss_register_entities()
1340 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev; in camss_register_entities()
1341 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; in camss_register_entities()
1343 ret = media_create_pad_link(&ispif->entity, in camss_register_entities()
1345 &vfe->entity, in camss_register_entities()
1349 dev_err(camss->dev, in camss_register_entities()
1350 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1351 ispif->entity.name, in camss_register_entities()
1352 vfe->entity.name, in camss_register_entities()
1358 for (i = 0; i < camss->res->csid_num; i++) in camss_register_entities()
1359 for (k = 0; k < camss->res->vfe_num; k++) in camss_register_entities()
1360 for (j = 0; j < camss->vfe[k].line_num; j++) { in camss_register_entities()
1361 struct v4l2_subdev *csid = &camss->csid[i].subdev; in camss_register_entities()
1362 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev; in camss_register_entities()
1364 ret = media_create_pad_link(&csid->entity, in camss_register_entities()
1366 &vfe->entity, in camss_register_entities()
1370 dev_err(camss->dev, in camss_register_entities()
1371 "Failed to link %s->%s entities: %d\n", in camss_register_entities()
1372 csid->entity.name, in camss_register_entities()
1373 vfe->entity.name, in camss_register_entities()
1383 i = camss->res->vfe_num; in camss_register_entities()
1385 for (i--; i >= 0; i--) in camss_register_entities()
1386 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_register_entities()
1389 msm_ispif_unregister_entities(camss->ispif); in camss_register_entities()
1391 i = camss->res->csid_num; in camss_register_entities()
1393 for (i--; i >= 0; i--) in camss_register_entities()
1394 msm_csid_unregister_entity(&camss->csid[i]); in camss_register_entities()
1396 i = camss->res->csiphy_num; in camss_register_entities()
1398 for (i--; i >= 0; i--) in camss_register_entities()
1399 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_register_entities()
1405 * camss_unregister_entities - Unregister subdev nodes
1414 for (i = 0; i < camss->res->csiphy_num; i++) in camss_unregister_entities()
1415 msm_csiphy_unregister_entity(&camss->csiphy[i]); in camss_unregister_entities()
1417 for (i = 0; i < camss->res->csid_num; i++) in camss_unregister_entities()
1418 msm_csid_unregister_entity(&camss->csid[i]); in camss_unregister_entities()
1420 msm_ispif_unregister_entities(camss->ispif); in camss_unregister_entities()
1422 for (i = 0; i < camss->res->vfe_num; i++) in camss_unregister_entities()
1423 msm_vfe_unregister_entities(&camss->vfe[i]); in camss_unregister_entities()
1433 u8 id = csd->interface.csiphy_id; in camss_subdev_notifier_bound()
1434 struct csiphy_device *csiphy = &camss->csiphy[id]; in camss_subdev_notifier_bound()
1436 csiphy->cfg.csi2 = &csd->interface.csi2; in camss_subdev_notifier_bound()
1437 subdev->host_priv = csiphy; in camss_subdev_notifier_bound()
1445 struct v4l2_device *v4l2_dev = &camss->v4l2_dev; in camss_subdev_notifier_complete()
1449 list_for_each_entry(sd, &v4l2_dev->subdevs, list) { in camss_subdev_notifier_complete()
1450 if (sd->host_priv) { in camss_subdev_notifier_complete()
1451 struct media_entity *sensor = &sd->entity; in camss_subdev_notifier_complete()
1453 (struct csiphy_device *) sd->host_priv; in camss_subdev_notifier_complete()
1454 struct media_entity *input = &csiphy->subdev.entity; in camss_subdev_notifier_complete()
1457 for (i = 0; i < sensor->num_pads; i++) { in camss_subdev_notifier_complete()
1458 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE) in camss_subdev_notifier_complete()
1461 if (i == sensor->num_pads) { in camss_subdev_notifier_complete()
1462 dev_err(camss->dev, in camss_subdev_notifier_complete()
1464 return -EINVAL; in camss_subdev_notifier_complete()
1471 dev_err(camss->dev, in camss_subdev_notifier_complete()
1472 "Failed to link %s->%s entities: %d\n", in camss_subdev_notifier_complete()
1473 sensor->name, input->name, ret); in camss_subdev_notifier_complete()
1479 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_subdev_notifier_complete()
1483 return media_device_register(&camss->media_dev); in camss_subdev_notifier_complete()
1497 const struct camss_resources *res = camss->res; in camss_configure_pd()
1498 struct device *dev = camss->dev; in camss_configure_pd()
1503 camss->genpd_num = of_count_phandle_with_args(dev->of_node, in camss_configure_pd()
1504 "power-domains", in camss_configure_pd()
1505 "#power-domain-cells"); in camss_configure_pd()
1506 if (camss->genpd_num < 0) { in camss_configure_pd()
1508 return camss->genpd_num; in camss_configure_pd()
1516 if (camss->genpd_num == 1) in camss_configure_pd()
1519 /* count the # of VFEs which have flagged power-domain */ in camss_configure_pd()
1520 for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) { in camss_configure_pd()
1521 if (res->vfe_res[i].has_pd) in camss_configure_pd()
1526 * If the number of power-domains is greater than the number of VFEs in camss_configure_pd()
1527 * then the additional power-domain is for the entire CAMSS block. in camss_configure_pd()
1529 if (!(camss->genpd_num > vfepd_num)) in camss_configure_pd()
1533 * If a power-domain name is defined try to use it. in camss_configure_pd()
1537 if (camss->res->pd_name) { in camss_configure_pd()
1538 camss->genpd = dev_pm_domain_attach_by_name(camss->dev, in camss_configure_pd()
1539 camss->res->pd_name); in camss_configure_pd()
1540 if (IS_ERR(camss->genpd)) { in camss_configure_pd()
1541 ret = PTR_ERR(camss->genpd); in camss_configure_pd()
1546 if (!camss->genpd) { in camss_configure_pd()
1549 * item in the power-domain list. in camss_configure_pd()
1551 camss->genpd = dev_pm_domain_attach_by_id(camss->dev, in camss_configure_pd()
1552 camss->genpd_num - 1); in camss_configure_pd()
1554 if (IS_ERR_OR_NULL(camss->genpd)) { in camss_configure_pd()
1555 if (!camss->genpd) in camss_configure_pd()
1556 ret = -ENODEV; in camss_configure_pd()
1558 ret = PTR_ERR(camss->genpd); in camss_configure_pd()
1561 camss->genpd_link = device_link_add(camss->dev, camss->genpd, in camss_configure_pd()
1564 if (!camss->genpd_link) { in camss_configure_pd()
1565 ret = -EINVAL; in camss_configure_pd()
1572 dev_pm_domain_detach(camss->genpd, true); in camss_configure_pd()
1582 icc_res = camss->res->icc_res; in camss_icc_get()
1584 for (i = 0; i < camss->res->icc_path_num; i++) { in camss_icc_get()
1585 camss->icc_path[i] = devm_of_icc_get(camss->dev, in camss_icc_get()
1587 if (IS_ERR(camss->icc_path[i])) in camss_icc_get()
1588 return PTR_ERR(camss->icc_path[i]); in camss_icc_get()
1598 for (i = 0; i < camss->res->vfe_num; i++) in camss_genpd_subdevice_cleanup()
1599 msm_vfe_genpd_cleanup(&camss->vfe[i]); in camss_genpd_subdevice_cleanup()
1604 if (camss->genpd_num == 1) in camss_genpd_cleanup()
1609 if (camss->genpd_link) in camss_genpd_cleanup()
1610 device_link_del(camss->genpd_link); in camss_genpd_cleanup()
1612 dev_pm_domain_detach(camss->genpd, true); in camss_genpd_cleanup()
1616 * camss_probe - Probe CAMSS platform device
1623 struct device *dev = &pdev->dev; in camss_probe()
1630 return -ENOMEM; in camss_probe()
1632 camss->res = of_device_get_match_data(dev); in camss_probe()
1634 atomic_set(&camss->ref_count, 0); in camss_probe()
1635 camss->dev = dev; in camss_probe()
1638 camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num, in camss_probe()
1639 sizeof(*camss->csiphy), GFP_KERNEL); in camss_probe()
1640 if (!camss->csiphy) in camss_probe()
1641 return -ENOMEM; in camss_probe()
1643 camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid), in camss_probe()
1645 if (!camss->csid) in camss_probe()
1646 return -ENOMEM; in camss_probe()
1648 if (camss->res->version == CAMSS_8x16 || in camss_probe()
1649 camss->res->version == CAMSS_8x96) { in camss_probe()
1650 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); in camss_probe()
1651 if (!camss->ispif) in camss_probe()
1652 return -ENOMEM; in camss_probe()
1655 camss->vfe = devm_kcalloc(dev, camss->res->vfe_num, in camss_probe()
1656 sizeof(*camss->vfe), GFP_KERNEL); in camss_probe()
1657 if (!camss->vfe) in camss_probe()
1658 return -ENOMEM; in camss_probe()
1678 camss->media_dev.dev = camss->dev; in camss_probe()
1679 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem", in camss_probe()
1680 sizeof(camss->media_dev.model)); in camss_probe()
1681 camss->media_dev.ops = &camss_media_ops; in camss_probe()
1682 media_device_init(&camss->media_dev); in camss_probe()
1684 camss->v4l2_dev.mdev = &camss->media_dev; in camss_probe()
1685 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev); in camss_probe()
1691 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); in camss_probe()
1704 camss->notifier.ops = &camss_subdev_notifier_ops; in camss_probe()
1706 ret = v4l2_async_nf_register(&camss->notifier); in camss_probe()
1714 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev); in camss_probe()
1721 ret = media_device_register(&camss->media_dev); in camss_probe()
1736 v4l2_device_unregister(&camss->v4l2_dev); in camss_probe()
1737 v4l2_async_nf_cleanup(&camss->notifier); in camss_probe()
1746 v4l2_device_unregister(&camss->v4l2_dev); in camss_delete()
1747 media_device_unregister(&camss->media_dev); in camss_delete()
1748 media_device_cleanup(&camss->media_dev); in camss_delete()
1750 pm_runtime_disable(camss->dev); in camss_delete()
1754 * camss_remove - Remove CAMSS platform device
1763 v4l2_async_nf_unregister(&camss->notifier); in camss_remove()
1764 v4l2_async_nf_cleanup(&camss->notifier); in camss_remove()
1767 if (atomic_read(&camss->ref_count) == 0) in camss_remove()
1830 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
1831 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
1832 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
1833 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
1834 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
1846 for (i = 0; i < camss->res->icc_path_num; i++) { in camss_runtime_suspend()
1847 ret = icc_set_bw(camss->icc_path[i], 0, 0); in camss_runtime_suspend()
1858 const struct resources_icc *icc_res = camss->res->icc_res; in camss_runtime_resume()
1862 for (i = 0; i < camss->res->icc_path_num; i++) { in camss_runtime_resume()
1863 ret = icc_set_bw(camss->icc_path[i], in camss_runtime_resume()
1883 .name = "qcom-camss",
1891 MODULE_ALIAS("platform:qcom-camss");