From 7d2af3a1263f75dbc882d1c1111c6b5696207979 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 01/13] 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. 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 cab82648134c5..776214ba92692 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 b583348642f76830be2887a1fbbc9895afc7776e Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 02/13] 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. 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 d37f71de0f42c..1516024702e23 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; } @@ -1028,10 +1038,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; @@ -1040,9 +1051,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)); @@ -1069,6 +1094,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 c627fd68699929bb7e1bfdbb777f43153125d3ee Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 03/13] 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. 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 7d9a7303ff4da61f7435a5b2c55311e55b276327 Mon Sep 17 00:00:00 2001 From: Petr Hodina Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 04/13] 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. Signed-off-by: Petr Hodina Signed-off-by: David Heidelberg Signed-off-by: Anusha Arun Nandi --- .../qcom/camss/camss-csiphy-3ph-1-0.c | 92 ++++++++++++------- 1 file changed, 58 insertions(+), 34 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 1516024702e23..6acdbafaecb29 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 @@ -1049,6 +1049,63 @@ 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_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; @@ -1120,50 +1177,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_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 81fca8a2e75b6352ccfc1811cd3c7baec5d59eab Mon Sep 17 00:00:00 2001 From: Casey Connolly Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 05/13] 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. 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 6acdbafaecb29..7462a40b14dd7 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[] = { @@ -1051,7 +1117,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 8dc3fe33fd12bffd26f637ce912439988244a7b5 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 06/13] 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. 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 7462a40b14dd7..82d66b7cb2c9d 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 274b5f8741f4bd0b0e0a1e05dd24481146d5b31e Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 07/13] 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. 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 82d66b7cb2c9d..d2f8cc0a6981d 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[] = { @@ -1135,7 +1242,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 a676eb1c2048352d5aca1cc2593cdeb1386b54d3 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 08/13] 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. -- 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 d2f8cc0a6981d..b8fb315c741d5 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 @@ -1222,6 +1222,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 1297e418eef25375fce69499345cf852fe5f0400 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 09/13] 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 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 776214ba92692..212914d84a0b3 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 541b5c8bf1926..731c8cf542cac 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -170,7 +170,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 79ecbb4fc9b944bed783f1d9352410ab2323761e Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:14 -0700 Subject: [PATCH 10/13] CHROMIUM: media: qcom: camss: Program common control register Use these switch cases to add the sa8775p (CAMSS_8775P) 3-phase 1.5 Gsps settings, programming the appropriate common-control register 5/6/7 and reset-release values for C-PHY and D-PHY. Signed-off-by: Jigarkumar Zala 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 b8fb315c741d5..617d5139d6620 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) @@ -1329,9 +1327,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 0e9445a77ab89f42dcb20707dba8b5b519f4c574 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 11/13] CHROMIUM: media: qcom: camss: Prepare CSID for C-PHY support in gen3 Add the CSI2 RX PHY type select bitfield and program it from the configured PHY type so that the CSID RX path is told whether the incoming data is C-PHY or D-PHY. Signed-off-by: Jigarkumar Zala 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 cf42b6c7ddf816c86ac2df9057b8dc6dadbfc9c0 Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 12/13] CHROMIUM: 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. Signed-off-by: Jigarkumar Zala 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 617d5139d6620..1d6887092a8fa 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 @@ -1228,7 +1323,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: @@ -1290,12 +1384,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 9f3992a4982f6f20233117970cb9d761d3fe2578 Mon Sep 17 00:00:00 2001 From: Anusha Arun Nandi Date: Tue, 9 Jun 2026 14:47:15 -0700 Subject: [PATCH 13/13] CHROMIUM: media: qcom: camss: Add CAMSS_8300 C-PHY support 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. 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 1d6887092a8fa..698d059eb1c7b 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 @@ -1322,7 +1322,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: @@ -1384,11 +1383,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];