* [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms
@ 2026-01-17 15:36 David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration David Heidelberg via B4 Relay
` (7 more replies)
0 siblings, 8 replies; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
# Short summary
This patch series extends the Qualcomm CAMSS (Camera Subsystem),
including CSID and CSIPHY components, to support C-PHY mode configuration.
# Background and motivation
Modern smartphone cameras increasingly rely on MIPI C-PHY rather than
D-PHY, thanks to its higher data throughput and signal efficiency.
As a result, many OEMs adopt C-PHY interfaces for main (rear) cameras on
Qualcomm-based devices.
Until now, mainline Linux lacked C-PHY configuration support for Qualcomm
chipsets, preventing bring-up of primary camera sensors on several
Snapdragon platforms. This series closes that gap.
- Introduces C-PHY configuration support for the CAMSS driver stack,
covering both CSID and CSIPHY blocks.
- Successfully enables C-PHY operation on the Snapdragon 845 platform.
- Tested on OnePlus 6 and 6T phones running mainline Linux,
using the Sony IMX519 main camera sensor.
- The new configuration allows other chipsets versionsto enable C-PHY by
simply adding corresponding sensor driver support and csiphy
initialization data, following the example set for sdm845.
With this patch series, mainline Linux gains working C-PHY support for
Snapdragon 845, paving the way for improved main camera functionality
across many Qualcomm-based devices. The groundwork also simplifies
future enablement efforts for additional SoCs and sensors.
Until merged, the series will be also available at:
https://gitlab.com/sdm845/sdm845-next/-/commits/b4/qcom-cphy
Signed-off-by: David Heidelberg <david@ixit.cz>
---
Changes in v3:
- Make lanes_enable return sucess or error, since I couldn't move the
configuration to the _init.
- Dropped R-b tags on
"media: qcom: camss: Initialize lanes after lane configuration is available"
as I changed formatting.
- Link to v2: https://lore.kernel.org/r/20251204-qcom-cphy-v2-0-6b35ef8b071e@ixit.cz
Changes in v2:
- This is still WIP patch series, thus I wanted to publish already
changed parts to get feedback regarding to the direction of patchset.
- When switch to using odd bits, zeroed val which was left unitialized in v1.
- Accidentally missed archs added back in the commit moving lane regs to
new location.
- Remove commit with reverting check for only D-PHY is supported and
adjusted the check to also account for C-PHY.
- Documented link frequency calculation with defines. (Casey)
- Changed the cphy boolean to phy_cfg enum in the camss/camss-csiphy.
(Brian)
- Added patch for csiphy-3ph enablement for sm7280 from Luca as I'm
meanwhile trying to bring up the C-PHY sensor on FairPhone 5.
- Merged these two commits together
csiphy-3ph: Enable sdm845 C-PHY sequence
csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
merged R-b.
- Link to v1: https://lore.kernel.org/r/20251109-qcom-cphy-v1-0-165f7e79b0e1@ixit.cz
---
Casey Connolly (1):
media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
David Heidelberg (5):
media: qcom: camss: csiphy: Introduce PHY configuration
media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
media: qcom: camss: Prepare CSID for C-PHY support
media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration
media: qcom: camss: Account for C-PHY when calculating link frequency
Luca Weiss (1):
media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init
Petr Hodina (1):
media: qcom: camss: Initialize lanes after lane configuration is available
.../media/platform/qcom/camss/camss-csid-gen2.c | 1 +
drivers/media/platform/qcom/camss/camss-csid.c | 3 +-
drivers/media/platform/qcom/camss/camss-csid.h | 1 +
.../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 +-
.../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 332 ++++++++++++++++++---
drivers/media/platform/qcom/camss/camss-csiphy.c | 10 +-
drivers/media/platform/qcom/camss/camss-csiphy.h | 8 +-
drivers/media/platform/qcom/camss/camss.c | 34 ++-
drivers/media/platform/qcom/camss/camss.h | 2 +-
9 files changed, 331 insertions(+), 68 deletions(-)
---
base-commit: 46fe65a2c28ecf5df1a7475aba1f08ccf4c0ac1b
change-id: 20251109-qcom-cphy-bb8cbda1c644
Best regards,
--
David Heidelberg <david@ixit.cz>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:29 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes David Heidelberg via B4 Relay
` (6 subsequent siblings)
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: David Heidelberg <david@ixit.cz>
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 <david@ixit.cz>
---
drivers/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 2d5054819df7f..d198171700e73 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -28,11 +28,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 00b87fd9afbd8..ea0c8cf3cd806 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -4411,11 +4411,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;
}
@@ -4423,9 +4423,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),
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:38 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support David Heidelberg via B4 Relay
` (5 subsequent siblings)
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: David Heidelberg <david@ixit.cz>
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 <david@ixit.cz>
---
.../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
.../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/media-bus-format.h>
#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 |= (1 << 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 |= 1 << lane_cfg->data[i].pos;
+ break;
+ default:
+ break;
+ }
return lane_mask;
}
@@ -1027,10 +1037,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;
@@ -1039,9 +1050,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));
@@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
wmb();
}
- csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
-
- return 0;
+ return csiphy->res->hw_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 d198171700e73..21cf2ce931c1d 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -73,9 +73,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);
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:39 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available David Heidelberg via B4 Relay
` (4 subsequent siblings)
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: David Heidelberg <david@ixit.cz>
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 <david@ixit.cz>
---
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 ed1820488c987..b50b0cfe280c1 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -1275,6 +1275,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);
}
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index aedc96ed84b2f..a82db31bd2335 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;
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
` (2 preceding siblings ...)
2026-01-17 15:36 ` [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 15:53 ` David Heidelberg
2026-01-17 21:45 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init David Heidelberg via B4 Relay
` (3 subsequent siblings)
7 siblings, 2 replies; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: Petr Hodina <phodina@protonmail.com>
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 <phodina@protonmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
.../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 91 ++++++++++++++--------
1 file changed, 57 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 f3a8625511e1e..9e8470358515f 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
@@ -1048,6 +1048,62 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
u8 val;
int i;
+ switch (csiphy->camss->res->version) {
+ case CAMSS_845:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_sdm845[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
+ }
+ break;
+ case CAMSS_2290:
+ case CAMSS_6150:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_qcm2290[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290);
+ }
+ break;
+ case CAMSS_7280:
+ case CAMSS_8250:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_sm8250[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
+ }
+ break;
+ case CAMSS_8280XP:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_sc8280xp[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp);
+ }
+ break;
+ case CAMSS_X1E80100:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_x1e80100[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_x1e80100);
+ }
+ break;
+ case CAMSS_8550:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_sm8550[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550);
+ }
+ break;
+ case CAMSS_8650:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ regs->lane_regs = &lane_regs_sm8650[0];
+ regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650);
+ }
+ break;
+ case CAMSS_8300:
+ case CAMSS_8775P:
+ { /* V4L2_MBUS_CSI2_DPHY */
+ 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;
@@ -1119,49 +1175,16 @@ 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:
- 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;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
` (3 preceding siblings ...)
2026-01-17 15:36 ` [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:49 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init David Heidelberg via B4 Relay
` (2 subsequent siblings)
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: Casey Connolly <casey.connolly@linaro.org>
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 <casey.connolly@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
.../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 70 +++++++++++++++++++++-
1 file changed, 69 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 9e8470358515f..f819472511823 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,69 @@ 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[] = {
@@ -1050,7 +1114,11 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
switch (csiphy->camss->res->version) {
case CAMSS_845:
- { /* V4L2_MBUS_CSI2_DPHY */
+ 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 { /* V4L2_MBUS_CSI2_DPHY */
regs->lane_regs = &lane_regs_sdm845[0];
regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
` (4 preceding siblings ...)
2026-01-17 15:36 ` [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:51 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency David Heidelberg via B4 Relay
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: Luca Weiss <luca.weiss@fairphone.com>
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 <luca.weiss@fairphone.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
.../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 110 ++++++++++++++++++++-
1 file changed, 109 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 f819472511823..d82a88dad74b5 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
@@ -548,6 +548,111 @@ 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[] = {
@@ -1132,7 +1237,10 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
break;
case CAMSS_7280:
case CAMSS_8250:
- { /* V4L2_MBUS_CSI2_DPHY */
+ 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 { /* V4L2_MBUS_CSI2_DPHY */
regs->lane_regs = &lane_regs_sm8250[0];
regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
` (5 preceding siblings ...)
2026-01-17 15:36 ` [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 21:54 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency David Heidelberg via B4 Relay
7 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: David Heidelberg <david@ixit.cz>
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.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/media/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 d82a88dad74b5..89bfe3710fc3a 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
@@ -1217,6 +1217,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(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) {
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
` (6 preceding siblings ...)
2026-01-17 15:36 ` [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration David Heidelberg via B4 Relay
@ 2026-01-17 15:36 ` David Heidelberg via B4 Relay
2026-01-17 20:27 ` kernel test robot
2026-01-17 21:56 ` Bryan O'Donoghue
7 siblings, 2 replies; 26+ messages in thread
From: David Heidelberg via B4 Relay @ 2026-01-17 15:36 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel,
David Heidelberg
From: David Heidelberg <david@ixit.cz>
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 <sakari.ailus@linux.intel.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/media/platform/qcom/camss/camss-csid.c | 2 +-
drivers/media/platform/qcom/camss/camss-csiphy.c | 6 ++++--
drivers/media/platform/qcom/camss/camss.c | 16 +++++++++++++---
drivers/media/platform/qcom/camss/camss.h | 2 +-
4 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index b50b0cfe280c1..24f244d2959c9 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -545,7 +545,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);
+ csid->phy.lane_cnt, csid->phy.cphy);
if (link_freq < 0)
link_freq = 0;
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 08dd238e52799..1ea0d0ef354ff 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -144,8 +144,9 @@ static int csiphy_set_clock_rates(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;
+ bool cphy = csiphy->cfg.csi2->lane_cfg.phy_cfg == V4L2_MBUS_CSI2_CPHY;
- link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
+ link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes, cphy);
if (link_freq < 0)
link_freq = 0;
@@ -270,9 +271,10 @@ static int csiphy_stream_on(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;
+ bool cphy = csiphy->cfg.csi2->lane_cfg.phy_cfg == V4L2_MBUS_CSI2_CPHY;
u8 val;
- link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
+ link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes, cphy);
if (link_freq < 0) {
dev_err(csiphy->camss->dev,
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index ea0c8cf3cd806..556fedd92e065 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -32,6 +32,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[] = {
@@ -4280,20 +4288,22 @@ struct media_pad *camss_find_sensor_pad(struct media_entity *entity)
* camss_get_link_freq - Get link frequency from sensor
* @entity: Media entity in the current pipeline
* @bpp: Number of bits per pixel for the current format
- * @lanes: Number of lanes in the link to the sensor
+ * @nr_of_lanes: Number of lanes in the link to the sensor
*
* 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)
+ unsigned int nr_of_lanes, bool cphy)
{
struct media_pad *sensor_pad;
+ unsigned int div = nr_of_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 6d048414c919e..6bf7738837b89 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -163,7 +163,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);
+ unsigned int lanes, bool cphy);
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);
--
2.51.0
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available
2026-01-17 15:36 ` [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available David Heidelberg via B4 Relay
@ 2026-01-17 15:53 ` David Heidelberg
2026-01-17 21:45 ` Bryan O'Donoghue
1 sibling, 0 replies; 26+ messages in thread
From: David Heidelberg @ 2026-01-17 15:53 UTC (permalink / raw)
To: Robert Foss, Todor Tomov, Bryan O'Donoghue,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 16:36, David Heidelberg via B4 Relay wrote:
> From: Petr Hodina <phodina@protonmail.com>
>
> 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 <phodina@protonmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 91 ++++++++++++++--------
> 1 file changed, 57 insertions(+), 34 deletions(-)
>
Now we going to setup D/C-PHY in lanes_enable, which I perceive as
sub-optimal, because when C-PHY is set on the device-tree level, while
the device may handle both D-PHY and C-PHY, the intent is use C-PHY only
when available, because of the advantages, where as disadvantages are
mainly in the implementation complexity (which is already done).
Thus it would be most optimal to take care of the configuration in the
csiphy init, which starts at point, where the device-tree properties
aren't parsed yet.
I tried to do shuffling in camss_probe to make
csiphy->cfg.csi2->lane_cfg available in the subdevice (csiphy) init phase.
Everytime I moved camss_parse_ports earlier or camss_init_subdevices
later I got into some kind of trouble, thus I assume current solution is
(at least until some rewrite) best.
David
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency
2026-01-17 15:36 ` [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency David Heidelberg via B4 Relay
@ 2026-01-17 20:27 ` kernel test robot
2026-01-17 21:56 ` Bryan O'Donoghue
1 sibling, 0 replies; 26+ messages in thread
From: kernel test robot @ 2026-01-17 20:27 UTC (permalink / raw)
To: David Heidelberg via B4 Relay, Robert Foss, Todor Tomov,
Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab,
Luca Weiss, Petr Hodina, Casey Connolly, Dr. Git
Cc: oe-kbuild-all, linux-media, Konrad Dybcio, Joel Selvaraj,
Kieran Bingham, Sakari Ailus, linux-arm-msm, linux-kernel,
phone-devel, David Heidelberg
Hi David,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 46fe65a2c28ecf5df1a7475aba1f08ccf4c0ac1b]
url: https://github.com/intel-lab-lkp/linux/commits/David-Heidelberg-via-B4-Relay/media-qcom-camss-csiphy-Introduce-PHY-configuration/20260117-234024
base: 46fe65a2c28ecf5df1a7475aba1f08ccf4c0ac1b
patch link: https://lore.kernel.org/r/20260117-qcom-cphy-v3-8-8ce76a06f7db%40ixit.cz
patch subject: [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20260118/202601180402.n3SE2vPM-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260118/202601180402.n3SE2vPM-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601180402.n3SE2vPM-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> Warning: drivers/media/platform/qcom/camss/camss.c:4296 function parameter 'cphy' not described in 'camss_get_link_freq'
>> Warning: drivers/media/platform/qcom/camss/camss.c:4296 function parameter 'cphy' not described in 'camss_get_link_freq'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration
2026-01-17 15:36 ` [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration David Heidelberg via B4 Relay
@ 2026-01-17 21:29 ` Bryan O'Donoghue
0 siblings, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:29 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> + if (lncfg->phy_cfg != V4L2_MBUS_CSI2_CPHY) {
> + lncfg->clk.pos = mipi_csi2->clock_lane;
> + lncfg->clk.pol = mipi_csi2->lane_polarities[0];
> + }
Just wondering as I look at this code; is it possible to set clock_lane
to say 0xff in DT ?
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-17 15:36 ` [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes David Heidelberg via B4 Relay
@ 2026-01-17 21:38 ` Bryan O'Donoghue
2026-01-18 12:05 ` Kieran Bingham
0 siblings, 1 reply; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:38 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
>
> 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 <david@ixit.cz>
> ---
> .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
> drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
> drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
> 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
> #include <linux/interrupt.h>
> #include <linux/io.h>
> +#include <linux/media-bus-format.h>
>
> #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 |= (1 << lane_cfg->data[i].pos) + 1;
1 << anything == BIT(anything)
I've always disliked the look of this code and now it occurs to me why.
This code is analogous to:
lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
but BIT() is less janky and more upstreamy.
janky/upstreamy - this is the on-point technical argument y'all came
here for :)
> + 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 |= 1 << lane_cfg->data[i].pos;
> + break;
> + default:
> + break;
> + }
>
> return lane_mask;
> }
> @@ -1027,10 +1037,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;
> @@ -1039,9 +1050,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));
> @@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
> wmb();
> }
>
> - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
> -
> - return 0;
> + return csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
ick.
More high brow stuff from bod here but, more seriously this is three
levels of indirection deep and the statement keeps getting longer.
Could you get a pointer to hw_ops() to reduce this down a bit.
> }
>
> /*
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
> index d198171700e73..21cf2ce931c1d 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
> @@ -73,9 +73,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);
>
With those tweaks.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support
2026-01-17 15:36 ` [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support David Heidelberg via B4 Relay
@ 2026-01-17 21:39 ` Bryan O'Donoghue
0 siblings, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:39 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
>
> 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 <david@ixit.cz>
> ---
> 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 ed1820488c987..b50b0cfe280c1 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -1275,6 +1275,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);
> }
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index aedc96ed84b2f..a82db31bd2335 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;
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available
2026-01-17 15:36 ` [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available David Heidelberg via B4 Relay
2026-01-17 15:53 ` David Heidelberg
@ 2026-01-17 21:45 ` Bryan O'Donoghue
1 sibling, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:45 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: Petr Hodina <phodina@protonmail.com>
>
> 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 <phodina@protonmail.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 91 ++++++++++++++--------
> 1 file changed, 57 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 f3a8625511e1e..9e8470358515f 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
> @@ -1048,6 +1048,62 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
> u8 val;
> int i;
>
> + switch (csiphy->camss->res->version) {
> + case CAMSS_845:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_sdm845[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
> + }
> + break;
> + case CAMSS_2290:
> + case CAMSS_6150:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_qcm2290[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_qcm2290);
> + }
> + break;
> + case CAMSS_7280:
> + case CAMSS_8250:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_sm8250[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
> + }
> + break;
> + case CAMSS_8280XP:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_sc8280xp[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp);
> + }
> + break;
> + case CAMSS_X1E80100:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_x1e80100[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_x1e80100);
> + }
> + break;
> + case CAMSS_8550:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_sm8550[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550);
> + }
> + break;
> + case CAMSS_8650:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + regs->lane_regs = &lane_regs_sm8650[0];
> + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650);
> + }
> + break;
> + case CAMSS_8300:
> + case CAMSS_8775P:
> + { /* V4L2_MBUS_CSI2_DPHY */
> + 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;
> @@ -1119,49 +1175,16 @@ 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:
> - 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;
> }
>
>
Subject to testing.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
2026-01-17 15:36 ` [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init David Heidelberg via B4 Relay
@ 2026-01-17 21:49 ` Bryan O'Donoghue
2026-01-18 9:51 ` David Heidelberg
0 siblings, 1 reply; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:49 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: Casey Connolly <casey.connolly@linaro.org>
>
> 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 <casey.connolly@linaro.org>
> Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Co-developed-by: David Heidelberg <david@ixit.cz>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 70 +++++++++++++++++++++-
> 1 file changed, 69 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 9e8470358515f..f819472511823 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,69 @@ 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[] = {
> @@ -1050,7 +1114,11 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
>
> switch (csiphy->camss->res->version) {
> case CAMSS_845:
> - { /* V4L2_MBUS_CSI2_DPHY */
> + 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 { /* V4L2_MBUS_CSI2_DPHY */
This is inconsistent commenting Ted and I'd reckon something
checkpatch.pl spits back at you.
If checkpatch.pl doesn't complain about it, I think it probably should.
Please standardise the location of the comment and have one for the CPHY
and one for the DPHY configs.
> regs->lane_regs = &lane_regs_sdm845[0];
> regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
> }
>
Once implemented.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init
2026-01-17 15:36 ` [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init David Heidelberg via B4 Relay
@ 2026-01-17 21:51 ` Bryan O'Donoghue
0 siblings, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:51 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: Luca Weiss <luca.weiss@fairphone.com>
>
> 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 <luca.weiss@fairphone.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 110 ++++++++++++++++++++-
> 1 file changed, 109 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 f819472511823..d82a88dad74b5 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
> @@ -548,6 +548,111 @@ 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[] = {
> @@ -1132,7 +1237,10 @@ static int csiphy_lanes_enable(struct csiphy_device *csiphy,
> break;
> case CAMSS_7280:
> case CAMSS_8250:
> - { /* V4L2_MBUS_CSI2_DPHY */
> + 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 { /* V4L2_MBUS_CSI2_DPHY */
> regs->lane_regs = &lane_regs_sm8250[0];
> regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
> }
>
Glorious, two PHY init sequences in the one go. It feels like an analog
to my birthday.
BOD makes technology jokes.
Please fixup the comment in the code per previous patch comment.
Then.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration
2026-01-17 15:36 ` [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration David Heidelberg via B4 Relay
@ 2026-01-17 21:54 ` Bryan O'Donoghue
0 siblings, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:54 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
>
> 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.
>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> drivers/media/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 d82a88dad74b5..89bfe3710fc3a 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
> @@ -1217,6 +1217,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(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) {
>
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.
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency
2026-01-17 15:36 ` [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency David Heidelberg via B4 Relay
2026-01-17 20:27 ` kernel test robot
@ 2026-01-17 21:56 ` Bryan O'Donoghue
1 sibling, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-17 21:56 UTC (permalink / raw)
To: david, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
>
> 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 <sakari.ailus@linux.intel.com>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> drivers/media/platform/qcom/camss/camss-csid.c | 2 +-
> drivers/media/platform/qcom/camss/camss-csiphy.c | 6 ++++--
> drivers/media/platform/qcom/camss/camss.c | 16 +++++++++++++---
> drivers/media/platform/qcom/camss/camss.h | 2 +-
> 4 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index b50b0cfe280c1..24f244d2959c9 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -545,7 +545,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);
> + csid->phy.lane_cnt, csid->phy.cphy);
Just pass &csid->phy ..
> if (link_freq < 0)
> link_freq = 0;
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index 08dd238e52799..1ea0d0ef354ff 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -144,8 +144,9 @@ static int csiphy_set_clock_rates(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;
> + bool cphy = csiphy->cfg.csi2->lane_cfg.phy_cfg == V4L2_MBUS_CSI2_CPHY;
>
> - link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
> + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes, cphy);
CPHY shouldn't be a boolean special case - you have a use-case for the
containing structure, so pass that instead.
> if (link_freq < 0)
> link_freq = 0;
>
> @@ -270,9 +271,10 @@ static int csiphy_stream_on(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;
> + bool cphy = csiphy->cfg.csi2->lane_cfg.phy_cfg == V4L2_MBUS_CSI2_CPHY;
> u8 val;
>
> - link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
> + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes, cphy);
>
> if (link_freq < 0) {
> dev_err(csiphy->camss->dev,
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index ea0c8cf3cd806..556fedd92e065 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -32,6 +32,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[] = {
> @@ -4280,20 +4288,22 @@ struct media_pad *camss_find_sensor_pad(struct media_entity *entity)
> * camss_get_link_freq - Get link frequency from sensor
> * @entity: Media entity in the current pipeline
> * @bpp: Number of bits per pixel for the current format
> - * @lanes: Number of lanes in the link to the sensor
> + * @nr_of_lanes: Number of lanes in the link to the sensor
> *
> * 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)
> + unsigned int nr_of_lanes, bool cphy)
> {
> struct media_pad *sensor_pad;
> + unsigned int div = nr_of_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 6d048414c919e..6bf7738837b89 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -163,7 +163,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);
> + unsigned int lanes, bool cphy);
> 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);
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
2026-01-17 21:49 ` Bryan O'Donoghue
@ 2026-01-18 9:51 ` David Heidelberg
2026-01-18 10:27 ` Bryan O'Donoghue
0 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg @ 2026-01-18 9:51 UTC (permalink / raw)
To: Bryan O'Donoghue, Robert Foss, Todor Tomov,
Vladimir Zapolskiy, Mauro Carvalho Chehab, Luca Weiss,
Petr Hodina, Casey Connolly, Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 17/01/2026 22:49, Bryan O'Donoghue wrote:
> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
>> From: Casey Connolly <casey.connolly@linaro.org>
>>
>> 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 <casey.connolly@linaro.org>
>> Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>> Co-developed-by: David Heidelberg <david@ixit.cz>
>> Signed-off-by: David Heidelberg <david@ixit.cz>
>> ---
>> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 70 ++++++++++++
>> +++++++++-
>> 1 file changed, 69 insertions(+), 1 deletion(-)
>>
[...]
>> @@ -1050,7 +1114,11 @@ static int csiphy_lanes_enable(struct
>> csiphy_device *csiphy,
>> switch (csiphy->camss->res->version) {
>> case CAMSS_845:
>> - { /* V4L2_MBUS_CSI2_DPHY */
>> + 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 { /* V4L2_MBUS_CSI2_DPHY */
>
> This is inconsistent commenting Ted and I'd reckon something
> checkpatch.pl spits back at you.
>
> If checkpatch.pl doesn't complain about it, I think it probably should.
>
> Please standardise the location of the comment and have one for the CPHY
> and one for the DPHY configs.
Then I can rather replace the else with elseif (== DPHY) and make the
comment irrelevant. What is your recommendation?
David>
>> regs->lane_regs = &lane_regs_sdm845[0];
>> regs->lane_array_size = ARRAY_SIZE(lane_regs_sdm845);
>> }
>>
>
> Once implemented.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> ---
> bod
--
David Heidelberg
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init
2026-01-18 9:51 ` David Heidelberg
@ 2026-01-18 10:27 ` Bryan O'Donoghue
0 siblings, 0 replies; 26+ messages in thread
From: Bryan O'Donoghue @ 2026-01-18 10:27 UTC (permalink / raw)
To: David Heidelberg, Robert Foss, Todor Tomov, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Luca Weiss, Petr Hodina, Casey Connolly,
Dr. Git
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 18/01/2026 09:51, David Heidelberg wrote:
>>
>> If checkpatch.pl doesn't complain about it, I think it probably should.
>>
>> Please standardise the location of the comment and have one for the
>> CPHY and one for the DPHY configs.
>
> Then I can rather replace the else with elseif (== DPHY) and make the
> comment irrelevant. What is your recommendation?
>
> David>
I think the code is pretty self-documenting without a comment.
---
bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-17 21:38 ` Bryan O'Donoghue
@ 2026-01-18 12:05 ` Kieran Bingham
2026-01-18 12:45 ` David Heidelberg
` (2 more replies)
0 siblings, 3 replies; 26+ messages in thread
From: Kieran Bingham @ 2026-01-18 12:05 UTC (permalink / raw)
To: Bryan O'Donoghue, Casey Connolly, Dr. Git, Luca Weiss,
Mauro Carvalho Chehab, Petr Hodina, Robert Foss, Todor Tomov,
Vladimir Zapolskiy, david
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
Quoting Bryan O'Donoghue (2026-01-17 21:38:17)
> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> > From: David Heidelberg <david@ixit.cz>
> >
> > 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 <david@ixit.cz>
> > ---
> > .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
> > .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
> > drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
> > drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
> > 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
> > #include <linux/interrupt.h>
> > #include <linux/io.h>
> > +#include <linux/media-bus-format.h>
> >
> > #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 |= (1 << lane_cfg->data[i].pos) + 1;
>
> 1 << anything == BIT(anything)
>
> I've always disliked the look of this code and now it occurs to me why.
>
> This code is analogous to:
>
> lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
I see that addition to a bit mask and get a little bit scared.
This gives:
pos mask
0 0b00000010 (note 0 bit is zero here but 1 on all others)
1 0b00000011
2 0b00000101
3 0b00001001
4 0b00010001
Is that expected?
Can data[i].pos ever be position 0 ??
I assume this starts at position 1 - and the +1 here is to always set
the zeroth bit ?
Perhapse this might be precise to convey that in such a case?
lane_mask |= BIT(pos) | 1;
I guess it depends on what this is really being used for which I don't
have in my context.
--
Kieran
>
> but BIT() is less janky and more upstreamy.
>
> janky/upstreamy - this is the on-point technical argument y'all came
> here for :)
>
> > + 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 |= 1 << lane_cfg->data[i].pos;
> > + break;
> > + default:
> > + break;
> > + }
> >
> > return lane_mask;
> > }
> > @@ -1027,10 +1037,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;
> > @@ -1039,9 +1050,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));
> > @@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
> > --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> > +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> > @@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
> > wmb();
> > }
> >
> > - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
> > -
> > - return 0;
> > + return csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
>
> ick.
>
> More high brow stuff from bod here but, more seriously this is three
> levels of indirection deep and the statement keeps getting longer.
>
> Could you get a pointer to hw_ops() to reduce this down a bit.
>
> > }
> >
> > /*
> > diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
> > index d198171700e73..21cf2ce931c1d 100644
> > --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
> > +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
> > @@ -73,9 +73,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);
> >
>
> With those tweaks.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>
> ---
> bod
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-18 12:05 ` Kieran Bingham
@ 2026-01-18 12:45 ` David Heidelberg
2026-02-20 17:44 ` David Heidelberg
2026-02-28 22:37 ` David Heidelberg
2 siblings, 0 replies; 26+ messages in thread
From: David Heidelberg @ 2026-01-18 12:45 UTC (permalink / raw)
To: Kieran Bingham, Bryan O'Donoghue, Casey Connolly, Dr. Git,
Luca Weiss, Mauro Carvalho Chehab, Petr Hodina, Robert Foss,
Todor Tomov, Vladimir Zapolskiy
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 18/01/2026 13:05, Kieran Bingham wrote:
> Quoting Bryan O'Donoghue (2026-01-17 21:38:17)
>> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
>>> From: David Heidelberg <david@ixit.cz>
>>>
>>> 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 <david@ixit.cz>
>>> ---
>>> .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
>>> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
>>> drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
>>> drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
>>> 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
>>> #include <linux/interrupt.h>
>>> #include <linux/io.h>
>>> +#include <linux/media-bus-format.h>
>>>
>>> #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 |= (1 << lane_cfg->data[i].pos) + 1;
>>
>> 1 << anything == BIT(anything)
>>
>> I've always disliked the look of this code and now it occurs to me why.
>>
>> This code is analogous to:
>>
>> lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
>
> I see that addition to a bit mask and get a little bit scared.
>
> This gives:
> pos mask
> 0 0b00000010 (note 0 bit is zero here but 1 on all others)
> 1 0b00000011
> 2 0b00000101
> 3 0b00001001
> 4 0b00010001
>
> Is that expected?
>
> Can data[i].pos ever be position 0 ??
>
> I assume this starts at position 1 - and the +1 here is to always set
> the zeroth bit ?
>
> Perhapse this might be precise to convey that in such a case?
>
> lane_mask |= BIT(pos) | 1;
>
> I guess it depends on what this is really being used for which I don't
> have in my context.
If it's relevant, that's how the usage looks like:
https://gitlab.com/sdm845/sdm845-next/-/blob/sdm845-next/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi#L559
David>
> --
> Kieran
[...]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-18 12:05 ` Kieran Bingham
2026-01-18 12:45 ` David Heidelberg
@ 2026-02-20 17:44 ` David Heidelberg
2026-02-28 22:37 ` David Heidelberg
2 siblings, 0 replies; 26+ messages in thread
From: David Heidelberg @ 2026-02-20 17:44 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Konrad Dybcio,
Dmitry Baryshkov, Bjorn Andersson
Cc: Joel Selvaraj, Kieran Bingham, Robert Foss, Todor Tomov,
Casey Connolly, Sakari Ailus, linux-media, Luca Weiss,
linux-arm-msm, Mauro Carvalho Chehab, Kieran Bingham,
linux-kernel, phone-devel, Dr. Git, Petr Hodina
On 18/01/2026 13:05, Kieran Bingham wrote:
> Quoting Bryan O'Donoghue (2026-01-17 21:38:17)
>> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
>>> From: David Heidelberg <david@ixit.cz>
>>>
>>> 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 <david@ixit.cz>
>>> ---
>>> .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
>>> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
>>> drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
>>> drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
>>> 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
>>> #include <linux/interrupt.h>
>>> #include <linux/io.h>
>>> +#include <linux/media-bus-format.h>
>>>
>>> #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 |= (1 << lane_cfg->data[i].pos) + 1;
>>
>> 1 << anything == BIT(anything)
>>
>> I've always disliked the look of this code and now it occurs to me why.
>>
>> This code is analogous to:
>>
>> lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
>
> I see that addition to a bit mask and get a little bit scared.
>
> This gives:
> pos mask
> 0 0b00000010 (note 0 bit is zero here but 1 on all others)
> 1 0b00000011
> 2 0b00000101
> 3 0b00001001
> 4 0b00010001
>
> Is that expected?
>
> Can data[i].pos ever be position 0 ??
>
> I assume this starts at position 1 - and the +1 here is to always set
> the zeroth bit ?
>
> Perhapse this might be precise to convey that in such a case?
>
> lane_mask |= BIT(pos) | 1;
>
> I guess it depends on what this is really being used for which I don't
> have in my context.
I currently don't see clear way forward, maybe someone from qcom could
give a hint how to continue?
Thanks
David
>
> --
> Kieran
>
>
>
>>
>> but BIT() is less janky and more upstreamy.
>>
>> janky/upstreamy - this is the on-point technical argument y'all came
>> here for :)
>>
>>> + 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 |= 1 << lane_cfg->data[i].pos;
>>> + break;
>>> + default:
>>> + break;
>>> + }
>>>
>>> return lane_mask;
>>> }
>>> @@ -1027,10 +1037,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;
>>> @@ -1039,9 +1050,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));
>>> @@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
>>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
>>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
>>> @@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
>>> wmb();
>>> }
>>>
>>> - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
>>> -
>>> - return 0;
>>> + return csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
>>
>> ick.
>>
>> More high brow stuff from bod here but, more seriously this is three
>> levels of indirection deep and the statement keeps getting longer.
>>
>> Could you get a pointer to hw_ops() to reduce this down a bit.
>>
>>> }
>>>
>>> /*
>>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> index d198171700e73..21cf2ce931c1d 100644
>>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> @@ -73,9 +73,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);
>>>
>>
>> With those tweaks.
>>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>>
>> ---
>> bod
--
David Heidelberg
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-01-18 12:05 ` Kieran Bingham
2026-01-18 12:45 ` David Heidelberg
2026-02-20 17:44 ` David Heidelberg
@ 2026-02-28 22:37 ` David Heidelberg
2026-03-01 11:42 ` Kieran Bingham
2 siblings, 1 reply; 26+ messages in thread
From: David Heidelberg @ 2026-02-28 22:37 UTC (permalink / raw)
To: Kieran Bingham, Bryan O'Donoghue, Casey Connolly, Dr. Git,
Luca Weiss, Mauro Carvalho Chehab, Petr Hodina, Robert Foss,
Todor Tomov, Vladimir Zapolskiy
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
On 18/01/2026 13:05, Kieran Bingham wrote:
> Quoting Bryan O'Donoghue (2026-01-17 21:38:17)
>> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
>>> From: David Heidelberg <david@ixit.cz>
>>>
>>> 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 <david@ixit.cz>
>>> ---
>>> .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
>>> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
>>> drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
>>> drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
>>> 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
>>> #include <linux/interrupt.h>
>>> #include <linux/io.h>
>>> +#include <linux/media-bus-format.h>
>>>
>>> #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 |= (1 << lane_cfg->data[i].pos) + 1;
>>
>> 1 << anything == BIT(anything)
>>
>> I've always disliked the look of this code and now it occurs to me why.
>>
>> This code is analogous to:
>>
>> lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
>
> I see that addition to a bit mask and get a little bit scared.
>
> This gives:
> pos mask
> 0 0b00000010 (note 0 bit is zero here but 1 on all others)
> 1 0b00000011
> 2 0b00000101
> 3 0b00001001
> 4 0b00010001
>
> Is that expected?
>
> Can data[i].pos ever be position 0 ??
>
> I assume this starts at position 1 - and the +1 here is to always set
> the zeroth bit ?
>
> Perhapse this might be precise to convey that in such a case?
>
> lane_mask |= BIT(pos) | 1;
>
> I guess it depends on what this is really being used for which I don't
> have in my context.
Ok, I started looking again into the lovely downstream code.
D-PHY has bits 0b0D_D_D_D
C-PHY has bits 0b0_C_C_C_
so for some reason it worked in my usecase without proper lane mask, but
the original formula should be
- lane_mask |= (1 << lane_cfg->data[i].pos) + 1;
+ lane_mask |= (1 << lane_cfg->data[i].pos + 1);
Thus
BIT(lane_cfg->data[i].pos + 1);
>
> --
> Kieran
>
>
>
>>
>> but BIT() is less janky and more upstreamy.
>>
>> janky/upstreamy - this is the on-point technical argument y'all came
>> here for :)
>>
>>> + 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 |= 1 << lane_cfg->data[i].pos;
>>> + break;
>>> + default:
>>> + break;
>>> + }
>>>
>>> return lane_mask;
>>> }
>>> @@ -1027,10 +1037,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;
>>> @@ -1039,9 +1050,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));
>>> @@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
>>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
>>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
>>> @@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
>>> wmb();
>>> }
>>>
>>> - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
>>> -
>>> - return 0;
>>> + return csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
>>
>> ick.
>>
>> More high brow stuff from bod here but, more seriously this is three
>> levels of indirection deep and the statement keeps getting longer.
>>
>> Could you get a pointer to hw_ops() to reduce this down a bit.
>>
>>> }
>>>
>>> /*
>>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> index d198171700e73..21cf2ce931c1d 100644
>>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
>>> @@ -73,9 +73,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);
>>>
>>
>> With those tweaks.
>>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
>>
>> ---
>> bod
--
David Heidelberg
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes
2026-02-28 22:37 ` David Heidelberg
@ 2026-03-01 11:42 ` Kieran Bingham
0 siblings, 0 replies; 26+ messages in thread
From: Kieran Bingham @ 2026-03-01 11:42 UTC (permalink / raw)
To: Bryan O'Donoghue, Casey Connolly, David Heidelberg, Dr. Git,
Luca Weiss, Mauro Carvalho Chehab, Petr Hodina, Robert Foss,
Todor Tomov, Vladimir Zapolskiy
Cc: Konrad Dybcio, Joel Selvaraj, Kieran Bingham, Sakari Ailus,
linux-media, linux-arm-msm, linux-kernel, phone-devel
Quoting David Heidelberg (2026-02-28 22:37:57)
> On 18/01/2026 13:05, Kieran Bingham wrote:
> > Quoting Bryan O'Donoghue (2026-01-17 21:38:17)
> >> On 17/01/2026 15:36, David Heidelberg via B4 Relay wrote:
> >>> From: David Heidelberg <david@ixit.cz>
> >>>
> >>> 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 <david@ixit.cz>
> >>> ---
> >>> .../platform/qcom/camss/camss-csiphy-2ph-1-0.c | 8 ++--
> >>> .../platform/qcom/camss/camss-csiphy-3ph-1-0.c | 49 +++++++++++++++++-----
> >>> drivers/media/platform/qcom/camss/camss-csiphy.c | 4 +-
> >>> drivers/media/platform/qcom/camss/camss-csiphy.h | 6 +--
> >>> 4 files changed, 47 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 4154832745525..f3a8625511e1e 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 <linux/delay.h>
> >>> #include <linux/interrupt.h>
> >>> #include <linux/io.h>
> >>> +#include <linux/media-bus-format.h>
> >>>
> >>> #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 |= (1 << lane_cfg->data[i].pos) + 1;
> >>
> >> 1 << anything == BIT(anything)
> >>
> >> I've always disliked the look of this code and now it occurs to me why.
> >>
> >> This code is analogous to:
> >>
> >> lane_mask |= BIT(lane_cfg->data[i].pos) + 1);
> >
> > I see that addition to a bit mask and get a little bit scared.
> >
> > This gives:
> > pos mask
> > 0 0b00000010 (note 0 bit is zero here but 1 on all others)
> > 1 0b00000011
> > 2 0b00000101
> > 3 0b00001001
> > 4 0b00010001
> >
> > Is that expected?
> >
> > Can data[i].pos ever be position 0 ??
> >
> > I assume this starts at position 1 - and the +1 here is to always set
> > the zeroth bit ?
> >
> > Perhapse this might be precise to convey that in such a case?
> >
> > lane_mask |= BIT(pos) | 1;
> >
> > I guess it depends on what this is really being used for which I don't
> > have in my context.
>
> Ok, I started looking again into the lovely downstream code.
>
> D-PHY has bits 0b0D_D_D_D
> C-PHY has bits 0b0_C_C_C_
>
> so for some reason it worked in my usecase without proper lane mask, but
> the original formula should be
>
> - lane_mask |= (1 << lane_cfg->data[i].pos) + 1;
> + lane_mask |= (1 << lane_cfg->data[i].pos + 1);
>
> Thus
>
> BIT(lane_cfg->data[i].pos + 1);
That looks a lot more sane!
--
Kieran
>
> >
> > --
> > Kieran
> >
> >
> >
> >>
> >> but BIT() is less janky and more upstreamy.
> >>
> >> janky/upstreamy - this is the on-point technical argument y'all came
> >> here for :)
> >>
> >>> + 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 |= 1 << lane_cfg->data[i].pos;
> >>> + break;
> >>> + default:
> >>> + break;
> >>> + }
> >>>
> >>> return lane_mask;
> >>> }
> >>> @@ -1027,10 +1037,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;
> >>> @@ -1039,9 +1050,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));
> >>> @@ -1068,6 +1093,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 62623393f4144..08dd238e52799 100644
> >>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> >>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> >>> @@ -295,9 +295,7 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
> >>> wmb();
> >>> }
> >>>
> >>> - csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
> >>> -
> >>> - return 0;
> >>> + return csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
> >>
> >> ick.
> >>
> >> More high brow stuff from bod here but, more seriously this is three
> >> levels of indirection deep and the statement keeps getting longer.
> >>
> >> Could you get a pointer to hw_ops() to reduce this down a bit.
> >>
> >>> }
> >>>
> >>> /*
> >>> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.h b/drivers/media/platform/qcom/camss/camss-csiphy.h
> >>> index d198171700e73..21cf2ce931c1d 100644
> >>> --- a/drivers/media/platform/qcom/camss/camss-csiphy.h
> >>> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.h
> >>> @@ -73,9 +73,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);
> >>>
> >>
> >> With those tweaks.
> >>
> >> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> >>
> >> ---
> >> bod
>
> --
> David Heidelberg
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-03-01 11:43 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-17 15:36 [PATCH v3 0/8] media: camss: Add support for C-PHY configuration on Qualcomm platforms David Heidelberg via B4 Relay
2026-01-17 15:36 ` [PATCH v3 1/8] media: qcom: camss: csiphy: Introduce PHY configuration David Heidelberg via B4 Relay
2026-01-17 21:29 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 2/8] media: qcom: camss: csiphy-3ph: Use odd bits for configuring C-PHY lanes David Heidelberg via B4 Relay
2026-01-17 21:38 ` Bryan O'Donoghue
2026-01-18 12:05 ` Kieran Bingham
2026-01-18 12:45 ` David Heidelberg
2026-02-20 17:44 ` David Heidelberg
2026-02-28 22:37 ` David Heidelberg
2026-03-01 11:42 ` Kieran Bingham
2026-01-17 15:36 ` [PATCH v3 3/8] media: qcom: camss: Prepare CSID for C-PHY support David Heidelberg via B4 Relay
2026-01-17 21:39 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 4/8] media: qcom: camss: Initialize lanes after lane configuration is available David Heidelberg via B4 Relay
2026-01-17 15:53 ` David Heidelberg
2026-01-17 21:45 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 5/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.1 MIPI CSI-2 CPHY init David Heidelberg via B4 Relay
2026-01-17 21:49 ` Bryan O'Donoghue
2026-01-18 9:51 ` David Heidelberg
2026-01-18 10:27 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 6/8] media: qcom: camss: csiphy-3ph: Add Gen2 v1.2.1 MIPI CSI-2 C-PHY init David Heidelberg via B4 Relay
2026-01-17 21:51 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 7/8] media: qcom: camss: csiphy-3ph: C-PHY needs own lane configuration David Heidelberg via B4 Relay
2026-01-17 21:54 ` Bryan O'Donoghue
2026-01-17 15:36 ` [PATCH v3 8/8] media: qcom: camss: Account for C-PHY when calculating link frequency David Heidelberg via B4 Relay
2026-01-17 20:27 ` kernel test robot
2026-01-17 21:56 ` Bryan O'Donoghue
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox