From: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
To: Robert Foss <rfoss@kernel.org>, Todor Tomov <todor.too@gmail.com>,
Bryan O'Donoghue <bryan.odonoghue@linaro.org>,
Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linux-arm-msm@vger.kernel.org,
Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
Subject: [PATCH v8 2/3] media: qcom: camss: Add link support for TPG
Date: Tue, 13 Jan 2026 17:03:27 +0800 [thread overview]
Message-ID: <20260113-camss_tpg-v8-2-fa2cb186a018@oss.qualcomm.com> (raw)
In-Reply-To: <20260113-camss_tpg-v8-0-fa2cb186a018@oss.qualcomm.com>
TPG is connected to the csid as an entity, the link
needs to be adapted.
Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss-csid.c | 45 +++++++++++++------
drivers/media/platform/qcom/camss/camss-csid.h | 1 +
drivers/media/platform/qcom/camss/camss-csiphy.c | 1 +
drivers/media/platform/qcom/camss/camss-csiphy.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 55 ++++++++++++++++++++++++
5 files changed, 90 insertions(+), 14 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 5284b5857368c37c202cd89dad6ae8042b637537..42fb299a655354face660308c3d535b09caa8ed2 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -35,6 +35,8 @@
#define HW_VERSION_REVISION 16
#define HW_VERSION_GENERATION 28
+#define LANE_CFG_BITWIDTH 4
+
#define MSM_CSID_NAME "msm_csid"
const char * const csid_testgen_modes[] = {
@@ -1227,18 +1229,22 @@ void msm_csid_get_csid_id(struct media_entity *entity, u8 *id)
}
/*
- * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter
- * @lane_cfg - CSI2 lane configuration
+ * csid_get_lane_assign - Calculate lane assign by csiphy/tpg lane num
+ * @num: lane num
+ * @pos_array: Array of lane positions
*
* Return lane assign
*/
-static u32 csid_get_lane_assign(struct csiphy_lanes_cfg *lane_cfg)
+static u32 csid_get_lane_assign(struct csiphy_lanes_cfg *lane_cfg, int num_lanes)
{
u32 lane_assign = 0;
+ int pos;
int i;
- for (i = 0; i < lane_cfg->num_data; i++)
- lane_assign |= lane_cfg->data[i].pos << (i * 4);
+ for (i = 0; i < num_lanes; i++) {
+ pos = lane_cfg ? lane_cfg->data[i].pos : i;
+ lane_assign |= pos << (i * LANE_CFG_BITWIDTH);
+ }
return lane_assign;
}
@@ -1263,6 +1269,7 @@ static int csid_link_setup(struct media_entity *entity,
if ((local->flags & MEDIA_PAD_FL_SINK) &&
(flags & MEDIA_LNK_FL_ENABLED)) {
struct v4l2_subdev *sd;
+ struct tpg_device *tpg;
struct csid_device *csid;
struct csiphy_device *csiphy;
struct csiphy_lanes_cfg *lane_cfg;
@@ -1277,18 +1284,28 @@ 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 (sd->grp_id == TPG_GUP_ID) {
+ 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_lane_assign(NULL, csid->phy.lane_cnt);
+ csid->tpg_linked = true;
+ } else {
+ csiphy = v4l2_get_subdevdata(sd);
- csid->phy.csiphy_id = csiphy->id;
+ /* If a sensor is not linked to CSIPHY */
+ /* do no allow a link from CSIPHY to CSID */
+ if (!csiphy->cfg.csi2)
+ return -EPERM;
- 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);
+ 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->num_data);
+ csid->tpg_linked = false;
+ }
}
/* 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-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index aedc96ed84b2fcc3f352160dcfd31554a671d0fc..5296b10f6bac839a3faa1039bdbf0fbbbe9456ac 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -161,6 +161,7 @@ struct csid_device {
int num_supplies;
struct completion reset_complete;
struct csid_testgen_config testgen;
+ bool tpg_linked;
struct csid_phy_config phy;
struct v4l2_mbus_framefmt fmt[MSM_CSID_PADS_NUM];
struct v4l2_ctrl_handler ctrls;
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index a734fb7dde0a492cf6e33f53e379557665d54f64..c15990d9d09cc8f9960729bdc112d81751b4938c 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -800,6 +800,7 @@ int msm_csiphy_register_entity(struct csiphy_device *csiphy,
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
MSM_CSIPHY_NAME, csiphy->id);
+ sd->grp_id = CSIPHY_GUP_ID;
v4l2_set_subdevdata(sd, csiphy);
ret = csiphy_init_formats(sd, NULL);
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
index 895f80003c441dcacf98435f91567f90afa29279..b7bcf2bdd2124f77b5354b15b33aa1e0983143e8 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -21,6 +21,8 @@
#define MSM_CSIPHY_PAD_SRC 1
#define MSM_CSIPHY_PADS_NUM 2
+#define CSIPHY_GUP_ID 1
+
struct csiphy_lane {
u8 pos;
u8 pol;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index fcc2b2c3cba076e598bc8aacd34efce5d71713ca..43fdcb9af101ef34b118035ca9c68757b66118df 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -4145,6 +4145,19 @@ static int camss_init_subdevices(struct camss *camss)
}
}
+ 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;
+ }
+ }
+ }
+
/* note: SM8250 requires VFE to be initialized before CSID */
for (i = 0; i < camss->res->vfe_num; i++) {
ret = msm_vfe_subdev_init(camss, &camss->vfe[i],
@@ -4233,6 +4246,23 @@ static int camss_link_entities(struct camss *camss)
}
}
+ 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++) {
@@ -4337,6 +4367,19 @@ static int camss_register_entities(struct camss *camss)
}
}
+ 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->csid_num; i++) {
ret = msm_csid_register_entity(&camss->csid[i],
&camss->v4l2_dev);
@@ -4380,6 +4423,13 @@ static int camss_register_entities(struct camss *camss)
for (i--; i >= 0; i--)
msm_csid_unregister_entity(&camss->csid[i]);
+ i = camss->res->tpg_num;
+err_reg_tpg:
+ if (camss->tpg) {
+ for (i--; i >= 0; i--)
+ msm_tpg_unregister_entity(&camss->tpg[i]);
+ }
+
i = camss->res->csiphy_num;
err_reg_csiphy:
for (i--; i >= 0; i--)
@@ -4401,6 +4451,11 @@ static void camss_unregister_entities(struct camss *camss)
for (i = 0; i < camss->res->csiphy_num; i++)
msm_csiphy_unregister_entity(&camss->csiphy[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->csid_num; i++)
msm_csid_unregister_entity(&camss->csid[i]);
--
2.34.1
next prev parent reply other threads:[~2026-01-13 9:03 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-13 9:03 [PATCH v8 0/3] media: qcom: camss: Add camss TPG support for multiple targets Wenmeng Liu
2026-01-13 9:03 ` [PATCH v8 1/3] media: qcom: camss: Add common TPG support Wenmeng Liu
2026-01-13 16:27 ` Vladimir Zapolskiy
2026-01-14 3:04 ` Wenmeng Liu
2026-01-14 5:05 ` Vladimir Zapolskiy
2026-01-14 9:43 ` Konrad Dybcio
2026-01-14 12:18 ` Wenmeng Liu
2026-01-14 22:07 ` Vladimir Zapolskiy
2026-01-15 1:06 ` Bryan O'Donoghue
2026-01-15 2:58 ` Vladimir Zapolskiy
2026-01-15 15:54 ` Bryan O'Donoghue
2026-01-16 9:24 ` Vladimir Zapolskiy
2026-01-19 9:59 ` Bryan O'Donoghue
2026-01-13 9:03 ` Wenmeng Liu [this message]
2026-01-13 9:03 ` [PATCH v8 3/3] media: qcom: camss: tpg: Add TPG support for multiple targets Wenmeng Liu
2026-01-15 15:48 ` kernel test robot
2026-01-16 19:32 ` Vijay Kumar Tumati
2026-01-19 3:29 ` Wenmeng Liu
2026-01-21 18:45 ` Vijay Kumar Tumati
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260113-camss_tpg-v8-2-fa2cb186a018@oss.qualcomm.com \
--to=wenmeng.liu@oss.qualcomm.com \
--cc=bryan.odonoghue@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=rfoss@kernel.org \
--cc=todor.too@gmail.com \
--cc=vladimir.zapolskiy@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®