From 9d33b779b0739720a11522e41e26366403ffbb75 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 01/15] FROMLIST: media: qcom: camss: csiphy: Introduce PHY configuration Read PHY configuration from the device-tree bus-type and save it into the csiphy structure for later use. For C-PHY, skip clock line configuration, as there is none. Link: https://lore.kernel.org/all/20260301-qcom-cphy-v4-1-e53316d2cc65@ixit.cz/ Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../media/platform/qcom/camss/camss-csiphy.h | 2 ++ drivers/media/platform/qcom/camss/camss.c | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 1879826034aac..e8a7445f146db 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -31,11 +31,13 @@ struct csiphy_lane { /** * struct csiphy_lanes_cfg - CSIPHY lanes configuration + * @phy_cfg: interface selection (C-PHY or D-PHY) * @num_data: number of data lanes * @data: data lanes configuration * @clk: clock lane configuration (only for D-PHY) */ struct csiphy_lanes_cfg { + enum v4l2_mbus_type phy_cfg; int num_data; struct csiphy_lane *data; struct csiphy_lane clk; diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 3a45271c33a62..533461eb7dc6f 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4564,11 +4564,11 @@ static int camss_parse_endpoint_node(struct device *dev, if (ret) return ret; - /* - * Most SoCs support both D-PHY and C-PHY standards, but currently only - * D-PHY is supported in the driver. - */ - if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) { + switch (vep.bus_type) { + case V4L2_MBUS_CSI2_CPHY: + case V4L2_MBUS_CSI2_DPHY: + break; + default: dev_err(dev, "Unsupported bus type %d\n", vep.bus_type); return -EINVAL; } @@ -4576,9 +4576,13 @@ static int camss_parse_endpoint_node(struct device *dev, csd->interface.csiphy_id = vep.base.port; mipi_csi2 = &vep.bus.mipi_csi2; - lncfg->clk.pos = mipi_csi2->clock_lane; - lncfg->clk.pol = mipi_csi2->lane_polarities[0]; lncfg->num_data = mipi_csi2->num_data_lanes; + lncfg->phy_cfg = vep.bus_type; + + if (lncfg->phy_cfg != V4L2_MBUS_CSI2_CPHY) { + lncfg->clk.pos = mipi_csi2->clock_lane; + lncfg->clk.pol = mipi_csi2->lane_polarities[0]; + } lncfg->data = devm_kcalloc(dev, lncfg->num_data, sizeof(*lncfg->data), From 4a47a1eab8b87120df07897bcfe27633630eb335 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 02/15] FROMLIST: media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes So far, only D-PHY mode was supported, which uses even bits when enabling or masking lanes. For C-PHY configuration, the hardware instead requires using the odd bits. Since there can be unrecognized configuration allow returning failure. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-2-e53316d2cc65@ixit.cz/ Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-2ph-1-0.c | 8 +-- .../qcom/camss/camss-csiphy-3ph-1-0.c | 49 ++++++++++++++----- .../media/platform/qcom/camss/camss-csiphy.c | 5 +- .../media/platform/qcom/camss/camss-csiphy.h | 6 +-- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c index 9d67e7fa6366a..bb4b91f69616b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c @@ -94,9 +94,9 @@ static u8 csiphy_settle_cnt_calc(s64 link_freq, u32 timer_clk_rate) return settle_cnt; } -static void csiphy_lanes_enable(struct csiphy_device *csiphy, - struct csiphy_config *cfg, - s64 link_freq, u8 lane_mask) +static int csiphy_lanes_enable(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + s64 link_freq, u8 lane_mask) { struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; u8 settle_cnt; @@ -132,6 +132,8 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, writel_relaxed(0x3f, csiphy->base + CAMSS_CSI_PHY_INTERRUPT_CLEARn(l)); } + + return 0; } static void csiphy_lanes_disable(struct csiphy_device *csiphy, diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index babf7e663bdd3..baf7bb7805a85 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -14,6 +14,7 @@ #include #include #include +#include #define CSIPHY_3PH_LNn_CFG1(n) (0x000 + 0x100 * (n)) #define CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG (BIT(7) | BIT(6)) @@ -993,13 +994,22 @@ static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy, static u8 csiphy_get_lane_mask(struct csiphy_lanes_cfg *lane_cfg) { - u8 lane_mask; - int i; + u8 lane_mask = 0; - lane_mask = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; + switch (lane_cfg->phy_cfg) { + case V4L2_MBUS_CSI2_CPHY: + for (int i = 0; i < lane_cfg->num_data; i++) + lane_mask |= BIT(lane_cfg->data[i].pos + 1); + break; + case V4L2_MBUS_CSI2_DPHY: + lane_mask = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; - for (i = 0; i < lane_cfg->num_data; i++) - lane_mask |= 1 << lane_cfg->data[i].pos; + for (int i = 0; i < lane_cfg->num_data; i++) + lane_mask |= BIT(lane_cfg->data[i].pos); + break; + default: + break; + } return lane_mask; } @@ -1029,10 +1039,11 @@ static bool csiphy_is_gen2(u32 version) return ret; } -static void csiphy_lanes_enable(struct csiphy_device *csiphy, - struct csiphy_config *cfg, - s64 link_freq, u8 lane_mask) +static int csiphy_lanes_enable(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + s64 link_freq, u8 lane_mask) { + struct device *dev = csiphy->camss->dev; struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; struct csiphy_device_regs *regs = csiphy->regs; u8 settle_cnt; @@ -1041,9 +1052,23 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate); - val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; - for (i = 0; i < c->num_data; i++) - val |= BIT(c->data[i].pos * 2); + val = 0; + + switch (c->phy_cfg) { + case V4L2_MBUS_CSI2_CPHY: + for (i = 0; i < c->num_data; i++) + val |= BIT((c->data[i].pos * 2) + 1); + break; + case V4L2_MBUS_CSI2_DPHY: + val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL5_CLK_ENABLE; + + for (i = 0; i < c->num_data; i++) + val |= BIT(c->data[i].pos * 2); + break; + default: + dev_err(dev, "Unsupported bus type %d\n", c->phy_cfg); + return -EINVAL; + } writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 5)); @@ -1070,6 +1095,8 @@ static void csiphy_lanes_enable(struct csiphy_device *csiphy, writel_relaxed(0, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, i)); } + + return 0; } static void csiphy_lanes_disable(struct csiphy_device *csiphy, diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index b9f7d6573a0f0..a67924787b7d3 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -267,6 +267,7 @@ static int csiphy_set_power_legacy(struct v4l2_subdev *sd, int on) static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) { struct csiphy_config *cfg = &csiphy->cfg; + const struct csiphy_hw_ops *ops = csiphy->res->hw_ops; s64 link_freq; u8 lane_mask = csiphy->res->hw_ops->get_lane_mask(&cfg->csi2->lane_cfg); u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, @@ -297,9 +298,7 @@ static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) wmb(); } - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask); - - return 0; + return ops->lanes_enable(csiphy, cfg, link_freq, lane_mask); } /* diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index e8a7445f146db..8643ab57c3786 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -76,9 +76,9 @@ struct csiphy_hw_ops { void (*hw_version_read)(struct csiphy_device *csiphy, struct device *dev); void (*reset)(struct csiphy_device *csiphy); - void (*lanes_enable)(struct csiphy_device *csiphy, - struct csiphy_config *cfg, - s64 link_freq, u8 lane_mask); + int (*lanes_enable)(struct csiphy_device *csiphy, + struct csiphy_config *cfg, + s64 link_freq, u8 lane_mask); void (*lanes_disable)(struct csiphy_device *csiphy, struct csiphy_config *cfg); irqreturn_t (*isr)(int irq, void *dev); From 63affc4dc4bd5dc31ff080f11f2a6a6ba49d7ffb Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 03/15] FROMLIST: media: qcom: camss: Prepare CSID for C-PHY support Inherit C-PHY information from CSIPHY, so we can configure CSID properly. CSI2_RX_CFG0_PHY_TYPE_SEL must be set to 1, when C-PHY mode is used. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-3-e53316d2cc65@ixit.cz Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- drivers/media/platform/qcom/camss/camss-csid-gen2.c | 1 + drivers/media/platform/qcom/camss/camss-csid.c | 1 + drivers/media/platform/qcom/camss/camss-csid.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c index 2a1746dcc1c5b..033036ae28a4f 100644 --- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c +++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c @@ -183,6 +183,7 @@ static void __csid_configure_rx(struct csid_device *csid, val = (lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES; val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL; val |= phy->csiphy_id << CSI2_RX_CFG0_PHY_NUM_SEL; + val |= csid->phy.cphy << CSI2_RX_CFG0_PHY_TYPE_SEL; writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0); val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN; diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 48459b46a981b..71f2bb75c3bdd 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -1290,6 +1290,7 @@ static int csid_link_setup(struct media_entity *entity, csid->phy.csiphy_id = csiphy->id; lane_cfg = &csiphy->cfg.csi2->lane_cfg; + csid->phy.cphy = (lane_cfg->phy_cfg == V4L2_MBUS_CSI2_CPHY); 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; diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h index 5296b10f6bac8..00e2669db64c9 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.h +++ b/drivers/media/platform/qcom/camss/camss-csid.h @@ -70,6 +70,7 @@ struct csid_phy_config { u32 lane_assign; u32 en_vc; u8 need_vc_update; + bool cphy; }; struct csid_device; From b6202dfc5e6dad5609cb0cd395720b62ca63f98a Mon Sep 17 00:00:00 2001 From: Petr Hodina Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 04/15] FROMLIST: media: qcom: camss: Initialize lanes after lane configuration is available The lanes must not be initialized before the driver has access to the lane configuration, as it depends on whether D-PHY or C-PHY mode is in use. Move the lane initialization to a later stage where the configuration structures are available. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-4-e53316d2cc65@ixit.cz Signed-off-by: Petr Hodina Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 94 ++++++++++++------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index baf7bb7805a85..f0ceaaef5683c 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -1050,6 +1050,64 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, u8 val; int i; + switch (csiphy->camss->res->version) { + case CAMSS_845: + { + regs->lane_regs = &lane_regs_sdm845[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845); + } + break; + case CAMSS_2290: + case CAMSS_2390: + case CAMSS_6150: + { + regs->lane_regs = &lane_regs_qcm2290[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290); + } + break; + case CAMSS_7280: + case CAMSS_8250: + { + regs->lane_regs = &lane_regs_sm8250[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250); + } + break; + case CAMSS_8280XP: + { + regs->lane_regs = &lane_regs_sc8280xp[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp); + } + break; + case CAMSS_X1E80100: + case CAMSS_X1P42100: + { + regs->lane_regs = &lane_regs_x1e80100[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_x1e80100); + } + break; + case CAMSS_8550: + { + regs->lane_regs = &lane_regs_sm8550[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550); + } + break; + case CAMSS_8650: + { + regs->lane_regs = &lane_regs_sm8650[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650); + } + break; + case CAMSS_8300: + case CAMSS_8775P: + { + regs->lane_regs = &lane_regs_sa8775p[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); + } + break; + default: + break; + } + settle_cnt = csiphy_settle_cnt_calc(link_freq, csiphy->timer_clk_rate); val = 0; @@ -1121,51 +1179,17 @@ static int csiphy_init(struct csiphy_device *csiphy) return -ENOMEM; csiphy->regs = regs; - regs->offset = 0x800; regs->common_status_offset = 0xb0; switch (csiphy->camss->res->version) { - case CAMSS_845: - regs->lane_regs = &lane_regs_sdm845[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845); - break; - case CAMSS_2290: - case CAMSS_2390: - case CAMSS_6150: - regs->lane_regs = &lane_regs_qcm2290[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290); - break; - case CAMSS_7280: - case CAMSS_8250: - regs->lane_regs = &lane_regs_sm8250[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250); - break; - case CAMSS_8280XP: - regs->lane_regs = &lane_regs_sc8280xp[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp); - break; case CAMSS_X1E80100: case CAMSS_X1P42100: - regs->lane_regs = &lane_regs_x1e80100[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_x1e80100); - regs->offset = 0x1000; - break; case CAMSS_8550: - regs->lane_regs = &lane_regs_sm8550[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550); - regs->offset = 0x1000; - break; case CAMSS_8650: - regs->lane_regs = &lane_regs_sm8650[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650); regs->offset = 0x1000; break; - case CAMSS_8300: - case CAMSS_8775P: - regs->lane_regs = &lane_regs_sa8775p[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); - break; default: + regs->offset = 0x800; break; } From e07e36e5210585fd402dd68fd2dd0c6cf60194ab Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 05/15] FROMLIST: media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init Add a PHY configuration sequence for the sdm845 which uses a Qualcomm Gen 2 version 1.1 CSI-2 PHY. The PHY can be configured as two phase or three phase in C-PHY or D-PHY mode. This configuration supports three-phase C-PHY mode. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-5-e53316d2cc65@ixit.cz/ Signed-off-by: Casey Connolly Reviewed-by: Vladimir Zapolskiy Reviewed-by: Bryan O'Donoghue Co-developed-by: David Heidelberg Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index f0ceaaef5683c..699597f8b0276 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -146,6 +146,7 @@ csiphy_lane_regs lane_regs_sa8775p[] = { }; /* GEN2 1.0 2PH */ +/* 5 entries: clock + 4 lanes */ static const struct csiphy_lane_regs lane_regs_sdm845[] = { {0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -220,6 +221,71 @@ csiphy_lane_regs lane_regs_sdm845[] = { {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }; +/* GEN2 1.0 3PH */ +/* 3 entries: 3 lanes (C-PHY) */ +static const struct +csiphy_lane_regs lane_regs_sdm845_3ph[] = { + {0x015c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0118, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x011c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0120, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0124, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x012c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0x12, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01dc, 0x51, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x035c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0318, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x031c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0320, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0324, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x032c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0x12, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03dc, 0x51, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x055c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0518, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x051c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0520, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0524, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x052c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0x12, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05dc, 0x51, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + /* GEN2 1.1 2PH */ static const struct csiphy_lane_regs lane_regs_sc8280xp[] = { @@ -1052,7 +1118,11 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, switch (csiphy->camss->res->version) { case CAMSS_845: - { + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { + regs->lane_regs = &lane_regs_sdm845_3ph[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845_3ph); + + } else { regs->lane_regs = &lane_regs_sdm845[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845); } From 20baa41cdd4e7f007b11677ff82fb872846dad32 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 06/15] FROMLIST: media: qcom: camss: csiphy-3ph: Update Gen2 v1.1 MIPI CSI-2 CPHY init These values should improve C-PHY behaviour. Should match most recent Qualcomm code. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-6-e53316d2cc65@ixit.cz/ Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 699597f8b0276..c6dd7d2b30940 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -225,9 +225,9 @@ csiphy_lane_regs lane_regs_sdm845[] = { /* 3 entries: 3 lanes (C-PHY) */ static const struct csiphy_lane_regs lane_regs_sdm845_3ph[] = { - {0x015c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0168, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x016c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015c, 0x63, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0xac, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016c, 0xa5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x010c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -245,9 +245,9 @@ csiphy_lane_regs lane_regs_sdm845_3ph[] = { {0x0164, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x01dc, 0x51, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x035c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0368, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x036c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035c, 0x63, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0xac, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036c, 0xa5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x030c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, @@ -265,9 +265,9 @@ csiphy_lane_regs lane_regs_sdm845_3ph[] = { {0x0364, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x03dc, 0x51, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x055c, 0x43, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x0568, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, - {0x056c, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055c, 0x63, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0xac, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056c, 0xa5, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x050c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, From 50613f0ae885141e91fe9b29acaebf67aa981176 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 07/15] FROMLIST: media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init Add a PHY configuration sequence for the sm8250 which uses a Qualcomm Gen 2 version 1.2.1 CSI-2 PHY. The PHY can be configured as two phase or three phase in C-PHY or D-PHY mode. This configuration supports three-phase C-PHY mode. Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-7-e53316d2cc65@ixit.cz/ Signed-off-by: Luca Weiss Reviewed-by: Konrad Dybcio Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 112 +++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index c6dd7d2b30940..bb9cc020ff4cc 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -550,6 +550,113 @@ csiphy_lane_regs lane_regs_qcm2290[] = { {0x0664, 0x3f, 0x00, CSIPHY_DEFAULT_PARAMS}, }; +/* GEN2 1.2.1 3PH */ +/* 3 entries: 3 lanes (C-PHY) */ +static const struct +csiphy_lane_regs lane_regs_sm8250_3ph[] = { + {0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0990, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0998, 0x1a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x098c, 0xaf, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x015c, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0188, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x018c, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0190, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0118, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x011c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0120, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0124, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x012c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01dc, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09ac, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09b0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x0e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0a90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a98, 0x1a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a8c, 0xaf, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x035c, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0388, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x038c, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0390, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0318, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x031c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0320, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0324, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x032c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03dc, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0a80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0aac, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0ab0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x0e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0b90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b98, 0x1a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b8c, 0xaf, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x055c, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0xa0, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050c, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0588, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x058c, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0590, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0518, 0x3e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x051c, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0520, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0524, 0x7f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x052c, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05cc, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05dc, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0b80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0bac, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0bb0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x0e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + /* GEN2 2.1.2 2PH DPHY mode */ static const struct csiphy_lane_regs lane_regs_sm8550[] = { @@ -1137,7 +1244,10 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, break; case CAMSS_7280: case CAMSS_8250: - { + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { + regs->lane_regs = &lane_regs_sm8250_3ph[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250_3ph); + } else { regs->lane_regs = &lane_regs_sm8250[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250); } From dd6051f9c42bc3d984fbf8c5074c2d3adddc41bd Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 08/15] FROMLIST: media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration Catch when C-PHY configuration gets used on SoC with CAMSS missing C-PHY configuration lane registers. Hopefully this check will disappear as these lane regs gets populated. -- @bod Proliferating special cases in switch statements on a per-SoC basis is verboten. Please find another way to do this, you already have a bool to indicate cphy in struct csid_phy_config {} so at some level CAMSS already has a bool to indicate what to do. Please make that logic accessible to logical consumers throughout, in this case the CPHY code. -- Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-8-e53316d2cc65@ixit.cz Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index bb9cc020ff4cc..6562424f5ef2b 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -1223,6 +1223,22 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, u8 val; int i; + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { + switch (csiphy->camss->res->version) { + case CAMSS_2290: + case CAMSS_8280XP: + case CAMSS_X1E80100: + case CAMSS_8550: + case CAMSS_8650: + case CAMSS_8300: + case CAMSS_8775P: + dev_err(csiphy->camss->dev, "Missing lane_regs definition for C-PHY\n"); + return -EINVAL; + default: + break; + } + } + switch (csiphy->camss->res->version) { case CAMSS_845: if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { From 71f6e8ba161a788dafe9e0f273ce47e134a1df00 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 09/15] FROMLIST: media: qcom: camss: Account for C-PHY when calculating link frequency Ensure that the link frequency divider correctly accounts for C-PHY operation. The divider differs between D-PHY and C-PHY, as described in the MIPI CSI-2 specification. For more details, see: https://docs.kernel.org/driver-api/media/tx-rx.html#pixel-rate Link: https://lore.kernel.org/r/20260301-qcom-cphy-v4-9-e53316d2cc65@ixit.cz Suggested-by: Sakari Ailus Signed-off-by: David Heidelberg Signed-off-by: Jigarkumar Zala Signed-off-by: Anusha Arun Nandi --- drivers/media/platform/qcom/camss/camss-csid.c | 9 +++++---- drivers/media/platform/qcom/camss/camss-csiphy.c | 8 +++----- drivers/media/platform/qcom/camss/camss.c | 16 ++++++++++++++-- drivers/media/platform/qcom/camss/camss.h | 2 +- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index 71f2bb75c3bdd..16ce2d29d78e1 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -536,9 +536,11 @@ const struct csid_format_info *csid_get_fmt_entry(const struct csid_format_info * csid_set_clock_rates - Calculate and set clock rates on CSID module * @csiphy: CSID device */ -static int csid_set_clock_rates(struct csid_device *csid) +static int csid_set_clock_rates(struct v4l2_subdev *sd, struct csid_device *csid) { struct device *dev = csid->camss->dev; + struct csiphy_device *csiphy = &csid->camss->csiphy[csid->phy.csiphy_id]; + struct csiphy_lanes_cfg *lane_cfg = &csiphy->cfg.csi2->lane_cfg; const struct csid_format_info *fmt; s64 link_freq; int i, j; @@ -546,8 +548,7 @@ static int csid_set_clock_rates(struct csid_device *csid) fmt = csid_get_fmt_entry(csid->res->formats->formats, csid->res->formats->nformats, csid->fmt[MSM_CSIPHY_PAD_SINK].code); - link_freq = camss_get_link_freq(&csid->subdev.entity, fmt->bpp, - csid->phy.lane_cnt); + link_freq = camss_get_link_freq(&csid->subdev.entity, fmt->bpp, lane_cfg); if (link_freq < 0) link_freq = 0; @@ -705,7 +706,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on) return ret; } - ret = csid_set_clock_rates(csid); + ret = csid_set_clock_rates(sd, csid); if (ret < 0) { regulator_bulk_disable(csid->num_supplies, csid->supplies); diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index a67924787b7d3..0903d16d4e26c 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -145,9 +145,8 @@ static int csiphy_set_clock_rates_legacy(struct csiphy_device *csiphy) u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); - u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; - link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, &csiphy->cfg.csi2->lane_cfg); if (link_freq < 0) link_freq = 0; @@ -272,10 +271,9 @@ static int csiphy_stream_on_legacy(struct csiphy_device *csiphy) u8 lane_mask = csiphy->res->hw_ops->get_lane_mask(&cfg->csi2->lane_cfg); u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); - u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; u8 val; - link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, &csiphy->cfg.csi2->lane_cfg); if (link_freq < 0) { dev_err(csiphy->camss->dev, @@ -336,7 +334,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy) dphy_cfg = &dphy_opts.mipi_dphy; - link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, &csiphy->cfg.csi2->lane_cfg); if (link_freq < 0) { dev_err(dev, diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 533461eb7dc6f..f7a78764b352c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -33,6 +33,14 @@ #define CAMSS_CLOCK_MARGIN_NUMERATOR 105 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 +/* + * C-PHY encodes data by 16/7 ~ 2.28 bits/symbol + * D-PHY doesn't encode data, thus 16/16 = 1 b/s + */ +#define CAMSS_COMMON_PHY_DIVIDENT 16 +#define CAMSS_CPHY_DIVISOR 7 +#define CAMSS_DPHY_DIVISOR 16 + static const struct parent_dev_ops vfe_parent_dev_ops; static const struct camss_subdev_resources csiphy_res_8x16[] = { @@ -4438,15 +4446,19 @@ struct media_pad *camss_find_sensor_pad(struct media_entity *entity) * Return link frequency on success or a negative error code otherwise */ s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, - unsigned int lanes) + struct csiphy_lanes_cfg *lane_cfg) { struct media_pad *sensor_pad; + u8 num_lanes = lane_cfg->num_data; + bool cphy = lane_cfg->phy_cfg == V4L2_MBUS_CSI2_CPHY; + unsigned int div = num_lanes * 2 * (cphy ? CAMSS_CPHY_DIVISOR : + CAMSS_DPHY_DIVISOR); sensor_pad = camss_find_sensor_pad(entity); if (!sensor_pad) return -ENODEV; - return v4l2_get_link_freq(sensor_pad, bpp, 2 * lanes); + return v4l2_get_link_freq(sensor_pad, CAMSS_COMMON_PHY_DIVIDENT * bpp, div); } /* diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 0e49aaba3438e..f2e51079e9d4e 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -171,7 +171,7 @@ int camss_enable_clocks(int nclocks, struct camss_clock *clock, void camss_disable_clocks(int nclocks, struct camss_clock *clock); struct media_pad *camss_find_sensor_pad(struct media_entity *entity); s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp, - unsigned int lanes); + struct csiphy_lanes_cfg *lane_cfg); int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock); int camss_pm_domain_on(struct camss *camss, int id); void camss_pm_domain_off(struct camss *camss, int id); From 8f77c4bd002410c9547c75458bfb4a3561eaa391 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 10/15] FROMLIST: media: qcom: camss: Program CSIPHY common control registers Program the CSIPHY common-control registers during lane enable so SA8775P uses the required 3-phase 1.5 Gsps reset-release values for both C-PHY and D-PHY. Keep the existing reset-release value for the other CAMSS variants. Link: https://lore.kernel.org/r/20260717231331.1229693-2-anusha.nandi@oss.qualcomm.com Signed-off-by: Jigarkumar Zala Co-developed-by: Anusha Arun Nandi Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 6562424f5ef2b..9be40880e9c5f 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -1011,8 +1011,6 @@ static void csiphy_reset(struct csiphy_device *csiphy) writel_relaxed(0x1, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 0)); usleep_range(5000, 8000); - writel_relaxed(0x0, csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 0)); } static irqreturn_t csiphy_isr(int irq, void *dev) @@ -1331,9 +1329,37 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 6)); - val = 0x02; - writel_relaxed(val, csiphy->base + - CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 7)); + switch (platform_version) { + case CAMSS_8300: + case CAMSS_8775P: + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { + val = 0x5A; + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 7)); + val = 0xE; + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 0)); + } else { + val = 0x02; + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 7)); + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 0)); + } + break; + case CAMSS_7280: + case CAMSS_8250: + case CAMSS_8280XP: + case CAMSS_845: + default: + val = 0x02; + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 7)); + val = 0x0; + writel_relaxed(val, csiphy->base + + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->offset, 0)); + break; + } val = 0x00; writel_relaxed(val, csiphy->base + From 7b6367e061f85cc4b5b3018439de74e284e2c5bc Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 11/15] FROMLIST: media: qcom: camss: Prepare CSID for C-PHY support in gen3 Program the gen3 CSID CSI2 RX PHY type field from the configured PHY type. The RX path needs this value to distinguish C-PHY from D-PHY input, so leaving it at the default makes C-PHY configuration incomplete. Link: https://lore.kernel.org/r/20260717231331.1229693-3-anusha.nandi@oss.qualcomm.com Signed-off-by: Jigarkumar Zala Co-developed-by: Anusha Arun Nandi Signed-off-by: Anusha Arun Nandi --- drivers/media/platform/qcom/camss/camss-csid-gen3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen3.c b/drivers/media/platform/qcom/camss/camss-csid-gen3.c index 222765fe7914d..310933cf19da2 100644 --- a/drivers/media/platform/qcom/camss/camss-csid-gen3.c +++ b/drivers/media/platform/qcom/camss/camss-csid-gen3.c @@ -66,6 +66,7 @@ #define CSI2_RX_CFG0_VC_MODE 3 #define CSI2_RX_CFG0_DL0_INPUT_SEL 4 #define CSI2_RX_CFG0_PHY_NUM_SEL 20 +#define CSI2_RX_CFG0_PHY_TYPE_SEL 24 #define CSI2_RX_CFG0_TPG_MUX_EN BIT(27) #define CSI2_RX_CFG0_TPG_MUX_SEL GENMASK(29, 28) @@ -115,6 +116,7 @@ static void __csid_configure_rx(struct csid_device *csid, camss = csid->camss; val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES; + val |= phy->cphy << CSI2_RX_CFG0_PHY_TYPE_SEL; val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL; if (camss->tpg && csid->tpg_linked && From dd6a113a76f5321965c75fdf55a5dc4335e374aa Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 12/15] FROMLIST: media: qcom: camss: Add sa8775p C-PHY 3ph lane config Add the lane_regs_sa8775p_3ph[] register table for the sa8775p Gen3 CSIPHY at 1.5 Gsps, and select it in csiphy_lanes_enable() for CAMSS_8775P when the endpoint is configured for C-PHY, falling back to the existing sa8775p D-PHY table otherwise. Link: https://lore.kernel.org/r/20260717231331.1229693-4-anusha.nandi@oss.qualcomm.com Signed-off-by: Jigarkumar Zala Co-developed-by: Anusha Arun Nandi Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 106 +++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 9be40880e9c5f..4f2d5c08af787 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -145,6 +145,101 @@ csiphy_lane_regs lane_regs_sa8775p[] = { {0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }; +/* GEN3 3PH sa8775p 1.5Gsps */ +/* 3 entries: 3 lanes (C-PHY) */ +static const struct +csiphy_lane_regs lane_regs_sa8775p_3ph[] = { + {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0188, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x018C, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0190, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0118, 0x3E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x011C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0388, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x038C, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0390, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0318, 0x3E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x031C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0320, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE}, + {0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0588, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x058C, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0590, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0518, 0x3E, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x051C, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0520, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0980, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x09B4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A80, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B80, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x24, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x035C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x24, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x055C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x24, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x09B4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + /* GEN2 1.0 2PH */ /* 5 entries: clock + 4 lanes */ static const struct @@ -1229,7 +1324,6 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, case CAMSS_8550: case CAMSS_8650: case CAMSS_8300: - case CAMSS_8775P: dev_err(csiphy->camss->dev, "Missing lane_regs definition for C-PHY\n"); return -EINVAL; default: @@ -1292,12 +1386,20 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, } break; case CAMSS_8300: - case CAMSS_8775P: { regs->lane_regs = &lane_regs_sa8775p[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); } break; + case CAMSS_8775P: + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { + regs->lane_regs = &lane_regs_sa8775p_3ph[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p_3ph); + } else { + regs->lane_regs = &lane_regs_sa8775p[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); + } + break; default: break; } From e6e0ed0e36f6ad425ec8fd1cf28d9e3dbb3b7e19 Mon Sep 17 00:00:00 2001 From: Anusha Arun Nandi Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 13/15] FROMLIST: media: qcom: camss: Add sa8300 C-PHY 3ph lane config Share the C-PHY/D-PHY lane_regs selection for CAMSS_8300 so the sa8300 platform uses the same 3ph handling as CAMSS_8775P. Also drop CAMSS_8300 from the missing-C-PHY-table guard now that a C-PHY table is provided. Link: https://lore.kernel.org/r/20260717231331.1229693-5-anusha.nandi@oss.qualcomm.com Co-developed-by: Jigarkumar Zala Signed-off-by: Jigarkumar Zala Signed-off-by: Anusha Arun Nandi --- drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index 4f2d5c08af787..a294cde011b1e 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -1323,7 +1323,6 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, case CAMSS_X1E80100: case CAMSS_8550: case CAMSS_8650: - case CAMSS_8300: dev_err(csiphy->camss->dev, "Missing lane_regs definition for C-PHY\n"); return -EINVAL; default: @@ -1386,11 +1385,6 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, } break; case CAMSS_8300: - { - regs->lane_regs = &lane_regs_sa8775p[0]; - regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); - } - break; case CAMSS_8775P: if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { regs->lane_regs = &lane_regs_sa8775p_3ph[0]; From 5c97b3af32ed45532b45612be0d19382c010a529 Mon Sep 17 00:00:00 2001 From: Anusha Arun Nandi Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 14/15] FROMLIST: media: qcom: camss: Dynamic data-rate specific C-PHY register settings The C-PHY PHY register configuration needs to vary with the link (symbol) data rate. Until now only a single base lane_regs table was applied per platform, regardless of the negotiated rate. Introduce a data-rate selection mechanism for C-PHY: - Add struct data_rate_reg_info describing a per-bandwidth register override table. - Add csiphy_cphy_data_rate_config(), which selects the first table entry whose bandwidth satisfies the required PHY data rate (derived from the resolved link frequency) and writes those overrides on top of the base lane_regs configuration. The settle-count parameter types are handled specially. When the link frequency cannot be resolved, it falls back to the lowest supported rate. - Add per-data-rate register tables and data_rate_settings tables for sa8775p and 8300(1.5/1.7/2.5/3.5/4.5 GSpS) and sm8250 (2.5/3.5/4.5 GSpS). - Select the appropriate data-rate settings table in csiphy_lanes_enable() for both platforms when the endpoint is configured for C-PHY. Link: https://lore.kernel.org/r/20260717231331.1229693-6-anusha.nandi@oss.qualcomm.com Co-developed-by: Jigarkumar Zala Signed-off-by: Jigarkumar Zala Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 251 ++++++++++++++++++ .../media/platform/qcom/camss/camss-csiphy.h | 6 + 2 files changed, 257 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index a294cde011b1e..b7ab11276618c 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -59,6 +59,8 @@ #define CSIPHY_3PH_REGS 6 #define CSIPHY_SKEW_CAL 7 +#define CSIPHY_CPHY_DATA_RATE_DEFAULT_IDX 0 + struct csiphy_lane_regs { s32 reg_addr; s32 reg_data; @@ -223,6 +225,9 @@ csiphy_lane_regs lane_regs_sa8775p_3ph[] = { {0x0B80, 0x61, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sa8775p_3ph_1p5Gsps[] = { {0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, @@ -240,6 +245,183 @@ csiphy_lane_regs lane_regs_sa8775p_3ph[] = { {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, }; +struct csiphy_lane_regs datarate_sa8775p_3ph_1p7Gsps[] = { + {0x015C, 0x56, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0168, 0xAE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x65, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x035C, 0x56, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0368, 0xAE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x65, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x055C, 0x56, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0568, 0xAE, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x65, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x09B4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sa8775p_3ph_2p5Gsps[] = { + {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0368, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0568, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0xC8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x09B4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sa8775p_3ph_3p5Gsps[] = { + {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0368, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0568, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x09B4, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sa8775p_3ph_4p5Gsps[] = { + {0x0168, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x010C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0368, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x035C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x030C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0568, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x055C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x050C, 0x08, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x09B4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0AB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0BB4, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +static struct data_rate_reg_info data_rate_settings_sa8775p_3ph[] = { + { + /* 1.5 GSpS */ + .bandwidth = 1500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sa8775p_3ph_1p5Gsps), + .data_rate_reg_array = datarate_sa8775p_3ph_1p5Gsps, + }, + { + /* 1.7 GSpS */ + .bandwidth = 1700000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sa8775p_3ph_1p7Gsps), + .data_rate_reg_array = datarate_sa8775p_3ph_1p7Gsps, + }, + { + /* 2.5 GSpS */ + .bandwidth = 2500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sa8775p_3ph_2p5Gsps), + .data_rate_reg_array = datarate_sa8775p_3ph_2p5Gsps, + }, + { + /* 3.5 GSpS */ + .bandwidth = 3500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sa8775p_3ph_3p5Gsps), + .data_rate_reg_array = datarate_sa8775p_3ph_3p5Gsps, + }, + { + /* 4.5 GSpS */ + .bandwidth = 4500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sa8775p_3ph_4p5Gsps), + .data_rate_reg_array = datarate_sa8775p_3ph_4p5Gsps, + }, +}; + +struct csiphy_lane_regs datarate_sm8250_3ph_2p5Gsps[] = { + {0x144, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x164, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x364, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x564, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sm8250_3ph_3p5Gsps[] = { + {0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS}, +}; + +struct csiphy_lane_regs datarate_sm8250_3ph_4p5Gsps[] = { + {0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x9B4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xAB4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS}, + {0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0xBB4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS}, +}; + +static struct data_rate_reg_info data_rate_settings_sm8250_3ph[] = { + { + /* 2.5 GSpS */ + .bandwidth = 2500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sm8250_3ph_2p5Gsps), + .data_rate_reg_array = datarate_sm8250_3ph_2p5Gsps, + }, + { + /* 3.5 GSpS */ + .bandwidth = 3500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sm8250_3ph_3p5Gsps), + .data_rate_reg_array = datarate_sm8250_3ph_3p5Gsps, + }, + { + /* 4.5 GSpS */ + .bandwidth = 4500000000, + .data_rate_reg_array_size = ARRAY_SIZE(datarate_sm8250_3ph_4p5Gsps), + .data_rate_reg_array = datarate_sm8250_3ph_4p5Gsps, + }, +}; + /* GEN2 1.0 2PH */ /* 5 entries: clock + 4 lanes */ static const struct @@ -1231,6 +1413,60 @@ static void csiphy_gen1_config_lanes(struct csiphy_device *csiphy, writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_MISC1(l)); } +/* + * csiphy_cphy_data_rate_config - Apply data-rate specific C-PHY overrides + * + * Applied on top of the base lane_regs. Selects the first table entry whose + * bandwidth >= the data rate derived from @link_freq (highest entry if none + * qualifies, default entry if @link_freq is unknown) and writes its overrides. + */ +static void csiphy_cphy_data_rate_config(struct csiphy_device *csiphy, + struct data_rate_reg_info *settings, + size_t num_settings, + s64 link_freq, u8 settle_cnt) +{ + struct device *dev = csiphy->camss->dev; + const struct csiphy_lane_regs *r; + size_t idx, i; + u32 val; + + if (!settings || !num_settings) + return; + + if (!link_freq) { + /* Link frequency unknown; use the default (lowest) entry. */ + idx = CSIPHY_CPHY_DATA_RATE_DEFAULT_IDX; + } else { + /* First entry that satisfies the rate, else the highest. */ + for (idx = 0; idx < num_settings; idx++) { + if (settings[idx].bandwidth >= link_freq) + break; + } + } + + dev_dbg(dev, + "CSIPHY using specific bandwidth %llu bits/s (entry %zu) for link_freq %lld\n", + settings[idx].bandwidth, idx, link_freq); + + r = settings[idx].data_rate_reg_array; + for (i = 0; i < settings[idx].data_rate_reg_array_size; i++, r++) { + switch (r->csiphy_param_type) { + case CSIPHY_SETTLE_CNT_LOWER_BYTE: + val = settle_cnt & 0xff; + break; + case CSIPHY_SETTLE_CNT_HIGHER_BYTE: + val = (settle_cnt >> 8) & 0xff; + break; + default: + val = r->reg_data; + break; + } + writel_relaxed(val, csiphy->base + r->reg_addr); + if (r->delay_us) + udelay(r->delay_us); + } +} + static void csiphy_gen2_config_lanes(struct csiphy_device *csiphy, u8 settle_cnt) { @@ -1312,6 +1548,8 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, struct device *dev = csiphy->camss->dev; struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg; struct csiphy_device_regs *regs = csiphy->regs; + struct data_rate_reg_info *data_rate_settings = NULL; + size_t num_data_rate_settings = 0; u8 settle_cnt; u8 val; int i; @@ -1354,6 +1592,8 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { regs->lane_regs = &lane_regs_sm8250_3ph[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250_3ph); + data_rate_settings = data_rate_settings_sm8250_3ph; + num_data_rate_settings = ARRAY_SIZE(data_rate_settings_sm8250_3ph); } else { regs->lane_regs = &lane_regs_sm8250[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250); @@ -1389,6 +1629,8 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY) { regs->lane_regs = &lane_regs_sa8775p_3ph[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p_3ph); + data_rate_settings = data_rate_settings_sa8775p_3ph; + num_data_rate_settings = ARRAY_SIZE(data_rate_settings_sa8775p_3ph); } else { regs->lane_regs = &lane_regs_sa8775p[0]; regs->lane_array_size = ARRAY_SIZE(lane_regs_sa8775p); @@ -1466,6 +1708,15 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy, else csiphy_gen1_config_lanes(csiphy, cfg, settle_cnt); + /* + * For C-PHY platforms with a data-rate settings table, apply the + * data-rate specific overrides on top of the base lane_regs config. + */ + if (c->phy_cfg == V4L2_MBUS_CSI2_CPHY && data_rate_settings) + csiphy_cphy_data_rate_config(csiphy, data_rate_settings, + num_data_rate_settings, + link_freq, settle_cnt); + /* IRQ_MASK registers - disable all interrupts */ for (i = 11; i < 22; i++) { writel_relaxed(0, csiphy->base + diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h index 8643ab57c3786..c1232986a2598 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.h +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h @@ -63,6 +63,12 @@ struct csiphy_formats { const struct csiphy_format_info *formats; }; +struct data_rate_reg_info { + u64 bandwidth; + ssize_t data_rate_reg_array_size; + struct csiphy_lane_regs *data_rate_reg_array; +}; + struct csiphy_device; struct csiphy_hw_ops { From b2037da7177fe0c49fdf52312b39ca09e81fd7e1 Mon Sep 17 00:00:00 2001 From: Anusha Arun Nandi Date: Tue, 23 Jun 2026 02:13:41 +0000 Subject: [PATCH 15/15] FROMLIST: media: qcom: camss: validate local/remote endpoint bus-type A link is invalid if the local CSIPHY endpoint and the remote sensor endpoint describe different bus types. Such a mismatch can otherwise go undetected until later probe or streaming failures. Parse the remote endpoint in camss_parse_endpoint_node() and compare its bus-type with the local endpoint. Reject the link with -EINVAL if the two ends disagree, so C-PHY/D-PHY mismatches are caught early during probe. Link: https://lore.kernel.org/r/20260717231331.1229693-7-anusha.nandi@oss.qualcomm.com Co-developed-by: Jigarkumar Zala Signed-off-by: Jigarkumar Zala Signed-off-by: Anusha Arun Nandi --- drivers/media/platform/qcom/camss/camss.c | 28 ++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index f7a78764b352c..779c75efa0a58 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -4568,7 +4568,9 @@ static int camss_parse_endpoint_node(struct device *dev, { struct csiphy_lanes_cfg *lncfg = &csd->interface.csi2.lane_cfg; struct v4l2_mbus_config_mipi_csi2 *mipi_csi2; - struct v4l2_fwnode_endpoint vep = { { 0 } }; + struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_UNKNOWN }; + struct v4l2_fwnode_endpoint remote_vep = { .bus_type = V4L2_MBUS_UNKNOWN }; + struct fwnode_handle *remote_ep; unsigned int i; int ret; @@ -4585,6 +4587,30 @@ static int camss_parse_endpoint_node(struct device *dev, return -EINVAL; } + /* Get the remote (sensor) endpoint handle, e.g. imx686_ep1 */ + remote_ep = fwnode_graph_get_remote_endpoint(ep); + if (!remote_ep) { + dev_dbg(dev, "No remote endpoint found for %pfw\n", ep); + return -ENODEV; + } + + /* Parse the remote bus type and release the handle */ + ret = v4l2_fwnode_endpoint_parse(remote_ep, &remote_vep); + fwnode_handle_put(remote_ep); + if (ret) { + dev_dbg(dev, "Failed to parse remote endpoint\n"); + return ret; + } + + /* The local (CSIPHY) and remote (sensor) ends must agree */ + if (vep.bus_type != remote_vep.bus_type) { + dev_dbg(dev, "Bus type mismatch! Local (CSI-PHY): %u, Remote (Sensor): %u\n", + vep.bus_type, remote_vep.bus_type); + return -EINVAL; + } + + dev_dbg(dev, "Verified link: both ends use bus-type %u\n", vep.bus_type); + csd->interface.csiphy_id = vep.base.port; mipi_csi2 = &vep.bus.mipi_csi2;