* [PATCH v23 00/15] media: qcom: camss: Add Kaanapali support
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Krzysztof Kozlowski, Atiya Kailany, Konrad Dybcio
Add support for the RDI only CAMSS camera driver on Kaanapali. Enabling
RDI path involves adding the support for a set of CSIPHY, CSID and TFE
modules, with each TFE having multiple RDI ports. This hardware
architecture requires 'qdss_debug_xo' clock for CAMNOC to be functional.
Kaanapali camera subsystem provides:
- 6 x CSIPHY (CSI Physical Layer)
- 3 x TPG (Test Pattern Generator)
- 3 x CSID (CSI Decoder)
- 2 x CSID Lite
- 3 x VFE (Video Front End), 5 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE Lite
This series has been tested using the following commands with S5KJN5 sensor.
- media-ctl --reset
- media-ctl -V '"msm_csiphy2":0[fmt:SGBRG10/4096x3072]'
- media-ctl -V '"msm_csid0":0[fmt:SGBRG10/4096x3072]'
- media-ctl -V '"msm_vfe0_rdi0":0[fmt:SGBRG10/4096x3072]'
- media-ctl -l '"msm_csiphy2":1->"msm_csid0":0[1]'
- media-ctl -l '"msm_csid0":1->"msm_vfe0_rdi0":0[1]'
- yavta --capture=20 -I -n 5 -f SGBRG10P -s 4096x3072 -F /dev/video0
PHY driver part for maintainer Vinod Koul (3):
[1] dt-bindings: phy: qcom,x1e80100-csi2-phy: Add Kaanapali CSI2 PHY
[2] phy: qcom-mipi-csi2: Parametrise the common status register offset
[3] phy: qcom-mipi-csi2: Add Kaanapali support
CAMSS driver part for maintainer Bryan O'Donoghue (8):
[1] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
[2] media: dt-bindings: Add CAMSS device for Kaanapali
[3] media: qcom: camss: Add Kaanapali compatible
[4] media: qcom: camss: Add PM clock definitions for Kaanapali
[5] media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
[6] media: qcom: camss: csid: Add support for CSID 1080
[7] media: qcom: camss: vfe: Add support for VFE 1080
[8] media: qcom: camss: tpg: Add support for v2.4.0 TPG
DTS part for maintainer Bjorn Andersson (4):
[1] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
[2] arm64: dts: qcom: kaanapali: Add CCI controller nodes
[3] arm64: dts: qcom: kaanapali: Add camera MCLK pinctrl
[4] arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
Changes in v23:
- Add the CAMSS top register region to the DTS - Loic
- Use the GPIO function with bias disabled for CCI sleep states - Loic
- Move the common CPAS/GCC AHB and AXI clocks to the pm_clks array
in a separate patch and drop them from the VFE clock lists - Loic
- Replace the CSID AUP/RUP union with separate reg_update/addr_update
field pairs to simplify the logic - Loic
- Link to v22: https://patch.msgid.link/20261024-kaanapali-camss-v22-0-7da3ea49c8a1@oss.qualcomm.com
Changes in v22:
- Add addr_update operation function to CSID and VFE to extend the
CAMSS capability for split AUP/RUP in CSID instead of traversing
the media graph to dig out CSID reg_update capability - Loic/bod
- Modify CSID 1080 and VFE 1080 to adapt the split AUP/RUP design
- Add SOF and EOF enable bits with top level RDI status offset to
allow their corresponding interrupts but not configured on - bod
- Remove redundant space between the specific property and its
paired property name - Konrad
- Collect RBs and Acks from Bryan and Konrad
- Link to v21: https://patch.msgid.link/20261011-kaanapali-camss-v21-0-04fd28d815c6@oss.qualcomm.com
Changes in v21:
- Drop reg_update_after_csid_config flag. Skip the VFE-side stream-on
REG_UPDATE only when the connected CSID implements reg_update - bod
- Add address and size cell properties in camera node to avoid
potential warnings during compilation
- Link to v20: https://patch.msgid.link/20261010-kaanapali-camss-v20-0-63e98ce9ac0c@oss.qualcomm.com
Changes in v20:
- Remove the redundant null check for reg_update_clear in VFE - bod
- Define the port property for CSIPHY nodes and align the style of
CAMSS and CSIPHY nodes - bod
- Replace bias-pull-up and bias-pull-down with bias-disable for the
SCL/SDA pins of CCI nodes in TLMM, as internal weak pull is inproper
with existing board level pull up resistors - Loic
- Align the if-else condition in TPG version judgement and remove the
redundant comments in TPG code but describe the hardware changes in
commit description
- Add Kaanapali camera subsystem and S5KJN5 enablement dtso
- Link to v19: https://patch.msgid.link/20261008-kaanapali-camss-v19-0-b2c583ef50e0@oss.qualcomm.com
Changes in v19:
- Remove the internal CSIPHY hardware operations for CAMSS - bod
- Collect RBs tags from Bryan and Rob for CAMSS binding - bod/Rob
- Split the PHY and CAMSS into separate parts and document the
corresponding maintainers in cover letter - bod
- Link to v18: https://patch.msgid.link/20261003-kaanapali-camss-v18-0-87ba4ebe0db1@oss.qualcomm.com
Changes in v18:
- Rename CSID and VFE hardware version from Gen4 to 1080 - bod
- Correct the description for CAMSS ports in binding - Krzysztof
- Add lane count fallback path for CSID RX configuration - Sashiko
- Align the TFE lite line count with the commit description - Sashiko
- Use hyphenated pattern for MCLK node names - Sashiko
- Resolve conflicts introduced by Glymur in CSI2 PHY binding
- Correct the spelling mistakes in cover letter and enhance commit
description for compatible and CSIPHY
- Link to v17: https://lore.kernel.org/r/20260928-kaanapali-camss-v17-0-dcf3fd37f76c@oss.qualcomm.com
Changes in v17:
- Rebase due to CSIPHY re-arch dependencies merged - bod
- Remove redundant CSIPHY resources in CAMSS block
- Enhance the commit title description for CAMSS and CSIPHY blocks
- Collet RBs from Loic
- Link to v16: https://lore.kernel.org/r/20260915-kaanapali-camss-v16-0-c9f3f6f4180c@oss.qualcomm.com
Changes in v16:
- Remove RBs for binding, CSIPHY and CAMSS DT as tags stale due to
split-CSIPHY re-arch - Krzysztof
- Update CAMSS bindings and driver support for the standalone CSI2 PHY
provider and graph-based PHY lookup model - bod
- Add the CDM IOMMU stream and simplify CAMSS binding example part by
removing redundant subnodes - bod
- Improve commit descriptions for CAMSS compatible, CSID, VFE, TPG
- Clarify the common-status-offset change with x1e80100 compatibility
details and future SoC offset considerations
- Add Kaanapali camera DT descriptions, including CAMSS, six CSIPHYs,
three CCI controllers, camera-control I2C, and MCLK pinctrl states
- Rename I2C and MCLK pinctrl nodes to include interface identifiers
- Link to v15: https://lore.kernel.org/r/20260720-kaanapali-camss-v15-0-c0b1c1167c5d@oss.qualcomm.com
Changes in v15:
- Add TPG v2.4.0 support
- Drive the CSIPHY through the standalone phy-qcom-mipi-csi2 DPHY
driver, which let CAMSS csiphy_res only carry id, ops and formats
- Add a preparatory patch parametrising the PHY common status offset
- Add the mipi_csi2_dphy_3nm_kaanapali config and "qcom,kaanapali-csi2-phy"
based on the new split-csiphy arch
- Link to v14: https://lore.kernel.org/r/20260601-kaanapali-camss-v14-0-e76f26aa6691@oss.qualcomm.com
Changes in v14:
- Define 'CSI2_RX_CFG0_PHY_SEL_BASE_IDX' locally in camss-csid-gen4.c - bod
- Align csiphy lane registers value capitalization and case rule for 2.4.0
- Rebase this series due to conflict - bod
- Link to v13: https://lore.kernel.org/r/20260508-kaanapali-camss-v13-0-2541d8e55651@oss.qualcomm.com
Changes in v13:
- Remove prerequisite dependencies that have been merged upstream
- Remove redundant empty 'regulators' initializers in csid and vfe - bod
- Revert binding from full hardware description to CAMSS-only scope for
modular and incremental development - bod
- Rename icc path names and vfe clock names to drop redundancies - Krzysztof
- Separate port index from VC value in csid_configure_stream(). Previously
vc was used as both the loop iterator and the hardware VC, causing
misconfiguration on RDI path starting from 1 - bod
- Link to v12: https://lore.kernel.org/all/20260112-kaanapali-camss-v12-0-15b7af73401e@oss.qualcomm.com/
Changes in v12:
- Add CSIPHY regulator current due to regulator interface changed - bod
- Link to v11: https://lore.kernel.org/r/20260112-kaanapali-camss-v11-0-81e4f59a5d08@oss.qualcomm.com
Changes in v11:
- Rebase this series due to conflict - bod
- Update binding commit message to align with previous generations
- Link to v10: https://lore.kernel.org/r/20251211-add-support-for-camss-on-kaanapali-v10-0-39e8874dcd27@oss.qualcomm.com
Changes in v10:
- Update interconnect and CX domain AXI clock names to be consistent with
previous generations - bod
- Update the struct name for csiphy lane register settings to make it reusable
for other compatible chipsets
- Updated power domain names to IFE for consistency - Krzysztof
- Add description for acronyms listed in binding commit message - Dmitry
- Link to v9: https://lore.kernel.org/r/20251208-add-support-for-camss-on-kaanapali-v9-0-3fcd31258415@oss.qualcomm.com
Changes in v9:
- Updates the names of some of the resources in DT bindings to be consistent
with previous generations and improve the commit its message. The name
changes are also applied to csiphy and vfe camss resource lists - bod
- Link to v8: https://lore.kernel.org/r/20251130-add-support-for-camss-on-kaanapali-v8-0-143a8265e6e8@oss.qualcomm.com
Changes in v8:
- Change csid and vfe driver file names as 'gen4' to reuse for other SOCs - bod
- Add missing register descriptions to binding and cover letter commit log - bod
- Link to v7: https://lore.kernel.org/r/20251120-add-support-for-camss-on-kaanapali-v7-0-de27f9a67ce6@oss.qualcomm.com
Changes in v7:
- Add ICP SYS registers to camss binding - bod
- Rename 'is_deferred' to 'reg_update_after_csid_config' to do rup/aup
after csid config to make it clearer and simplify its call path - bod
- Remove unnecessary bitwise AND while configuring image address to bus- bod
- Tidy up a comment and a couple of hex values and csid/vfe - bod
- Link to v6: https://lore.kernel.org/r/20251113-add-support-for-camss-on-kaanapali-v6-0-1e6038785a8e@oss.qualcomm.com
Changes in v6:
- Modified the bindings to represent the whole of the camera hardware on
KNP than just what is exercised by the CAMSS driver by extending the
descriptions and the properties, the regs, clocks, interrupts, power
domains, iommus etc. In addition, use the word 'vfe' everywhere in the
bindings to be clear that all of those resources are referring to the
same front end modules. - Krzysztof/bod
- Change camss vfe power domain names to align with the binding file
- Link to v5: https://lore.kernel.org/r/20251030-add-support-for-camss-on-kaanapali-v5-0-f8e12bea3d02@oss.qualcomm.com
Changes in v5:
- Refine v4 change log - Krzysztof
- Fix typo by removing redundant numerical version in kaanapali camss binding
comment description - Krzysztof
- Add missing tags that should be posted with v4 revision - Krzysztof/Andi
- Link to v4: https://lore.kernel.org/r/20251028-add-support-for-camss-on-kaanapali-v4-0-7eb484c89585@oss.qualcomm.com
Changes in v4:
- Add detailed hardware descriptions and revise message title to follow the
standard comment format for kaanapali camss binding file - Krzysztof
- Format kaanapali camss binding file to keep style consistency, by reverting
power domain name from TFE to IFE and keeping clocks name order as last
generation - Krzysztof
- Separate the 1.2 and 0.9 voltage supply DT flags for each CSIPHY to allow
for arbitrary board design with common or unique supplies to each of the PHYs
in kaanapali camss binding example, based on v2 comments - bod/Vladimir
- Link to v3: https://lore.kernel.org/r/20251023-add-support-for-camss-on-kaanapali-v3-0-02abc9a107bf@oss.qualcomm.com
Changes in v3:
- Use the name 'ahb' for 'cam_top_ahb' clock in cci binding file - Vladimir
- Reduce and simplify CSIPHY supply, port properties in camss bindings - Vladimir
- Resolve the dependency issues in the camss bindings file using ephemeral
DT nodes - Vladimir/Dmitry
- Update hf mnoc name and bandwidth values for icc module - bod
- Split CSIPHY status macro changes into a separate patch series - bod
- Add clear functions for AUP/RUP update in csid and vfe for consistency - bod
- Clarify why the RUP and AUP register update process is deferred - bod
- Clarify the necessity to keep NRT clocks for vfe - Vijay
- Link to v2: https://lore.kernel.org/r/20251014-add-support-for-camss-on-kaanapali-v2-0-f5745ba2dff9@oss.qualcomm.com
Changes in v2:
- Aggregate CSI2_RX_CFG0_PHY_SEL_BASE_IDX definition into 'camss-csid.h' - bod
- Remove 'camss-csid-1080.h' and use 'camss-csid-gen3.h' header instead - bod
- Remove redundant code in 'camss-csid-1080.c' and align the namespaces - bod
- Slipt 'camnoc_rt_axi' clock in vfe matching list into a single patch - bod
- Add whole vfe write engine client mappings in comment - bod
- Remove hardcoded image buffer number but use 'CAMSS_INIT_BUF_COUNT' - bod
- Remove SoC specific logic for vfe ops->reg_update and add a new variable
to determine whether ops->reg_update is deferred or not - bod
- Add description to explain why 'qdss_debug_xo' should be retained - bod
- Add the procss node in csiphy register list comment - bod
- Rename the variable 'cmn_status_offset' to 'common_status_offset' and
align this with macro in csiphy register structure to avoid ambiguity - bod
- Aggregate Kaanapali items into the definition that introduced by
'qcom,qcm2290-cci' in cci binding file - Loic
- Format 'kaanpali-camss.yaml' binding file
- Link to v1: https://lore.kernel.org/r/20250924-knp-cam-v1-0-b72d6deea054@oss.qualcomm.com
---
Hangxiang Ma (15):
dt-bindings: phy: qcom,x1e80100-csi2-phy: Add Kaanapali CSI2 PHY
phy: qcom-mipi-csi2: Parametrise the common status register offset
phy: qcom-mipi-csi2: Add Kaanapali support
media: qcom: camss: Add addr_update hooks and guard CSID reg_update
media: dt-bindings: Add CAMSS device for Kaanapali
media: qcom: camss: Add Kaanapali compatible
media: qcom: camss: Add PM clock definitions for Kaanapali
media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
media: qcom: camss: csid: Add support for CSID 1080
media: qcom: camss: vfe: Add support for VFE 1080
media: qcom: camss: tpg: Add support for v2.4.0 TPG
arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
arm64: dts: qcom: kaanapali: Add CCI controller nodes
arm64: dts: qcom: kaanapali: Add camera MCLK pinctrl
arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
.../bindings/media/qcom,kaanapali-camss.yaml | 306 +++++++++
.../bindings/phy/qcom,x1e80100-csi2-phy.yaml | 4 +-
arch/arm64/boot/dts/qcom/Makefile | 5 +
.../boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso | 81 +++
arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 7 +
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 760 +++++++++++++++++++++
drivers/media/platform/qcom/camss/Makefile | 2 +
.../media/platform/qcom/camss/camss-csid-1080.c | 413 +++++++++++
drivers/media/platform/qcom/camss/camss-csid.h | 10 +
drivers/media/platform/qcom/camss/camss-tpg-gen1.c | 23 +-
drivers/media/platform/qcom/camss/camss-vfe-1080.c | 213 ++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 11 +-
drivers/media/platform/qcom/camss/camss-vfe.h | 4 +
drivers/media/platform/qcom/camss/camss.c | 288 +++++++-
drivers/media/platform/qcom/camss/camss.h | 3 +
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 32 +-
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 1 +
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 2 +
18 files changed, 2151 insertions(+), 14 deletions(-)
---
base-commit: 5fed66a6fde4dcc6a63ecec6f32e1a331dc4e1a4
change-id: 20260112-kaanapali-camss-73772d44eff7
Best regards,
--
Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread* [PATCH v23 01/15] dt-bindings: phy: qcom,x1e80100-csi2-phy: Add Kaanapali CSI2 PHY
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Krzysztof Kozlowski
The Kaanapali CSI2 PHY is compatible with the existing x1e80100 CSI2
C-PHY/DPHY binding. Add the "qcom,kaanapali-csi2-phy" compatible.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
index 1f1e2a4993b2..6e9eb8e265df 100644
--- a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
@@ -17,7 +17,9 @@ description:
properties:
compatible:
oneOf:
- - const: qcom,x1e80100-csi2-phy
+ - enum:
+ - qcom,kaanapali-csi2-phy
+ - qcom,x1e80100-csi2-phy
- items:
- const: qcom,glymur-csi2-phy
- const: qcom,x1e80100-csi2-phy
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 01/15] dt-bindings: phy: qcom,x1e80100-csi2-phy: Add Kaanapali CSI2 PHY
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Krzysztof Kozlowski
The Kaanapali CSI2 PHY is compatible with the existing x1e80100 CSI2
C-PHY/DPHY binding. Add the "qcom,kaanapali-csi2-phy" compatible.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
index 1f1e2a4993b2..6e9eb8e265df 100644
--- a/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/qcom,x1e80100-csi2-phy.yaml
@@ -17,7 +17,9 @@ description:
properties:
compatible:
oneOf:
- - const: qcom,x1e80100-csi2-phy
+ - enum:
+ - qcom,kaanapali-csi2-phy
+ - qcom,x1e80100-csi2-phy
- items:
- const: qcom,glymur-csi2-phy
- const: qcom,x1e80100-csi2-phy
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH v23 02/15] phy: qcom-mipi-csi2: Parametrise the common status register offset
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
The CSI2 PHY common status registers are not at a fixed offset from the
common register block across SoCs: x1e80100 uses 0xb0 while other 3PH
v2.4.0 parts differ.
Replace the hard-coded 0xb0 in CSIPHY_3PH_CMN_CSI_COMMON_STATUSn() with
a per-SoC common_status_offset field in struct mipi_csi2phy_device_regs,
initialising x1e80100 to 0xb0 so behaviour is unchanged. This is a
no-functional-change preparation for describing other SoC offsets.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 +++++++++++-----
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
index 966d79c98f9b..8cd331cfb4b3 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
@@ -19,7 +19,8 @@
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0)
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1)
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL10_IRQ_CLEAR_CMD BIT(0)
-#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, n) ((offset) + 0xb0 + 0x4 * (n))
+#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, common_status_offset, n) \
+ ((offset) + (common_status_offset) + 0x4 * (n))
#define CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(n) ((0x200 * (n)) + 0x24)
@@ -176,19 +177,23 @@ static void phy_qcom_mipi_csi2_hw_version_read(struct mipi_csi2phy_device *csi2p
CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6));
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 12));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 12));
csi2phy->hw_version = tmp;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 13));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 13));
csi2phy->hw_version |= (tmp << 8) & 0xFF00;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 14));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 14));
csi2phy->hw_version |= (tmp << 16) & 0xFF0000;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 15));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 15));
csi2phy->hw_version |= (tmp << 24) & 0xFF000000;
dev_dbg_once(csi2phy->dev, "CSIPHY 3PH HW Version = 0x%08x\n", csi2phy->hw_version);
@@ -375,6 +380,7 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
.init_seq = lane_regs_x1e80100,
.lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
.common_regs_offset = 0x1000,
+ .common_status_offset = 0xb0,
},
.supply_names = (const char **)x1e_supplies,
.num_supplies = ARRAY_SIZE(x1e_supplies),
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
index 7e55ae007370..d6366f809e51 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
@@ -51,6 +51,7 @@ struct mipi_csi2phy_device_regs {
const struct mipi_csi2phy_lane_regs *init_seq;
const int lane_array_size;
const u32 common_regs_offset;
+ const u32 common_status_offset;
};
struct mipi_csi2_genpd {
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 02/15] phy: qcom-mipi-csi2: Parametrise the common status register offset
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
The CSI2 PHY common status registers are not at a fixed offset from the
common register block across SoCs: x1e80100 uses 0xb0 while other 3PH
v2.4.0 parts differ.
Replace the hard-coded 0xb0 in CSIPHY_3PH_CMN_CSI_COMMON_STATUSn() with
a per-SoC common_status_offset field in struct mipi_csi2phy_device_regs,
initialising x1e80100 to 0xb0 so behaviour is unchanged. This is a
no-functional-change preparation for describing other SoC offsets.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 +++++++++++-----
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
index 966d79c98f9b..8cd331cfb4b3 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
@@ -19,7 +19,8 @@
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B BIT(0)
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID BIT(1)
#define CSIPHY_3PH_CMN_CSI_COMMON_CTRL10_IRQ_CLEAR_CMD BIT(0)
-#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, n) ((offset) + 0xb0 + 0x4 * (n))
+#define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(offset, common_status_offset, n) \
+ ((offset) + (common_status_offset) + 0x4 * (n))
#define CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(n) ((0x200 * (n)) + 0x24)
@@ -176,19 +177,23 @@ static void phy_qcom_mipi_csi2_hw_version_read(struct mipi_csi2phy_device *csi2p
CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(regs->common_regs_offset, 6));
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 12));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 12));
csi2phy->hw_version = tmp;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 13));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 13));
csi2phy->hw_version |= (tmp << 8) & 0xFF00;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 14));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 14));
csi2phy->hw_version |= (tmp << 16) & 0xFF0000;
tmp = readl_relaxed(csi2phy->base +
- CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset, 15));
+ CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(regs->common_regs_offset,
+ regs->common_status_offset, 15));
csi2phy->hw_version |= (tmp << 24) & 0xFF000000;
dev_dbg_once(csi2phy->dev, "CSIPHY 3PH HW Version = 0x%08x\n", csi2phy->hw_version);
@@ -375,6 +380,7 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
.init_seq = lane_regs_x1e80100,
.lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
.common_regs_offset = 0x1000,
+ .common_status_offset = 0xb0,
},
.supply_names = (const char **)x1e_supplies,
.num_supplies = ARRAY_SIZE(x1e_supplies),
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
index 7e55ae007370..d6366f809e51 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
@@ -51,6 +51,7 @@ struct mipi_csi2phy_device_regs {
const struct mipi_csi2phy_lane_regs *init_seq;
const int lane_array_size;
const u32 common_regs_offset;
+ const u32 common_status_offset;
};
struct mipi_csi2_genpd {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 02/15] phy: qcom-mipi-csi2: Parametrise the common status register offset
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:27 ` Abel Vesa
-1 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:27 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:36, Hangxiang Ma wrote:
> The CSI2 PHY common status registers are not at a fixed offset from the
> common register block across SoCs: x1e80100 uses 0xb0 while other 3PH
> v2.4.0 parts differ.
>
> Replace the hard-coded 0xb0 in CSIPHY_3PH_CMN_CSI_COMMON_STATUSn() with
> a per-SoC common_status_offset field in struct mipi_csi2phy_device_regs,
> initialising x1e80100 to 0xb0 so behaviour is unchanged. This is a
> no-functional-change preparation for describing other SoC offsets.
>
> Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 02/15] phy: qcom-mipi-csi2: Parametrise the common status register offset
@ 2026-10-28 15:27 ` Abel Vesa
0 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:27 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:36, Hangxiang Ma wrote:
> The CSI2 PHY common status registers are not at a fixed offset from the
> common register block across SoCs: x1e80100 uses 0xb0 while other 3PH
> v2.4.0 parts differ.
>
> Replace the hard-coded 0xb0 in CSIPHY_3PH_CMN_CSI_COMMON_STATUSn() with
> a per-SoC common_status_offset field in struct mipi_csi2phy_device_regs,
> initialising x1e80100 to 0xb0 so behaviour is unchanged. This is a
> no-functional-change preparation for describing other SoC offsets.
>
> Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 03/15] phy: qcom-mipi-csi2: Add Kaanapali support
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add the Kaanapali 3nm configuration for the standalone CSI2 DPHY
driver, including the Kaanapali common status offset and power domain.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 ++++++++++++++++
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 1 +
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
3 files changed, 18 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
index 8cd331cfb4b3..658a39463104 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
@@ -389,3 +389,19 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
.genpds = x1e_genpds,
.num_genpds = ARRAY_SIZE(x1e_genpds),
};
+
+const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali = {
+ .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
+ .reg_info = {
+ .init_seq = lane_regs_x1e80100,
+ .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
+ .common_regs_offset = 0x1000,
+ .common_status_offset = 0x138,
+ },
+ .supply_names = (const char **)x1e_supplies,
+ .num_supplies = ARRAY_SIZE(x1e_supplies),
+ .clk_names = (const char **)x1e_clks,
+ .num_clk = ARRAY_SIZE(x1e_clks),
+ .genpds = x1e_genpds,
+ .num_genpds = ARRAY_SIZE(x1e_genpds),
+};
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
index c0a4fa20eaf0..aff9e66f0352 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
@@ -444,6 +444,7 @@ static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev)
static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = {
{ .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
+ { .compatible = "qcom,kaanapali-csi2-phy", .data = &mipi_csi2_dphy_3nm_kaanapali },
{ }
};
MODULE_DEVICE_TABLE(of, phy_qcom_mipi_csi2_of_match_table);
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
index d6366f809e51..2355a1db9b94 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
@@ -94,5 +94,6 @@ struct mipi_csi2phy_device {
};
extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e;
+extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali;
#endif /* __PHY_QCOM_MIPI_CSI2_H__ */
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 03/15] phy: qcom-mipi-csi2: Add Kaanapali support
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add the Kaanapali 3nm configuration for the standalone CSI2 DPHY
driver, including the Kaanapali common status offset and power domain.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 ++++++++++++++++
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 1 +
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
3 files changed, 18 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
index 8cd331cfb4b3..658a39463104 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
@@ -389,3 +389,19 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
.genpds = x1e_genpds,
.num_genpds = ARRAY_SIZE(x1e_genpds),
};
+
+const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali = {
+ .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
+ .reg_info = {
+ .init_seq = lane_regs_x1e80100,
+ .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
+ .common_regs_offset = 0x1000,
+ .common_status_offset = 0x138,
+ },
+ .supply_names = (const char **)x1e_supplies,
+ .num_supplies = ARRAY_SIZE(x1e_supplies),
+ .clk_names = (const char **)x1e_clks,
+ .num_clk = ARRAY_SIZE(x1e_clks),
+ .genpds = x1e_genpds,
+ .num_genpds = ARRAY_SIZE(x1e_genpds),
+};
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
index c0a4fa20eaf0..aff9e66f0352 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
@@ -444,6 +444,7 @@ static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev)
static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = {
{ .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
+ { .compatible = "qcom,kaanapali-csi2-phy", .data = &mipi_csi2_dphy_3nm_kaanapali },
{ }
};
MODULE_DEVICE_TABLE(of, phy_qcom_mipi_csi2_of_match_table);
diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
index d6366f809e51..2355a1db9b94 100644
--- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
+++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2.h
@@ -94,5 +94,6 @@ struct mipi_csi2phy_device {
};
extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e;
+extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali;
#endif /* __PHY_QCOM_MIPI_CSI2_H__ */
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 03/15] phy: qcom-mipi-csi2: Add Kaanapali support
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:26 ` Abel Vesa
-1 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:26 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:37, Hangxiang Ma wrote:
> Add the Kaanapali 3nm configuration for the standalone CSI2 DPHY
> driver, including the Kaanapali common status offset and power domain.
>
> Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 ++++++++++++++++
> drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 1 +
> drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
> 3 files changed, 18 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> index 8cd331cfb4b3..658a39463104 100644
> --- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> @@ -389,3 +389,19 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
> .genpds = x1e_genpds,
> .num_genpds = ARRAY_SIZE(x1e_genpds),
> };
> +
> +const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali = {
> + .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
> + .reg_info = {
> + .init_seq = lane_regs_x1e80100,
> + .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
> + .common_regs_offset = 0x1000,
> + .common_status_offset = 0x138,
> + },
> + .supply_names = (const char **)x1e_supplies,
> + .num_supplies = ARRAY_SIZE(x1e_supplies),
> + .clk_names = (const char **)x1e_clks,
> + .num_clk = ARRAY_SIZE(x1e_clks),
> + .genpds = x1e_genpds,
> + .num_genpds = ARRAY_SIZE(x1e_genpds),
> +};
> diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> index c0a4fa20eaf0..aff9e66f0352 100644
> --- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> @@ -444,6 +444,7 @@ static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev)
>
> static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = {
> { .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
> + { .compatible = "qcom,kaanapali-csi2-phy", .data = &mipi_csi2_dphy_3nm_kaanapali },
Nit: Shouldn't we sort by compatible here?
The rest looks good to me, so:
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 03/15] phy: qcom-mipi-csi2: Add Kaanapali support
@ 2026-10-28 15:26 ` Abel Vesa
0 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:26 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:37, Hangxiang Ma wrote:
> Add the Kaanapali 3nm configuration for the standalone CSI2 DPHY
> driver, including the Kaanapali common status offset and power domain.
>
> Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 16 ++++++++++++++++
> drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c | 1 +
> drivers/phy/qualcomm/phy-qcom-mipi-csi2.h | 1 +
> 3 files changed, 18 insertions(+)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> index 8cd331cfb4b3..658a39463104 100644
> --- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c
> @@ -389,3 +389,19 @@ const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e = {
> .genpds = x1e_genpds,
> .num_genpds = ARRAY_SIZE(x1e_genpds),
> };
> +
> +const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_3nm_kaanapali = {
> + .ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
> + .reg_info = {
> + .init_seq = lane_regs_x1e80100,
> + .lane_array_size = ARRAY_SIZE(lane_regs_x1e80100),
> + .common_regs_offset = 0x1000,
> + .common_status_offset = 0x138,
> + },
> + .supply_names = (const char **)x1e_supplies,
> + .num_supplies = ARRAY_SIZE(x1e_supplies),
> + .clk_names = (const char **)x1e_clks,
> + .num_clk = ARRAY_SIZE(x1e_clks),
> + .genpds = x1e_genpds,
> + .num_genpds = ARRAY_SIZE(x1e_genpds),
> +};
> diff --git a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> index c0a4fa20eaf0..aff9e66f0352 100644
> --- a/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> +++ b/drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c
> @@ -444,6 +444,7 @@ static int phy_qcom_mipi_csi2_probe(struct platform_device *pdev)
>
> static const struct of_device_id phy_qcom_mipi_csi2_of_match_table[] = {
> { .compatible = "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
> + { .compatible = "qcom,kaanapali-csi2-phy", .data = &mipi_csi2_dphy_3nm_kaanapali },
Nit: Shouldn't we sort by compatible here?
The rest looks good to me, so:
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
From CSID 680 on, CAMIF was moved into the CSID and the CSID became
responsible for issuing RUP commands. Starting with CSID 980, RUP and
AUP are issued separately, and each command must have its corresponding
SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
CSID 980 and newer require a specific stream-on sequence. After the RX
is configured and before the RDI path is enabled, the CSID must first
issue an AUP and then a RUP. A RUP issued before that point would leave
the VFE without a BUF_DONE event. Therefore, once addr_update is set,
the VFE must skip the initial RUP during stream-on.
Add addr_update hooks and camss_addr_update, and make camss_reg_update
handle a missing callback safely. The VFE keeps issuing its initial RUP
during stream-on and behavior is unchanged if nullify addr_update. The
skip takes effect once a generation that sets addr_update is enabled.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss-csid.h | 8 ++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
drivers/media/platform/qcom/camss/camss-vfe.h | 3 +++
drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++++++-
drivers/media/platform/qcom/camss/camss.h | 2 ++
5 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 5296b10f6bac..2f7e593defed 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -137,6 +137,14 @@ struct csid_hw_ops {
* @is_clear: Indicate if it is clearing reg update or setting reg update
*/
void (*reg_update)(struct csid_device *csid, int port_id, bool is_clear);
+
+ /*
+ * addr_update - latch buffer address update through AUP
+ * @csid: CSID device
+ * @port_id: Port id
+ * @is_clear: Indicate if it is clearing addr update or setting addr update
+ */
+ void (*addr_update)(struct csid_device *csid, int port_id, bool is_clear);
};
struct csid_subdev_resources {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 2680a9914765..4f8867daea4c 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -487,6 +487,8 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
ops->vfe_wm_update(vfe, output->wm_idx[0],
output->buf[index]->addr[0],
line);
+ if (ops->addr_update)
+ ops->addr_update(vfe, line->id);
ops->reg_update(vfe, line->id);
} else {
output->gen2.active_num--;
@@ -525,6 +527,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
spin_lock_irqsave(&vfe->output_lock, flags);
+ if (ops->addr_update_clear)
+ ops->addr_update_clear(vfe, line->id);
ops->reg_update_clear(vfe, line->id);
if (output->state > VFE_OUTPUT_RESERVED) {
@@ -552,7 +556,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
output->gen2.active_num++;
ops->vfe_wm_update(vfe, output->wm_idx[0],
output->buf[i]->addr[0], line);
- ops->reg_update(vfe, line->id);
+ if (!ops->addr_update)
+ ops->reg_update(vfe, line->id);
}
spin_unlock_irqrestore(&vfe->output_lock, flags);
@@ -588,6 +593,8 @@ int vfe_queue_buffer_v2(struct camss_video *vid,
output->buf[output->gen2.active_num++] = buf;
ops->vfe_wm_update(vfe, output->wm_idx[0],
buf->addr[0], line);
+ if (ops->addr_update)
+ ops->addr_update(vfe, line->id);
ops->reg_update(vfe, line->id);
} else {
vfe_buf_add_pending(output, buf);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index ae9dad353a37..8312e4c91e98 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -99,6 +99,9 @@ struct vfe_line {
struct vfe_device;
struct vfe_hw_ops {
+ void (*addr_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
+ void (*addr_update_clear)(struct vfe_device *vfe,
+ enum vfe_line_id line_id);
void (*enable_irq)(struct vfe_device *vfe);
void (*global_reset)(struct vfe_device *vfe);
u32 (*hw_version)(struct vfe_device *vfe);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index c54185c93a8a..be58a39f4a8b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5049,7 +5049,20 @@ void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear
if (hw_id < camss->res->csid_num) {
csid = &camss->csid[hw_id];
- csid->res->hw_ops->reg_update(csid, port_id, is_clear);
+ if (csid->res->hw_ops->reg_update)
+ csid->res->hw_ops->reg_update(csid, port_id, is_clear);
+ }
+}
+
+void camss_addr_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
+{
+ struct csid_device *csid;
+
+ if (hw_id < camss->res->csid_num) {
+ csid = &camss->csid[hw_id];
+
+ if (csid->res->hw_ops->addr_update)
+ csid->res->hw_ops->addr_update(csid, port_id, is_clear);
}
}
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 7dc2fd9f03e0..431afeb381aa 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -182,5 +182,7 @@ void camss_delete(struct camss *camss);
void camss_buf_done(struct camss *camss, int hw_id, int port_id);
void camss_reg_update(struct camss *camss, int hw_id,
int port_id, bool is_clear);
+void camss_addr_update(struct camss *camss, int hw_id,
+ int port_id, bool is_clear);
#endif /* QC_MSM_CAMSS_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
From CSID 680 on, CAMIF was moved into the CSID and the CSID became
responsible for issuing RUP commands. Starting with CSID 980, RUP and
AUP are issued separately, and each command must have its corresponding
SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
CSID 980 and newer require a specific stream-on sequence. After the RX
is configured and before the RDI path is enabled, the CSID must first
issue an AUP and then a RUP. A RUP issued before that point would leave
the VFE without a BUF_DONE event. Therefore, once addr_update is set,
the VFE must skip the initial RUP during stream-on.
Add addr_update hooks and camss_addr_update, and make camss_reg_update
handle a missing callback safely. The VFE keeps issuing its initial RUP
during stream-on and behavior is unchanged if nullify addr_update. The
skip takes effect once a generation that sets addr_update is enabled.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss-csid.h | 8 ++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
drivers/media/platform/qcom/camss/camss-vfe.h | 3 +++
drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++++++-
drivers/media/platform/qcom/camss/camss.h | 2 ++
5 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 5296b10f6bac..2f7e593defed 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -137,6 +137,14 @@ struct csid_hw_ops {
* @is_clear: Indicate if it is clearing reg update or setting reg update
*/
void (*reg_update)(struct csid_device *csid, int port_id, bool is_clear);
+
+ /*
+ * addr_update - latch buffer address update through AUP
+ * @csid: CSID device
+ * @port_id: Port id
+ * @is_clear: Indicate if it is clearing addr update or setting addr update
+ */
+ void (*addr_update)(struct csid_device *csid, int port_id, bool is_clear);
};
struct csid_subdev_resources {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 2680a9914765..4f8867daea4c 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -487,6 +487,8 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
ops->vfe_wm_update(vfe, output->wm_idx[0],
output->buf[index]->addr[0],
line);
+ if (ops->addr_update)
+ ops->addr_update(vfe, line->id);
ops->reg_update(vfe, line->id);
} else {
output->gen2.active_num--;
@@ -525,6 +527,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
spin_lock_irqsave(&vfe->output_lock, flags);
+ if (ops->addr_update_clear)
+ ops->addr_update_clear(vfe, line->id);
ops->reg_update_clear(vfe, line->id);
if (output->state > VFE_OUTPUT_RESERVED) {
@@ -552,7 +556,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
output->gen2.active_num++;
ops->vfe_wm_update(vfe, output->wm_idx[0],
output->buf[i]->addr[0], line);
- ops->reg_update(vfe, line->id);
+ if (!ops->addr_update)
+ ops->reg_update(vfe, line->id);
}
spin_unlock_irqrestore(&vfe->output_lock, flags);
@@ -588,6 +593,8 @@ int vfe_queue_buffer_v2(struct camss_video *vid,
output->buf[output->gen2.active_num++] = buf;
ops->vfe_wm_update(vfe, output->wm_idx[0],
buf->addr[0], line);
+ if (ops->addr_update)
+ ops->addr_update(vfe, line->id);
ops->reg_update(vfe, line->id);
} else {
vfe_buf_add_pending(output, buf);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index ae9dad353a37..8312e4c91e98 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -99,6 +99,9 @@ struct vfe_line {
struct vfe_device;
struct vfe_hw_ops {
+ void (*addr_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
+ void (*addr_update_clear)(struct vfe_device *vfe,
+ enum vfe_line_id line_id);
void (*enable_irq)(struct vfe_device *vfe);
void (*global_reset)(struct vfe_device *vfe);
u32 (*hw_version)(struct vfe_device *vfe);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index c54185c93a8a..be58a39f4a8b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5049,7 +5049,20 @@ void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear
if (hw_id < camss->res->csid_num) {
csid = &camss->csid[hw_id];
- csid->res->hw_ops->reg_update(csid, port_id, is_clear);
+ if (csid->res->hw_ops->reg_update)
+ csid->res->hw_ops->reg_update(csid, port_id, is_clear);
+ }
+}
+
+void camss_addr_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
+{
+ struct csid_device *csid;
+
+ if (hw_id < camss->res->csid_num) {
+ csid = &camss->csid[hw_id];
+
+ if (csid->res->hw_ops->addr_update)
+ csid->res->hw_ops->addr_update(csid, port_id, is_clear);
}
}
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 7dc2fd9f03e0..431afeb381aa 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -182,5 +182,7 @@ void camss_delete(struct camss *camss);
void camss_buf_done(struct camss *camss, int hw_id, int port_id);
void camss_reg_update(struct camss *camss, int hw_id,
int port_id, bool is_clear);
+void camss_addr_update(struct camss *camss, int hw_id,
+ int port_id, bool is_clear);
#endif /* QC_MSM_CAMSS_H */
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:29 ` Bryan O'Donoghue
-1 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> From CSID 680 on, CAMIF was moved into the CSID and the CSID became
> responsible for issuing RUP commands. Starting with CSID 980, RUP and
> AUP are issued separately, and each command must have its corresponding
> SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
>
> CSID 980 and newer require a specific stream-on sequence. After the RX
> is configured and before the RDI path is enabled, the CSID must first
> issue an AUP and then a RUP. A RUP issued before that point would leave
> the VFE without a BUF_DONE event. Therefore, once addr_update is set,
> the VFE must skip the initial RUP during stream-on.
>
> Add addr_update hooks and camss_addr_update, and make camss_reg_update
> handle a missing callback safely. The VFE keeps issuing its initial RUP
> during stream-on and behavior is unchanged if nullify addr_update. The
> skip takes effect once a generation that sets addr_update is enabled.
>
> Signed-off-by: Hangxiang Ma<hangxiang.ma@oss.qualcomm.com>
I think we should probably serialise reg_update() and addr_update() with
the completion in the ISR but, I also think that can be done in a later
series.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
@ 2026-10-28 15:29 ` Bryan O'Donoghue
0 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> From CSID 680 on, CAMIF was moved into the CSID and the CSID became
> responsible for issuing RUP commands. Starting with CSID 980, RUP and
> AUP are issued separately, and each command must have its corresponding
> SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
>
> CSID 980 and newer require a specific stream-on sequence. After the RX
> is configured and before the RDI path is enabled, the CSID must first
> issue an AUP and then a RUP. A RUP issued before that point would leave
> the VFE without a BUF_DONE event. Therefore, once addr_update is set,
> the VFE must skip the initial RUP during stream-on.
>
> Add addr_update hooks and camss_addr_update, and make camss_reg_update
> handle a missing callback safely. The VFE keeps issuing its initial RUP
> during stream-on and behavior is unchanged if nullify addr_update. The
> skip takes effect once a generation that sets addr_update is enabled.
>
> Signed-off-by: Hangxiang Ma<hangxiang.ma@oss.qualcomm.com>
I think we should probably serialise reg_update() and addr_update() with
the completion in the ISR but, I also think that can be done in a later
series.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 16:36 ` Loic Poulain
-1 siblings, 0 replies; 62+ messages in thread
From: Loic Poulain @ 2026-10-28 16:36 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa,
linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On Wed, Oct 28, 2026 at 4:21 PM Hangxiang Ma
<hangxiang.ma@oss.qualcomm.com> wrote:
>
> From CSID 680 on, CAMIF was moved into the CSID and the CSID became
> responsible for issuing RUP commands. Starting with CSID 980, RUP and
> AUP are issued separately, and each command must have its corresponding
> SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
>
> CSID 980 and newer require a specific stream-on sequence. After the RX
> is configured and before the RDI path is enabled, the CSID must first
> issue an AUP and then a RUP. A RUP issued before that point would leave
> the VFE without a BUF_DONE event. Therefore, once addr_update is set,
> the VFE must skip the initial RUP during stream-on.
>
> Add addr_update hooks and camss_addr_update, and make camss_reg_update
> handle a missing callback safely. The VFE keeps issuing its initial RUP
> during stream-on and behavior is unchanged if nullify addr_update. The
> skip takes effect once a generation that sets addr_update is enabled.
>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid.h | 8 ++++++++
> drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
> drivers/media/platform/qcom/camss/camss-vfe.h | 3 +++
> drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++++++-
> drivers/media/platform/qcom/camss/camss.h | 2 ++
> 5 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 5296b10f6bac..2f7e593defed 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -137,6 +137,14 @@ struct csid_hw_ops {
> * @is_clear: Indicate if it is clearing reg update or setting reg update
> */
> void (*reg_update)(struct csid_device *csid, int port_id, bool is_clear);
> +
> + /*
> + * addr_update - latch buffer address update through AUP
> + * @csid: CSID device
> + * @port_id: Port id
> + * @is_clear: Indicate if it is clearing addr update or setting addr update
> + */
> + void (*addr_update)(struct csid_device *csid, int port_id, bool is_clear);
> };
>
> struct csid_subdev_resources {
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 2680a9914765..4f8867daea4c 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -487,6 +487,8 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> output->buf[index]->addr[0],
> line);
> + if (ops->addr_update)
> + ops->addr_update(vfe, line->id);
> ops->reg_update(vfe, line->id);
> } else {
> output->gen2.active_num--;
> @@ -525,6 +527,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
>
> spin_lock_irqsave(&vfe->output_lock, flags);
>
> + if (ops->addr_update_clear)
> + ops->addr_update_clear(vfe, line->id);
> ops->reg_update_clear(vfe, line->id);
>
> if (output->state > VFE_OUTPUT_RESERVED) {
> @@ -552,7 +556,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
> output->gen2.active_num++;
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> output->buf[i]->addr[0], line);
> - ops->reg_update(vfe, line->id);
> + if (!ops->addr_update)
> + ops->reg_update(vfe, line->id);
> }
>
> spin_unlock_irqrestore(&vfe->output_lock, flags);
> @@ -588,6 +593,8 @@ int vfe_queue_buffer_v2(struct camss_video *vid,
> output->buf[output->gen2.active_num++] = buf;
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> buf->addr[0], line);
> + if (ops->addr_update)
> + ops->addr_update(vfe, line->id);
> ops->reg_update(vfe, line->id);
> } else {
> vfe_buf_add_pending(output, buf);
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index ae9dad353a37..8312e4c91e98 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -99,6 +99,9 @@ struct vfe_line {
> struct vfe_device;
>
> struct vfe_hw_ops {
> + void (*addr_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
> + void (*addr_update_clear)(struct vfe_device *vfe,
> + enum vfe_line_id line_id);
> void (*enable_irq)(struct vfe_device *vfe);
> void (*global_reset)(struct vfe_device *vfe);
> u32 (*hw_version)(struct vfe_device *vfe);
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index c54185c93a8a..be58a39f4a8b 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -5049,7 +5049,20 @@ void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear
> if (hw_id < camss->res->csid_num) {
> csid = &camss->csid[hw_id];
>
> - csid->res->hw_ops->reg_update(csid, port_id, is_clear);
> + if (csid->res->hw_ops->reg_update)
> + csid->res->hw_ops->reg_update(csid, port_id, is_clear);
> + }
> +}
> +
> +void camss_addr_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
> +{
> + struct csid_device *csid;
> +
> + if (hw_id < camss->res->csid_num) {
> + csid = &camss->csid[hw_id];
> +
> + if (csid->res->hw_ops->addr_update)
> + csid->res->hw_ops->addr_update(csid, port_id, is_clear);
> }
> }
>
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index 7dc2fd9f03e0..431afeb381aa 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -182,5 +182,7 @@ void camss_delete(struct camss *camss);
> void camss_buf_done(struct camss *camss, int hw_id, int port_id);
> void camss_reg_update(struct camss *camss, int hw_id,
> int port_id, bool is_clear);
> +void camss_addr_update(struct camss *camss, int hw_id,
> + int port_id, bool is_clear);
>
> #endif /* QC_MSM_CAMSS_H */
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 04/15] media: qcom: camss: Add addr_update hooks and guard CSID reg_update
@ 2026-10-28 16:36 ` Loic Poulain
0 siblings, 0 replies; 62+ messages in thread
From: Loic Poulain @ 2026-10-28 16:36 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa,
linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On Wed, Oct 28, 2026 at 4:21 PM Hangxiang Ma
<hangxiang.ma@oss.qualcomm.com> wrote:
>
> From CSID 680 on, CAMIF was moved into the CSID and the CSID became
> responsible for issuing RUP commands. Starting with CSID 980, RUP and
> AUP are issued separately, and each command must have its corresponding
> SET bit asserted in RUP_AUP_CMD; otherwise, the hardware ignores it.
>
> CSID 980 and newer require a specific stream-on sequence. After the RX
> is configured and before the RDI path is enabled, the CSID must first
> issue an AUP and then a RUP. A RUP issued before that point would leave
> the VFE without a BUF_DONE event. Therefore, once addr_update is set,
> the VFE must skip the initial RUP during stream-on.
>
> Add addr_update hooks and camss_addr_update, and make camss_reg_update
> handle a missing callback safely. The VFE keeps issuing its initial RUP
> during stream-on and behavior is unchanged if nullify addr_update. The
> skip takes effect once a generation that sets addr_update is enabled.
>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss-csid.h | 8 ++++++++
> drivers/media/platform/qcom/camss/camss-vfe.c | 9 ++++++++-
> drivers/media/platform/qcom/camss/camss-vfe.h | 3 +++
> drivers/media/platform/qcom/camss/camss.c | 15 ++++++++++++++-
> drivers/media/platform/qcom/camss/camss.h | 2 ++
> 5 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 5296b10f6bac..2f7e593defed 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -137,6 +137,14 @@ struct csid_hw_ops {
> * @is_clear: Indicate if it is clearing reg update or setting reg update
> */
> void (*reg_update)(struct csid_device *csid, int port_id, bool is_clear);
> +
> + /*
> + * addr_update - latch buffer address update through AUP
> + * @csid: CSID device
> + * @port_id: Port id
> + * @is_clear: Indicate if it is clearing addr update or setting addr update
> + */
> + void (*addr_update)(struct csid_device *csid, int port_id, bool is_clear);
> };
>
> struct csid_subdev_resources {
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 2680a9914765..4f8867daea4c 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -487,6 +487,8 @@ void vfe_buf_done(struct vfe_device *vfe, int wm)
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> output->buf[index]->addr[0],
> line);
> + if (ops->addr_update)
> + ops->addr_update(vfe, line->id);
> ops->reg_update(vfe, line->id);
> } else {
> output->gen2.active_num--;
> @@ -525,6 +527,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
>
> spin_lock_irqsave(&vfe->output_lock, flags);
>
> + if (ops->addr_update_clear)
> + ops->addr_update_clear(vfe, line->id);
> ops->reg_update_clear(vfe, line->id);
>
> if (output->state > VFE_OUTPUT_RESERVED) {
> @@ -552,7 +556,8 @@ int vfe_enable_output_v2(struct vfe_line *line)
> output->gen2.active_num++;
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> output->buf[i]->addr[0], line);
> - ops->reg_update(vfe, line->id);
> + if (!ops->addr_update)
> + ops->reg_update(vfe, line->id);
> }
>
> spin_unlock_irqrestore(&vfe->output_lock, flags);
> @@ -588,6 +593,8 @@ int vfe_queue_buffer_v2(struct camss_video *vid,
> output->buf[output->gen2.active_num++] = buf;
> ops->vfe_wm_update(vfe, output->wm_idx[0],
> buf->addr[0], line);
> + if (ops->addr_update)
> + ops->addr_update(vfe, line->id);
> ops->reg_update(vfe, line->id);
> } else {
> vfe_buf_add_pending(output, buf);
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index ae9dad353a37..8312e4c91e98 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -99,6 +99,9 @@ struct vfe_line {
> struct vfe_device;
>
> struct vfe_hw_ops {
> + void (*addr_update)(struct vfe_device *vfe, enum vfe_line_id line_id);
> + void (*addr_update_clear)(struct vfe_device *vfe,
> + enum vfe_line_id line_id);
> void (*enable_irq)(struct vfe_device *vfe);
> void (*global_reset)(struct vfe_device *vfe);
> u32 (*hw_version)(struct vfe_device *vfe);
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index c54185c93a8a..be58a39f4a8b 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -5049,7 +5049,20 @@ void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear
> if (hw_id < camss->res->csid_num) {
> csid = &camss->csid[hw_id];
>
> - csid->res->hw_ops->reg_update(csid, port_id, is_clear);
> + if (csid->res->hw_ops->reg_update)
> + csid->res->hw_ops->reg_update(csid, port_id, is_clear);
> + }
> +}
> +
> +void camss_addr_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
> +{
> + struct csid_device *csid;
> +
> + if (hw_id < camss->res->csid_num) {
> + csid = &camss->csid[hw_id];
> +
> + if (csid->res->hw_ops->addr_update)
> + csid->res->hw_ops->addr_update(csid, port_id, is_clear);
> }
> }
>
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index 7dc2fd9f03e0..431afeb381aa 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -182,5 +182,7 @@ void camss_delete(struct camss *camss);
> void camss_buf_done(struct camss *camss, int hw_id, int port_id);
> void camss_reg_update(struct camss *camss, int hw_id,
> int port_id, bool is_clear);
> +void camss_addr_update(struct camss *camss, int hw_id,
> + int port_id, bool is_clear);
>
> #endif /* QC_MSM_CAMSS_H */
>
> --
> 2.34.1
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 05/15] media: dt-bindings: Add CAMSS device for Kaanapali
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add bindings for Camera Subsystem (CAMSS) on the Qualcomm Kaanapali
platform.
The Kaanapali platform provides:
- 6 x CSIPHY (CSI Physical Layer)
- 3 x TPG (Test Pattern Generator)
- 3 x CSID (CSI Decoder)
- 2 x CSID Lite
- 3 x VFE (Video Front End), 5 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE Lite
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
.../bindings/media/qcom,kaanapali-camss.yaml | 306 +++++++++++++++++++++
1 file changed, 306 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml b/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml
new file mode 100644
index 000000000000..dec451fc940f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml
@@ -0,0 +1,306 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,kaanapali-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Kaanapali Camera Subsystem (CAMSS)
+
+maintainers:
+ - Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
+
+description:
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+ compatible:
+ const: qcom,kaanapali-camss
+
+ reg:
+ maxItems: 14
+
+ reg-names:
+ items:
+ - const: top
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid_lite0
+ - const: csid_lite1
+ - const: csitpg0
+ - const: csitpg1
+ - const: csitpg2
+ - const: vfe0
+ - const: vfe1
+ - const: vfe2
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ clocks:
+ maxItems: 23
+
+ clock-names:
+ items:
+ - const: camnoc_nrt_axi
+ - const: camnoc_rt_axi
+ - const: cpas_ahb
+ - const: cpas_fast_ahb
+ - const: cpas_vfe0
+ - const: cpas_vfe1
+ - const: cpas_vfe2
+ - const: cpas_vfe_lite
+ - const: csid
+ - const: csid_csiphy_rx
+ - const: gcc_axi_hf
+ - const: gcc_axi_sf
+ - const: vfe0
+ - const: vfe0_fast_ahb
+ - const: vfe1
+ - const: vfe1_fast_ahb
+ - const: vfe2
+ - const: vfe2_fast_ahb
+ - const: vfe_lite
+ - const: vfe_lite_ahb
+ - const: vfe_lite_cphy_rx
+ - const: vfe_lite_csid
+ - const: qdss_debug_xo
+
+ interrupts:
+ maxItems: 10
+
+ interrupt-names:
+ items:
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid_lite0
+ - const: csid_lite1
+ - const: vfe0
+ - const: vfe1
+ - const: vfe2
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ interconnects:
+ maxItems: 2
+
+ interconnect-names:
+ items:
+ - const: ahb
+ - const: hf_mnoc
+
+ iommus:
+ items:
+ - description: S1 HLOS IFE non-protected stream
+
+ power-domains:
+ items:
+ - description: IFE0 GDSC - Global Distributed Switch Controller for IFE0.
+ - description: IFE1 GDSC - Global Distributed Switch Controller for IFE1.
+ - description: IFE2 GDSC - Global Distributed Switch Controller for IFE2.
+ - description: Titan Top GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+ power-domain-names:
+ items:
+ - const: ife0
+ - const: ife1
+ - const: ife2
+ - const: top
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ description:
+ CSI input ports. Each port receives the CSI data
+ decoded by the matching CSIPHY.
+
+ patternProperties:
+ "^port@[0-5]$":
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data from CSIPHY 0-5.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ bus-type:
+ enum:
+ - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
+ - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+ required:
+ - data-lanes
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - interrupts
+ - interrupt-names
+ - interconnects
+ - interconnect-names
+ - iommus
+ - power-domains
+ - power-domain-names
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,kaanapali-gcc.h>
+ #include <dt-bindings/clock/qcom,kaanapali-camcc.h>
+ #include <dt-bindings/interconnect/qcom,icc.h>
+ #include <dt-bindings/interconnect/qcom,kaanapali-rpmh.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/qcom,rpmhpd.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ isp@900b000 {
+ compatible = "qcom,kaanapali-camss";
+
+ reg = <0x0 0x0900b000 0x0 0x1000>,
+ <0x0 0x09253000 0x0 0x5e80>,
+ <0x0 0x09263000 0x0 0x5e80>,
+ <0x0 0x09273000 0x0 0x5e80>,
+ <0x0 0x092d3000 0x0 0x3880>,
+ <0x0 0x092e7000 0x0 0x3880>,
+ <0x0 0x093fd000 0x0 0x400>,
+ <0x0 0x093fe000 0x0 0x400>,
+ <0x0 0x093ff000 0x0 0x400>,
+ <0x0 0x09151000 0x0 0x20000>,
+ <0x0 0x09171000 0x0 0x20000>,
+ <0x0 0x09191000 0x0 0x20000>,
+ <0x0 0x092dc000 0x0 0x1300>,
+ <0x0 0x092f0000 0x0 0x1300>;
+
+ reg-names = "top",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "csitpg0",
+ "csitpg1",
+ "csitpg2",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ clocks = <&camcc CAM_CC_CAMNOC_NRT_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_AXI_CLK>,
+ <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CAM_TOP_FAST_AHB_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_IFE_LITE_CLK>,
+ <&camcc CAM_CC_CSID_CLK>,
+ <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+
+ clock-names = "camnoc_nrt_axi",
+ "camnoc_rt_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb",
+ "cpas_vfe0",
+ "cpas_vfe1",
+ "cpas_vfe2",
+ "cpas_vfe_lite",
+ "csid",
+ "csid_csiphy_rx",
+ "gcc_axi_hf",
+ "gcc_axi_sf",
+ "vfe0",
+ "vfe0_fast_ahb",
+ "vfe1",
+ "vfe1_fast_ahb",
+ "vfe2",
+ "vfe2_fast_ahb",
+ "vfe_lite",
+ "vfe_lite_ahb",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_csid",
+ "qdss_debug_xo";
+
+ interrupts = <GIC_SPI 601 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 603 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 431 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 457 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 606 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+ <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "ahb",
+ "hf_mnoc";
+
+ iommus = <&apps_smmu 0x1c00 0x00>;
+
+ power-domains = <&camcc CAM_CC_TFE_0_GDSC>,
+ <&camcc CAM_CC_TFE_1_GDSC>,
+ <&camcc CAM_CC_TFE_2_GDSC>,
+ <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ power-domain-names = "ife0",
+ "ife1",
+ "ife2",
+ "top";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ camss_csiphy0_ep: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy0_out>;
+ };
+ };
+ };
+ };
+ };
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 05/15] media: dt-bindings: Add CAMSS device for Kaanapali
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add bindings for Camera Subsystem (CAMSS) on the Qualcomm Kaanapali
platform.
The Kaanapali platform provides:
- 6 x CSIPHY (CSI Physical Layer)
- 3 x TPG (Test Pattern Generator)
- 3 x CSID (CSI Decoder)
- 2 x CSID Lite
- 3 x VFE (Video Front End), 5 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE Lite
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
.../bindings/media/qcom,kaanapali-camss.yaml | 306 +++++++++++++++++++++
1 file changed, 306 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml b/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml
new file mode 100644
index 000000000000..dec451fc940f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/qcom,kaanapali-camss.yaml
@@ -0,0 +1,306 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,kaanapali-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Kaanapali Camera Subsystem (CAMSS)
+
+maintainers:
+ - Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
+
+description:
+ The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+ compatible:
+ const: qcom,kaanapali-camss
+
+ reg:
+ maxItems: 14
+
+ reg-names:
+ items:
+ - const: top
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid_lite0
+ - const: csid_lite1
+ - const: csitpg0
+ - const: csitpg1
+ - const: csitpg2
+ - const: vfe0
+ - const: vfe1
+ - const: vfe2
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ clocks:
+ maxItems: 23
+
+ clock-names:
+ items:
+ - const: camnoc_nrt_axi
+ - const: camnoc_rt_axi
+ - const: cpas_ahb
+ - const: cpas_fast_ahb
+ - const: cpas_vfe0
+ - const: cpas_vfe1
+ - const: cpas_vfe2
+ - const: cpas_vfe_lite
+ - const: csid
+ - const: csid_csiphy_rx
+ - const: gcc_axi_hf
+ - const: gcc_axi_sf
+ - const: vfe0
+ - const: vfe0_fast_ahb
+ - const: vfe1
+ - const: vfe1_fast_ahb
+ - const: vfe2
+ - const: vfe2_fast_ahb
+ - const: vfe_lite
+ - const: vfe_lite_ahb
+ - const: vfe_lite_cphy_rx
+ - const: vfe_lite_csid
+ - const: qdss_debug_xo
+
+ interrupts:
+ maxItems: 10
+
+ interrupt-names:
+ items:
+ - const: csid0
+ - const: csid1
+ - const: csid2
+ - const: csid_lite0
+ - const: csid_lite1
+ - const: vfe0
+ - const: vfe1
+ - const: vfe2
+ - const: vfe_lite0
+ - const: vfe_lite1
+
+ interconnects:
+ maxItems: 2
+
+ interconnect-names:
+ items:
+ - const: ahb
+ - const: hf_mnoc
+
+ iommus:
+ items:
+ - description: S1 HLOS IFE non-protected stream
+
+ power-domains:
+ items:
+ - description: IFE0 GDSC - Global Distributed Switch Controller for IFE0.
+ - description: IFE1 GDSC - Global Distributed Switch Controller for IFE1.
+ - description: IFE2 GDSC - Global Distributed Switch Controller for IFE2.
+ - description: Titan Top GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+ power-domain-names:
+ items:
+ - const: ife0
+ - const: ife1
+ - const: ife2
+ - const: top
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ description:
+ CSI input ports. Each port receives the CSI data
+ decoded by the matching CSIPHY.
+
+ patternProperties:
+ "^port@[0-5]$":
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description:
+ Input port for receiving CSI data from CSIPHY 0-5.
+
+ properties:
+ endpoint:
+ $ref: video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ bus-type:
+ enum:
+ - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
+ - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+ required:
+ - data-lanes
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+ - interrupts
+ - interrupt-names
+ - interconnects
+ - interconnect-names
+ - iommus
+ - power-domains
+ - power-domain-names
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,kaanapali-gcc.h>
+ #include <dt-bindings/clock/qcom,kaanapali-camcc.h>
+ #include <dt-bindings/interconnect/qcom,icc.h>
+ #include <dt-bindings/interconnect/qcom,kaanapali-rpmh.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/power/qcom,rpmhpd.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ isp@900b000 {
+ compatible = "qcom,kaanapali-camss";
+
+ reg = <0x0 0x0900b000 0x0 0x1000>,
+ <0x0 0x09253000 0x0 0x5e80>,
+ <0x0 0x09263000 0x0 0x5e80>,
+ <0x0 0x09273000 0x0 0x5e80>,
+ <0x0 0x092d3000 0x0 0x3880>,
+ <0x0 0x092e7000 0x0 0x3880>,
+ <0x0 0x093fd000 0x0 0x400>,
+ <0x0 0x093fe000 0x0 0x400>,
+ <0x0 0x093ff000 0x0 0x400>,
+ <0x0 0x09151000 0x0 0x20000>,
+ <0x0 0x09171000 0x0 0x20000>,
+ <0x0 0x09191000 0x0 0x20000>,
+ <0x0 0x092dc000 0x0 0x1300>,
+ <0x0 0x092f0000 0x0 0x1300>;
+
+ reg-names = "top",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "csitpg0",
+ "csitpg1",
+ "csitpg2",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ clocks = <&camcc CAM_CC_CAMNOC_NRT_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_AXI_CLK>,
+ <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CAM_TOP_FAST_AHB_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_IFE_LITE_CLK>,
+ <&camcc CAM_CC_CSID_CLK>,
+ <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+
+ clock-names = "camnoc_nrt_axi",
+ "camnoc_rt_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb",
+ "cpas_vfe0",
+ "cpas_vfe1",
+ "cpas_vfe2",
+ "cpas_vfe_lite",
+ "csid",
+ "csid_csiphy_rx",
+ "gcc_axi_hf",
+ "gcc_axi_sf",
+ "vfe0",
+ "vfe0_fast_ahb",
+ "vfe1",
+ "vfe1_fast_ahb",
+ "vfe2",
+ "vfe2_fast_ahb",
+ "vfe_lite",
+ "vfe_lite_ahb",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_csid",
+ "qdss_debug_xo";
+
+ interrupts = <GIC_SPI 601 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 603 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 431 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 457 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 606 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+ <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "ahb",
+ "hf_mnoc";
+
+ iommus = <&apps_smmu 0x1c00 0x00>;
+
+ power-domains = <&camcc CAM_CC_TFE_0_GDSC>,
+ <&camcc CAM_CC_TFE_1_GDSC>,
+ <&camcc CAM_CC_TFE_2_GDSC>,
+ <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ power-domain-names = "ife0",
+ "ife1",
+ "ife2",
+ "top";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ camss_csiphy0_ep: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy0_out>;
+ };
+ };
+ };
+ };
+ };
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH v23 06/15] media: qcom: camss: Add Kaanapali compatible
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add CAMSS_KAANAPALI enum, Kaanapali compatible and Kaanapali CAMSS driver
private data. The private data currently includes only basic information.
Later changes will add CSIPHY, TPG, CSID and VFE resources.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 22 ++++++++++++++++++++++
drivers/media/platform/qcom/camss/camss.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index be58a39f4a8b..98ec23c39fda 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -38,6 +38,20 @@
static const struct parent_dev_ops vfe_parent_dev_ops;
+static const struct resources_icc icc_res_kaanapali[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 150000,
+ .icc_bw_tbl.peak = 300000,
+ },
+ /* Based on 4096 x 3072 30 FPS 2496 Mbps mode */
+ {
+ .name = "hf_mnoc",
+ .icc_bw_tbl.avg = 471860,
+ .icc_bw_tbl.peak = 925857,
+ }
+};
+
static const struct camss_subdev_resources csiphy_res_8x16[] = {
/* CSIPHY0 */
{
@@ -5589,6 +5603,13 @@ static void camss_remove(struct platform_device *pdev)
camss_genpd_cleanup(camss);
}
+static const struct camss_resources kaanapali_resources = {
+ .version = CAMSS_KAANAPALI,
+ .pd_name = "top",
+ .icc_res = icc_res_kaanapali,
+ .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
+};
+
static const struct camss_resources msm8916_resources = {
.version = CAMSS_8x16,
.csiphy_res = csiphy_res_8x16,
@@ -5823,6 +5844,7 @@ static const struct camss_resources x1e80100_resources = {
};
static const struct of_device_id camss_dt_match[] = {
+ { .compatible = "qcom,kaanapali-camss", .data = &kaanapali_resources },
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
{ .compatible = "qcom,msm8939-camss", .data = &msm8939_resources },
{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 431afeb381aa..97fec24e6804 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -96,6 +96,7 @@ enum camss_version {
CAMSS_8550,
CAMSS_8650,
CAMSS_8775P,
+ CAMSS_KAANAPALI,
CAMSS_X1E80100,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 06/15] media: qcom: camss: Add Kaanapali compatible
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add CAMSS_KAANAPALI enum, Kaanapali compatible and Kaanapali CAMSS driver
private data. The private data currently includes only basic information.
Later changes will add CSIPHY, TPG, CSID and VFE resources.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 22 ++++++++++++++++++++++
drivers/media/platform/qcom/camss/camss.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index be58a39f4a8b..98ec23c39fda 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -38,6 +38,20 @@
static const struct parent_dev_ops vfe_parent_dev_ops;
+static const struct resources_icc icc_res_kaanapali[] = {
+ {
+ .name = "ahb",
+ .icc_bw_tbl.avg = 150000,
+ .icc_bw_tbl.peak = 300000,
+ },
+ /* Based on 4096 x 3072 30 FPS 2496 Mbps mode */
+ {
+ .name = "hf_mnoc",
+ .icc_bw_tbl.avg = 471860,
+ .icc_bw_tbl.peak = 925857,
+ }
+};
+
static const struct camss_subdev_resources csiphy_res_8x16[] = {
/* CSIPHY0 */
{
@@ -5589,6 +5603,13 @@ static void camss_remove(struct platform_device *pdev)
camss_genpd_cleanup(camss);
}
+static const struct camss_resources kaanapali_resources = {
+ .version = CAMSS_KAANAPALI,
+ .pd_name = "top",
+ .icc_res = icc_res_kaanapali,
+ .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
+};
+
static const struct camss_resources msm8916_resources = {
.version = CAMSS_8x16,
.csiphy_res = csiphy_res_8x16,
@@ -5823,6 +5844,7 @@ static const struct camss_resources x1e80100_resources = {
};
static const struct of_device_id camss_dt_match[] = {
+ { .compatible = "qcom,kaanapali-camss", .data = &kaanapali_resources },
{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
{ .compatible = "qcom,msm8939-camss", .data = &msm8939_resources },
{ .compatible = "qcom,msm8953-camss", .data = &msm8953_resources },
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 431afeb381aa..97fec24e6804 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -96,6 +96,7 @@ enum camss_version {
CAMSS_8550,
CAMSS_8650,
CAMSS_8775P,
+ CAMSS_KAANAPALI,
CAMSS_X1E80100,
};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH v23 07/15] media: qcom: camss: Add PM clock definitions for Kaanapali
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
The CPAS AHB and AXI clocks are shared by every Kaanapali TFE and IFE
sub-block. Register them as PM clocks so the PM clock framework enables
them once when CAMSS resumes, instead of each sub-block listing them and
taking its own reference.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 98ec23c39fda..a64242c66cf0 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5606,6 +5606,7 @@ static void camss_remove(struct platform_device *pdev)
static const struct camss_resources kaanapali_resources = {
.version = CAMSS_KAANAPALI,
.pd_name = "top",
+ .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
};
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 07/15] media: qcom: camss: Add PM clock definitions for Kaanapali
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
The CPAS AHB and AXI clocks are shared by every Kaanapali TFE and IFE
sub-block. Register them as PM clocks so the PM clock framework enables
them once when CAMSS resumes, instead of each sub-block listing them and
taking its own reference.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 98ec23c39fda..a64242c66cf0 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5606,6 +5606,7 @@ static void camss_remove(struct platform_device *pdev)
static const struct camss_resources kaanapali_resources = {
.version = CAMSS_KAANAPALI,
.pd_name = "top",
+ .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 07/15] media: qcom: camss: Add PM clock definitions for Kaanapali
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:31 ` Bryan O'Donoghue
-1 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:31 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> The CPAS AHB and AXI clocks are shared by every Kaanapali TFE and IFE
> sub-block. Register them as PM clocks so the PM clock framework enables
> them once when CAMSS resumes, instead of each sub-block listing them and
> taking its own reference.
>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 98ec23c39fda..a64242c66cf0 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -5606,6 +5606,7 @@ static void camss_remove(struct platform_device *pdev)
> static const struct camss_resources kaanapali_resources = {
> .version = CAMSS_KAANAPALI,
> .pd_name = "top",
> + .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> };
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 07/15] media: qcom: camss: Add PM clock definitions for Kaanapali
@ 2026-10-28 15:31 ` Bryan O'Donoghue
0 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:31 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> The CPAS AHB and AXI clocks are shared by every Kaanapali TFE and IFE
> sub-block. Register them as PM clocks so the PM clock framework enables
> them once when CAMSS resumes, instead of each sub-block listing them and
> taking its own reference.
>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/camss.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 98ec23c39fda..a64242c66cf0 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -5606,6 +5606,7 @@ static void camss_remove(struct platform_device *pdev)
> static const struct camss_resources kaanapali_resources = {
> .version = CAMSS_KAANAPALI,
> .pd_name = "top",
> + .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> };
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 08/15] media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add support for the v2.4.0 two-phase CSIPHY found on Kaanapali, where
the PHY is driven by the standalone phy-qcom-mipi-csi2 DPHY driver
rather than by CAMSS. Add the mipi_csi2_dphy_3nm_kaanapali configuration,
which reuses the x1e80100 lane sequence, clocks and supplies but selects
the v2.4.0 common status offset, adds Kaanapali power domain and register
the "qcom,kaanapali-csi2-phy" compatible.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 47 +++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index a64242c66cf0..b0b63dd3d958 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -38,6 +38,51 @@
static const struct parent_dev_ops vfe_parent_dev_ops;
+static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
+ /* CSIPHY0 */
+ {
+ .csiphy = {
+ .id = 0,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY1 */
+ {
+ .csiphy = {
+ .id = 1,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY2 */
+ {
+ .csiphy = {
+ .id = 2,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY3 */
+ {
+ .csiphy = {
+ .id = 3,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY4 */
+ {
+ .csiphy = {
+ .id = 4,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY5 */
+ {
+ .csiphy = {
+ .id = 5,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5607,8 +5652,10 @@ static const struct camss_resources kaanapali_resources = {
.version = CAMSS_KAANAPALI,
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
+ .csiphy_res = csiphy_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 08/15] media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add support for the v2.4.0 two-phase CSIPHY found on Kaanapali, where
the PHY is driven by the standalone phy-qcom-mipi-csi2 DPHY driver
rather than by CAMSS. Add the mipi_csi2_dphy_3nm_kaanapali configuration,
which reuses the x1e80100 lane sequence, clocks and supplies but selects
the v2.4.0 common status offset, adds Kaanapali power domain and register
the "qcom,kaanapali-csi2-phy" compatible.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/camss.c | 47 +++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index a64242c66cf0..b0b63dd3d958 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -38,6 +38,51 @@
static const struct parent_dev_ops vfe_parent_dev_ops;
+static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
+ /* CSIPHY0 */
+ {
+ .csiphy = {
+ .id = 0,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY1 */
+ {
+ .csiphy = {
+ .id = 1,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY2 */
+ {
+ .csiphy = {
+ .id = 2,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY3 */
+ {
+ .csiphy = {
+ .id = 3,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY4 */
+ {
+ .csiphy = {
+ .id = 4,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+ /* CSIPHY5 */
+ {
+ .csiphy = {
+ .id = 5,
+ .formats = &csiphy_formats_sdm845
+ },
+ },
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5607,8 +5652,10 @@ static const struct camss_resources kaanapali_resources = {
.version = CAMSS_KAANAPALI,
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
+ .csiphy_res = csiphy_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
+ .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 08/15] media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:31 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:31 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] media: qcom: camss: NULL deref in msm_csiphy_subdev_init_legacy()
- [Medium] media: qcom: camss: commit message describes phy driver changes
--
commit 746e86a20142c7ce6cfd5e7633a02e7c5b459ec6
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
This patch defines the csiphy subdevice resource table for Kaanapali and
wires it into kaanapali_resources in camss.
> media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
>
> Add support for the v2.4.0 two-phase CSIPHY found on Kaanapali, where
> the PHY is driven by the standalone phy-qcom-mipi-csi2 DPHY driver
> rather than by CAMSS. Add the mipi_csi2_dphy_3nm_kaanapali configuration,
> which reuses the x1e80100 lane sequence, clocks and supplies but selects
> the v2.4.0 common status offset, adds Kaanapali power domain and register
> the "qcom,kaanapali-csi2-phy" compatible.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
[Severity: Medium]
Does this commit message match the changes in this patch?
The commit message states that this patch adds the
mipi_csi2_dphy_3nm_kaanapali configuration and registers the
"qcom,kaanapali-csi2-phy" compatible, which were added in commit 09220cf48f3f
("phy: qcom-mipi-csi2: Add Kaanapali support") in drivers/phy/qualcomm/,
whereas this patch only populates csiphy_res_kaanapali and wires it into
kaanapali_resources in drivers/media/platform/qcom/camss/camss.c.
In addition, the subject and commit description refer to a "v2.4.0 two-phase"
phy, while Kaanapali uses a 3-phase v2.4.0 phy. Could the commit subject and
description be updated to reflect the camss changes here?
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index a64242c66cf06..b0b63dd3d958e 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -38,6 +38,51 @@
>
> static const struct parent_dev_ops vfe_parent_dev_ops;
>
> +static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
> + /* CSIPHY0 */
> + {
> + .csiphy = {
> + .id = 0,
> + .formats = &csiphy_formats_sdm845
> + },
> + },
[ ... ]
> @@ -5607,8 +5652,10 @@ static const struct camss_resources kaanapali_resources = {
> .version = CAMSS_KAANAPALI,
> .pd_name = "top",
> .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> + .csiphy_res = csiphy_res_kaanapali,
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> + .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
> };
[Severity: High]
Can this trigger a null pointer dereference in msm_csiphy_subdev_init_legacy()
when probing camss on Kaanapali without a remote "phy" endpoint in the device
tree?
Each entry in csiphy_res_kaanapali[] only initializes .csiphy.id and
.csiphy.formats, leaving .csiphy.hw_ops as null because the Kaanapali phy is
driven by the standalone phy-qcom-mipi-csi2 driver.
However, during camss_probe() -> camss_init_subdevices() ->
camss_detect_legacy_phy(), camss->legacy_phy defaults to true:
drivers/media/platform/qcom/camss/camss.c:camss_detect_legacy_phy() {
...
camss->legacy_phy = true;
/* Find first remote-endpoint and determine if its a PHY */
for_each_endpoint_of_node(camss->dev->of_node, ep) {
remote = of_graph_get_remote_port_parent(ep);
if (!remote)
continue;
camss->legacy_phy = !of_node_name_eq(remote, "phy");
of_node_put(remote);
of_node_put(ep);
break;
}
}
If camss is enabled without an active endpoint connected to a node named "phy"
(for example, with unconnected ports in a base board device tree or when
using only the internal test pattern generators csitpg0..2),
camss->legacy_phy remains true.
camss_init_subdevices() then takes the legacy initialization path for each of
the 6 csiphy_res_kaanapali entries:
drivers/media/platform/qcom/camss/camss.c:camss_init_subdevices() {
...
for (i = 0; i < camss->res->csiphy_num; i++) {
if (!camss->legacy_phy) {
ret = msm_csiphy_subdev_init(camss, i);
} else {
ret = msm_csiphy_subdev_init_legacy(camss,
&camss->csiphy[i],
&res->csiphy_res[i],
res->csiphy_res[i].csiphy.id);
}
...
}
And msm_csiphy_subdev_init_legacy() unconditionally dereferences
csiphy->res->hw_ops:
drivers/media/platform/qcom/camss/camss-csiphy.c:msm_csiphy_subdev_init_legacy() {
...
csiphy->res = &res->csiphy;
ret = csiphy->res->hw_ops->init(csiphy);
...
}
Should camss_init_subdevices() or camss_detect_legacy_phy() guard against
taking the legacy path when res->csiphy_res[i].csiphy.hw_ops is null?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=8
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 08/15] media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
@ 2026-10-28 15:31 ` sashiko-bot
0 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:31 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] media: qcom: camss: NULL deref in msm_csiphy_subdev_init_legacy()
- [Medium] media: qcom: camss: commit message describes phy driver changes
--
commit 746e86a20142c7ce6cfd5e7633a02e7c5b459ec6
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
This patch defines the csiphy subdevice resource table for Kaanapali and
wires it into kaanapali_resources in camss.
> media: qcom: camss: csiphy: Add support for v2.4.0 two-phase CSIPHY
>
> Add support for the v2.4.0 two-phase CSIPHY found on Kaanapali, where
> the PHY is driven by the standalone phy-qcom-mipi-csi2 DPHY driver
> rather than by CAMSS. Add the mipi_csi2_dphy_3nm_kaanapali configuration,
> which reuses the x1e80100 lane sequence, clocks and supplies but selects
> the v2.4.0 common status offset, adds Kaanapali power domain and register
> the "qcom,kaanapali-csi2-phy" compatible.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
[Severity: Medium]
Does this commit message match the changes in this patch?
The commit message states that this patch adds the
mipi_csi2_dphy_3nm_kaanapali configuration and registers the
"qcom,kaanapali-csi2-phy" compatible, which were added in commit 09220cf48f3f
("phy: qcom-mipi-csi2: Add Kaanapali support") in drivers/phy/qualcomm/,
whereas this patch only populates csiphy_res_kaanapali and wires it into
kaanapali_resources in drivers/media/platform/qcom/camss/camss.c.
In addition, the subject and commit description refer to a "v2.4.0 two-phase"
phy, while Kaanapali uses a 3-phase v2.4.0 phy. Could the commit subject and
description be updated to reflect the camss changes here?
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index a64242c66cf06..b0b63dd3d958e 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -38,6 +38,51 @@
>
> static const struct parent_dev_ops vfe_parent_dev_ops;
>
> +static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
> + /* CSIPHY0 */
> + {
> + .csiphy = {
> + .id = 0,
> + .formats = &csiphy_formats_sdm845
> + },
> + },
[ ... ]
> @@ -5607,8 +5652,10 @@ static const struct camss_resources kaanapali_resources = {
> .version = CAMSS_KAANAPALI,
> .pd_name = "top",
> .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> + .csiphy_res = csiphy_res_kaanapali,
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> + .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
> };
[Severity: High]
Can this trigger a null pointer dereference in msm_csiphy_subdev_init_legacy()
when probing camss on Kaanapali without a remote "phy" endpoint in the device
tree?
Each entry in csiphy_res_kaanapali[] only initializes .csiphy.id and
.csiphy.formats, leaving .csiphy.hw_ops as null because the Kaanapali phy is
driven by the standalone phy-qcom-mipi-csi2 driver.
However, during camss_probe() -> camss_init_subdevices() ->
camss_detect_legacy_phy(), camss->legacy_phy defaults to true:
drivers/media/platform/qcom/camss/camss.c:camss_detect_legacy_phy() {
...
camss->legacy_phy = true;
/* Find first remote-endpoint and determine if its a PHY */
for_each_endpoint_of_node(camss->dev->of_node, ep) {
remote = of_graph_get_remote_port_parent(ep);
if (!remote)
continue;
camss->legacy_phy = !of_node_name_eq(remote, "phy");
of_node_put(remote);
of_node_put(ep);
break;
}
}
If camss is enabled without an active endpoint connected to a node named "phy"
(for example, with unconnected ports in a base board device tree or when
using only the internal test pattern generators csitpg0..2),
camss->legacy_phy remains true.
camss_init_subdevices() then takes the legacy initialization path for each of
the 6 csiphy_res_kaanapali entries:
drivers/media/platform/qcom/camss/camss.c:camss_init_subdevices() {
...
for (i = 0; i < camss->res->csiphy_num; i++) {
if (!camss->legacy_phy) {
ret = msm_csiphy_subdev_init(camss, i);
} else {
ret = msm_csiphy_subdev_init_legacy(camss,
&camss->csiphy[i],
&res->csiphy_res[i],
res->csiphy_res[i].csiphy.id);
}
...
}
And msm_csiphy_subdev_init_legacy() unconditionally dereferences
csiphy->res->hw_ops:
drivers/media/platform/qcom/camss/camss-csiphy.c:msm_csiphy_subdev_init_legacy() {
...
csiphy->res = &res->csiphy;
ret = csiphy->res->hw_ops->init(csiphy);
...
}
Should camss_init_subdevices() or camss_detect_legacy_phy() guard against
taking the legacy path when res->csiphy_res[i].csiphy.hw_ops is null?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=8
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 09/15] media: qcom: camss: csid: Add support for CSID 1080
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Atiya Kailany
Add support for the CSID 1080 hardware found on the Kaanapali SoC.
Introduce the CSID 1080 hardware resource descriptions and implement
the hardware-specific register programming, reset sequence, and
BUF_DONE interrupt handling.
CSID 1080 uses separate registers for RUP and AUP updates, with a SET
register used to commit them. Extend the CSID interface to support this
scheme while retaining the legacy combined reg_update mechanism.
Also define the INFO_INPUT_EOF and INFO_CAMIF_EOF bits in the per-RDI
IRQ status register alongside the existing SOF bits, as well as
TOP_IRQ_STATUS_RDI_OFFSET for RDI0 in the top-level IRQ registers.
These definitions are added for completeness and don't enable SOF or
EOF interrupts.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
.../media/platform/qcom/camss/camss-csid-1080.c | 402 +++++++++++++++++++++
drivers/media/platform/qcom/camss/camss-csid.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 75 ++++
4 files changed, 480 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 27898b3cc7d3..218ba3a95939 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -8,6 +8,7 @@ qcom-camss-objs += \
camss-csid-4-7.o \
camss-csid-340.o \
camss-csid-680.o \
+ camss-csid-1080.o \
camss-csid-gen2.o \
camss-csid-gen3.o \
camss-csiphy.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
new file mode 100644
index 000000000000..3d90d31201fa
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
@@ -0,0 +1,402 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-1080.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "camss.h"
+#include "camss-csid.h"
+#include "camss-csid-gen3.h"
+
+/* Reset and Command Registers */
+#define CSID_RST_CFG 0x108
+#define RST_MODE BIT(0)
+#define RST_LOCATION BIT(4)
+
+/* Reset and Command Registers */
+#define CSID_RST_CMD 0x10C
+#define SELECT_HW_RST BIT(0)
+#define SELECT_IRQ_RST BIT(2)
+#define CSID_IRQ_CMD 0x110
+#define IRQ_CMD_CLEAR BIT(0)
+
+/* Register Update Commands, RUP/AUP */
+#define CSID_RUP_CMD 0x114
+#define CSID_AUP_CMD 0x118
+#define CSID_RUP_AUP_RDI(rdi) (BIT(8) << (rdi))
+#define CSID_RUP_AUP_CMD 0x11C
+#define RUP_SET BIT(0)
+#define MUP BIT(4)
+
+/* Top level interrupt registers */
+#define CSID_TOP_IRQ_STATUS 0x180
+#define CSID_TOP_IRQ_MASK 0x184
+#define CSID_TOP_IRQ_CLEAR 0x188
+#define INFO_RST_DONE BIT(0)
+#define CSI2_RX_IRQ_STATUS BIT(2)
+#define BUF_DONE_IRQ_STATUS BIT(3)
+#define TOP_IRQ_STATUS_RDI_OFFSET 16
+
+/* Buffer done interrupt registers */
+#define CSID_BUF_DONE_IRQ_STATUS 0x1A0
+#define BUF_DONE_IRQ_STATUS_RDI_OFFSET 16
+#define CSID_BUF_DONE_IRQ_MASK 0x1A4
+#define CSID_BUF_DONE_IRQ_CLEAR 0x1A8
+#define CSID_BUF_DONE_IRQ_SET 0x1AC
+
+/* CSI2 RX interrupt registers */
+#define CSID_CSI2_RX_IRQ_STATUS 0x1B0
+#define CSID_CSI2_RX_IRQ_MASK 0x1B4
+#define CSID_CSI2_RX_IRQ_CLEAR 0x1B8
+#define CSID_CSI2_RX_IRQ_SET 0x1BC
+
+/* CSI2 RX Configuration */
+#define CSID_CSI2_RX_CFG0 0x880
+#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
+#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
+#define CSI2_RX_CFG0_PHY_NUM_SEL 20
+#define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1
+#define CSID_CSI2_RX_CFG1 0x884
+#define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0)
+#define CSI2_RX_CFG1_VC_MODE BIT(2)
+
+#define MSM_CSID_MAX_SRC_STREAMS_1080 (csid_is_lite(csid) ? 4 : 5)
+
+/* RDI Configuration */
+#define CSID_RDI_CFG0(rdi) (csid_is_lite(csid) ?\
+ (0x3080 + 0x200 * (rdi)) :\
+ (0x5480 + 0x200 * (rdi)))
+#define RDI_CFG0_RETIME_BS BIT(5)
+#define RDI_CFG0_TIMESTAMP_EN BIT(6)
+#define RDI_CFG0_TIMESTAMP_STB_SEL BIT(8)
+#define RDI_CFG0_DECODE_FORMAT 12
+#define RDI_CFG0_DT 16
+#define RDI_CFG0_VC 22
+#define RDI_CFG0_EN BIT(31)
+
+/* RDI Control and Configuration */
+#define CSID_RDI_CTRL(rdi) (csid_is_lite(csid) ?\
+ (0x3088 + 0x200 * (rdi)) :\
+ (0x5488 + 0x200 * (rdi)))
+#define RDI_CTRL_START_CMD BIT(0)
+
+#define CSID_RDI_CFG1(rdi) (csid_is_lite(csid) ?\
+ (0x3094 + 0x200 * (rdi)) :\
+ (0x5494 + 0x200 * (rdi)))
+#define RDI_CFG1_DROP_H_EN BIT(5)
+#define RDI_CFG1_DROP_V_EN BIT(6)
+#define RDI_CFG1_CROP_H_EN BIT(7)
+#define RDI_CFG1_CROP_V_EN BIT(8)
+#define RDI_CFG1_PACKING_FORMAT_MIPI BIT(15)
+
+/* RDI Pixel Store Configuration */
+#define CSID_RDI_PIX_STORE_CFG0(rdi) (0x5498 + 0x200 * (rdi))
+#define RDI_PIX_STORE_CFG0_EN BIT(0)
+#define RDI_PIX_STORE_CFG0_MIN_HBI 1
+
+/* RDI IRQ Status in wrapper */
+#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0x224 + (0x10 * (rdi)))
+#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0x228 + (0x10 * (rdi)))
+#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0x22C + (0x10 * (rdi)))
+#define INFO_RUP_DONE BIT(23)
+#define INFO_INPUT_SOF BIT(12)
+#define INFO_INPUT_EOF BIT(9)
+#define INFO_CAMIF_SOF BIT(4)
+#define INFO_CAMIF_EOF BIT(3)
+
+static void __csid_aup_rup_trigger(struct csid_device *csid)
+{
+ /* trigger SET in combined register */
+ writel(RUP_SET, csid->base + CSID_RUP_AUP_CMD);
+}
+
+static void __csid_addr_update(struct csid_device *csid, int port_id)
+{
+ csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
+ writel(csid->addr_update, csid->base + CSID_AUP_CMD);
+
+ __csid_aup_rup_trigger(csid);
+}
+
+static void __csid_addr_update_clear(struct csid_device *csid, int port_id)
+{
+ csid->addr_update &= ~CSID_RUP_AUP_RDI(port_id);
+}
+
+static void __csid_reg_update(struct csid_device *csid, int port_id)
+{
+ csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
+ writel(csid->reg_update, csid->base + CSID_RUP_CMD);
+
+ __csid_aup_rup_trigger(csid);
+}
+
+static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
+{
+ csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id);
+}
+
+static void __csid_configure_rx(struct csid_device *csid,
+ struct csid_phy_config *phy)
+{
+ u8 lane_cnt = phy->lane_cnt;
+ int val;
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ 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_SEL_BASE_IDX)
+ << CSI2_RX_CFG0_PHY_NUM_SEL;
+ writel(val, csid->base + CSID_CSI2_RX_CFG0);
+
+ val = CSI2_RX_CFG1_ECC_CORRECTION_EN;
+ writel(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_configure_rx_vc(struct csid_device *csid, int vc)
+{
+ int val;
+
+ if (vc > 3) {
+ val = readl(csid->base + CSID_CSI2_RX_CFG1);
+ val |= CSI2_RX_CFG1_VC_MODE;
+ writel(val, csid->base + CSID_CSI2_RX_CFG1);
+ }
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+ int val = 0;
+
+ if (enable)
+ val = RDI_CTRL_START_CMD;
+
+ writel(val, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_rdi_pix_store(struct csid_device *csid, u8 rdi)
+{
+ u32 val;
+
+ /*
+ * Configure pixel store to allow absorption of hblanking or idle time.
+ * This helps with horizontal crop and prevents line buffer conflicts.
+ * Reset state is 0x8 which has MIN_HBI=4, we keep the default MIN_HBI
+ * and just enable the pixel store functionality.
+ */
+ val = (4 << RDI_PIX_STORE_CFG0_MIN_HBI) | RDI_PIX_STORE_CFG0_EN;
+ writel(val, csid->base + CSID_RDI_PIX_STORE_CFG0(rdi));
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 port, u8 vc)
+{
+ u8 lane_cnt = csid->phy.lane_cnt;
+ u32 val;
+
+ /* Source pads matching RDI channels on hardware.
+ * E.g. Pad 1 -> RDI0, Pad 2 -> RDI1, etc.
+ */
+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
+ const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+ csid->res->formats->nformats,
+ input_format->code);
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ val = RDI_CFG0_TIMESTAMP_EN;
+ val |= RDI_CFG0_TIMESTAMP_STB_SEL;
+ val |= RDI_CFG0_RETIME_BS;
+
+ /* note: for non-RDI path, this should be format->decode_format */
+ val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
+ val |= vc << RDI_CFG0_VC;
+ val |= format->data_type << RDI_CFG0_DT;
+ writel(val, csid->base + CSID_RDI_CFG0(port));
+
+ val = RDI_CFG1_PACKING_FORMAT_MIPI;
+ writel(val, csid->base + CSID_RDI_CFG1(port));
+
+ /* Configure pixel store using dedicated register in 1080 */
+ if (!csid_is_lite(csid))
+ __csid_configure_rdi_pix_store(csid, port);
+
+ val = 0;
+ writel(val, csid->base + CSID_RDI_CTRL(port));
+
+ val = readl(csid->base + CSID_RDI_CFG0(port));
+
+ if (enable)
+ val |= RDI_CFG0_EN;
+
+ writel(val, csid->base + CSID_RDI_CFG0(port));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ u8 i, k;
+
+ __csid_configure_rx(csid, &csid->phy);
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ __csid_configure_rdi_stream(csid, enable, i, 0);
+ __csid_configure_rx_vc(csid, 0);
+
+ for (k = 0; k < CAMSS_INIT_BUF_COUNT; k++)
+ __csid_addr_update(csid, i);
+
+ __csid_reg_update(csid, i);
+
+ __csid_ctrl_rdi(csid, enable, i);
+ }
+ }
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ return 0;
+}
+
+static void csid_subdev_reg_update(struct csid_device *csid, int port_id, bool is_clear)
+{
+ if (is_clear)
+ __csid_reg_update_clear(csid, port_id);
+ else
+ __csid_reg_update(csid, port_id);
+}
+
+static void csid_subdev_addr_update(struct csid_device *csid, int port_id, bool is_clear)
+{
+ if (is_clear)
+ __csid_addr_update_clear(csid, port_id);
+ else
+ __csid_addr_update(csid, port_id);
+}
+
+/**
+ * csid_isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 val, buf_done_val;
+ u8 reset_done;
+ int i;
+
+ val = readl(csid->base + CSID_TOP_IRQ_STATUS);
+ writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
+
+ reset_done = val & INFO_RST_DONE;
+
+ buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
+ writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
+ writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+
+ if (val & INFO_RUP_DONE) {
+ __csid_addr_update_clear(csid, i);
+ __csid_reg_update_clear(csid, i);
+ }
+
+ if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
+ camss_buf_done(csid->camss, csid->id, i);
+ }
+ }
+
+ val = IRQ_CMD_CLEAR;
+ writel(val, csid->base + CSID_IRQ_CMD);
+
+ if (reset_done)
+ complete(&csid->reset_complete);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * csid_reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+ u32 val;
+ int i;
+
+ reinit_completion(&csid->reset_complete);
+
+ val = INFO_RST_DONE | BUF_DONE_IRQ_STATUS;
+ writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
+ writel(val, csid->base + CSID_TOP_IRQ_MASK);
+
+ val = 0;
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ /*
+ * Only need to clear buf done IRQ status here,
+ * RUP done IRQ status will be cleared once isr
+ * strobe generated by CSID_RST_CMD
+ */
+ val |= BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i);
+ }
+ }
+ writel(val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+ writel(val, csid->base + CSID_BUF_DONE_IRQ_MASK);
+
+ /* Clear all IRQ status with CLEAR bits set */
+ val = IRQ_CMD_CLEAR;
+ writel(val, csid->base + CSID_IRQ_CMD);
+
+ val = RST_LOCATION | RST_MODE;
+ writel(val, csid->base + CSID_RST_CFG);
+
+ val = SELECT_HW_RST | SELECT_IRQ_RST;
+ writel(val, csid->base + CSID_RST_CMD);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID reset timeout\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+ csid->testgen.nmodes = CSID_PAYLOAD_MODE_DISABLED;
+}
+
+const struct csid_hw_ops csid_ops_1080 = {
+ .configure_stream = csid_configure_stream,
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+ .reg_update = csid_subdev_reg_update,
+ .addr_update = csid_subdev_addr_update,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 2f7e593defed..a3ab2a384bb4 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -163,6 +163,7 @@ struct csid_device {
u32 irq;
char irq_name[30];
u32 reg_update;
+ u32 addr_update;
struct camss_clock *clock;
int nclocks;
struct regulator_bulk_data *supplies;
@@ -224,6 +225,7 @@ extern const struct csid_hw_ops csid_ops_4_1;
extern const struct csid_hw_ops csid_ops_4_7;
extern const struct csid_hw_ops csid_ops_340;
extern const struct csid_hw_ops csid_ops_680;
+extern const struct csid_hw_ops csid_ops_1080;
extern const struct csid_hw_ops csid_ops_gen2;
extern const struct csid_hw_ops csid_ops_gen3;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index b0b63dd3d958..12dfe760fc54 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -83,6 +83,79 @@ static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
},
};
+static const struct camss_subdev_resources csid_res_kaanapali[] = {
+ /* CSID0 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID1 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID2 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid2" },
+ .interrupt = { "csid2" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID_LITE0 */
+ {
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid_lite0" },
+ .interrupt = { "csid_lite0" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID_LITE1 */
+ {
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid_lite1" },
+ .interrupt = { "csid_lite1" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ }
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5653,9 +5726,11 @@ static const struct camss_resources kaanapali_resources = {
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
+ .csid_res = csid_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
+ .csid_num = ARRAY_SIZE(csid_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 09/15] media: qcom: camss: csid: Add support for CSID 1080
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Atiya Kailany
Add support for the CSID 1080 hardware found on the Kaanapali SoC.
Introduce the CSID 1080 hardware resource descriptions and implement
the hardware-specific register programming, reset sequence, and
BUF_DONE interrupt handling.
CSID 1080 uses separate registers for RUP and AUP updates, with a SET
register used to commit them. Extend the CSID interface to support this
scheme while retaining the legacy combined reg_update mechanism.
Also define the INFO_INPUT_EOF and INFO_CAMIF_EOF bits in the per-RDI
IRQ status register alongside the existing SOF bits, as well as
TOP_IRQ_STATUS_RDI_OFFSET for RDI0 in the top-level IRQ registers.
These definitions are added for completeness and don't enable SOF or
EOF interrupts.
Reviewed-by: Bryan O'Donoghue <bod@kernel.org>
Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
.../media/platform/qcom/camss/camss-csid-1080.c | 402 +++++++++++++++++++++
drivers/media/platform/qcom/camss/camss-csid.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 75 ++++
4 files changed, 480 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 27898b3cc7d3..218ba3a95939 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -8,6 +8,7 @@ qcom-camss-objs += \
camss-csid-4-7.o \
camss-csid-340.o \
camss-csid-680.o \
+ camss-csid-1080.o \
camss-csid-gen2.o \
camss-csid-gen3.o \
camss-csiphy.o \
diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
new file mode 100644
index 000000000000..3d90d31201fa
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
@@ -0,0 +1,402 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-1080.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "camss.h"
+#include "camss-csid.h"
+#include "camss-csid-gen3.h"
+
+/* Reset and Command Registers */
+#define CSID_RST_CFG 0x108
+#define RST_MODE BIT(0)
+#define RST_LOCATION BIT(4)
+
+/* Reset and Command Registers */
+#define CSID_RST_CMD 0x10C
+#define SELECT_HW_RST BIT(0)
+#define SELECT_IRQ_RST BIT(2)
+#define CSID_IRQ_CMD 0x110
+#define IRQ_CMD_CLEAR BIT(0)
+
+/* Register Update Commands, RUP/AUP */
+#define CSID_RUP_CMD 0x114
+#define CSID_AUP_CMD 0x118
+#define CSID_RUP_AUP_RDI(rdi) (BIT(8) << (rdi))
+#define CSID_RUP_AUP_CMD 0x11C
+#define RUP_SET BIT(0)
+#define MUP BIT(4)
+
+/* Top level interrupt registers */
+#define CSID_TOP_IRQ_STATUS 0x180
+#define CSID_TOP_IRQ_MASK 0x184
+#define CSID_TOP_IRQ_CLEAR 0x188
+#define INFO_RST_DONE BIT(0)
+#define CSI2_RX_IRQ_STATUS BIT(2)
+#define BUF_DONE_IRQ_STATUS BIT(3)
+#define TOP_IRQ_STATUS_RDI_OFFSET 16
+
+/* Buffer done interrupt registers */
+#define CSID_BUF_DONE_IRQ_STATUS 0x1A0
+#define BUF_DONE_IRQ_STATUS_RDI_OFFSET 16
+#define CSID_BUF_DONE_IRQ_MASK 0x1A4
+#define CSID_BUF_DONE_IRQ_CLEAR 0x1A8
+#define CSID_BUF_DONE_IRQ_SET 0x1AC
+
+/* CSI2 RX interrupt registers */
+#define CSID_CSI2_RX_IRQ_STATUS 0x1B0
+#define CSID_CSI2_RX_IRQ_MASK 0x1B4
+#define CSID_CSI2_RX_IRQ_CLEAR 0x1B8
+#define CSID_CSI2_RX_IRQ_SET 0x1BC
+
+/* CSI2 RX Configuration */
+#define CSID_CSI2_RX_CFG0 0x880
+#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
+#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
+#define CSI2_RX_CFG0_PHY_NUM_SEL 20
+#define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1
+#define CSID_CSI2_RX_CFG1 0x884
+#define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0)
+#define CSI2_RX_CFG1_VC_MODE BIT(2)
+
+#define MSM_CSID_MAX_SRC_STREAMS_1080 (csid_is_lite(csid) ? 4 : 5)
+
+/* RDI Configuration */
+#define CSID_RDI_CFG0(rdi) (csid_is_lite(csid) ?\
+ (0x3080 + 0x200 * (rdi)) :\
+ (0x5480 + 0x200 * (rdi)))
+#define RDI_CFG0_RETIME_BS BIT(5)
+#define RDI_CFG0_TIMESTAMP_EN BIT(6)
+#define RDI_CFG0_TIMESTAMP_STB_SEL BIT(8)
+#define RDI_CFG0_DECODE_FORMAT 12
+#define RDI_CFG0_DT 16
+#define RDI_CFG0_VC 22
+#define RDI_CFG0_EN BIT(31)
+
+/* RDI Control and Configuration */
+#define CSID_RDI_CTRL(rdi) (csid_is_lite(csid) ?\
+ (0x3088 + 0x200 * (rdi)) :\
+ (0x5488 + 0x200 * (rdi)))
+#define RDI_CTRL_START_CMD BIT(0)
+
+#define CSID_RDI_CFG1(rdi) (csid_is_lite(csid) ?\
+ (0x3094 + 0x200 * (rdi)) :\
+ (0x5494 + 0x200 * (rdi)))
+#define RDI_CFG1_DROP_H_EN BIT(5)
+#define RDI_CFG1_DROP_V_EN BIT(6)
+#define RDI_CFG1_CROP_H_EN BIT(7)
+#define RDI_CFG1_CROP_V_EN BIT(8)
+#define RDI_CFG1_PACKING_FORMAT_MIPI BIT(15)
+
+/* RDI Pixel Store Configuration */
+#define CSID_RDI_PIX_STORE_CFG0(rdi) (0x5498 + 0x200 * (rdi))
+#define RDI_PIX_STORE_CFG0_EN BIT(0)
+#define RDI_PIX_STORE_CFG0_MIN_HBI 1
+
+/* RDI IRQ Status in wrapper */
+#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0x224 + (0x10 * (rdi)))
+#define CSID_CSI2_RDIN_IRQ_MASK(rdi) (0x228 + (0x10 * (rdi)))
+#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0x22C + (0x10 * (rdi)))
+#define INFO_RUP_DONE BIT(23)
+#define INFO_INPUT_SOF BIT(12)
+#define INFO_INPUT_EOF BIT(9)
+#define INFO_CAMIF_SOF BIT(4)
+#define INFO_CAMIF_EOF BIT(3)
+
+static void __csid_aup_rup_trigger(struct csid_device *csid)
+{
+ /* trigger SET in combined register */
+ writel(RUP_SET, csid->base + CSID_RUP_AUP_CMD);
+}
+
+static void __csid_addr_update(struct csid_device *csid, int port_id)
+{
+ csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
+ writel(csid->addr_update, csid->base + CSID_AUP_CMD);
+
+ __csid_aup_rup_trigger(csid);
+}
+
+static void __csid_addr_update_clear(struct csid_device *csid, int port_id)
+{
+ csid->addr_update &= ~CSID_RUP_AUP_RDI(port_id);
+}
+
+static void __csid_reg_update(struct csid_device *csid, int port_id)
+{
+ csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
+ writel(csid->reg_update, csid->base + CSID_RUP_CMD);
+
+ __csid_aup_rup_trigger(csid);
+}
+
+static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
+{
+ csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id);
+}
+
+static void __csid_configure_rx(struct csid_device *csid,
+ struct csid_phy_config *phy)
+{
+ u8 lane_cnt = phy->lane_cnt;
+ int val;
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ 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_SEL_BASE_IDX)
+ << CSI2_RX_CFG0_PHY_NUM_SEL;
+ writel(val, csid->base + CSID_CSI2_RX_CFG0);
+
+ val = CSI2_RX_CFG1_ECC_CORRECTION_EN;
+ writel(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_configure_rx_vc(struct csid_device *csid, int vc)
+{
+ int val;
+
+ if (vc > 3) {
+ val = readl(csid->base + CSID_CSI2_RX_CFG1);
+ val |= CSI2_RX_CFG1_VC_MODE;
+ writel(val, csid->base + CSID_CSI2_RX_CFG1);
+ }
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+ int val = 0;
+
+ if (enable)
+ val = RDI_CTRL_START_CMD;
+
+ writel(val, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_rdi_pix_store(struct csid_device *csid, u8 rdi)
+{
+ u32 val;
+
+ /*
+ * Configure pixel store to allow absorption of hblanking or idle time.
+ * This helps with horizontal crop and prevents line buffer conflicts.
+ * Reset state is 0x8 which has MIN_HBI=4, we keep the default MIN_HBI
+ * and just enable the pixel store functionality.
+ */
+ val = (4 << RDI_PIX_STORE_CFG0_MIN_HBI) | RDI_PIX_STORE_CFG0_EN;
+ writel(val, csid->base + CSID_RDI_PIX_STORE_CFG0(rdi));
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 port, u8 vc)
+{
+ u8 lane_cnt = csid->phy.lane_cnt;
+ u32 val;
+
+ /* Source pads matching RDI channels on hardware.
+ * E.g. Pad 1 -> RDI0, Pad 2 -> RDI1, etc.
+ */
+ struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
+ const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+ csid->res->formats->nformats,
+ input_format->code);
+
+ if (!lane_cnt)
+ lane_cnt = 4;
+
+ val = RDI_CFG0_TIMESTAMP_EN;
+ val |= RDI_CFG0_TIMESTAMP_STB_SEL;
+ val |= RDI_CFG0_RETIME_BS;
+
+ /* note: for non-RDI path, this should be format->decode_format */
+ val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
+ val |= vc << RDI_CFG0_VC;
+ val |= format->data_type << RDI_CFG0_DT;
+ writel(val, csid->base + CSID_RDI_CFG0(port));
+
+ val = RDI_CFG1_PACKING_FORMAT_MIPI;
+ writel(val, csid->base + CSID_RDI_CFG1(port));
+
+ /* Configure pixel store using dedicated register in 1080 */
+ if (!csid_is_lite(csid))
+ __csid_configure_rdi_pix_store(csid, port);
+
+ val = 0;
+ writel(val, csid->base + CSID_RDI_CTRL(port));
+
+ val = readl(csid->base + CSID_RDI_CFG0(port));
+
+ if (enable)
+ val |= RDI_CFG0_EN;
+
+ writel(val, csid->base + CSID_RDI_CFG0(port));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+ u8 i, k;
+
+ __csid_configure_rx(csid, &csid->phy);
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ __csid_configure_rdi_stream(csid, enable, i, 0);
+ __csid_configure_rx_vc(csid, 0);
+
+ for (k = 0; k < CAMSS_INIT_BUF_COUNT; k++)
+ __csid_addr_update(csid, i);
+
+ __csid_reg_update(csid, i);
+
+ __csid_ctrl_rdi(csid, enable, i);
+ }
+ }
+}
+
+static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
+{
+ return 0;
+}
+
+static void csid_subdev_reg_update(struct csid_device *csid, int port_id, bool is_clear)
+{
+ if (is_clear)
+ __csid_reg_update_clear(csid, port_id);
+ else
+ __csid_reg_update(csid, port_id);
+}
+
+static void csid_subdev_addr_update(struct csid_device *csid, int port_id, bool is_clear)
+{
+ if (is_clear)
+ __csid_addr_update_clear(csid, port_id);
+ else
+ __csid_addr_update(csid, port_id);
+}
+
+/**
+ * csid_isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+ struct csid_device *csid = dev;
+ u32 val, buf_done_val;
+ u8 reset_done;
+ int i;
+
+ val = readl(csid->base + CSID_TOP_IRQ_STATUS);
+ writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
+
+ reset_done = val & INFO_RST_DONE;
+
+ buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
+ writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
+ writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+
+ if (val & INFO_RUP_DONE) {
+ __csid_addr_update_clear(csid, i);
+ __csid_reg_update_clear(csid, i);
+ }
+
+ if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
+ camss_buf_done(csid->camss, csid->id, i);
+ }
+ }
+
+ val = IRQ_CMD_CLEAR;
+ writel(val, csid->base + CSID_IRQ_CMD);
+
+ if (reset_done)
+ complete(&csid->reset_complete);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * csid_reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int csid_reset(struct csid_device *csid)
+{
+ unsigned long time;
+ u32 val;
+ int i;
+
+ reinit_completion(&csid->reset_complete);
+
+ val = INFO_RST_DONE | BUF_DONE_IRQ_STATUS;
+ writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
+ writel(val, csid->base + CSID_TOP_IRQ_MASK);
+
+ val = 0;
+ for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
+ if (csid->phy.en_vc & BIT(i)) {
+ /*
+ * Only need to clear buf done IRQ status here,
+ * RUP done IRQ status will be cleared once isr
+ * strobe generated by CSID_RST_CMD
+ */
+ val |= BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i);
+ }
+ }
+ writel(val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+ writel(val, csid->base + CSID_BUF_DONE_IRQ_MASK);
+
+ /* Clear all IRQ status with CLEAR bits set */
+ val = IRQ_CMD_CLEAR;
+ writel(val, csid->base + CSID_IRQ_CMD);
+
+ val = RST_LOCATION | RST_MODE;
+ writel(val, csid->base + CSID_RST_CFG);
+
+ val = SELECT_HW_RST | SELECT_IRQ_RST;
+ writel(val, csid->base + CSID_RST_CMD);
+
+ time = wait_for_completion_timeout(&csid->reset_complete,
+ msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+
+ if (!time) {
+ dev_err(csid->camss->dev, "CSID reset timeout\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+ csid->testgen.nmodes = CSID_PAYLOAD_MODE_DISABLED;
+}
+
+const struct csid_hw_ops csid_ops_1080 = {
+ .configure_stream = csid_configure_stream,
+ .configure_testgen_pattern = csid_configure_testgen_pattern,
+ .hw_version = csid_hw_version,
+ .isr = csid_isr,
+ .reset = csid_reset,
+ .src_pad_code = csid_src_pad_code,
+ .subdev_init = csid_subdev_init,
+ .reg_update = csid_subdev_reg_update,
+ .addr_update = csid_subdev_addr_update,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 2f7e593defed..a3ab2a384bb4 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -163,6 +163,7 @@ struct csid_device {
u32 irq;
char irq_name[30];
u32 reg_update;
+ u32 addr_update;
struct camss_clock *clock;
int nclocks;
struct regulator_bulk_data *supplies;
@@ -224,6 +225,7 @@ extern const struct csid_hw_ops csid_ops_4_1;
extern const struct csid_hw_ops csid_ops_4_7;
extern const struct csid_hw_ops csid_ops_340;
extern const struct csid_hw_ops csid_ops_680;
+extern const struct csid_hw_ops csid_ops_1080;
extern const struct csid_hw_ops csid_ops_gen2;
extern const struct csid_hw_ops csid_ops_gen3;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index b0b63dd3d958..12dfe760fc54 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -83,6 +83,79 @@ static const struct camss_subdev_resources csiphy_res_kaanapali[] = {
},
};
+static const struct camss_subdev_resources csid_res_kaanapali[] = {
+ /* CSID0 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid0" },
+ .interrupt = { "csid0" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID1 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid1" },
+ .interrupt = { "csid1" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID2 */
+ {
+ .clock = { "csid", "csid_csiphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid2" },
+ .interrupt = { "csid2" },
+ .csid = {
+ .is_lite = false,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID_LITE0 */
+ {
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid_lite0" },
+ .interrupt = { "csid_lite0" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ },
+ /* CSID_LITE1 */
+ {
+ .clock = { "vfe_lite_csid", "vfe_lite_cphy_rx" },
+ .clock_rate = { { 400000000, 480000000 },
+ { 400000000, 480000000 } },
+ .reg = { "csid_lite1" },
+ .interrupt = { "csid_lite1" },
+ .csid = {
+ .is_lite = true,
+ .parent_dev_ops = &vfe_parent_dev_ops,
+ .hw_ops = &csid_ops_1080,
+ .formats = &csid_formats_gen2
+ }
+ }
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5653,9 +5726,11 @@ static const struct camss_resources kaanapali_resources = {
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
+ .csid_res = csid_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
+ .csid_num = ARRAY_SIZE(csid_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 09/15] media: qcom: camss: csid: Add support for CSID 1080
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:36 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:36 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] media: qcom: camss: out-of-bounds fmt access in __csid_configure_rdi_stream()
- [Medium] media: qcom: camss: csid-1080: race on addr_update and reg_update bitmasks
- [Low] media: qcom: camss: unused variable lane_cnt in __csid_configure_rdi_stream()
--
commit a4bf52311267182465594dfcec0df1e6e7980755
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: csid: Add support for CSID 1080
This commit adds hardware resource definitions and driver support for the
CSID 1080 module on the Qualcomm Kaanapali SoC, including RUP/AUP register
update handling, stream configuration, reset, and BUF_DONE interrupt
handling.
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
> new file mode 100644
> index 0000000000000..3d90d31201fa5
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
[ ... ]
> +#define MSM_CSID_MAX_SRC_STREAMS_1080 (csid_is_lite(csid) ? 4 : 5)
[ ... ]
> +static void __csid_addr_update(struct csid_device *csid, int port_id)
> +{
> + csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
> + writel(csid->addr_update, csid->base + CSID_AUP_CMD);
> +
> + __csid_aup_rup_trigger(csid);
> +}
> +
> +static void __csid_addr_update_clear(struct csid_device *csid, int port_id)
> +{
> + csid->addr_update &= ~CSID_RUP_AUP_RDI(port_id);
> +}
> +
> +static void __csid_reg_update(struct csid_device *csid, int port_id)
> +{
> + csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
> + writel(csid->reg_update, csid->base + CSID_RUP_CMD);
> +
> + __csid_aup_rup_trigger(csid);
> +}
> +
> +static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
> +{
> + csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id);
> +}
[ ... ]
> +static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 port, u8 vc)
> +{
> + u8 lane_cnt = csid->phy.lane_cnt;
> + u32 val;
> +
> + /* Source pads matching RDI channels on hardware.
> + * E.g. Pad 1 -> RDI0, Pad 2 -> RDI1, etc.
> + */
> + struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
> + const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
> + csid->res->formats->nformats,
> + input_format->code);
> +
> + if (!lane_cnt)
> + lane_cnt = 4;
[Severity: Low]
In __csid_configure_rdi_stream(), lane_cnt is initialized and updated here
but never read anywhere in the function. Will this trigger an
-Wunused-but-set-variable warning?
> +
> + val = RDI_CFG0_TIMESTAMP_EN;
> + val |= RDI_CFG0_TIMESTAMP_STB_SEL;
> + val |= RDI_CFG0_RETIME_BS;
> +
> + /* note: for non-RDI path, this should be format->decode_format */
> + val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
> + val |= vc << RDI_CFG0_VC;
> + val |= format->data_type << RDI_CFG0_DT;
> + writel(val, csid->base + CSID_RDI_CFG0(port));
> +
> + val = RDI_CFG1_PACKING_FORMAT_MIPI;
> + writel(val, csid->base + CSID_RDI_CFG1(port));
> +
> + /* Configure pixel store using dedicated register in 1080 */
> + if (!csid_is_lite(csid))
> + __csid_configure_rdi_pix_store(csid, port);
> +
> + val = 0;
> + writel(val, csid->base + CSID_RDI_CTRL(port));
> +
> + val = readl(csid->base + CSID_RDI_CFG0(port));
> +
> + if (enable)
> + val |= RDI_CFG0_EN;
> +
> + writel(val, csid->base + CSID_RDI_CFG0(port));
> +}
> +
> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
> +{
> + u8 i, k;
> +
> + __csid_configure_rx(csid, &csid->phy);
> +
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
> + if (csid->phy.en_vc & BIT(i)) {
> + __csid_configure_rdi_stream(csid, enable, i, 0);
[Severity: High]
Can this read past the end of csid->fmt[] on non-lite CSID 1080 instances?
For non-lite instances (CSID0, CSID1, CSID2 in csid_res_kaanapali),
MSM_CSID_MAX_SRC_STREAMS_1080 evaluates to 5, so csid_configure_stream()
iterates i from 0 to 4 and passes port = 4 into
__csid_configure_rdi_stream().
Inside __csid_configure_rdi_stream(), input_format is computed as:
struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
However, in drivers/media/platform/qcom/camss/camss-csid.h,
MSM_CSID_PAD_FIRST_SRC is 1 and MSM_CSID_PADS_NUM is still 5:
#define MSM_CSID_PAD_SINK 0
#define MSM_CSID_PAD_FIRST_SRC 1
#define MSM_CSID_PADS_NUM 5
...
struct csid_device {
...
struct media_pad pads[MSM_CSID_PADS_NUM];
...
struct v4l2_mbus_framefmt fmt[MSM_CSID_PADS_NUM];
When port is 4, MSM_CSID_PAD_FIRST_SRC + port is 5, which indexes one
element past the end of csid->fmt[5] when reading input_format->code (and
msm_csid_register_entity() only registers 4 source pads). Should
MSM_CSID_PADS_NUM and MSM_CSID_MAX_SRC_STREAMS be updated to accommodate
the 5th RDI stream, or should MSM_CSID_MAX_SRC_STREAMS_1080 be capped to
the number of source pads?
> + __csid_configure_rx_vc(csid, 0);
> +
> + for (k = 0; k < CAMSS_INIT_BUF_COUNT; k++)
> + __csid_addr_update(csid, i);
> +
> + __csid_reg_update(csid, i);
> +
> + __csid_ctrl_rdi(csid, enable, i);
> + }
> + }
> +}
[ ... ]
> +static irqreturn_t csid_isr(int irq, void *dev)
> +{
> + struct csid_device *csid = dev;
> + u32 val, buf_done_val;
> + u8 reset_done;
> + int i;
> +
> + val = readl(csid->base + CSID_TOP_IRQ_STATUS);
> + writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
> +
> + reset_done = val & INFO_RST_DONE;
> +
> + buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
> + writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
> +
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
> + if (csid->phy.en_vc & BIT(i)) {
> + val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
> + writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
> +
> + if (val & INFO_RUP_DONE) {
> + __csid_addr_update_clear(csid, i);
> + __csid_reg_update_clear(csid, i);
> + }
> +
> + if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
> + camss_buf_done(csid->camss, csid->id, i);
[Severity: Medium]
Could the unlocked updates to csid->addr_update and csid->reg_update here
race with vfe_queue_buffer_v2() and vfe_enable_output_v2(), or re-trigger
updates for other RDI ports?
In drivers/media/platform/qcom/camss/camss-vfe.c, vfe_queue_buffer_v2() and
vfe_enable_output_v2() call ops->addr_update() and ops->reg_update() while
holding vfe->output_lock:
vfe_queue_buffer_v2()
spin_lock_irqsave(&vfe->output_lock, flags);
ops->addr_update(vfe, line->id)
-> csid_subdev_addr_update()
-> __csid_addr_update()
ops->reg_update(vfe, line->id)
-> csid_subdev_reg_update()
-> __csid_reg_update()
In csid_isr(), __csid_addr_update_clear() and __csid_reg_update_clear()
modify csid->addr_update and csid->reg_update without holding
vfe->output_lock or a CSID spinlock. If csid_isr() runs on one CPU while
vfe_queue_buffer_v2() or vfe_enable_output_v2() runs on another CPU, the
read-modify-write on csid->addr_update and csid->reg_update can lose a
newly set RDI bit or write a stale cleared bit back into CSID_AUP_CMD and
CSID_RUP_CMD.
Also, within this loop in csid_isr(), camss_buf_done() -> vfe_buf_done() is
called for port i before INFO_RUP_DONE is checked and cleared for ports
j > i. When vfe_buf_done() calls __csid_addr_update(csid, i), it writes the
entire csid->addr_update bitmask to CSID_AUP_CMD while completed ports
j > i still have their CSID_RUP_AUP_RDI(j) bits set. Should INFO_RUP_DONE
be processed for all ports before invoking camss_buf_done(), or does
CSID_AUP_CMD / CSID_RUP_CMD only need CSID_RUP_AUP_RDI(port_id) written
directly?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=9
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 09/15] media: qcom: camss: csid: Add support for CSID 1080
@ 2026-10-28 15:36 ` sashiko-bot
0 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:36 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] media: qcom: camss: out-of-bounds fmt access in __csid_configure_rdi_stream()
- [Medium] media: qcom: camss: csid-1080: race on addr_update and reg_update bitmasks
- [Low] media: qcom: camss: unused variable lane_cnt in __csid_configure_rdi_stream()
--
commit a4bf52311267182465594dfcec0df1e6e7980755
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: csid: Add support for CSID 1080
This commit adds hardware resource definitions and driver support for the
CSID 1080 module on the Qualcomm Kaanapali SoC, including RUP/AUP register
update handling, stream configuration, reset, and BUF_DONE interrupt
handling.
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
> new file mode 100644
> index 0000000000000..3d90d31201fa5
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
[ ... ]
> +#define MSM_CSID_MAX_SRC_STREAMS_1080 (csid_is_lite(csid) ? 4 : 5)
[ ... ]
> +static void __csid_addr_update(struct csid_device *csid, int port_id)
> +{
> + csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
> + writel(csid->addr_update, csid->base + CSID_AUP_CMD);
> +
> + __csid_aup_rup_trigger(csid);
> +}
> +
> +static void __csid_addr_update_clear(struct csid_device *csid, int port_id)
> +{
> + csid->addr_update &= ~CSID_RUP_AUP_RDI(port_id);
> +}
> +
> +static void __csid_reg_update(struct csid_device *csid, int port_id)
> +{
> + csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
> + writel(csid->reg_update, csid->base + CSID_RUP_CMD);
> +
> + __csid_aup_rup_trigger(csid);
> +}
> +
> +static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
> +{
> + csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id);
> +}
[ ... ]
> +static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 port, u8 vc)
> +{
> + u8 lane_cnt = csid->phy.lane_cnt;
> + u32 val;
> +
> + /* Source pads matching RDI channels on hardware.
> + * E.g. Pad 1 -> RDI0, Pad 2 -> RDI1, etc.
> + */
> + struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
> + const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
> + csid->res->formats->nformats,
> + input_format->code);
> +
> + if (!lane_cnt)
> + lane_cnt = 4;
[Severity: Low]
In __csid_configure_rdi_stream(), lane_cnt is initialized and updated here
but never read anywhere in the function. Will this trigger an
-Wunused-but-set-variable warning?
> +
> + val = RDI_CFG0_TIMESTAMP_EN;
> + val |= RDI_CFG0_TIMESTAMP_STB_SEL;
> + val |= RDI_CFG0_RETIME_BS;
> +
> + /* note: for non-RDI path, this should be format->decode_format */
> + val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
> + val |= vc << RDI_CFG0_VC;
> + val |= format->data_type << RDI_CFG0_DT;
> + writel(val, csid->base + CSID_RDI_CFG0(port));
> +
> + val = RDI_CFG1_PACKING_FORMAT_MIPI;
> + writel(val, csid->base + CSID_RDI_CFG1(port));
> +
> + /* Configure pixel store using dedicated register in 1080 */
> + if (!csid_is_lite(csid))
> + __csid_configure_rdi_pix_store(csid, port);
> +
> + val = 0;
> + writel(val, csid->base + CSID_RDI_CTRL(port));
> +
> + val = readl(csid->base + CSID_RDI_CFG0(port));
> +
> + if (enable)
> + val |= RDI_CFG0_EN;
> +
> + writel(val, csid->base + CSID_RDI_CFG0(port));
> +}
> +
> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
> +{
> + u8 i, k;
> +
> + __csid_configure_rx(csid, &csid->phy);
> +
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
> + if (csid->phy.en_vc & BIT(i)) {
> + __csid_configure_rdi_stream(csid, enable, i, 0);
[Severity: High]
Can this read past the end of csid->fmt[] on non-lite CSID 1080 instances?
For non-lite instances (CSID0, CSID1, CSID2 in csid_res_kaanapali),
MSM_CSID_MAX_SRC_STREAMS_1080 evaluates to 5, so csid_configure_stream()
iterates i from 0 to 4 and passes port = 4 into
__csid_configure_rdi_stream().
Inside __csid_configure_rdi_stream(), input_format is computed as:
struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + port];
However, in drivers/media/platform/qcom/camss/camss-csid.h,
MSM_CSID_PAD_FIRST_SRC is 1 and MSM_CSID_PADS_NUM is still 5:
#define MSM_CSID_PAD_SINK 0
#define MSM_CSID_PAD_FIRST_SRC 1
#define MSM_CSID_PADS_NUM 5
...
struct csid_device {
...
struct media_pad pads[MSM_CSID_PADS_NUM];
...
struct v4l2_mbus_framefmt fmt[MSM_CSID_PADS_NUM];
When port is 4, MSM_CSID_PAD_FIRST_SRC + port is 5, which indexes one
element past the end of csid->fmt[5] when reading input_format->code (and
msm_csid_register_entity() only registers 4 source pads). Should
MSM_CSID_PADS_NUM and MSM_CSID_MAX_SRC_STREAMS be updated to accommodate
the 5th RDI stream, or should MSM_CSID_MAX_SRC_STREAMS_1080 be capped to
the number of source pads?
> + __csid_configure_rx_vc(csid, 0);
> +
> + for (k = 0; k < CAMSS_INIT_BUF_COUNT; k++)
> + __csid_addr_update(csid, i);
> +
> + __csid_reg_update(csid, i);
> +
> + __csid_ctrl_rdi(csid, enable, i);
> + }
> + }
> +}
[ ... ]
> +static irqreturn_t csid_isr(int irq, void *dev)
> +{
> + struct csid_device *csid = dev;
> + u32 val, buf_done_val;
> + u8 reset_done;
> + int i;
> +
> + val = readl(csid->base + CSID_TOP_IRQ_STATUS);
> + writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
> +
> + reset_done = val & INFO_RST_DONE;
> +
> + buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
> + writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
> +
> + for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS_1080; i++) {
> + if (csid->phy.en_vc & BIT(i)) {
> + val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
> + writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
> +
> + if (val & INFO_RUP_DONE) {
> + __csid_addr_update_clear(csid, i);
> + __csid_reg_update_clear(csid, i);
> + }
> +
> + if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
> + camss_buf_done(csid->camss, csid->id, i);
[Severity: Medium]
Could the unlocked updates to csid->addr_update and csid->reg_update here
race with vfe_queue_buffer_v2() and vfe_enable_output_v2(), or re-trigger
updates for other RDI ports?
In drivers/media/platform/qcom/camss/camss-vfe.c, vfe_queue_buffer_v2() and
vfe_enable_output_v2() call ops->addr_update() and ops->reg_update() while
holding vfe->output_lock:
vfe_queue_buffer_v2()
spin_lock_irqsave(&vfe->output_lock, flags);
ops->addr_update(vfe, line->id)
-> csid_subdev_addr_update()
-> __csid_addr_update()
ops->reg_update(vfe, line->id)
-> csid_subdev_reg_update()
-> __csid_reg_update()
In csid_isr(), __csid_addr_update_clear() and __csid_reg_update_clear()
modify csid->addr_update and csid->reg_update without holding
vfe->output_lock or a CSID spinlock. If csid_isr() runs on one CPU while
vfe_queue_buffer_v2() or vfe_enable_output_v2() runs on another CPU, the
read-modify-write on csid->addr_update and csid->reg_update can lose a
newly set RDI bit or write a stale cleared bit back into CSID_AUP_CMD and
CSID_RUP_CMD.
Also, within this loop in csid_isr(), camss_buf_done() -> vfe_buf_done() is
called for port i before INFO_RUP_DONE is checked and cleared for ports
j > i. When vfe_buf_done() calls __csid_addr_update(csid, i), it writes the
entire csid->addr_update bitmask to CSID_AUP_CMD while completed ports
j > i still have their CSID_RUP_AUP_RDI(j) bits set. Should INFO_RUP_DONE
be processed for all ports before invoking camss_buf_done(), or does
CSID_AUP_CMD / CSID_RUP_CMD only need CSID_RUP_AUP_RDI(port_id) written
directly?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=9
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Atiya Kailany
Add support for the VFE (Video Front End) 1080 found on Kaanapali SoC.
In the Kaanapali camera subsystem, the front-end blocks are referred to
as TFEs (Thin Front Ends). This driver continues to use the VFE naming
in some places to preserve consistency with the existing code and avoid
unnecessary renaming. Support is currently limited to three output lines,
matching the constraints of the CAMSS framework.
Kaanapali requires REG_UPDATE and AUP_UPDATE to be issued only after all
CSID configuration has completed. In addition, the number of AUP_UPDATE
requests must match the number of buffers queued to the write master
while it is being enabled.
Although real-time TFE traffic is routed through RT_CAMNOC, both
camnoc_rt_axi and camnoc_nrt_axi clocks must be enabled. This ensures
that the PDX_NOC, which sits downstream of both RT and NRT NOCs, exits
reset in a fully idle state.
Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
drivers/media/platform/qcom/camss/camss-vfe-1080.c | 213 +++++++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 2 +
drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
drivers/media/platform/qcom/camss/camss.c | 126 ++++++++++++
5 files changed, 343 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 218ba3a95939..42a14e8fe1b7 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -26,6 +26,7 @@ qcom-camss-objs += \
camss-vfe-340.o \
camss-vfe-480.o \
camss-vfe-680.o \
+ camss-vfe-1080.o \
camss-vfe-gen1.o \
camss-vfe-gen3.o \
camss-vfe-vbif.o \
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
new file mode 100644
index 000000000000..68798f13fbea
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-1080.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 1080
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+/* VFE-1080 Bus Register Base Addresses */
+#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x800 : 0x1000)
+
+#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
+#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0x128)
+
+#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x500 + (n) * 0x100)
+#define WM_CFG_EN BIT(0)
+#define WM_VIR_FRM_EN BIT(1)
+#define WM_CFG_MODE BIT(16)
+#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x504 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x508 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x50C + (n) * 0x100)
+#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
+#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x514 + (n) * 0x100)
+#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
+#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x518 + (n) * 0x100)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x530 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x534 + (n) * 0x100)
+
+/* VFE lite has no such registers */
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x538 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x53C + (n) * 0x100)
+
+#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x560 + (n) * 0x100)
+#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x564 + (n) * 0x100)
+
+/*
+ * IFE write master client IDs
+ *
+ * VIDEO_FULL 0
+ * VIDEO_DC4_Y 1
+ * VIDEO_DC4_C 2
+ * VIDEO_DC16_Y 3
+ * VIDEO_DC16_C 4
+ * DISPLAY_DS2_Y 5
+ * DISPLAY_DS2_C 6
+ * FD_Y 7
+ * FD_C 8
+ * PIXEL_RAW 9
+ * STATS_AEC_BG 10
+ * STATS_AEC_BHIST 11
+ * STATS_TINTLESS_BG 12
+ * STATS_AWB_BG 13
+ * STATS_AWB_BFW 14
+ * STATS_AF_BHIST 15
+ * STATS_ALSC_BG 16
+ * STATS_FLICKER_BAYERRS 17
+ * STATS_TMC_BHIST 18
+ * PDAF_0 19
+ * PDAF_1 20
+ * PDAF_2 21
+ * PDAF_3 22
+ * RDI0 23
+ * RDI1 24
+ * RDI2 25
+ * RDI3 26
+ * RDI4 27
+ *
+ * IFE Lite write master client IDs
+ *
+ * RDI0 0
+ * RDI1 1
+ * RDI2 2
+ * RDI3 3
+ * GAMMA 4
+ * STATES_BE 5
+ */
+#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+ struct v4l2_pix_format_mplane *pix =
+ &line->video_out.active_fmt.fmt.pix_mp;
+
+ wm = RDI_WM(wm);
+
+ /* no clock gating at bus input */
+ writel(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+ writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+ writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
+ vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+ writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
+ writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
+ writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
+
+ /* no dropped frames, one irq per frame */
+ if (!vfe_is_lite(vfe)) {
+ writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
+ writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
+ }
+
+ writel(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
+ writel(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
+
+ writel(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
+ writel(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
+
+ writel(WM_CFG_EN | WM_CFG_MODE, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+ wm = RDI_WM(wm);
+ writel(0, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
+ struct vfe_line *line)
+{
+ wm = RDI_WM(wm);
+ writel(addr >> 8, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+
+ dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n", wm, addr);
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_reg_update(vfe->camss, vfe->id, port_id, false);
+}
+
+static void vfe_reg_update_clear(struct vfe_device *vfe,
+ enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_reg_update(vfe->camss, vfe->id, port_id, true);
+}
+
+static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_addr_update(vfe->camss, vfe->id, port_id, false);
+}
+
+static void vfe_addr_update_clear(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_addr_update(vfe->camss, vfe->id, port_id, true);
+}
+
+static const struct camss_video_ops vfe_video_ops_1080 = {
+ .queue_buffer = vfe_queue_buffer_v2,
+ .flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+ vfe->video_ops = vfe_video_ops_1080;
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+ vfe_isr_reset_ack(vfe);
+}
+
+static irqreturn_t vfe_isr(int irq, void *dev)
+{
+ /* nop */
+ return IRQ_HANDLED;
+}
+
+static int vfe_halt(struct vfe_device *vfe)
+{
+ /* rely on vfe_disable_output() to stop the VFE */
+ return 0;
+}
+
+const struct vfe_hw_ops vfe_ops_1080 = {
+ .addr_update = vfe_addr_update,
+ .addr_update_clear = vfe_addr_update_clear,
+ .global_reset = vfe_global_reset,
+ .hw_version = vfe_hw_version,
+ .isr = vfe_isr,
+ .pm_domain_off = vfe_pm_domain_off,
+ .pm_domain_on = vfe_pm_domain_on,
+ .reg_update = vfe_reg_update,
+ .reg_update_clear = vfe_reg_update_clear,
+ .subdev_init = vfe_subdev_init,
+ .vfe_disable = vfe_disable,
+ .vfe_enable = vfe_enable_v2,
+ .vfe_halt = vfe_halt,
+ .vfe_wm_start = vfe_wm_start,
+ .vfe_wm_stop = vfe_wm_stop,
+ .vfe_buf_done = vfe_buf_done,
+ .vfe_wm_update = vfe_wm_update,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 4f8867daea4c..221abf7bfd47 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -353,6 +353,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
case CAMSS_8550:
case CAMSS_8650:
case CAMSS_8775P:
+ case CAMSS_KAANAPALI:
case CAMSS_X1E80100:
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
@@ -2020,6 +2021,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
case CAMSS_8550:
case CAMSS_8650:
case CAMSS_8775P:
+ case CAMSS_KAANAPALI:
case CAMSS_X1E80100:
ret = 16;
break;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 8312e4c91e98..0a91440cfe43 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -251,6 +251,7 @@ extern const struct vfe_hw_ops vfe_ops_170;
extern const struct vfe_hw_ops vfe_ops_340;
extern const struct vfe_hw_ops vfe_ops_480;
extern const struct vfe_hw_ops vfe_ops_680;
+extern const struct vfe_hw_ops vfe_ops_1080;
extern const struct vfe_hw_ops vfe_ops_gen3;
int vfe_get(struct vfe_device *vfe);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 12dfe760fc54..6ff82dd2aeaf 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -156,6 +156,130 @@ static const struct camss_subdev_resources csid_res_kaanapali[] = {
}
};
+/* In Kaanapali, CAMNOC requires all CPAS_TFEX clocks
+ * to operate on any TFE Full.
+ */
+static const struct camss_subdev_resources vfe_res_kaanapali[] = {
+ /* VFE0 - TFE Full */
+ {
+ .clock = { "vfe0_fast_ahb", "vfe0",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife0",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE1 - TFE Full */
+ {
+ .clock = { "vfe1_fast_ahb", "vfe1",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife1",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE2 - TFE Full */
+ {
+ .clock = { "vfe2_fast_ahb", "vfe2",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe2" },
+ .interrupt = { "vfe2" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife2",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE3 - IFE Lite */
+ {
+ .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 266666667, 400000000, 480000000 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe_lite0" },
+ .interrupt = { "vfe_lite0" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE4 - IFE Lite */
+ {
+ .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 266666667, 400000000, 480000000 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe_lite1" },
+ .interrupt = { "vfe_lite1" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5727,10 +5851,12 @@ static const struct camss_resources kaanapali_resources = {
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
.csid_res = csid_res_kaanapali,
+ .vfe_res = vfe_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
.csid_num = ARRAY_SIZE(csid_res_kaanapali),
+ .vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Atiya Kailany
Add support for the VFE (Video Front End) 1080 found on Kaanapali SoC.
In the Kaanapali camera subsystem, the front-end blocks are referred to
as TFEs (Thin Front Ends). This driver continues to use the VFE naming
in some places to preserve consistency with the existing code and avoid
unnecessary renaming. Support is currently limited to three output lines,
matching the constraints of the CAMSS framework.
Kaanapali requires REG_UPDATE and AUP_UPDATE to be issued only after all
CSID configuration has completed. In addition, the number of AUP_UPDATE
requests must match the number of buffers queued to the write master
while it is being enabled.
Although real-time TFE traffic is routed through RT_CAMNOC, both
camnoc_rt_axi and camnoc_nrt_axi clocks must be enabled. This ensures
that the PDX_NOC, which sits downstream of both RT and NRT NOCs, exits
reset in a fully idle state.
Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
drivers/media/platform/qcom/camss/Makefile | 1 +
drivers/media/platform/qcom/camss/camss-vfe-1080.c | 213 +++++++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.c | 2 +
drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
drivers/media/platform/qcom/camss/camss.c | 126 ++++++++++++
5 files changed, 343 insertions(+)
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
index 218ba3a95939..42a14e8fe1b7 100644
--- a/drivers/media/platform/qcom/camss/Makefile
+++ b/drivers/media/platform/qcom/camss/Makefile
@@ -26,6 +26,7 @@ qcom-camss-objs += \
camss-vfe-340.o \
camss-vfe-480.o \
camss-vfe-680.o \
+ camss-vfe-1080.o \
camss-vfe-gen1.o \
camss-vfe-gen3.o \
camss-vfe-vbif.o \
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
new file mode 100644
index 000000000000..68798f13fbea
--- /dev/null
+++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-1080.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 1080
+ *
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+/* VFE-1080 Bus Register Base Addresses */
+#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x800 : 0x1000)
+
+#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
+#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0x128)
+
+#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x500 + (n) * 0x100)
+#define WM_CFG_EN BIT(0)
+#define WM_VIR_FRM_EN BIT(1)
+#define WM_CFG_MODE BIT(16)
+#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x504 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x508 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x50C + (n) * 0x100)
+#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
+#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x514 + (n) * 0x100)
+#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
+#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x518 + (n) * 0x100)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x530 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x534 + (n) * 0x100)
+
+/* VFE lite has no such registers */
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x538 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x53C + (n) * 0x100)
+
+#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x560 + (n) * 0x100)
+#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x564 + (n) * 0x100)
+
+/*
+ * IFE write master client IDs
+ *
+ * VIDEO_FULL 0
+ * VIDEO_DC4_Y 1
+ * VIDEO_DC4_C 2
+ * VIDEO_DC16_Y 3
+ * VIDEO_DC16_C 4
+ * DISPLAY_DS2_Y 5
+ * DISPLAY_DS2_C 6
+ * FD_Y 7
+ * FD_C 8
+ * PIXEL_RAW 9
+ * STATS_AEC_BG 10
+ * STATS_AEC_BHIST 11
+ * STATS_TINTLESS_BG 12
+ * STATS_AWB_BG 13
+ * STATS_AWB_BFW 14
+ * STATS_AF_BHIST 15
+ * STATS_ALSC_BG 16
+ * STATS_FLICKER_BAYERRS 17
+ * STATS_TMC_BHIST 18
+ * PDAF_0 19
+ * PDAF_1 20
+ * PDAF_2 21
+ * PDAF_3 22
+ * RDI0 23
+ * RDI1 24
+ * RDI2 25
+ * RDI3 26
+ * RDI4 27
+ *
+ * IFE Lite write master client IDs
+ *
+ * RDI0 0
+ * RDI1 1
+ * RDI2 2
+ * RDI3 3
+ * GAMMA 4
+ * STATES_BE 5
+ */
+#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+ struct v4l2_pix_format_mplane *pix =
+ &line->video_out.active_fmt.fmt.pix_mp;
+
+ wm = RDI_WM(wm);
+
+ /* no clock gating at bus input */
+ writel(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+ writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+ writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
+ vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+ writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
+ writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
+ vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
+ writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
+
+ /* no dropped frames, one irq per frame */
+ if (!vfe_is_lite(vfe)) {
+ writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
+ writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
+ }
+
+ writel(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
+ writel(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
+
+ writel(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
+ writel(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
+
+ writel(WM_CFG_EN | WM_CFG_MODE, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+ wm = RDI_WM(wm);
+ writel(0, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
+ struct vfe_line *line)
+{
+ wm = RDI_WM(wm);
+ writel(addr >> 8, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+
+ dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n", wm, addr);
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_reg_update(vfe->camss, vfe->id, port_id, false);
+}
+
+static void vfe_reg_update_clear(struct vfe_device *vfe,
+ enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_reg_update(vfe->camss, vfe->id, port_id, true);
+}
+
+static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_addr_update(vfe->camss, vfe->id, port_id, false);
+}
+
+static void vfe_addr_update_clear(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+ int port_id = line_id;
+
+ camss_addr_update(vfe->camss, vfe->id, port_id, true);
+}
+
+static const struct camss_video_ops vfe_video_ops_1080 = {
+ .queue_buffer = vfe_queue_buffer_v2,
+ .flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+ vfe->video_ops = vfe_video_ops_1080;
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+ vfe_isr_reset_ack(vfe);
+}
+
+static irqreturn_t vfe_isr(int irq, void *dev)
+{
+ /* nop */
+ return IRQ_HANDLED;
+}
+
+static int vfe_halt(struct vfe_device *vfe)
+{
+ /* rely on vfe_disable_output() to stop the VFE */
+ return 0;
+}
+
+const struct vfe_hw_ops vfe_ops_1080 = {
+ .addr_update = vfe_addr_update,
+ .addr_update_clear = vfe_addr_update_clear,
+ .global_reset = vfe_global_reset,
+ .hw_version = vfe_hw_version,
+ .isr = vfe_isr,
+ .pm_domain_off = vfe_pm_domain_off,
+ .pm_domain_on = vfe_pm_domain_on,
+ .reg_update = vfe_reg_update,
+ .reg_update_clear = vfe_reg_update_clear,
+ .subdev_init = vfe_subdev_init,
+ .vfe_disable = vfe_disable,
+ .vfe_enable = vfe_enable_v2,
+ .vfe_halt = vfe_halt,
+ .vfe_wm_start = vfe_wm_start,
+ .vfe_wm_stop = vfe_wm_stop,
+ .vfe_buf_done = vfe_buf_done,
+ .vfe_wm_update = vfe_wm_update,
+};
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 4f8867daea4c..221abf7bfd47 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -353,6 +353,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
case CAMSS_8550:
case CAMSS_8650:
case CAMSS_8775P:
+ case CAMSS_KAANAPALI:
case CAMSS_X1E80100:
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
@@ -2020,6 +2021,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
case CAMSS_8550:
case CAMSS_8650:
case CAMSS_8775P:
+ case CAMSS_KAANAPALI:
case CAMSS_X1E80100:
ret = 16;
break;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 8312e4c91e98..0a91440cfe43 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -251,6 +251,7 @@ extern const struct vfe_hw_ops vfe_ops_170;
extern const struct vfe_hw_ops vfe_ops_340;
extern const struct vfe_hw_ops vfe_ops_480;
extern const struct vfe_hw_ops vfe_ops_680;
+extern const struct vfe_hw_ops vfe_ops_1080;
extern const struct vfe_hw_ops vfe_ops_gen3;
int vfe_get(struct vfe_device *vfe);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 12dfe760fc54..6ff82dd2aeaf 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -156,6 +156,130 @@ static const struct camss_subdev_resources csid_res_kaanapali[] = {
}
};
+/* In Kaanapali, CAMNOC requires all CPAS_TFEX clocks
+ * to operate on any TFE Full.
+ */
+static const struct camss_subdev_resources vfe_res_kaanapali[] = {
+ /* VFE0 - TFE Full */
+ {
+ .clock = { "vfe0_fast_ahb", "vfe0",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe0" },
+ .interrupt = { "vfe0" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife0",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE1 - TFE Full */
+ {
+ .clock = { "vfe1_fast_ahb", "vfe1",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe1" },
+ .interrupt = { "vfe1" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife1",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE2 - TFE Full */
+ {
+ .clock = { "vfe2_fast_ahb", "vfe2",
+ "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 360280000, 480000000, 630000000, 716000000,
+ 833000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe2" },
+ .interrupt = { "vfe2" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = false,
+ .has_pd = true,
+ .pd_name = "ife2",
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE3 - IFE Lite */
+ {
+ .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 266666667, 400000000, 480000000 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe_lite0" },
+ .interrupt = { "vfe_lite0" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+ /* VFE4 - IFE Lite */
+ {
+ .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
+ "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
+ .clock_rate = { { 0 },
+ { 266666667, 400000000, 480000000 },
+ { 0 },
+ { 200000000, 300000000, 400000000, 480000000 },
+ { 0 },
+ { 0 } },
+ .reg = { "vfe_lite1" },
+ .interrupt = { "vfe_lite1" },
+ .vfe = {
+ .line_num = 3,
+ .is_lite = true,
+ .hw_ops = &vfe_ops_1080,
+ .formats_rdi = &vfe_formats_rdi_845,
+ .formats_pix = &vfe_formats_pix_845
+ }
+ },
+};
+
static const struct resources_icc icc_res_kaanapali[] = {
{
.name = "ahb",
@@ -5727,10 +5851,12 @@ static const struct camss_resources kaanapali_resources = {
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
.csid_res = csid_res_kaanapali,
+ .vfe_res = vfe_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
.csid_num = ARRAY_SIZE(csid_res_kaanapali),
+ .vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
};
static const struct camss_resources msm8916_resources = {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:33 ` Bryan O'Donoghue
-1 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:33 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Atiya Kailany
On 28/10/2026 15:20, Hangxiang Ma wrote:
> Add support for the VFE (Video Front End) 1080 found on Kaanapali SoC.
>
> In the Kaanapali camera subsystem, the front-end blocks are referred to
> as TFEs (Thin Front Ends). This driver continues to use the VFE naming
> in some places to preserve consistency with the existing code and avoid
> unnecessary renaming. Support is currently limited to three output lines,
> matching the constraints of the CAMSS framework.
>
> Kaanapali requires REG_UPDATE and AUP_UPDATE to be issued only after all
> CSID configuration has completed. In addition, the number of AUP_UPDATE
> requests must match the number of buffers queued to the write master
> while it is being enabled.
>
> Although real-time TFE traffic is routed through RT_CAMNOC, both
> camnoc_rt_axi and camnoc_nrt_axi clocks must be enabled. This ensures
> that the PDX_NOC, which sits downstream of both RT and NRT NOCs, exits
> reset in a fully idle state.
>
> Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
> Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/Makefile | 1 +
> drivers/media/platform/qcom/camss/camss-vfe-1080.c | 213 +++++++++++++++++++++
> drivers/media/platform/qcom/camss/camss-vfe.c | 2 +
> drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
> drivers/media/platform/qcom/camss/camss.c | 126 ++++++++++++
> 5 files changed, 343 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 218ba3a95939..42a14e8fe1b7 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -26,6 +26,7 @@ qcom-camss-objs += \
> camss-vfe-340.o \
> camss-vfe-480.o \
> camss-vfe-680.o \
> + camss-vfe-1080.o \
> camss-vfe-gen1.o \
> camss-vfe-gen3.o \
> camss-vfe-vbif.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> new file mode 100644
> index 000000000000..68798f13fbea
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> @@ -0,0 +1,213 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-vfe-1080.c
> + *
> + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 1080
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +
> +#include "camss.h"
> +#include "camss-vfe.h"
> +
> +/* VFE-1080 Bus Register Base Addresses */
> +#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x800 : 0x1000)
> +
> +#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
> +#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
> +
> +#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0x128)
> +
> +#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x500 + (n) * 0x100)
> +#define WM_CFG_EN BIT(0)
> +#define WM_VIR_FRM_EN BIT(1)
> +#define WM_CFG_MODE BIT(16)
> +#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x504 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x508 + (n) * 0x100)
> +#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x50C + (n) * 0x100)
> +#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
> +#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x514 + (n) * 0x100)
> +#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
> +#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x518 + (n) * 0x100)
> +
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x530 + (n) * 0x100)
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x534 + (n) * 0x100)
> +
> +/* VFE lite has no such registers */
> +#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x538 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x53C + (n) * 0x100)
> +
> +#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x560 + (n) * 0x100)
> +#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x564 + (n) * 0x100)
> +
> +/*
> + * IFE write master client IDs
> + *
> + * VIDEO_FULL 0
> + * VIDEO_DC4_Y 1
> + * VIDEO_DC4_C 2
> + * VIDEO_DC16_Y 3
> + * VIDEO_DC16_C 4
> + * DISPLAY_DS2_Y 5
> + * DISPLAY_DS2_C 6
> + * FD_Y 7
> + * FD_C 8
> + * PIXEL_RAW 9
> + * STATS_AEC_BG 10
> + * STATS_AEC_BHIST 11
> + * STATS_TINTLESS_BG 12
> + * STATS_AWB_BG 13
> + * STATS_AWB_BFW 14
> + * STATS_AF_BHIST 15
> + * STATS_ALSC_BG 16
> + * STATS_FLICKER_BAYERRS 17
> + * STATS_TMC_BHIST 18
> + * PDAF_0 19
> + * PDAF_1 20
> + * PDAF_2 21
> + * PDAF_3 22
> + * RDI0 23
> + * RDI1 24
> + * RDI2 25
> + * RDI3 26
> + * RDI4 27
> + *
> + * IFE Lite write master client IDs
> + *
> + * RDI0 0
> + * RDI1 1
> + * RDI2 2
> + * RDI3 3
> + * GAMMA 4
> + * STATES_BE 5
> + */
> +#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
> +
> +static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
> +{
> + struct v4l2_pix_format_mplane *pix =
> + &line->video_out.active_fmt.fmt.pix_mp;
> +
> + wm = RDI_WM(wm);
> +
> + /* no clock gating at bus input */
> + writel(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
> +
> + writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
> +
> + writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
> + vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
> + writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
> + writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
> + writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
> +
> + /* no dropped frames, one irq per frame */
> + if (!vfe_is_lite(vfe)) {
> + writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
> + writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
> + }
> +
> + writel(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
> + writel(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
> +
> + writel(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
> + writel(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
> +
> + writel(WM_CFG_EN | WM_CFG_MODE, vfe->base + VFE_BUS_WM_CFG(wm));
> +}
> +
> +static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
> +{
> + wm = RDI_WM(wm);
> + writel(0, vfe->base + VFE_BUS_WM_CFG(wm));
> +}
> +
> +static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
> + struct vfe_line *line)
> +{
> + wm = RDI_WM(wm);
> + writel(addr >> 8, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
> +
> + dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n", wm, addr);
> +}
> +
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_reg_update_clear(struct vfe_device *vfe,
> + enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_addr_update_clear(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static const struct camss_video_ops vfe_video_ops_1080 = {
> + .queue_buffer = vfe_queue_buffer_v2,
> + .flush_buffers = vfe_flush_buffers,
> +};
> +
> +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
> +{
> + vfe->video_ops = vfe_video_ops_1080;
> +}
> +
> +static void vfe_global_reset(struct vfe_device *vfe)
> +{
> + vfe_isr_reset_ack(vfe);
> +}
> +
> +static irqreturn_t vfe_isr(int irq, void *dev)
> +{
> + /* nop */
> + return IRQ_HANDLED;
> +}
> +
> +static int vfe_halt(struct vfe_device *vfe)
> +{
> + /* rely on vfe_disable_output() to stop the VFE */
> + return 0;
> +}
> +
> +const struct vfe_hw_ops vfe_ops_1080 = {
> + .addr_update = vfe_addr_update,
> + .addr_update_clear = vfe_addr_update_clear,
> + .global_reset = vfe_global_reset,
> + .hw_version = vfe_hw_version,
> + .isr = vfe_isr,
> + .pm_domain_off = vfe_pm_domain_off,
> + .pm_domain_on = vfe_pm_domain_on,
> + .reg_update = vfe_reg_update,
> + .reg_update_clear = vfe_reg_update_clear,
> + .subdev_init = vfe_subdev_init,
> + .vfe_disable = vfe_disable,
> + .vfe_enable = vfe_enable_v2,
> + .vfe_halt = vfe_halt,
> + .vfe_wm_start = vfe_wm_start,
> + .vfe_wm_stop = vfe_wm_stop,
> + .vfe_buf_done = vfe_buf_done,
> + .vfe_wm_update = vfe_wm_update,
> +};
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 4f8867daea4c..221abf7bfd47 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -353,6 +353,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
> case CAMSS_8550:
> case CAMSS_8650:
> case CAMSS_8775P:
> + case CAMSS_KAANAPALI:
> case CAMSS_X1E80100:
> switch (sink_code) {
> case MEDIA_BUS_FMT_YUYV8_1X16:
> @@ -2020,6 +2021,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
> case CAMSS_8550:
> case CAMSS_8650:
> case CAMSS_8775P:
> + case CAMSS_KAANAPALI:
> case CAMSS_X1E80100:
> ret = 16;
> break;
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index 8312e4c91e98..0a91440cfe43 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -251,6 +251,7 @@ extern const struct vfe_hw_ops vfe_ops_170;
> extern const struct vfe_hw_ops vfe_ops_340;
> extern const struct vfe_hw_ops vfe_ops_480;
> extern const struct vfe_hw_ops vfe_ops_680;
> +extern const struct vfe_hw_ops vfe_ops_1080;
> extern const struct vfe_hw_ops vfe_ops_gen3;
>
> int vfe_get(struct vfe_device *vfe);
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 12dfe760fc54..6ff82dd2aeaf 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -156,6 +156,130 @@ static const struct camss_subdev_resources csid_res_kaanapali[] = {
> }
> };
>
> +/* In Kaanapali, CAMNOC requires all CPAS_TFEX clocks
> + * to operate on any TFE Full.
> + */
> +static const struct camss_subdev_resources vfe_res_kaanapali[] = {
> + /* VFE0 - TFE Full */
> + {
> + .clock = { "vfe0_fast_ahb", "vfe0",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe0" },
> + .interrupt = { "vfe0" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife0",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE1 - TFE Full */
> + {
> + .clock = { "vfe1_fast_ahb", "vfe1",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe1" },
> + .interrupt = { "vfe1" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife1",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE2 - TFE Full */
> + {
> + .clock = { "vfe2_fast_ahb", "vfe2",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe2" },
> + .interrupt = { "vfe2" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife2",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE3 - IFE Lite */
> + {
> + .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 266666667, 400000000, 480000000 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe_lite0" },
> + .interrupt = { "vfe_lite0" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = true,
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE4 - IFE Lite */
> + {
> + .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 266666667, 400000000, 480000000 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe_lite1" },
> + .interrupt = { "vfe_lite1" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = true,
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> +};
> +
> static const struct resources_icc icc_res_kaanapali[] = {
> {
> .name = "ahb",
> @@ -5727,10 +5851,12 @@ static const struct camss_resources kaanapali_resources = {
> .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> .csiphy_res = csiphy_res_kaanapali,
> .csid_res = csid_res_kaanapali,
> + .vfe_res = vfe_res_kaanapali,
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
> .csid_num = ARRAY_SIZE(csid_res_kaanapali),
> + .vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
> };
>
> static const struct camss_resources msm8916_resources = {
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
@ 2026-10-28 15:33 ` Bryan O'Donoghue
0 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:33 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Atiya Kailany
On 28/10/2026 15:20, Hangxiang Ma wrote:
> Add support for the VFE (Video Front End) 1080 found on Kaanapali SoC.
>
> In the Kaanapali camera subsystem, the front-end blocks are referred to
> as TFEs (Thin Front Ends). This driver continues to use the VFE naming
> in some places to preserve consistency with the existing code and avoid
> unnecessary renaming. Support is currently limited to three output lines,
> matching the constraints of the CAMSS framework.
>
> Kaanapali requires REG_UPDATE and AUP_UPDATE to be issued only after all
> CSID configuration has completed. In addition, the number of AUP_UPDATE
> requests must match the number of buffers queued to the write master
> while it is being enabled.
>
> Although real-time TFE traffic is routed through RT_CAMNOC, both
> camnoc_rt_axi and camnoc_nrt_axi clocks must be enabled. This ensures
> that the PDX_NOC, which sits downstream of both RT and NRT NOCs, exits
> reset in a fully idle state.
>
> Co-developed-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
> Signed-off-by: Atiya Kailany <atiya.kailany@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
> ---
> drivers/media/platform/qcom/camss/Makefile | 1 +
> drivers/media/platform/qcom/camss/camss-vfe-1080.c | 213 +++++++++++++++++++++
> drivers/media/platform/qcom/camss/camss-vfe.c | 2 +
> drivers/media/platform/qcom/camss/camss-vfe.h | 1 +
> drivers/media/platform/qcom/camss/camss.c | 126 ++++++++++++
> 5 files changed, 343 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 218ba3a95939..42a14e8fe1b7 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -26,6 +26,7 @@ qcom-camss-objs += \
> camss-vfe-340.o \
> camss-vfe-480.o \
> camss-vfe-680.o \
> + camss-vfe-1080.o \
> camss-vfe-gen1.o \
> camss-vfe-gen3.o \
> camss-vfe-vbif.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> new file mode 100644
> index 000000000000..68798f13fbea
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> @@ -0,0 +1,213 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-vfe-1080.c
> + *
> + * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module 1080
> + *
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +
> +#include "camss.h"
> +#include "camss-vfe.h"
> +
> +/* VFE-1080 Bus Register Base Addresses */
> +#define BUS_REG_BASE (vfe_is_lite(vfe) ? 0x800 : 0x1000)
> +
> +#define VFE_BUS_WM_CGC_OVERRIDE (BUS_REG_BASE + 0x08)
> +#define WM_CGC_OVERRIDE_ALL (0x7FFFFFF)
> +
> +#define VFE_BUS_WM_TEST_BUS_CTRL (BUS_REG_BASE + 0x128)
> +
> +#define VFE_BUS_WM_CFG(n) (BUS_REG_BASE + 0x500 + (n) * 0x100)
> +#define WM_CFG_EN BIT(0)
> +#define WM_VIR_FRM_EN BIT(1)
> +#define WM_CFG_MODE BIT(16)
> +#define VFE_BUS_WM_IMAGE_ADDR(n) (BUS_REG_BASE + 0x504 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAME_INCR(n) (BUS_REG_BASE + 0x508 + (n) * 0x100)
> +#define VFE_BUS_WM_IMAGE_CFG_0(n) (BUS_REG_BASE + 0x50C + (n) * 0x100)
> +#define WM_IMAGE_CFG_0_DEFAULT_WIDTH (0xFFFF)
> +#define VFE_BUS_WM_IMAGE_CFG_2(n) (BUS_REG_BASE + 0x514 + (n) * 0x100)
> +#define WM_IMAGE_CFG_2_DEFAULT_STRIDE (0xFFFF)
> +#define VFE_BUS_WM_PACKER_CFG(n) (BUS_REG_BASE + 0x518 + (n) * 0x100)
> +
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n) (BUS_REG_BASE + 0x530 + (n) * 0x100)
> +#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n) (BUS_REG_BASE + 0x534 + (n) * 0x100)
> +
> +/* VFE lite has no such registers */
> +#define VFE_BUS_WM_FRAMEDROP_PERIOD(n) (BUS_REG_BASE + 0x538 + (n) * 0x100)
> +#define VFE_BUS_WM_FRAMEDROP_PATTERN(n) (BUS_REG_BASE + 0x53C + (n) * 0x100)
> +
> +#define VFE_BUS_WM_MMU_PREFETCH_CFG(n) (BUS_REG_BASE + 0x560 + (n) * 0x100)
> +#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n) (BUS_REG_BASE + 0x564 + (n) * 0x100)
> +
> +/*
> + * IFE write master client IDs
> + *
> + * VIDEO_FULL 0
> + * VIDEO_DC4_Y 1
> + * VIDEO_DC4_C 2
> + * VIDEO_DC16_Y 3
> + * VIDEO_DC16_C 4
> + * DISPLAY_DS2_Y 5
> + * DISPLAY_DS2_C 6
> + * FD_Y 7
> + * FD_C 8
> + * PIXEL_RAW 9
> + * STATS_AEC_BG 10
> + * STATS_AEC_BHIST 11
> + * STATS_TINTLESS_BG 12
> + * STATS_AWB_BG 13
> + * STATS_AWB_BFW 14
> + * STATS_AF_BHIST 15
> + * STATS_ALSC_BG 16
> + * STATS_FLICKER_BAYERRS 17
> + * STATS_TMC_BHIST 18
> + * PDAF_0 19
> + * PDAF_1 20
> + * PDAF_2 21
> + * PDAF_3 22
> + * RDI0 23
> + * RDI1 24
> + * RDI2 25
> + * RDI3 26
> + * RDI4 27
> + *
> + * IFE Lite write master client IDs
> + *
> + * RDI0 0
> + * RDI1 1
> + * RDI2 2
> + * RDI3 3
> + * GAMMA 4
> + * STATES_BE 5
> + */
> +#define RDI_WM(n) ((vfe_is_lite(vfe) ? 0x0 : 0x17) + (n))
> +
> +static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
> +{
> + struct v4l2_pix_format_mplane *pix =
> + &line->video_out.active_fmt.fmt.pix_mp;
> +
> + wm = RDI_WM(wm);
> +
> + /* no clock gating at bus input */
> + writel(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
> +
> + writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
> +
> + writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height >> 8,
> + vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
> + writel((WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF),
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
> + writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
> + vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
> + writel(0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
> +
> + /* no dropped frames, one irq per frame */
> + if (!vfe_is_lite(vfe)) {
> + writel(0, vfe->base + VFE_BUS_WM_FRAMEDROP_PERIOD(wm));
> + writel(1, vfe->base + VFE_BUS_WM_FRAMEDROP_PATTERN(wm));
> + }
> +
> + writel(0, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(wm));
> + writel(1, vfe->base + VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(wm));
> +
> + writel(1, vfe->base + VFE_BUS_WM_MMU_PREFETCH_CFG(wm));
> + writel(0xFFFFFFFF, vfe->base + VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(wm));
> +
> + writel(WM_CFG_EN | WM_CFG_MODE, vfe->base + VFE_BUS_WM_CFG(wm));
> +}
> +
> +static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
> +{
> + wm = RDI_WM(wm);
> + writel(0, vfe->base + VFE_BUS_WM_CFG(wm));
> +}
> +
> +static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
> + struct vfe_line *line)
> +{
> + wm = RDI_WM(wm);
> + writel(addr >> 8, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
> +
> + dev_dbg(vfe->camss->dev, "wm:%d, image buf addr:0x%x\n", wm, addr);
> +}
> +
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_reg_update_clear(struct vfe_device *vfe,
> + enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_addr_update_clear(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static const struct camss_video_ops vfe_video_ops_1080 = {
> + .queue_buffer = vfe_queue_buffer_v2,
> + .flush_buffers = vfe_flush_buffers,
> +};
> +
> +static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
> +{
> + vfe->video_ops = vfe_video_ops_1080;
> +}
> +
> +static void vfe_global_reset(struct vfe_device *vfe)
> +{
> + vfe_isr_reset_ack(vfe);
> +}
> +
> +static irqreturn_t vfe_isr(int irq, void *dev)
> +{
> + /* nop */
> + return IRQ_HANDLED;
> +}
> +
> +static int vfe_halt(struct vfe_device *vfe)
> +{
> + /* rely on vfe_disable_output() to stop the VFE */
> + return 0;
> +}
> +
> +const struct vfe_hw_ops vfe_ops_1080 = {
> + .addr_update = vfe_addr_update,
> + .addr_update_clear = vfe_addr_update_clear,
> + .global_reset = vfe_global_reset,
> + .hw_version = vfe_hw_version,
> + .isr = vfe_isr,
> + .pm_domain_off = vfe_pm_domain_off,
> + .pm_domain_on = vfe_pm_domain_on,
> + .reg_update = vfe_reg_update,
> + .reg_update_clear = vfe_reg_update_clear,
> + .subdev_init = vfe_subdev_init,
> + .vfe_disable = vfe_disable,
> + .vfe_enable = vfe_enable_v2,
> + .vfe_halt = vfe_halt,
> + .vfe_wm_start = vfe_wm_start,
> + .vfe_wm_stop = vfe_wm_stop,
> + .vfe_buf_done = vfe_buf_done,
> + .vfe_wm_update = vfe_wm_update,
> +};
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index 4f8867daea4c..221abf7bfd47 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -353,6 +353,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
> case CAMSS_8550:
> case CAMSS_8650:
> case CAMSS_8775P:
> + case CAMSS_KAANAPALI:
> case CAMSS_X1E80100:
> switch (sink_code) {
> case MEDIA_BUS_FMT_YUYV8_1X16:
> @@ -2020,6 +2021,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
> case CAMSS_8550:
> case CAMSS_8650:
> case CAMSS_8775P:
> + case CAMSS_KAANAPALI:
> case CAMSS_X1E80100:
> ret = 16;
> break;
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
> index 8312e4c91e98..0a91440cfe43 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.h
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.h
> @@ -251,6 +251,7 @@ extern const struct vfe_hw_ops vfe_ops_170;
> extern const struct vfe_hw_ops vfe_ops_340;
> extern const struct vfe_hw_ops vfe_ops_480;
> extern const struct vfe_hw_ops vfe_ops_680;
> +extern const struct vfe_hw_ops vfe_ops_1080;
> extern const struct vfe_hw_ops vfe_ops_gen3;
>
> int vfe_get(struct vfe_device *vfe);
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 12dfe760fc54..6ff82dd2aeaf 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -156,6 +156,130 @@ static const struct camss_subdev_resources csid_res_kaanapali[] = {
> }
> };
>
> +/* In Kaanapali, CAMNOC requires all CPAS_TFEX clocks
> + * to operate on any TFE Full.
> + */
> +static const struct camss_subdev_resources vfe_res_kaanapali[] = {
> + /* VFE0 - TFE Full */
> + {
> + .clock = { "vfe0_fast_ahb", "vfe0",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe0" },
> + .interrupt = { "vfe0" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife0",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE1 - TFE Full */
> + {
> + .clock = { "vfe1_fast_ahb", "vfe1",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe1" },
> + .interrupt = { "vfe1" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife1",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE2 - TFE Full */
> + {
> + .clock = { "vfe2_fast_ahb", "vfe2",
> + "cpas_vfe0", "cpas_vfe1", "cpas_vfe2",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 360280000, 480000000, 630000000, 716000000,
> + 833000000 },
> + { 0 },
> + { 0 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe2" },
> + .interrupt = { "vfe2" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = false,
> + .has_pd = true,
> + .pd_name = "ife2",
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE3 - IFE Lite */
> + {
> + .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 266666667, 400000000, 480000000 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe_lite0" },
> + .interrupt = { "vfe_lite0" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = true,
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> + /* VFE4 - IFE Lite */
> + {
> + .clock = { "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite",
> + "camnoc_rt_axi", "camnoc_nrt_axi", "qdss_debug_xo" },
> + .clock_rate = { { 0 },
> + { 266666667, 400000000, 480000000 },
> + { 0 },
> + { 200000000, 300000000, 400000000, 480000000 },
> + { 0 },
> + { 0 } },
> + .reg = { "vfe_lite1" },
> + .interrupt = { "vfe_lite1" },
> + .vfe = {
> + .line_num = 3,
> + .is_lite = true,
> + .hw_ops = &vfe_ops_1080,
> + .formats_rdi = &vfe_formats_rdi_845,
> + .formats_pix = &vfe_formats_pix_845
> + }
> + },
> +};
> +
> static const struct resources_icc icc_res_kaanapali[] = {
> {
> .name = "ahb",
> @@ -5727,10 +5851,12 @@ static const struct camss_resources kaanapali_resources = {
> .pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
> .csiphy_res = csiphy_res_kaanapali,
> .csid_res = csid_res_kaanapali,
> + .vfe_res = vfe_res_kaanapali,
> .icc_res = icc_res_kaanapali,
> .icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
> .csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
> .csid_num = ARRAY_SIZE(csid_res_kaanapali),
> + .vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
> };
>
> static const struct camss_resources msm8916_resources = {
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:34 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:34 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] media: qcom: camss: unsynchronized CSID RUP/AUP updates in vfe_ops_1080
--
commit 59a42f5889e4e9fb6937e5811830bc3f796b016a
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: vfe: Add support for VFE 1080
This commit adds support for the VFE 1080 hardware block found on the
Kaanapali SoC, including write master configuration, CSID register and
address update forwarding, and Kaanapali VFE resource definitions.
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> new file mode 100644
> index 0000000000000..68798f13fbea8
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> @@ -0,0 +1,213 @@
[ ... ]
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_reg_update_clear(struct vfe_device *vfe,
> + enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, false);
> +}
[Severity: High]
Can vfe_reg_update() and vfe_addr_update() race with csid_isr() when
updating csid->reg_update and csid->addr_update?
When userspace queues a buffer via vfe_queue_buffer_v2() or enables an
output line via vfe_enable_output_v2(), the VFE driver holds
vfe->output_lock and calls vfe_addr_update() or vfe_reg_update(), which
forwards through camss_addr_update() and camss_reg_update() to
drivers/media/platform/qcom/camss/camss-csid-1080.c:
static void __csid_addr_update(struct csid_device *csid, int port_id)
{
csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
writel(csid->addr_update, csid->base + CSID_AUP_CMD);
__csid_aup_rup_trigger(csid);
}
static void __csid_reg_update(struct csid_device *csid, int port_id)
{
csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
writel(csid->reg_update, csid->base + CSID_RUP_CMD);
__csid_aup_rup_trigger(csid);
}
Concurrently on another CPU, csid_isr() in camss-csid-1080.c clears those
same bitmasks upon INFO_RUP_DONE without holding vfe->output_lock or any
CSID lock before calling camss_buf_done():
if (val & INFO_RUP_DONE) {
__csid_addr_update_clear(csid, i);
__csid_reg_update_clear(csid, i);
}
if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
camss_buf_done(csid->camss, csid->id, i);
If csid_isr() runs between the bitwise OR on csid->addr_update or
csid->reg_update and the writel() to CSID_AUP_CMD or CSID_RUP_CMD (or
races with updates on another RDI port of the same CSID), could the newly
set bit be cleared or clobbered before __csid_aup_rup_trigger() is called,
causing the hardware to miss a buffer address update while
output->gen2.active_num is incremented?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=10
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 10/15] media: qcom: camss: vfe: Add support for VFE 1080
@ 2026-10-28 15:34 ` sashiko-bot
0 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:34 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] media: qcom: camss: unsynchronized CSID RUP/AUP updates in vfe_ops_1080
--
commit 59a42f5889e4e9fb6937e5811830bc3f796b016a
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: vfe: Add support for VFE 1080
This commit adds support for the VFE 1080 hardware block found on the
Kaanapali SoC, including write master configuration, CSID register and
address update forwarding, and Kaanapali VFE resource definitions.
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe-1080.c b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> new file mode 100644
> index 0000000000000..68798f13fbea8
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-vfe-1080.c
> @@ -0,0 +1,213 @@
[ ... ]
> +static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, false);
> +}
> +
> +static void vfe_reg_update_clear(struct vfe_device *vfe,
> + enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_reg_update(vfe->camss, vfe->id, port_id, true);
> +}
> +
> +static void vfe_addr_update(struct vfe_device *vfe, enum vfe_line_id line_id)
> +{
> + int port_id = line_id;
> +
> + camss_addr_update(vfe->camss, vfe->id, port_id, false);
> +}
[Severity: High]
Can vfe_reg_update() and vfe_addr_update() race with csid_isr() when
updating csid->reg_update and csid->addr_update?
When userspace queues a buffer via vfe_queue_buffer_v2() or enables an
output line via vfe_enable_output_v2(), the VFE driver holds
vfe->output_lock and calls vfe_addr_update() or vfe_reg_update(), which
forwards through camss_addr_update() and camss_reg_update() to
drivers/media/platform/qcom/camss/camss-csid-1080.c:
static void __csid_addr_update(struct csid_device *csid, int port_id)
{
csid->addr_update |= CSID_RUP_AUP_RDI(port_id);
writel(csid->addr_update, csid->base + CSID_AUP_CMD);
__csid_aup_rup_trigger(csid);
}
static void __csid_reg_update(struct csid_device *csid, int port_id)
{
csid->reg_update |= CSID_RUP_AUP_RDI(port_id);
writel(csid->reg_update, csid->base + CSID_RUP_CMD);
__csid_aup_rup_trigger(csid);
}
Concurrently on another CPU, csid_isr() in camss-csid-1080.c clears those
same bitmasks upon INFO_RUP_DONE without holding vfe->output_lock or any
CSID lock before calling camss_buf_done():
if (val & INFO_RUP_DONE) {
__csid_addr_update_clear(csid, i);
__csid_reg_update_clear(csid, i);
}
if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i))
camss_buf_done(csid->camss, csid->id, i);
If csid_isr() runs between the bitwise OR on csid->addr_update or
csid->reg_update and the writel() to CSID_AUP_CMD or CSID_RUP_CMD (or
races with updates on another RDI port of the same CSID), could the newly
set bit be cleared or clobbered before __csid_aup_rup_trigger() is called,
causing the hardware to miss a buffer address update while
output->gen2.active_num is incremented?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=10
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add support for the TPG found on Kaanapali. This TPG uses hardware
version 2.4.0, which drives test-enable and reset through the
TPG_CTRL_CMD register at offset 0x1f4 instead of the TEST_EN bit in
TPG_CTRL and the TPG_CLEAR register. Its output is routed into the
CSID 1080 RX through the CSI2 TPG mux, so the CSID selects the TPG as
the data source when a test pattern is selected.
Add the TPG resources to the Kaanapali camss resources so that the TPG
subdevices are created on this SoC.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
.../media/platform/qcom/camss/camss-csid-1080.c | 15 ++++++++++++--
drivers/media/platform/qcom/camss/camss-tpg-gen1.c | 23 ++++++++++++++++------
drivers/media/platform/qcom/camss/camss.c | 2 ++
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
index 3d90d31201fa..ec56ba85a0fa 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-1080.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
@@ -64,6 +64,8 @@
#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
#define CSI2_RX_CFG0_PHY_NUM_SEL 20
+#define CSI2_RX_CFG0_TPG_MUX_EN BIT(27)
+#define CSI2_RX_CFG0_TPG_MUX_SEL GENMASK(29, 28)
#define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1
#define CSID_CSI2_RX_CFG1 0x884
#define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0)
@@ -148,6 +150,7 @@ static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
static void __csid_configure_rx(struct csid_device *csid,
struct csid_phy_config *phy)
{
+ struct camss *camss = csid->camss;
u8 lane_cnt = phy->lane_cnt;
int val;
@@ -156,8 +159,16 @@ 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_SEL_BASE_IDX)
- << CSI2_RX_CFG0_PHY_NUM_SEL;
+
+ if (camss->tpg && csid->tpg_linked &&
+ camss->tpg[phy->csiphy_id].testgen.mode != TPG_PAYLOAD_MODE_DISABLED) {
+ val |= FIELD_PREP(CSI2_RX_CFG0_TPG_MUX_SEL, phy->csiphy_id + 1);
+ val |= CSI2_RX_CFG0_TPG_MUX_EN;
+ } else {
+ val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX)
+ << CSI2_RX_CFG0_PHY_NUM_SEL;
+ }
+
writel(val, csid->base + CSID_CSI2_RX_CFG0);
val = CSI2_RX_CFG1_ECC_CORRECTION_EN;
diff --git a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
index d29de5f93c18..cabbb2638cf3 100644
--- a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
+++ b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
@@ -22,6 +22,7 @@
#define TPG_HW_VER_2_0_0 TPG_HW_VER(2, 0, 0)
#define TPG_HW_VER_2_1_0 TPG_HW_VER(2, 1, 0)
+#define TPG_HW_VER_2_4_0 TPG_HW_VER(2, 4, 0)
#define TPG_HW_STATUS 0x4
@@ -33,7 +34,9 @@
# define TPG_CTRL_OVERLAP_SHDR_EN BIT(10)
# define TPG_CTRL_NUM_ACTIVE_VC GENMASK(31, 30)
-#define TPG_CLEAR 0x1F4
+#define TPG_CTRL_CMD 0x1F4
+# define TPG_CTRL_CMD_TEST_EN BIT(4)
+# define TPG_CTRL_CMD_HW_RESET BIT(0)
/* TPG VC-based registers */
#define TPG_VC_n_GAIN_CFG(n) (0x60 + (n) * 0x60)
@@ -164,18 +167,26 @@ static int tpg_stream_on(struct tpg_device *tpg)
}
/* Global TPG control */
- val = FIELD_PREP(TPG_CTRL_TEST_EN, 1) |
- FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
+ val = FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
FIELD_PREP(TPG_CTRL_NUM_ACTIVE_VC, last_vc);
- writel(val, tpg->base + TPG_CTRL);
+
+ if (tpg->hw_version < TPG_HW_VER_2_4_0) {
+ val |= FIELD_PREP(TPG_CTRL_TEST_EN, 1);
+ writel(val, tpg->base + TPG_CTRL);
+ } else {
+ writel(val, tpg->base + TPG_CTRL);
+ writel(TPG_CTRL_CMD_TEST_EN, tpg->base + TPG_CTRL_CMD);
+ }
return 0;
}
static int tpg_reset(struct tpg_device *tpg)
{
- writel(0, tpg->base + TPG_CTRL);
- writel(1, tpg->base + TPG_CLEAR);
+ if (tpg->hw_version < TPG_HW_VER_2_4_0)
+ writel(0, tpg->base + TPG_CTRL);
+
+ writel(TPG_CTRL_CMD_HW_RESET, tpg->base + TPG_CTRL_CMD);
return 0;
}
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 6ff82dd2aeaf..df4b4cf30711 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5850,11 +5850,13 @@ static const struct camss_resources kaanapali_resources = {
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
+ .tpg_res = tpg_res_x1e80100,
.csid_res = csid_res_kaanapali,
.vfe_res = vfe_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
+ .tpg_num = ARRAY_SIZE(tpg_res_x1e80100),
.csid_num = ARRAY_SIZE(csid_res_kaanapali),
.vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
};
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Add support for the TPG found on Kaanapali. This TPG uses hardware
version 2.4.0, which drives test-enable and reset through the
TPG_CTRL_CMD register at offset 0x1f4 instead of the TEST_EN bit in
TPG_CTRL and the TPG_CLEAR register. Its output is routed into the
CSID 1080 RX through the CSI2 TPG mux, so the CSID selects the TPG as
the data source when a test pattern is selected.
Add the TPG resources to the Kaanapali camss resources so that the TPG
subdevices are created on this SoC.
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
.../media/platform/qcom/camss/camss-csid-1080.c | 15 ++++++++++++--
drivers/media/platform/qcom/camss/camss-tpg-gen1.c | 23 ++++++++++++++++------
drivers/media/platform/qcom/camss/camss.c | 2 ++
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/qcom/camss/camss-csid-1080.c b/drivers/media/platform/qcom/camss/camss-csid-1080.c
index 3d90d31201fa..ec56ba85a0fa 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-1080.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-1080.c
@@ -64,6 +64,8 @@
#define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0
#define CSI2_RX_CFG0_DL0_INPUT_SEL 4
#define CSI2_RX_CFG0_PHY_NUM_SEL 20
+#define CSI2_RX_CFG0_TPG_MUX_EN BIT(27)
+#define CSI2_RX_CFG0_TPG_MUX_SEL GENMASK(29, 28)
#define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1
#define CSID_CSI2_RX_CFG1 0x884
#define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0)
@@ -148,6 +150,7 @@ static void __csid_reg_update_clear(struct csid_device *csid, int port_id)
static void __csid_configure_rx(struct csid_device *csid,
struct csid_phy_config *phy)
{
+ struct camss *camss = csid->camss;
u8 lane_cnt = phy->lane_cnt;
int val;
@@ -156,8 +159,16 @@ 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_SEL_BASE_IDX)
- << CSI2_RX_CFG0_PHY_NUM_SEL;
+
+ if (camss->tpg && csid->tpg_linked &&
+ camss->tpg[phy->csiphy_id].testgen.mode != TPG_PAYLOAD_MODE_DISABLED) {
+ val |= FIELD_PREP(CSI2_RX_CFG0_TPG_MUX_SEL, phy->csiphy_id + 1);
+ val |= CSI2_RX_CFG0_TPG_MUX_EN;
+ } else {
+ val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX)
+ << CSI2_RX_CFG0_PHY_NUM_SEL;
+ }
+
writel(val, csid->base + CSID_CSI2_RX_CFG0);
val = CSI2_RX_CFG1_ECC_CORRECTION_EN;
diff --git a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
index d29de5f93c18..cabbb2638cf3 100644
--- a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
+++ b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
@@ -22,6 +22,7 @@
#define TPG_HW_VER_2_0_0 TPG_HW_VER(2, 0, 0)
#define TPG_HW_VER_2_1_0 TPG_HW_VER(2, 1, 0)
+#define TPG_HW_VER_2_4_0 TPG_HW_VER(2, 4, 0)
#define TPG_HW_STATUS 0x4
@@ -33,7 +34,9 @@
# define TPG_CTRL_OVERLAP_SHDR_EN BIT(10)
# define TPG_CTRL_NUM_ACTIVE_VC GENMASK(31, 30)
-#define TPG_CLEAR 0x1F4
+#define TPG_CTRL_CMD 0x1F4
+# define TPG_CTRL_CMD_TEST_EN BIT(4)
+# define TPG_CTRL_CMD_HW_RESET BIT(0)
/* TPG VC-based registers */
#define TPG_VC_n_GAIN_CFG(n) (0x60 + (n) * 0x60)
@@ -164,18 +167,26 @@ static int tpg_stream_on(struct tpg_device *tpg)
}
/* Global TPG control */
- val = FIELD_PREP(TPG_CTRL_TEST_EN, 1) |
- FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
+ val = FIELD_PREP(TPG_CTRL_NUM_ACTIVE_LANES, lane_cnt - 1) |
FIELD_PREP(TPG_CTRL_NUM_ACTIVE_VC, last_vc);
- writel(val, tpg->base + TPG_CTRL);
+
+ if (tpg->hw_version < TPG_HW_VER_2_4_0) {
+ val |= FIELD_PREP(TPG_CTRL_TEST_EN, 1);
+ writel(val, tpg->base + TPG_CTRL);
+ } else {
+ writel(val, tpg->base + TPG_CTRL);
+ writel(TPG_CTRL_CMD_TEST_EN, tpg->base + TPG_CTRL_CMD);
+ }
return 0;
}
static int tpg_reset(struct tpg_device *tpg)
{
- writel(0, tpg->base + TPG_CTRL);
- writel(1, tpg->base + TPG_CLEAR);
+ if (tpg->hw_version < TPG_HW_VER_2_4_0)
+ writel(0, tpg->base + TPG_CTRL);
+
+ writel(TPG_CTRL_CMD_HW_RESET, tpg->base + TPG_CTRL_CMD);
return 0;
}
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 6ff82dd2aeaf..df4b4cf30711 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -5850,11 +5850,13 @@ static const struct camss_resources kaanapali_resources = {
.pd_name = "top",
.pm_clks = { "cpas_fast_ahb", "cpas_ahb", "gcc_axi_hf" },
.csiphy_res = csiphy_res_kaanapali,
+ .tpg_res = tpg_res_x1e80100,
.csid_res = csid_res_kaanapali,
.vfe_res = vfe_res_kaanapali,
.icc_res = icc_res_kaanapali,
.icc_path_num = ARRAY_SIZE(icc_res_kaanapali),
.csiphy_num = ARRAY_SIZE(csiphy_res_kaanapali),
+ .tpg_num = ARRAY_SIZE(tpg_res_x1e80100),
.csid_num = ARRAY_SIZE(csid_res_kaanapali),
.vfe_num = ARRAY_SIZE(vfe_res_kaanapali),
};
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:29 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] media: qcom: camss: uninitialized hw_version check in tpg_reset()
--
commit f50ae6ce8455f618cec0228f4b565ad64a56769a
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: tpg: Add support for v2.4.0 TPG
This commit adds support for the v2.4.0 TPG hardware found on Kaanapali,
routing TPG output through the CSI2 TPG mux in CSID 1080 RX and handling
test-enable and reset via TPG_CTRL_CMD.
> diff --git a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
> index d29de5f93c18e..cabbb2638cf38 100644
> --- a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
> +++ b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
[ ... ]
> @@ -164,18 +167,26 @@ static int tpg_stream_on(struct tpg_device *tpg)
[ ... ]
> static int tpg_reset(struct tpg_device *tpg)
> {
> - writel(0, tpg->base + TPG_CTRL);
> - writel(1, tpg->base + TPG_CLEAR);
> + if (tpg->hw_version < TPG_HW_VER_2_4_0)
> + writel(0, tpg->base + TPG_CTRL);
> +
> + writel(TPG_CTRL_CMD_HW_RESET, tpg->base + TPG_CTRL_CMD);
>
> return 0;
> }
[Severity: Medium]
Is tpg->hw_version initialized when tpg_reset() runs for the first time?
In drivers/media/platform/qcom/camss/camss-tpg.c, tpg_set_power() calls
reset() before hw_version():
drivers/media/platform/qcom/camss/camss-tpg.c:tpg_set_power() {
if (on) {
...
tpg->res->hw_ops->reset(tpg);
tpg->res->hw_ops->hw_version(tpg);
}
}
Since tpg_hw_version() in drivers/media/platform/qcom/camss/camss-tpg-gen1.c
is where tpg->hw_version is populated from the TPG_HW_VERSION register,
tpg->hw_version is still 0 on the initial power-on. Won't this cause
tpg_reset() to evaluate 0 < TPG_HW_VER_2_4_0 as true and write 0 to TPG_CTRL
even on v2.4.0 hardware?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=11
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
@ 2026-10-28 15:29 ` sashiko-bot
0 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] media: qcom: camss: uninitialized hw_version check in tpg_reset()
--
commit f50ae6ce8455f618cec0228f4b565ad64a56769a
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
media: qcom: camss: tpg: Add support for v2.4.0 TPG
This commit adds support for the v2.4.0 TPG hardware found on Kaanapali,
routing TPG output through the CSI2 TPG mux in CSID 1080 RX and handling
test-enable and reset via TPG_CTRL_CMD.
> diff --git a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
> index d29de5f93c18e..cabbb2638cf38 100644
> --- a/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
> +++ b/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
[ ... ]
> @@ -164,18 +167,26 @@ static int tpg_stream_on(struct tpg_device *tpg)
[ ... ]
> static int tpg_reset(struct tpg_device *tpg)
> {
> - writel(0, tpg->base + TPG_CTRL);
> - writel(1, tpg->base + TPG_CLEAR);
> + if (tpg->hw_version < TPG_HW_VER_2_4_0)
> + writel(0, tpg->base + TPG_CTRL);
> +
> + writel(TPG_CTRL_CMD_HW_RESET, tpg->base + TPG_CTRL_CMD);
>
> return 0;
> }
[Severity: Medium]
Is tpg->hw_version initialized when tpg_reset() runs for the first time?
In drivers/media/platform/qcom/camss/camss-tpg.c, tpg_set_power() calls
reset() before hw_version():
drivers/media/platform/qcom/camss/camss-tpg.c:tpg_set_power() {
if (on) {
...
tpg->res->hw_ops->reset(tpg);
tpg->res->hw_ops->hw_version(tpg);
}
}
Since tpg_hw_version() in drivers/media/platform/qcom/camss/camss-tpg-gen1.c
is where tpg->hw_version is populated from the TPG_HW_VERSION register,
tpg->hw_version is still 0 on the initial power-on. Won't this cause
tpg_reset() to evaluate 0 < TPG_HW_VER_2_4_0 as true and write 0 to TPG_CTRL
even on v2.4.0 hardware?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=11
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:36 ` Bryan O'Donoghue
-1 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:36 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> Add support for the TPG found on Kaanapali. This TPG uses hardware
> version 2.4.0, which drives test-enable and reset through the
> TPG_CTRL_CMD register at offset 0x1f4 instead of the TEST_EN bit in
> TPG_CTRL and the TPG_CLEAR register. Its output is routed into the
> CSID 1080 RX through the CSI2 TPG mux, so the CSID selects the TPG as
> the data source when a test pattern is selected.
>
> Add the TPG resources to the Kaanapali camss resources so that the TPG
> subdevices are created on this SoC.
>
> Signed-off-by: Hangxiang Ma<hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 11/15] media: qcom: camss: tpg: Add support for v2.4.0 TPG
@ 2026-10-28 15:36 ` Bryan O'Donoghue
0 siblings, 0 replies; 62+ messages in thread
From: Bryan O'Donoghue @ 2026-10-28 15:36 UTC (permalink / raw)
To: Hangxiang Ma, Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Bjorn Andersson, Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati
On 28/10/2026 15:20, Hangxiang Ma wrote:
> Add support for the TPG found on Kaanapali. This TPG uses hardware
> version 2.4.0, which drives test-enable and reset through the
> TPG_CTRL_CMD register at offset 0x1f4 instead of the TEST_EN bit in
> TPG_CTRL and the TPG_CLEAR register. Its output is routed into the
> CSID 1080 RX through the CSI2 TPG mux, so the CSID selects the TPG as
> the data source when a test pattern is selected.
>
> Add the TPG resources to the Kaanapali camss resources so that the TPG
> subdevices are created on this SoC.
>
> Signed-off-by: Hangxiang Ma<hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Describe the CAMSS and CSIPHY blocks on Kaanapali so that camera pipelines
can be enabled by board device trees.
The camera subsystem contains:
- 6 x CSIPHY (CSI Physical Layer)
- 3 x TPG (Test Pattern Generator)
- 3 x CSID (CSI Decoder)
- 2 x CSID Lite
- 3 x VFE (Video Front End), 5 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE Lite
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 401 ++++++++++++++++++++++++++++++++
1 file changed, 401 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index e48a179d0722..0c8fd7da55b7 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -20,6 +20,7 @@
#include <dt-bindings/interconnect/qcom,kaanapali-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
@@ -3597,6 +3598,384 @@ usb_dp_qmpphy_dp_in: endpoint {
};
};
+ camss: isp@900b000 {
+ compatible = "qcom,kaanapali-camss";
+
+ reg = <0x0 0x0900b000 0x0 0x1000>,
+ <0x0 0x09253000 0x0 0x5e80>,
+ <0x0 0x09263000 0x0 0x5e80>,
+ <0x0 0x09273000 0x0 0x5e80>,
+ <0x0 0x092d3000 0x0 0x3880>,
+ <0x0 0x092e7000 0x0 0x3880>,
+ <0x0 0x093fd000 0x0 0x400>,
+ <0x0 0x093fe000 0x0 0x400>,
+ <0x0 0x093ff000 0x0 0x400>,
+ <0x0 0x09151000 0x0 0x20000>,
+ <0x0 0x09171000 0x0 0x20000>,
+ <0x0 0x09191000 0x0 0x20000>,
+ <0x0 0x092dc000 0x0 0x1300>,
+ <0x0 0x092f0000 0x0 0x1300>;
+ reg-names = "top",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "csitpg0",
+ "csitpg1",
+ "csitpg2",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ clocks = <&camcc CAM_CC_CAMNOC_NRT_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_AXI_CLK>,
+ <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CAM_TOP_FAST_AHB_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_IFE_LITE_CLK>,
+ <&camcc CAM_CC_CSID_CLK>,
+ <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+ clock-names = "camnoc_nrt_axi",
+ "camnoc_rt_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb",
+ "cpas_vfe0",
+ "cpas_vfe1",
+ "cpas_vfe2",
+ "cpas_vfe_lite",
+ "csid",
+ "csid_csiphy_rx",
+ "gcc_axi_hf",
+ "gcc_axi_sf",
+ "vfe0",
+ "vfe0_fast_ahb",
+ "vfe1",
+ "vfe1_fast_ahb",
+ "vfe2",
+ "vfe2_fast_ahb",
+ "vfe_lite",
+ "vfe_lite_ahb",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_csid",
+ "qdss_debug_xo";
+
+ interrupts = <GIC_SPI 601 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 603 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 431 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 457 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 606 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+ <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "ahb",
+ "hf_mnoc";
+
+ iommus = <&apps_smmu 0x1c00 0x00>;
+
+ power-domains = <&camcc CAM_CC_TFE_0_GDSC>,
+ <&camcc CAM_CC_TFE_1_GDSC>,
+ <&camcc CAM_CC_TFE_2_GDSC>,
+ <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ power-domain-names = "ife0",
+ "ife1",
+ "ife2",
+ "top";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camss_csiphy0_in_port: port@0 {
+ reg = <0>;
+ };
+
+ camss_csiphy1_in_port: port@1 {
+ reg = <1>;
+ };
+
+ camss_csiphy2_in_port: port@2 {
+ reg = <2>;
+ };
+
+ camss_csiphy3_in_port: port@3 {
+ reg = <3>;
+ };
+
+ camss_csiphy4_in_port: port@4 {
+ reg = <4>;
+ };
+
+ camss_csiphy5_in_port: port@5 {
+ reg = <5>;
+ };
+ };
+ };
+
+ csiphy0: phy@9523000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09523000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
+ <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy0_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy0_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy1: phy@9525000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09525000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY1_CLK>,
+ <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy1_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy1_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy2: phy@9527000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09527000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY2_CLK>,
+ <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy2_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy2_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy3: phy@9529000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09529000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY3_CLK>,
+ <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy3_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy3_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy4: phy@952b000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x0952b000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY4_CLK>,
+ <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy4_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy4_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy5: phy@952d000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x0952d000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY5_CLK>,
+ <&camcc CAM_CC_CSI5PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy5_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy5_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
camcc: clock-controller@956d000 {
compatible = "qcom,kaanapali-camcc";
reg = <0x0 0x0956d000 0x0 0x80000>;
@@ -6548,6 +6927,28 @@ pdp_tx: scp-sram-section@100 {
};
};
+ csiphy_mxc_opp_table: opp-table-mxc {
+ compatible = "operating-points-v2";
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_low_svs_d1>,
+ <&rpmhpd_opp_low_svs_d1>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ required-opps = <&rpmhpd_opp_low_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ required-opps = <&rpmhpd_opp_low_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+ };
+
thermal-zones {
cpullc-0-0-thermal {
thermal-sensors = <&tsens0 0>;
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Describe the CAMSS and CSIPHY blocks on Kaanapali so that camera pipelines
can be enabled by board device trees.
The camera subsystem contains:
- 6 x CSIPHY (CSI Physical Layer)
- 3 x TPG (Test Pattern Generator)
- 3 x CSID (CSI Decoder)
- 2 x CSID Lite
- 3 x VFE (Video Front End), 5 RDI per VFE
- 2 x VFE Lite, 4 RDI per VFE Lite
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 401 ++++++++++++++++++++++++++++++++
1 file changed, 401 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index e48a179d0722..0c8fd7da55b7 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -20,6 +20,7 @@
#include <dt-bindings/interconnect/qcom,kaanapali-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
@@ -3597,6 +3598,384 @@ usb_dp_qmpphy_dp_in: endpoint {
};
};
+ camss: isp@900b000 {
+ compatible = "qcom,kaanapali-camss";
+
+ reg = <0x0 0x0900b000 0x0 0x1000>,
+ <0x0 0x09253000 0x0 0x5e80>,
+ <0x0 0x09263000 0x0 0x5e80>,
+ <0x0 0x09273000 0x0 0x5e80>,
+ <0x0 0x092d3000 0x0 0x3880>,
+ <0x0 0x092e7000 0x0 0x3880>,
+ <0x0 0x093fd000 0x0 0x400>,
+ <0x0 0x093fe000 0x0 0x400>,
+ <0x0 0x093ff000 0x0 0x400>,
+ <0x0 0x09151000 0x0 0x20000>,
+ <0x0 0x09171000 0x0 0x20000>,
+ <0x0 0x09191000 0x0 0x20000>,
+ <0x0 0x092dc000 0x0 0x1300>,
+ <0x0 0x092f0000 0x0 0x1300>;
+ reg-names = "top",
+ "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "csitpg0",
+ "csitpg1",
+ "csitpg2",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ clocks = <&camcc CAM_CC_CAMNOC_NRT_AXI_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_AXI_CLK>,
+ <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CAM_TOP_FAST_AHB_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_CAMNOC_RT_IFE_LITE_CLK>,
+ <&camcc CAM_CC_CSID_CLK>,
+ <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_0_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_1_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_CLK>,
+ <&camcc CAM_CC_TFE_2_MAIN_FAST_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CLK>,
+ <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+ <&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+ <&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+ clock-names = "camnoc_nrt_axi",
+ "camnoc_rt_axi",
+ "cpas_ahb",
+ "cpas_fast_ahb",
+ "cpas_vfe0",
+ "cpas_vfe1",
+ "cpas_vfe2",
+ "cpas_vfe_lite",
+ "csid",
+ "csid_csiphy_rx",
+ "gcc_axi_hf",
+ "gcc_axi_sf",
+ "vfe0",
+ "vfe0_fast_ahb",
+ "vfe1",
+ "vfe1_fast_ahb",
+ "vfe2",
+ "vfe2_fast_ahb",
+ "vfe_lite",
+ "vfe_lite_ahb",
+ "vfe_lite_cphy_rx",
+ "vfe_lite_csid",
+ "qdss_debug_xo";
+
+ interrupts = <GIC_SPI 601 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 603 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 431 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 433 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 436 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 457 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 606 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "csid0",
+ "csid1",
+ "csid2",
+ "csid_lite0",
+ "csid_lite1",
+ "vfe0",
+ "vfe1",
+ "vfe2",
+ "vfe_lite0",
+ "vfe_lite1";
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+ <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "ahb",
+ "hf_mnoc";
+
+ iommus = <&apps_smmu 0x1c00 0x00>;
+
+ power-domains = <&camcc CAM_CC_TFE_0_GDSC>,
+ <&camcc CAM_CC_TFE_1_GDSC>,
+ <&camcc CAM_CC_TFE_2_GDSC>,
+ <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ power-domain-names = "ife0",
+ "ife1",
+ "ife2",
+ "top";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camss_csiphy0_in_port: port@0 {
+ reg = <0>;
+ };
+
+ camss_csiphy1_in_port: port@1 {
+ reg = <1>;
+ };
+
+ camss_csiphy2_in_port: port@2 {
+ reg = <2>;
+ };
+
+ camss_csiphy3_in_port: port@3 {
+ reg = <3>;
+ };
+
+ camss_csiphy4_in_port: port@4 {
+ reg = <4>;
+ };
+
+ camss_csiphy5_in_port: port@5 {
+ reg = <5>;
+ };
+ };
+ };
+
+ csiphy0: phy@9523000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09523000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
+ <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy0_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy0_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy1: phy@9525000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09525000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY1_CLK>,
+ <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy1_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy1_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy2: phy@9527000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09527000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY2_CLK>,
+ <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy2_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy2_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy3: phy@9529000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x09529000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY3_CLK>,
+ <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy3_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy3_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy4: phy@952b000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x0952b000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY4_CLK>,
+ <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy4_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy4_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ csiphy5: phy@952d000 {
+ compatible = "qcom,kaanapali-csi2-phy";
+ reg = <0x0 0x0952d000 0x0 0x2000>;
+
+ clocks = <&camcc CAM_CC_CSIPHY5_CLK>,
+ <&camcc CAM_CC_CSI5PHYTIMER_CLK>,
+ <&camcc CAM_CC_CORE_AHB_CLK>;
+ clock-names = "core",
+ "timer",
+ "ahb";
+
+ interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
+
+ operating-points-v2 = <&csiphy_mxc_opp_table>;
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>,
+ <&rpmhpd RPMHPD_MMCX>,
+ <&rpmhpd RPMHPD_MXC>;
+ power-domain-names = "top",
+ "mmcx",
+ "mx";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csiphy5_in_port: port@0 {
+ reg = <0>;
+ };
+
+ csiphy5_out_port: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
camcc: clock-controller@956d000 {
compatible = "qcom,kaanapali-camcc";
reg = <0x0 0x0956d000 0x0 0x80000>;
@@ -6548,6 +6927,28 @@ pdp_tx: scp-sram-section@100 {
};
};
+ csiphy_mxc_opp_table: opp-table-mxc {
+ compatible = "operating-points-v2";
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_low_svs_d1>,
+ <&rpmhpd_opp_low_svs_d1>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ required-opps = <&rpmhpd_opp_low_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ required-opps = <&rpmhpd_opp_low_svs>,
+ <&rpmhpd_opp_low_svs>;
+ };
+ };
+
thermal-zones {
cpullc-0-0-thermal {
thermal-sensors = <&tsens0 0>;
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:28 ` Abel Vesa
-1 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:28 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati, Konrad Dybcio
On 26-10-28 08:20:46, Hangxiang Ma wrote:
> Describe the CAMSS and CSIPHY blocks on Kaanapali so that camera pipelines
> can be enabled by board device trees.
>
> The camera subsystem contains:
> - 6 x CSIPHY (CSI Physical Layer)
> - 3 x TPG (Test Pattern Generator)
> - 3 x CSID (CSI Decoder)
> - 2 x CSID Lite
> - 3 x VFE (Video Front End), 5 RDI per VFE
> - 2 x VFE Lite, 4 RDI per VFE Lite
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
@ 2026-10-28 15:28 ` Abel Vesa
0 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:28 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati, Konrad Dybcio
On 26-10-28 08:20:46, Hangxiang Ma wrote:
> Describe the CAMSS and CSIPHY blocks on Kaanapali so that camera pipelines
> can be enabled by board device trees.
>
> The camera subsystem contains:
> - 6 x CSIPHY (CSI Physical Layer)
> - 3 x TPG (Test Pattern Generator)
> - 3 x CSID (CSI Decoder)
> - 2 x CSID Lite
> - 3 x VFE (Video Front End), 5 RDI per VFE
> - 2 x VFE Lite, 4 RDI per VFE Lite
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:42 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:42 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] arm64: dts: qcom: kaanapali: csiphy_mxc_opp_table uses invalid 300 MHz OPP
--
commit 0cfa3a0207d1730d9c7ff716309df9aad06f00ba
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
This commit adds device tree definitions for the CAMSS ISP, six CSIPHY blocks,
and the associated CSIPHY MXC operating points table on the Qualcomm Kaanapali
platform.
> diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
> index e48a179d07220..0c8fd7da55b78 100644
> --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
[ ... ]
> @@ -6548,6 +6927,28 @@ pdp_tx: scp-sram-section@100 {
> };
> };
>
> + csiphy_mxc_opp_table: opp-table-mxc {
> + compatible = "operating-points-v2";
> +
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&rpmhpd_opp_low_svs_d1>,
> + <&rpmhpd_opp_low_svs_d1>;
> + };
> +
> + opp-400000000 {
> + opp-hz = /bits/ 64 <400000000>;
> + required-opps = <&rpmhpd_opp_low_svs>,
> + <&rpmhpd_opp_low_svs>;
> + };
[Severity: High]
Should the lowest operating point in csiphy_mxc_opp_table be 266666667 Hz
instead of 300000000 Hz?
In drivers/clk/qcom/camcc-kaanapali.c, the parent RCG for
CAM_CC_CSIPHY0_CLK through CAM_CC_CSIPHY5_CLK uses clk_rcg2_shared_ops
(which rounds up via qcom_find_freq()) and defines the following frequency
table:
static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
F(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0),
F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
{ }
};
When a sensor connected to csiphy0..csiphy5 configures a link frequency of
1.2 GHz or lower (so opp_rate = link_freq / 4 <= 300000000 Hz),
phy_qcom_mipi_csi2_configure() -> phy_qcom_mipi_csi2_set_clock_rates() in
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c looks up the ceiling OPP and
votes the power domains before setting the clock rate:
opp = dev_pm_opp_find_freq_ceil(dev, &opp_rate);
...
for (i = 0; i < csi2phy->pd_list->num_pds; i++) {
...
perf = dev_pm_opp_get_required_pstate(opp, pstate);
pstate += 1;
ret = dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], perf);
...
}
dev_pm_opp_put(opp);
ret = dev_pm_opp_set_rate(dev, opp_rate);
Because csiphy_mxc_opp_table lists 300000000 Hz,
phy_qcom_mipi_csi2_set_clock_rates() selects opp-300000000, votes
RPMHPD_MMCX and RPMHPD_MXC to rpmhpd_opp_low_svs_d1, and then calls
dev_pm_opp_set_rate(dev, 300000000).
Won't requesting 300000000 Hz skip the 266.67 MHz frequency and round the
CSIPHY core clock up to 400000000 Hz while leaving MMCX and MXC at
rpmhpd_opp_low_svs_d1 instead of the rpmhpd_opp_low_svs corner required for
400 MHz?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=12
^ permalink raw reply [flat|nested] 62+ messages in thread* Re: [PATCH v23 12/15] arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
@ 2026-10-28 15:42 ` sashiko-bot
0 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-10-28 15:42 UTC (permalink / raw)
To: Hangxiang Ma
Cc: linux-phy, devicetree, robh, conor+dt, media-ci, vkoul,
neil.armstrong, olteanv
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] arm64: dts: qcom: kaanapali: csiphy_mxc_opp_table uses invalid 300 MHz OPP
--
commit 0cfa3a0207d1730d9c7ff716309df9aad06f00ba
Author: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
arm64: dts: qcom: kaanapali: Add CAMSS and CSIPHY block definitions
This commit adds device tree definitions for the CAMSS ISP, six CSIPHY blocks,
and the associated CSIPHY MXC operating points table on the Qualcomm Kaanapali
platform.
> diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
> index e48a179d07220..0c8fd7da55b78 100644
> --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
> +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
[ ... ]
> @@ -6548,6 +6927,28 @@ pdp_tx: scp-sram-section@100 {
> };
> };
>
> + csiphy_mxc_opp_table: opp-table-mxc {
> + compatible = "operating-points-v2";
> +
> + opp-300000000 {
> + opp-hz = /bits/ 64 <300000000>;
> + required-opps = <&rpmhpd_opp_low_svs_d1>,
> + <&rpmhpd_opp_low_svs_d1>;
> + };
> +
> + opp-400000000 {
> + opp-hz = /bits/ 64 <400000000>;
> + required-opps = <&rpmhpd_opp_low_svs>,
> + <&rpmhpd_opp_low_svs>;
> + };
[Severity: High]
Should the lowest operating point in csiphy_mxc_opp_table be 266666667 Hz
instead of 300000000 Hz?
In drivers/clk/qcom/camcc-kaanapali.c, the parent RCG for
CAM_CC_CSIPHY0_CLK through CAM_CC_CSIPHY5_CLK uses clk_rcg2_shared_ops
(which rounds up via qcom_find_freq()) and defines the following frequency
table:
static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
F(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0),
F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
{ }
};
When a sensor connected to csiphy0..csiphy5 configures a link frequency of
1.2 GHz or lower (so opp_rate = link_freq / 4 <= 300000000 Hz),
phy_qcom_mipi_csi2_configure() -> phy_qcom_mipi_csi2_set_clock_rates() in
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c looks up the ceiling OPP and
votes the power domains before setting the clock rate:
opp = dev_pm_opp_find_freq_ceil(dev, &opp_rate);
...
for (i = 0; i < csi2phy->pd_list->num_pds; i++) {
...
perf = dev_pm_opp_get_required_pstate(opp, pstate);
pstate += 1;
ret = dev_pm_genpd_set_performance_state(csi2phy->pd_list->pd_devs[i], perf);
...
}
dev_pm_opp_put(opp);
ret = dev_pm_opp_set_rate(dev, opp_rate);
Because csiphy_mxc_opp_table lists 300000000 Hz,
phy_qcom_mipi_csi2_set_clock_rates() selects opp-300000000, votes
RPMHPD_MMCX and RPMHPD_MXC to rpmhpd_opp_low_svs_d1, and then calls
dev_pm_opp_set_rate(dev, 300000000).
Won't requesting 300000000 Hz skip the 266.67 MHz frequency and round the
CSIPHY core clock up to 400000000 Hz while leaving MMCX and MXC at
rpmhpd_opp_low_svs_d1 instead of the rpmhpd_opp_low_svs corner required for
400 MHz?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261028-kaanapali-camss-v23-0-95f250b18612@oss.qualcomm.com?part=12
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 13/15] arm64: dts: qcom: kaanapali: Add CCI controller nodes
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Add the three Camera Control Interface (CCI) controllers present on the
Kaanapali SoC. Each controller provides two I2C hosts used for camera
sensor control, so define the controller nodes and their pinctrl states.
The first bus has two CCI bus master pinouts:
cci_i2c_sda0 = gpio109
cci_i2c_scl0 = gpio110
cci_i2c_sda1 = gpio111
cci_i2c_scl1 = gpio112
The second bus has two CCI bus master pinouts:
cci_i2c_sda3 = gpio113
cci_i2c_scl3 = gpio114
cci_i2c_sda4 = gpio107
cci_i2c_scl4 = gpio160
The third bus has two CCI bus master pinouts:
cci_i2c_sda5 = gpio108
cci_i2c_scl5 = gpio149
cci_i2c_sda6 = gpio115
cci_i2c_scl6 = gpio116
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 303 ++++++++++++++++++++++++++++++++
1 file changed, 303 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index 0c8fd7da55b7..bf3922f0ffb3 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -3748,6 +3748,117 @@ camss_csiphy5_in_port: port@5 {
};
};
+ cci0: cci@941b000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941b000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 426 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_0_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci0_i2c0_default &cci0_i2c1_default>;
+ pinctrl-1 = <&cci0_i2c0_sleep &cci0_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci0_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci0_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci1: cci@941c000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941c000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 427 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_1_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci1_i2c0_default &cci1_i2c1_default>;
+ pinctrl-1 = <&cci1_i2c0_sleep &cci1_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci1_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci1_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci2: cci@941d000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941d000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 428 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_2_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci2_i2c0_default &cci2_i2c1_default>;
+ pinctrl-1 = <&cci2_i2c0_sleep &cci2_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci2_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci2_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
csiphy0: phy@9523000 {
compatible = "qcom,kaanapali-csi2-phy";
reg = <0x0 0x09523000 0x0 0x2000>;
@@ -4536,6 +4647,198 @@ tlmm: pinctrl@f100000 {
#interrupt-cells = <2>;
wakeup-parent = <&pdc>;
+ cci0_i2c0_default: cci0-i2c0-default-state {
+ scl-pins {
+ pins = "gpio110";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio109";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c0_sleep: cci0-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio110";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio109";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c1_default: cci0-i2c1-default-state {
+ scl-pins {
+ pins = "gpio112";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio111";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c1_sleep: cci0-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio112";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio111";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c0_default: cci1-i2c0-default-state {
+ scl-pins {
+ pins = "gpio114";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio113";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c0_sleep: cci1-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio114";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio113";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c1_default: cci1-i2c1-default-state {
+ scl-pins {
+ pins = "gpio160";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio107";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c1_sleep: cci1-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio160";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c0_default: cci2-i2c0-default-state {
+ scl-pins {
+ pins = "gpio149";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio108";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c0_sleep: cci2-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio149";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio108";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c1_default: cci2-i2c1-default-state {
+ scl-pins {
+ pins = "gpio116";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio115";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c1_sleep: cci2-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio116";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
hub_i2c0_data_clk: hub-i2c0-data-clk-state {
/* SDA, SCL */
pins = "gpio66", "gpio67";
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 13/15] arm64: dts: qcom: kaanapali: Add CCI controller nodes
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Add the three Camera Control Interface (CCI) controllers present on the
Kaanapali SoC. Each controller provides two I2C hosts used for camera
sensor control, so define the controller nodes and their pinctrl states.
The first bus has two CCI bus master pinouts:
cci_i2c_sda0 = gpio109
cci_i2c_scl0 = gpio110
cci_i2c_sda1 = gpio111
cci_i2c_scl1 = gpio112
The second bus has two CCI bus master pinouts:
cci_i2c_sda3 = gpio113
cci_i2c_scl3 = gpio114
cci_i2c_sda4 = gpio107
cci_i2c_scl4 = gpio160
The third bus has two CCI bus master pinouts:
cci_i2c_sda5 = gpio108
cci_i2c_scl5 = gpio149
cci_i2c_sda6 = gpio115
cci_i2c_scl6 = gpio116
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 303 ++++++++++++++++++++++++++++++++
1 file changed, 303 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index 0c8fd7da55b7..bf3922f0ffb3 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -3748,6 +3748,117 @@ camss_csiphy5_in_port: port@5 {
};
};
+ cci0: cci@941b000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941b000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 426 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_0_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci0_i2c0_default &cci0_i2c1_default>;
+ pinctrl-1 = <&cci0_i2c0_sleep &cci0_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci0_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci0_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci1: cci@941c000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941c000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 427 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_1_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci1_i2c0_default &cci1_i2c1_default>;
+ pinctrl-1 = <&cci1_i2c0_sleep &cci1_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci1_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci1_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci2: cci@941d000 {
+ compatible = "qcom,kaanapali-cci", "qcom,msm8996-cci";
+ reg = <0x0 0x0941d000 0x0 0x1000>;
+
+ interrupts = <GIC_SPI 428 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAM_CC_CAM_TOP_AHB_CLK>,
+ <&camcc CAM_CC_CCI_2_CLK>;
+ clock-names = "ahb",
+ "cci";
+
+ power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci2_i2c0_default &cci2_i2c1_default>;
+ pinctrl-1 = <&cci2_i2c0_sleep &cci2_i2c1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci2_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci2_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
csiphy0: phy@9523000 {
compatible = "qcom,kaanapali-csi2-phy";
reg = <0x0 0x09523000 0x0 0x2000>;
@@ -4536,6 +4647,198 @@ tlmm: pinctrl@f100000 {
#interrupt-cells = <2>;
wakeup-parent = <&pdc>;
+ cci0_i2c0_default: cci0-i2c0-default-state {
+ scl-pins {
+ pins = "gpio110";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio109";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c0_sleep: cci0-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio110";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio109";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c1_default: cci0-i2c1-default-state {
+ scl-pins {
+ pins = "gpio112";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio111";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci0_i2c1_sleep: cci0-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio112";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio111";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c0_default: cci1-i2c0-default-state {
+ scl-pins {
+ pins = "gpio114";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio113";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c0_sleep: cci1-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio114";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio113";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c1_default: cci1-i2c1-default-state {
+ scl-pins {
+ pins = "gpio160";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio107";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci1_i2c1_sleep: cci1-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio160";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c0_default: cci2-i2c0-default-state {
+ scl-pins {
+ pins = "gpio149";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio108";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c0_sleep: cci2-i2c0-sleep-state {
+ scl-pins {
+ pins = "gpio149";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio108";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c1_default: cci2-i2c1-default-state {
+ scl-pins {
+ pins = "gpio116";
+ function = "cci_i2c_scl";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio115";
+ function = "cci_i2c_sda";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ cci2_i2c1_sleep: cci2-i2c1-sleep-state {
+ scl-pins {
+ pins = "gpio116";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sda-pins {
+ pins = "gpio115";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
hub_i2c0_data_clk: hub-i2c0-data-clk-state {
/* SDA, SCL */
pins = "gpio66", "gpio67";
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 13/15] arm64: dts: qcom: kaanapali: Add CCI controller nodes
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:28 ` Abel Vesa
-1 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:28 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati, Konrad Dybcio
On 26-10-28 08:20:47, Hangxiang Ma wrote:
> Add the three Camera Control Interface (CCI) controllers present on the
> Kaanapali SoC. Each controller provides two I2C hosts used for camera
> sensor control, so define the controller nodes and their pinctrl states.
>
> The first bus has two CCI bus master pinouts:
> cci_i2c_sda0 = gpio109
> cci_i2c_scl0 = gpio110
>
> cci_i2c_sda1 = gpio111
> cci_i2c_scl1 = gpio112
>
> The second bus has two CCI bus master pinouts:
> cci_i2c_sda3 = gpio113
> cci_i2c_scl3 = gpio114
>
> cci_i2c_sda4 = gpio107
> cci_i2c_scl4 = gpio160
>
> The third bus has two CCI bus master pinouts:
> cci_i2c_sda5 = gpio108
> cci_i2c_scl5 = gpio149
>
> cci_i2c_sda6 = gpio115
> cci_i2c_scl6 = gpio116
>
> Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
> Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 13/15] arm64: dts: qcom: kaanapali: Add CCI controller nodes
@ 2026-10-28 15:28 ` Abel Vesa
0 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:28 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati, Konrad Dybcio
On 26-10-28 08:20:47, Hangxiang Ma wrote:
> Add the three Camera Control Interface (CCI) controllers present on the
> Kaanapali SoC. Each controller provides two I2C hosts used for camera
> sensor control, so define the controller nodes and their pinctrl states.
>
> The first bus has two CCI bus master pinouts:
> cci_i2c_sda0 = gpio109
> cci_i2c_scl0 = gpio110
>
> cci_i2c_sda1 = gpio111
> cci_i2c_scl1 = gpio112
>
> The second bus has two CCI bus master pinouts:
> cci_i2c_sda3 = gpio113
> cci_i2c_scl3 = gpio114
>
> cci_i2c_sda4 = gpio107
> cci_i2c_scl4 = gpio160
>
> The third bus has two CCI bus master pinouts:
> cci_i2c_sda5 = gpio108
> cci_i2c_scl5 = gpio149
>
> cci_i2c_sda6 = gpio115
> cci_i2c_scl6 = gpio116
>
> Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
> Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH v23 14/15] arm64: dts: qcom: kaanapali: Add camera MCLK pinctrl
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Add TLMM pinctrl states for the camera master clock GPIOs on Kaanapali so
camera sensor nodes can select the proper MCLK pin functions when enabled.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 56 +++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index bf3922f0ffb3..3f28f279e4e0 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -4647,6 +4647,62 @@ tlmm: pinctrl@f100000 {
#interrupt-cells = <2>;
wakeup-parent = <&pdc>;
+ cam_mclk0_default: cam-mclk0-default-state {
+ pins = "gpio89";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk1_default: cam-mclk1-default-state {
+ pins = "gpio90";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk2_default: cam-mclk2-default-state {
+ pins = "gpio91";
+ function = "cam_asc_mclk2";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk3_default: cam-mclk3-default-state {
+ pins = "gpio92";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk4_default: cam-mclk4-default-state {
+ pins = "gpio93";
+ function = "cam_asc_mclk4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk5_default: cam-mclk5-default-state {
+ pins = "gpio94";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk6_default: cam-mclk6-default-state {
+ pins = "gpio95";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk7_default: cam-mclk7-default-state {
+ pins = "gpio96";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
cci0_i2c0_default: cci0-i2c0-default-state {
scl-pins {
pins = "gpio110";
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 14/15] arm64: dts: qcom: kaanapali: Add camera MCLK pinctrl
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma,
Konrad Dybcio
Add TLMM pinctrl states for the camera master clock GPIOs on Kaanapali so
camera sensor nodes can select the proper MCLK pin functions when enabled.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kaanapali.dtsi | 56 +++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
index bf3922f0ffb3..3f28f279e4e0 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi
+++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -4647,6 +4647,62 @@ tlmm: pinctrl@f100000 {
#interrupt-cells = <2>;
wakeup-parent = <&pdc>;
+ cam_mclk0_default: cam-mclk0-default-state {
+ pins = "gpio89";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk1_default: cam-mclk1-default-state {
+ pins = "gpio90";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk2_default: cam-mclk2-default-state {
+ pins = "gpio91";
+ function = "cam_asc_mclk2";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk3_default: cam-mclk3-default-state {
+ pins = "gpio92";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk4_default: cam-mclk4-default-state {
+ pins = "gpio93";
+ function = "cam_asc_mclk4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk5_default: cam-mclk5-default-state {
+ pins = "gpio94";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk6_default: cam-mclk6-default-state {
+ pins = "gpio95";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk7_default: cam-mclk7-default-state {
+ pins = "gpio96";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
cci0_i2c0_default: cci0-i2c0-default-state {
scl-pins {
pins = "gpio110";
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH v23 15/15] arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:20 ` Hangxiang Ma
-1 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Enable the S5KJN5 image sensor via CCI on Kaanapali MTP board.
The Kaanapali MTP board connect S5KJN5 with QUP I2C bus by default. This
DTBO enables S5KJN5 on CCI-0 interface connected to the CSIPHY2 in four
lane mode on a rework camera module.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 5 ++
.../boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso | 81 ++++++++++++++++++++++
arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 7 ++
3 files changed, 93 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 88230c4e00ea..84b244d43e9e 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -48,6 +48,11 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp449.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp453.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9650-rdp488.dtb
+dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp-camera-s5kjn5.dtbo
+
+kaanapali-mtp-camera-s5kjn5-dtbs := kaanapali-mtp.dtb kaanapali-mtp-camera-s5kjn5.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp-camera-s5kjn5.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso b/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso
new file mode 100644
index 000000000000..d0e39855e0e6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h>
+#include <dt-bindings/clock/qcom,kaanapali-camcc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/media/video-interfaces.h>
+
+&camss {
+ status = "okay";
+};
+
+&camss_csiphy2_in_port {
+ camss_csiphy2_inep: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy2_out_ep>;
+ };
+};
+
+&cci0 {
+ status = "okay";
+};
+
+&cci0_i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@10 {
+ compatible = "samsung,s5kjn5";
+ reg = <0x10>;
+
+ reset-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cam_mclk2_default &cam_reset2_default>;
+
+ clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK2_CLK>;
+ assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK2_CLK>;
+ assigned-clock-rates = <19200000>;
+
+ vddio-supply = <&vreg_l4n_1p8>;
+ vddd-supply = <&vreg_l1m_1p0>;
+ vdda-supply = <&vreg_l4m_2p2>;
+ vddio1p2-supply = <&vreg_l2n_1p2>;
+ afvdd-supply = <&vreg_l7m_2p8>;
+
+ port {
+ s5kjn5_out_ep: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <1248000000>;
+ remote-endpoint = <&csiphy2_in_ep>;
+ };
+ };
+ };
+};
+
+&csiphy2 {
+ vdda-0p9-supply = <&vreg_l3d_0p8>;
+ vdda-1p2-supply = <&vreg_l1d_1p2>;
+
+ status = "okay";
+};
+
+&csiphy2_in_port {
+ csiphy2_in_ep: endpoint {
+ bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&s5kjn5_out_ep>;
+ };
+};
+
+&csiphy2_out_port {
+ csiphy2_out_ep: endpoint {
+ remote-endpoint = <&camss_csiphy2_inep>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
index 9eb02fd09dab..c70cd39bcb75 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
@@ -1243,6 +1243,13 @@ &tlmm {
<119 2>, /* SoCCP */
<144 4>; /* CXM UART */
+ cam_reset2_default: cam-reset2-default-state {
+ pins = "gpio3";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
wlan_en: wlan-en-state {
pins = "gpio16";
function = "gpio";
--
2.34.1
^ permalink raw reply related [flat|nested] 62+ messages in thread* [PATCH v23 15/15] arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
@ 2026-10-28 15:20 ` Hangxiang Ma
0 siblings, 0 replies; 62+ messages in thread
From: Hangxiang Ma @ 2026-10-28 15:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa
Cc: linux-phy, linux-media, linux-arm-msm, devicetree, linux-kernel,
jeyaprakash.soundrapandian, Vijay Kumar Tumati, Hangxiang Ma
Enable the S5KJN5 image sensor via CCI on Kaanapali MTP board.
The Kaanapali MTP board connect S5KJN5 with QUP I2C bus by default. This
DTBO enables S5KJN5 on CCI-0 interface connected to the CSIPHY2 in four
lane mode on a rework camera module.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 5 ++
.../boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso | 81 ++++++++++++++++++++++
arch/arm64/boot/dts/qcom/kaanapali-mtp.dts | 7 ++
3 files changed, 93 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 88230c4e00ea..84b244d43e9e 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -48,6 +48,11 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp449.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp453.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9650-rdp488.dtb
+dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp-camera-s5kjn5.dtbo
+
+kaanapali-mtp-camera-s5kjn5-dtbs := kaanapali-mtp.dtb kaanapali-mtp-camera-s5kjn5.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp-camera-s5kjn5.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-mtp.dtb
dtb-$(CONFIG_ARCH_QCOM) += kaanapali-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += lemans-evk.dtb
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso b/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso
new file mode 100644
index 000000000000..d0e39855e0e6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp-camera-s5kjn5.dtso
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h>
+#include <dt-bindings/clock/qcom,kaanapali-camcc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/media/video-interfaces.h>
+
+&camss {
+ status = "okay";
+};
+
+&camss_csiphy2_in_port {
+ camss_csiphy2_inep: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy2_out_ep>;
+ };
+};
+
+&cci0 {
+ status = "okay";
+};
+
+&cci0_i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@10 {
+ compatible = "samsung,s5kjn5";
+ reg = <0x10>;
+
+ reset-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&cam_mclk2_default &cam_reset2_default>;
+
+ clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK2_CLK>;
+ assigned-clocks = <&cambistmclkcc CAM_BIST_MCLK_CC_MCLK2_CLK>;
+ assigned-clock-rates = <19200000>;
+
+ vddio-supply = <&vreg_l4n_1p8>;
+ vddd-supply = <&vreg_l1m_1p0>;
+ vdda-supply = <&vreg_l4m_2p2>;
+ vddio1p2-supply = <&vreg_l2n_1p2>;
+ afvdd-supply = <&vreg_l7m_2p8>;
+
+ port {
+ s5kjn5_out_ep: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <1248000000>;
+ remote-endpoint = <&csiphy2_in_ep>;
+ };
+ };
+ };
+};
+
+&csiphy2 {
+ vdda-0p9-supply = <&vreg_l3d_0p8>;
+ vdda-1p2-supply = <&vreg_l1d_1p2>;
+
+ status = "okay";
+};
+
+&csiphy2_in_port {
+ csiphy2_in_ep: endpoint {
+ bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&s5kjn5_out_ep>;
+ };
+};
+
+&csiphy2_out_port {
+ csiphy2_out_ep: endpoint {
+ remote-endpoint = <&camss_csiphy2_inep>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
index 9eb02fd09dab..c70cd39bcb75 100644
--- a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
@@ -1243,6 +1243,13 @@ &tlmm {
<119 2>, /* SoCCP */
<144 4>; /* CXM UART */
+ cam_reset2_default: cam-reset2-default-state {
+ pins = "gpio3";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
wlan_en: wlan-en-state {
pins = "gpio16";
function = "gpio";
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related [flat|nested] 62+ messages in thread* Re: [PATCH v23 15/15] arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
2026-10-28 15:20 ` Hangxiang Ma
@ 2026-10-28 15:29 ` Abel Vesa
-1 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:49, Hangxiang Ma wrote:
> Enable the S5KJN5 image sensor via CCI on Kaanapali MTP board.
>
> The Kaanapali MTP board connect S5KJN5 with QUP I2C bus by default. This
> DTBO enables S5KJN5 on CCI-0 interface connected to the CSIPHY2 in four
> lane mode on a rework camera module.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH v23 15/15] arm64: dts: qcom: kaanapali-mtp-camera-s5kjn5: Add DT overlay
@ 2026-10-28 15:29 ` Abel Vesa
0 siblings, 0 replies; 62+ messages in thread
From: Abel Vesa @ 2026-10-28 15:29 UTC (permalink / raw)
To: Hangxiang Ma
Cc: Bryan O'Donoghue, Vinod Koul, Neil Armstrong,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bryan O'Donoghue, Vladimir Zapolskiy,
Loic Poulain, Mauro Carvalho Chehab, Bjorn Andersson,
Konrad Dybcio, Abel Vesa, linux-phy, linux-media, linux-arm-msm,
devicetree, linux-kernel, jeyaprakash.soundrapandian,
Vijay Kumar Tumati
On 26-10-28 08:20:49, Hangxiang Ma wrote:
> Enable the S5KJN5 image sensor via CCI on Kaanapali MTP board.
>
> The Kaanapali MTP board connect S5KJN5 with QUP I2C bus by default. This
> DTBO enables S5KJN5 on CCI-0 interface connected to the CSIPHY2 in four
> lane mode on a rework camera module.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Signed-off-by: Hangxiang Ma <hangxiang.ma@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply [flat|nested] 62+ messages in thread