TPG is connected to the csid as an entity, the link code needs to be adapted. Signed-off-by: Wenmeng Liu <quic_wenmliu@xxxxxxxxxxx> --- drivers/media/platform/qcom/camss/camss-csid.c | 44 ++++++++++++++++---- drivers/media/platform/qcom/camss/camss.c | 57 ++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index e26a69a454a759a6b156b8c736348a0fa4a838b6..2504cf41144d482eb3ad9c91387d4da7db421568 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -1225,6 +1225,23 @@ void msm_csid_get_csid_id(struct media_entity *entity, u8 *id) *id = csid->id; } +/* + * csid_get_csiphy_tpg_lane_assign - Calculate lane assign by tpg lane num + * @num - tpg lane num + * + * Return lane assign + */ +static u32 csid_get_csiphy_tpg_lane_assign(int num) +{ + u32 lane_assign = 0; + int i; + + for (i = (num - 1); i >= 0; i--) + lane_assign |= i << (i * 4); + + return lane_assign; +} + /* * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter * @lane_cfg - CSI2 lane configuration @@ -1265,6 +1282,7 @@ static int csid_link_setup(struct media_entity *entity, struct csid_device *csid; struct csiphy_device *csiphy; struct csiphy_lanes_cfg *lane_cfg; + struct tpg_device *tpg; sd = media_entity_to_v4l2_subdev(entity); csid = v4l2_get_subdevdata(sd); @@ -1276,18 +1294,26 @@ static int csid_link_setup(struct media_entity *entity, return -EBUSY; sd = media_entity_to_v4l2_subdev(remote->entity); - csiphy = v4l2_get_subdevdata(sd); + if (strnstr(sd->name, MSM_TPG_NAME, strlen(MSM_TPG_NAME))) { + tpg = v4l2_get_subdevdata(sd); - /* If a sensor is not linked to CSIPHY */ - /* do no allow a link from CSIPHY to CSID */ - if (!csiphy->cfg.csi2) - return -EPERM; + csid->phy.lane_cnt = tpg->res->lane_cnt; + csid->phy.csiphy_id = tpg->id; + csid->phy.lane_assign = csid_get_csiphy_tpg_lane_assign(csid->phy.lane_cnt); + } else { + csiphy = v4l2_get_subdevdata(sd); + + /* If a sensor is not linked to CSIPHY */ + /* do no allow a link from CSIPHY to CSID */ + if (!csiphy->cfg.csi2) + return -EPERM; - csid->phy.csiphy_id = csiphy->id; + csid->phy.csiphy_id = csiphy->id; - lane_cfg = &csiphy->cfg.csi2->lane_cfg; - csid->phy.lane_cnt = lane_cfg->num_data; - csid->phy.lane_assign = csid_get_lane_assign(lane_cfg); + lane_cfg = &csiphy->cfg.csi2->lane_cfg; + csid->phy.lane_cnt = lane_cfg->num_data; + csid->phy.lane_assign = csid_get_lane_assign(lane_cfg); + } } /* Decide which virtual channels to enable based on which source pads are enabled */ if (local->flags & MEDIA_PAD_FL_SOURCE) { diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 4df31c89c20c6d87d9564f217489181cb044abff..1efcc7a5ee62c7aa644b2390832b6f1f29cc69ff 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -3038,6 +3038,19 @@ static int camss_init_subdevices(struct camss *camss) return ret; } + if (camss->tpg) { + for (i = 0; i < camss->res->tpg_num; i++) { + ret = msm_tpg_subdev_init(camss, &camss->tpg[i], + &res->tpg_res[i], i); + if (ret < 0) { + dev_err(camss->dev, + "Failed to init tpg%d sub-device: %d\n", + i, ret); + return ret; + } + } + } + return 0; } @@ -3087,6 +3100,25 @@ static int camss_link_entities(struct camss *camss) } } + if (camss->tpg) { + for (i = 0; i < camss->res->tpg_num; i++) { + for (j = 0; j < camss->res->csid_num; j++) { + ret = media_create_pad_link(&camss->tpg[i].subdev.entity, + MSM_TPG_PAD_SRC, + &camss->csid[j].subdev.entity, + MSM_CSID_PAD_SINK, + 0); + if (ret < 0) { + camss_link_err(camss, + camss->tpg[i].subdev.entity.name, + camss->csid[j].subdev.entity.name, + ret); + return ret; + } + } + } + } + if (camss->ispif) { for (i = 0; i < camss->res->csid_num; i++) { for (j = 0; j < camss->ispif->line_num; j++) { @@ -3180,6 +3212,19 @@ static int camss_register_entities(struct camss *camss) int i; int ret; + if (camss->tpg) { + for (i = 0; i < camss->res->tpg_num; i++) { + ret = msm_tpg_register_entity(&camss->tpg[i], + &camss->v4l2_dev); + if (ret < 0) { + dev_err(camss->dev, + "Failed to register tpg%d entity: %d\n", + i, ret); + goto err_reg_tpg; + } + } + } + for (i = 0; i < camss->res->csiphy_num; i++) { ret = msm_csiphy_register_entity(&camss->csiphy[i], &camss->v4l2_dev); @@ -3239,6 +3284,13 @@ static int camss_register_entities(struct camss *camss) for (i--; i >= 0; i--) msm_csiphy_unregister_entity(&camss->csiphy[i]); + i = camss->res->tpg_num; +err_reg_tpg: + if (camss->tpg) { + for (i--; i >= 0; i--) + msm_tpg_unregister_entity(&camss->tpg[i]); + } + return ret; } @@ -3252,6 +3304,11 @@ static void camss_unregister_entities(struct camss *camss) { unsigned int i; + if (camss->tpg) { + for (i = 0; i < camss->res->tpg_num; i++) + msm_tpg_unregister_entity(&camss->tpg[i]); + } + for (i = 0; i < camss->res->csiphy_num; i++) msm_csiphy_unregister_entity(&camss->csiphy[i]); -- 2.34.1