Lines Matching +full:msm8953 +full:- +full:camss
1 // SPDX-License-Identifier: GPL-2.0
3 * camss.c
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>
30 #include "camss.h"
744 .regulators = { "vdda-phy", "vdda-pll" },
761 .regulators = { "vdda-phy", "vdda-pll" },
778 .regulators = { "vdda-phy", "vdda-pll" },
899 /* VFE-lite */
1013 .regulators = { "vdda-phy", "vdda-pll" },
1038 .regulators = { "vdda-phy", "vdda-pll" },
1063 .regulators = { "vdda-phy", "vdda-pll" },
1145 /* VFE-lite */
1175 .regulators = { "vdda-phy", "vdda-pll" },
1188 .regulators = { "vdda-phy", "vdda-pll" },
1201 .regulators = { "vdda-phy", "vdda-pll" },
1214 .regulators = { "vdda-phy", "vdda-pll" },
1227 .regulators = { "vdda-phy", "vdda-pll" },
1240 .regulators = { "vdda-phy", "vdda-pll" },
1453 .regulators = { "vdda-phy", "vdda-pll" },
1467 .regulators = { "vdda-phy", "vdda-pll" },
1481 .regulators = { "vdda-phy", "vdda-pll" },
1495 .regulators = { "vdda-phy", "vdda-pll" },
1509 .regulators = { "vdda-phy", "vdda-pll" },
1817 .regulators = { "vdda-phy", "vdda-pll" },
1833 .regulators = { "vdda-phy", "vdda-pll" },
1849 .regulators = { "vdda-phy", "vdda-pll" },
1865 .regulators = { "vdda-phy", "vdda-pll" },
1881 .regulators = { "vdda-phy", "vdda-pll" },
1897 .regulators = { "vdda-phy", "vdda-pll" },
1913 .regulators = { "vdda-phy", "vdda-pll" },
1929 .regulators = { "vdda-phy", "vdda-pll" },
2130 .regulators = { "vdda-phy", "vdda-pll" },
2143 .regulators = { "vdda-phy", "vdda-pll" },
2156 .regulators = { "vdda-phy", "vdda-pll" },
2169 .regulators = { "vdda-phy", "vdda-pll" },
2182 .regulators = { "vdda-phy", "vdda-pll" },
2195 .regulators = { "vdda-phy", "vdda-pll" },
2208 .regulators = { "vdda-phy", "vdda-pll" },
2221 .regulators = { "vdda-phy", "vdda-pll" },
2449 * camss_add_clock_margin - Add margin to clock frequency rate
2462 * camss_enable_clocks - Enable multiple clocks
2486 for (i--; i >= 0; i--)
2493 * camss_disable_clocks - Disable multiple clocks
2501 for (i = nclocks - 1; i >= 0; i--)
2506 * camss_find_sensor_pad - Find the media pad via which the sensor is linked
2516 pad = &entity->pads[0];
2517 if (!(pad->flags & MEDIA_PAD_FL_SINK))
2521 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
2524 entity = pad->entity;
2526 if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
2532 * camss_get_link_freq - Get link frequency from sensor
2546 return -ENODEV;
2552 * camss_get_pixel_clock - Get pixel clock rate from sensor
2566 return -ENODEV;
2568 subdev = media_entity_to_v4l2_subdev(sensor_pad->entity);
2570 ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE);
2573 return -EINVAL;
2580 int camss_pm_domain_on(struct camss *camss, int id)
2584 if (id < camss->res->vfe_num) {
2585 struct vfe_device *vfe = &camss->vfe[id];
2587 ret = vfe->res->hw_ops->pm_domain_on(vfe);
2593 void camss_pm_domain_off(struct camss *camss, int id)
2595 if (id < camss->res->vfe_num) {
2596 struct vfe_device *vfe = &camss->vfe[id];
2598 vfe->res->hw_ops->pm_domain_off(vfe);
2602 static int vfe_parent_dev_ops_get(struct camss *camss, int id)
2604 int ret = -EINVAL;
2606 if (id < camss->res->vfe_num) {
2607 struct vfe_device *vfe = &camss->vfe[id];
2615 static int vfe_parent_dev_ops_put(struct camss *camss, int id)
2617 if (id < camss->res->vfe_num) {
2618 struct vfe_device *vfe = &camss->vfe[id];
2627 *vfe_parent_dev_ops_get_base_address(struct camss *camss, int id)
2629 if (id < camss->res->vfe_num) {
2630 struct vfe_device *vfe = &camss->vfe[id];
2632 return vfe->base;
2645 * camss_of_parse_endpoint_node - Parse port endpoint node
2656 struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg;
2666 csd->interface.csiphy_id = vep.base.port;
2669 lncfg->clk.pos = mipi_csi2->clock_lane;
2670 lncfg->clk.pol = mipi_csi2->lane_polarities[0];
2671 lncfg->num_data = mipi_csi2->num_data_lanes;
2673 lncfg->data = devm_kcalloc(dev,
2674 lncfg->num_data, sizeof(*lncfg->data),
2676 if (!lncfg->data)
2677 return -ENOMEM;
2679 for (i = 0; i < lncfg->num_data; i++) {
2680 lncfg->data[i].pos = mipi_csi2->data_lanes[i];
2681 lncfg->data[i].pol = mipi_csi2->lane_polarities[i + 1];
2688 * camss_of_parse_ports - Parse ports node
2694 static int camss_of_parse_ports(struct camss *camss)
2696 struct device *dev = camss->dev;
2701 for_each_endpoint_of_node(dev->of_node, node) {
2710 ret = -EINVAL;
2714 csd = v4l2_async_nf_add_fwnode(&camss->notifier,
2738 * camss_init_subdevices - Initialize subdev structures and resources
2739 * @camss: CAMSS device
2743 static int camss_init_subdevices(struct camss *camss)
2745 struct platform_device *pdev = to_platform_device(camss->dev);
2746 const struct camss_resources *res = camss->res;
2750 for (i = 0; i < camss->res->csiphy_num; i++) {
2751 ret = msm_csiphy_subdev_init(camss, &camss->csiphy[i],
2752 &res->csiphy_res[i], i);
2754 dev_err(camss->dev,
2755 "Failed to init csiphy%d sub-device: %d\n",
2762 for (i = 0; i < camss->res->vfe_num; i++) {
2763 ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
2764 &res->vfe_res[i], i);
2766 dev_err(camss->dev,
2767 "Fail to init vfe%d sub-device: %d\n", i, ret);
2773 if (res->csid_wrapper_res) {
2774 char *reg = res->csid_wrapper_res->reg;
2780 camss->csid_wrapper_base = base;
2783 for (i = 0; i < camss->res->csid_num; i++) {
2784 ret = msm_csid_subdev_init(camss, &camss->csid[i],
2785 &res->csid_res[i], i);
2787 dev_err(camss->dev,
2788 "Failed to init csid%d sub-device: %d\n",
2794 ret = msm_ispif_subdev_init(camss, res->ispif_res);
2796 dev_err(camss->dev, "Failed to init ispif sub-device: %d\n",
2805 * camss_link_entities - Register subdev nodes and create links
2806 * camss_link_err - print error in case link creation fails
2810 inline void camss_link_err(struct camss *camss,
2815 dev_err(camss->dev,
2816 "Failed to link %s->%s entities: %d\n",
2823 * camss_link_entities - Register subdev nodes and create links
2824 * @camss: CAMSS device
2828 static int camss_link_entities(struct camss *camss)
2833 for (i = 0; i < camss->res->csiphy_num; i++) {
2834 for (j = 0; j < camss->res->csid_num; j++) {
2835 ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
2837 &camss->csid[j].subdev.entity,
2841 camss_link_err(camss,
2842 camss->csiphy[i].subdev.entity.name,
2843 camss->csid[j].subdev.entity.name,
2850 if (camss->ispif) {
2851 for (i = 0; i < camss->res->csid_num; i++) {
2852 for (j = 0; j < camss->ispif->line_num; j++) {
2853 ret = media_create_pad_link(&camss->csid[i].subdev.entity,
2855 &camss->ispif->line[j].subdev.entity,
2859 camss_link_err(camss,
2860 camss->csid[i].subdev.entity.name,
2861 camss->ispif->line[j].subdev.entity.name,
2868 for (i = 0; i < camss->ispif->line_num; i++)
2869 for (k = 0; k < camss->res->vfe_num; k++)
2870 for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2871 struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
2872 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2874 ret = media_create_pad_link(&ispif->entity,
2876 &vfe->entity,
2880 camss_link_err(camss, ispif->entity.name,
2881 vfe->entity.name,
2887 for (i = 0; i < camss->res->csid_num; i++)
2888 for (k = 0; k < camss->res->vfe_num; k++)
2889 for (j = 0; j < camss->vfe[k].res->line_num; j++) {
2890 struct v4l2_subdev *csid = &camss->csid[i].subdev;
2891 struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
2893 ret = media_create_pad_link(&csid->entity,
2895 &vfe->entity,
2899 camss_link_err(camss, csid->entity.name,
2900 vfe->entity.name,
2910 void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
2914 if (hw_id < camss->res->csid_num) {
2915 csid = &camss->csid[hw_id];
2917 csid->res->hw_ops->reg_update(csid, port_id, is_clear);
2921 void camss_buf_done(struct camss *camss, int hw_id, int port_id)
2925 if (hw_id < camss->res->vfe_num) {
2926 vfe = &camss->vfe[hw_id];
2928 vfe->res->hw_ops->vfe_buf_done(vfe, port_id);
2933 * camss_register_entities - Register subdev nodes and create links
2934 * @camss: CAMSS device
2938 static int camss_register_entities(struct camss *camss)
2943 for (i = 0; i < camss->res->csiphy_num; i++) {
2944 ret = msm_csiphy_register_entity(&camss->csiphy[i],
2945 &camss->v4l2_dev);
2947 dev_err(camss->dev,
2954 for (i = 0; i < camss->res->csid_num; i++) {
2955 ret = msm_csid_register_entity(&camss->csid[i],
2956 &camss->v4l2_dev);
2958 dev_err(camss->dev,
2965 ret = msm_ispif_register_entities(camss->ispif,
2966 &camss->v4l2_dev);
2968 dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret);
2972 for (i = 0; i < camss->res->vfe_num; i++) {
2973 ret = msm_vfe_register_entities(&camss->vfe[i],
2974 &camss->v4l2_dev);
2976 dev_err(camss->dev,
2986 for (i--; i >= 0; i--)
2987 msm_vfe_unregister_entities(&camss->vfe[i]);
2990 msm_ispif_unregister_entities(camss->ispif);
2992 i = camss->res->csid_num;
2994 for (i--; i >= 0; i--)
2995 msm_csid_unregister_entity(&camss->csid[i]);
2997 i = camss->res->csiphy_num;
2999 for (i--; i >= 0; i--)
3000 msm_csiphy_unregister_entity(&camss->csiphy[i]);
3006 * camss_unregister_entities - Unregister subdev nodes
3007 * @camss: CAMSS device
3011 static void camss_unregister_entities(struct camss *camss)
3015 for (i = 0; i < camss->res->csiphy_num; i++)
3016 msm_csiphy_unregister_entity(&camss->csiphy[i]);
3018 for (i = 0; i < camss->res->csid_num; i++)
3019 msm_csid_unregister_entity(&camss->csid[i]);
3021 msm_ispif_unregister_entities(camss->ispif);
3023 for (i = 0; i < camss->res->vfe_num; i++)
3024 msm_vfe_unregister_entities(&camss->vfe[i]);
3031 struct camss *camss = container_of(async, struct camss, notifier);
3034 u8 id = csd->interface.csiphy_id;
3035 struct csiphy_device *csiphy = &camss->csiphy[id];
3037 csiphy->cfg.csi2 = &csd->interface.csi2;
3038 subdev->host_priv = csiphy;
3045 struct camss *camss = container_of(async, struct camss, notifier);
3046 struct v4l2_device *v4l2_dev = &camss->v4l2_dev;
3050 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
3051 if (sd->host_priv) {
3052 struct media_entity *sensor = &sd->entity;
3054 (struct csiphy_device *) sd->host_priv;
3055 struct media_entity *input = &csiphy->subdev.entity;
3058 for (i = 0; i < sensor->num_pads; i++) {
3059 if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
3062 if (i == sensor->num_pads) {
3063 dev_err(camss->dev,
3065 return -EINVAL;
3072 camss_link_err(camss, sensor->name,
3073 input->name,
3080 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3084 return media_device_register(&camss->media_dev);
3096 static int camss_configure_pd(struct camss *camss)
3098 const struct camss_resources *res = camss->res;
3099 struct device *dev = camss->dev;
3104 camss->genpd_num = of_count_phandle_with_args(dev->of_node,
3105 "power-domains",
3106 "#power-domain-cells");
3107 if (camss->genpd_num < 0) {
3108 dev_err(dev, "Power domains are not defined for camss\n");
3109 return camss->genpd_num;
3115 * option to attach it again, this is the case for CAMSS on MSM8916.
3117 if (camss->genpd_num == 1)
3120 /* count the # of VFEs which have flagged power-domain */
3121 for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
3122 if (res->vfe_res[i].vfe.has_pd)
3127 * If the number of power-domains is greater than the number of VFEs
3128 * then the additional power-domain is for the entire CAMSS block.
3130 if (!(camss->genpd_num > vfepd_num))
3134 * If a power-domain name is defined try to use it.
3138 if (camss->res->pd_name) {
3139 camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
3140 camss->res->pd_name);
3141 if (IS_ERR(camss->genpd))
3142 return PTR_ERR(camss->genpd);
3145 if (!camss->genpd) {
3148 * item in the power-domain list.
3150 camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
3151 camss->genpd_num - 1);
3152 if (IS_ERR(camss->genpd))
3153 return PTR_ERR(camss->genpd);
3156 if (!camss->genpd)
3157 return -ENODEV;
3159 camss->genpd_link = device_link_add(camss->dev, camss->genpd,
3162 if (!camss->genpd_link) {
3163 ret = -EINVAL;
3170 dev_pm_domain_detach(camss->genpd, true);
3175 static int camss_icc_get(struct camss *camss)
3180 icc_res = camss->res->icc_res;
3182 for (i = 0; i < camss->res->icc_path_num; i++) {
3183 camss->icc_path[i] = devm_of_icc_get(camss->dev,
3185 if (IS_ERR(camss->icc_path[i]))
3186 return PTR_ERR(camss->icc_path[i]);
3192 static void camss_genpd_subdevice_cleanup(struct camss *camss)
3196 for (i = 0; i < camss->res->vfe_num; i++)
3197 msm_vfe_genpd_cleanup(&camss->vfe[i]);
3200 static void camss_genpd_cleanup(struct camss *camss)
3202 if (camss->genpd_num == 1)
3205 camss_genpd_subdevice_cleanup(camss);
3207 if (camss->genpd_link)
3208 device_link_del(camss->genpd_link);
3210 dev_pm_domain_detach(camss->genpd, true);
3214 * camss_probe - Probe CAMSS platform device
3215 * @pdev: Pointer to CAMSS platform device
3221 struct device *dev = &pdev->dev;
3222 struct camss *camss;
3226 camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
3227 if (!camss)
3228 return -ENOMEM;
3230 camss->res = of_device_get_match_data(dev);
3232 atomic_set(&camss->ref_count, 0);
3233 camss->dev = dev;
3234 platform_set_drvdata(pdev, camss);
3236 camss->csiphy = devm_kcalloc(dev, camss->res->csiphy_num,
3237 sizeof(*camss->csiphy), GFP_KERNEL);
3238 if (!camss->csiphy)
3239 return -ENOMEM;
3241 camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
3243 if (!camss->csid)
3244 return -ENOMEM;
3246 if (camss->res->version == CAMSS_8x16 ||
3247 camss->res->version == CAMSS_8x53 ||
3248 camss->res->version == CAMSS_8x96) {
3249 camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
3250 if (!camss->ispif)
3251 return -ENOMEM;
3254 camss->vfe = devm_kcalloc(dev, camss->res->vfe_num,
3255 sizeof(*camss->vfe), GFP_KERNEL);
3256 if (!camss->vfe)
3257 return -ENOMEM;
3259 ret = camss_icc_get(camss);
3263 ret = camss_configure_pd(camss);
3269 ret = camss_init_subdevices(camss);
3277 camss->media_dev.dev = camss->dev;
3278 strscpy(camss->media_dev.model, "Qualcomm Camera Subsystem",
3279 sizeof(camss->media_dev.model));
3280 camss->media_dev.ops = &camss_media_ops;
3281 media_device_init(&camss->media_dev);
3283 camss->v4l2_dev.mdev = &camss->media_dev;
3284 ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
3290 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
3294 num_subdevs = camss_of_parse_ports(camss);
3300 ret = camss_register_entities(camss);
3304 ret = camss->res->link_entities(camss);
3309 camss->notifier.ops = &camss_subdev_notifier_ops;
3311 ret = v4l2_async_nf_register(&camss->notifier);
3319 ret = v4l2_device_register_subdev_nodes(&camss->v4l2_dev);
3326 ret = media_device_register(&camss->media_dev);
3337 camss_unregister_entities(camss);
3339 v4l2_device_unregister(&camss->v4l2_dev);
3340 v4l2_async_nf_cleanup(&camss->notifier);
3343 camss_genpd_cleanup(camss);
3348 void camss_delete(struct camss *camss)
3350 v4l2_device_unregister(&camss->v4l2_dev);
3351 media_device_unregister(&camss->media_dev);
3352 media_device_cleanup(&camss->media_dev);
3354 pm_runtime_disable(camss->dev);
3358 * camss_remove - Remove CAMSS platform device
3359 * @pdev: Pointer to CAMSS platform device
3365 struct camss *camss = platform_get_drvdata(pdev);
3367 v4l2_async_nf_unregister(&camss->notifier);
3368 v4l2_async_nf_cleanup(&camss->notifier);
3369 camss_unregister_entities(camss);
3371 if (atomic_read(&camss->ref_count) == 0)
3372 camss_delete(camss);
3374 camss_genpd_cleanup(camss);
3509 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
3510 { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
3511 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
3512 { .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
3513 { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
3514 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
3515 { .compatible = "qcom,sdm670-camss", .data = &sdm670_resources },
3516 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
3517 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
3518 { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
3526 struct camss *camss = dev_get_drvdata(dev);
3530 for (i = 0; i < camss->res->icc_path_num; i++) {
3531 ret = icc_set_bw(camss->icc_path[i], 0, 0);
3541 struct camss *camss = dev_get_drvdata(dev);
3542 const struct resources_icc *icc_res = camss->res->icc_res;
3546 for (i = 0; i < camss->res->icc_path_num; i++) {
3547 ret = icc_set_bw(camss->icc_path[i],
3567 .name = "qcom-camss",
3575 MODULE_ALIAS("platform:qcom-camss");