Skip to contentSkip to conversation

media: qcom: camss: Add SM8150 CAMSS support

PATCH In review Andrew Gigena 7 participants 28 messages Nov 6 – Nov 11

Subsystems (9)
lore
Share & tools
lore
#0 lore raw

v3 cover media: qcom: camss: Add SM8150 CAMSS support

This series adds SoC-level CAMSS support for the Qualcomm SM8150 (Snapdragon 855), based on v7.4-rc1.

SM8150 contains four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances. The blocks are close to the existing SDM845/SM8250/SC8280XP implementations, so the driver change only adds platform data and hooks the SoC into the existing Gen2 CSID and VFE 17x code paths.

As requested in the v2 review, the CSIPHY I/O spaces, clocks, interrupts and supplies are excluded from the CAMSS container device and instead described by four qcom,sm8150-csi2-phy nodes driven by the dedicated CSI2 PHY driver. Each PHY node feeds one CAMSS CSI input port and is fed by the core and timer clocks, the vdda-phy and vdda-pll supplies, and the Titan top power domain. No new register programming sequences are introduced: the PHY driver reuses the existing SC8280XP lane register table.

The series documents the SM8150 CCI compatible, which the CCI nodes use with qcom,msm8996-cci as the fallback. The patches are ordered bindings first, then driver data, then the DT description. The series is intentionally SoC-level only: it does not add a board DTS, camera sensor drivers, or board-specific camera wiring.

Testing: with a local Pixel 4 (google-flame) board port and out-of-tree sensor drivers, the rear wide (IMX363), rear tele (IMX481), front (IMX520) and IR (dual OV7251, patched driver) cameras stream. The board port itself is not part of this series.

checkpatch reports no errors. The only warning is the new-binding "MAINTAINERS needs updating" prompt, which is a false positive because the existing CAMSS entry already covers qcom,*camss* bindings. dt_binding_check passes for qcom,sm8150-camss.yaml and qcom,sm8150-csi2-phy.yaml, and the new PHY/CAMSS drivers and DTS build.

Changes in v3:
- Switch to the new CSI2 PHY driver (Vladimir's v2 review request):
new qcom,sm8150-csi2-phy binding + driver, four phy@ nodes linked to
CAMSS CSI ports. CAMSS keeps only VFE/CSID resources (19 clocks,
8 IRQs). Timer pinned to 300 MHz (SM8150 timer only supports
19.2/300 MHz).
- Fix VFE lite clock match: restrict prefix match to numbered
"vfe_liteN" clocks to avoid matching aux clocks.
- Binding/DTS cleanup: patternProperties for ports, reg/reg-names after
compatible, sorted required list, redundant minItems dropped, aligned
example (lowercase hex, wrapped interconnects, isp@ name), ports
required, remote-endpoint in example, cam_hf_1_mnoc last, SDA/SCL
pinctrl comments, remote-only SoC endpoints (Glymur pattern).
- Order SM8150 before X1E80100 in PHY driver (7 nm predates 4 nm).
- The new CSI2 PHY driver does not support DPHY split mode, so the
Pixel 4 follower OV7251 (one of the two sensors sharing CSIPHY1) is
disabled in this series. A separate patchset adding split-mode support
to mainline OV7251 driver is planned.
- Link to v2: https://patch.msgid.link/20261106-sm8150-v7.4-rc1-camss-v2-0-39ee37787b00@andrewgigena.dev

Changes in v2:
- Address the review comments from Sashiko, Bryan and Val.
- Drop the internal CAMCC *_src clocks from the binding, the example and
the DTS; the binding now lists 27 clocks instead of 42.
- Remove clock-lanes from the CSI endpoints and use an unnumbered
endpoint in the example, matching the other CAMSS bindings.
- Describe vdda-phy-supply as 0.88V and vdda-pll-supply as 1.2V.
- Move the CSIPHY supplies from the CSID resources to the CSIPHY
resources, so they are enabled before the PHY is accessed.
- Add a separate fix for the VFE lite clock rates
- Tidy the CAMSS_8150 switch ordering.
- Link to v1: https://patch.msgid.link/20261104-sm8150-v7-4-rc1-camss-v1-0-7a9534a9a22f@andrewgigena.dev

---
Andrew Gigena (7):
dt-bindings: i2c: qcom-cci: Document SM8150 compatible
dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS
dt-bindings: phy: qcom,sm8150-csi2-phy: Add SM8150 CSI2 PHY
media: qcom: camss: Match VFE lite clocks by name prefix
media: qcom: camss: Add support for SM8150
phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support
arm64: dts: qcom: sm8150: Add CAMSS and CCI nodes

 .../devicetree/bindings/i2c/qcom,i2c-cci.yaml      |   2 +
 .../bindings/media/qcom,sm8150-camss.yaml          | 285 ++++++++++++
 .../bindings/phy/qcom,sm8150-csi2-phy.yaml         | 163 +++++++
 arch/arm64/boot/dts/qcom/sm8150.dtsi               | 488 +++++++++++++++++++++
 .../platform/qcom/camss/camss-csiphy-3ph-1-0.c     |   2 +
 drivers/media/platform/qcom/camss/camss-vfe.c      |   6 +
 drivers/media/platform/qcom/camss/camss.c          | 231 ++++++++++
 drivers/media/platform/qcom/camss/camss.h          |   1 +
 drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c |  97 ++++
 drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c     |  16 +-
 drivers/phy/qualcomm/phy-qcom-mipi-csi2.h          |   4 +
 11 files changed, 1294 insertions(+), 1 deletion(-)

---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261104-sm8150-v7.4-rc1-camss-d3dd5e02a170

Best regards,

Signature · 1 line
Andrew Gigena <[email protected]>
#1 lore raw

PATCH v3 1/7 dt-bindings: i2c: qcom-cci: Document SM8150 compatible

Add qcom,sm8150-cci as a CCI v2 compatible, with qcom,msm8996-cci as the fallback.

---
 Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +2 -0
index 1e8def25ec0e..1e7a8efaa398 100644
@@ -39,6 +39,7 @@ properties:
               - qcom,shikra-cci
               - qcom,sm6150-cci
               - qcom,sm6350-cci
+              - qcom,sm8150-cci
               - qcom,sm8250-cci
               - qcom,sm8450-cci
               - qcom,sm8550-cci
@@ -218,6 +219,7 @@ allOf:
           contains:
             enum:
               - qcom,sc7280-cci
+              - qcom,sm8150-cci
               - qcom,sm8250-cci
               - qcom,sm8450-cci
     then:
Signature · 1 line
2.56.0
reviewer Reviewed-by on v3 1/7
#2 lore raw

Re: [PATCH v3 1/7] dt-bindings: i2c: qcom-cci: Document SM8150 compatible

Quoted 25 lines · On 11/6/26 20:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Add qcom,sm8150-cci as a CCI v2 compatible, with qcom,msm8996-cci as the fallback.

---
  Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml | 2 ++
  1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +1 -0
index 1e8def25ec0e..1e7a8efaa398 100644
@@ -39,6 +39,7 @@ properties:
                - qcom,shikra-cci
                - qcom,sm6150-cci
                - qcom,sm6350-cci
+              - qcom,sm8150-cci
                - qcom,sm8250-cci
                - qcom,sm8450-cci
                - qcom,sm8550-cci

Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml allOf: · line 225

Quoted 7 lines
Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +1 -0
@@ -218,6 +219,7 @@ allOf:
            contains:
              enum:
                - qcom,sc7280-cci
+              - qcom,sm8150-cci
                - qcom,sm8250-cci
                - qcom,sm8450-cci
      then:
Signature · 2 lines
Best wishes,
Vladimir
Acked-by on v3 1/7
#3 lore raw

Re: [PATCH v3 1/7] dt-bindings: i2c: qcom-cci: Document SM8150 compatible

In reply to Andrew Gigena
Quoted 8 lines · On Fri, Nov 06, 2026 at 06:35:33PM +0000, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Add qcom,sm8150-cci as a CCI v2 compatible, with qcom,msm8996-cci as the fallback.

Andi, also no driver changes, qcom tree?

#4 lore raw

PATCH v3 2/7 dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS

In reply to Andrew Gigena

Document the Qualcomm SM8150 Camera Subsystem. The IP integrates four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances, with 19 clocks, 8 interrupts, eight IOMMU streams, four interconnect paths and three power domains.

The CSIPHY I/O spaces are not part of the CAMSS container device: each CSIPHY is driven by the dedicated qcom,sm8150-csi2-phy driver, so this binding only describes the VFE and CSID resources. Each CSI input port is described with data lanes starting at 1, as required by the CAMSS PHY mode.

Describe SM8150 in a dedicated schema instead of reusing another SoC's schema.

---
 .../bindings/media/qcom,sm8150-camss.yaml          | 285 +++++++++++++++++++++
 1 file changed, 285 insertions(+)
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +285 -0
new file mode 100644
index 000000000000..371ff1ce0bd2
@@ -0,0 +1,285 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sm8150-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 Camera Subsystem (CAMSS)
+
+maintainers:
+  - Andrew Gigena <[email protected]>
+
+description:
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+  compatible:
+    const: qcom,sm8150-camss
+
+  reg:
+    maxItems: 8
+
+  reg-names:
+    items:
+      - const: vfe0
+      - const: csid0
+      - const: vfe1
+      - const: csid1
+      - const: vfe_lite0
+      - const: csid_lite0
+      - const: vfe_lite1
+      - const: csid_lite1
+
+  clocks:
+    maxItems: 19
+
+  clock-names:
+    items:
+      - const: camnoc_axi
+      - const: cpas_ahb
+      - const: vfe0_axi
+      - const: vfe0
+      - const: vfe0_cphy_rx
+      - const: vfe0_csid
+      - const: vfe1_axi
+      - const: vfe1
+      - const: vfe1_cphy_rx
+      - const: vfe1_csid
+      - const: vfe_lite0
+      - const: vfe_lite0_cphy_rx
+      - const: vfe_lite0_csid
+      - const: vfe_lite1
+      - const: vfe_lite1_cphy_rx
+      - const: vfe_lite1_csid
+      - const: gcc_ahb
+      - const: gcc_axi_hf
+      - const: gcc_axi_sf
+
+  interrupts:
+    maxItems: 8
+
+  interrupt-names:
+    items:
+      - const: vfe0
+      - const: csid0
+      - const: vfe1
+      - const: csid1
+      - const: vfe_lite0
+      - const: csid_lite0
+      - const: vfe_lite1
+      - const: csid_lite1
+
+  interconnects:
+    maxItems: 4
+
+  interconnect-names:
+    items:
+      - const: cam_ahb
+      - const: cam_hf_0_mnoc
+      - const: cam_sf_0_mnoc
+      - const: cam_hf_1_mnoc
+
+  iommus:
+    maxItems: 8
+
+  power-domains:
+    items:
+      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: Titan Top GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+  power-domain-names:
+    items:
+      - const: ife0
+      - const: ife1
+      - const: top
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    description:
+      CSI input ports, one per CSI2 PHY instance.
+
+    patternProperties:
+      "^port@[0-3]$":
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+
+        description:
+          Input port for receiving CSI data from a CSIPHY.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  minimum: 1
+                  maximum: 4
+
+              bus-type:
+                enum:
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+            required:
+              - data-lanes
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - interconnects
+  - interconnect-names
+  - interrupts
+  - interrupt-names
+  - iommus
+  - power-domains
+  - power-domain-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/qcom,gcc-sm8150.h>
+    #include <dt-bindings/clock/qcom,sm8150-camcc.h>
+    #include <dt-bindings/interconnect/qcom,sm8150.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        isp@acaf000 {
+            compatible = "qcom,sm8150-camss";
+
+            reg = <0 0xacaf000 0 0x4000>,
+                  <0 0xacb3000 0 0x1000>,
+                  <0 0xacb6000 0 0x4000>,
+                  <0 0xacba000 0 0x1000>,
+                  <0 0xacc4000 0 0x4000>,
+                  <0 0xacc8000 0 0x1000>,
+                  <0 0xaccb000 0 0x4000>,
+                  <0 0xaccf000 0 0x1000>;
+
+            reg-names = "vfe0",
+                        "csid0",
+                        "vfe1",
+                        "csid1",
+                        "vfe_lite0",
+                        "csid_lite0",
+                        "vfe_lite1",
+                        "csid_lite1";
+
+            clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+                     <&camcc CAM_CC_CPAS_AHB_CLK>,
+                     <&camcc CAM_CC_IFE_0_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_0_CLK>,
+                     <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_1_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_1_CLK>,
+                     <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_1_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+                     <&gcc GCC_CAMERA_AHB_CLK>,
+                     <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&gcc GCC_CAMERA_SF_AXI_CLK>;
+
+            clock-names = "camnoc_axi",
+                          "cpas_ahb",
+                          "vfe0_axi",
+                          "vfe0",
+                          "vfe0_cphy_rx",
+                          "vfe0_csid",
+                          "vfe1_axi",
+                          "vfe1",
+                          "vfe1_cphy_rx",
+                          "vfe1_csid",
+                          "vfe_lite0",
+                          "vfe_lite0_cphy_rx",
+                          "vfe_lite0_csid",
+                          "vfe_lite1",
+                          "vfe_lite1_cphy_rx",
+                          "vfe_lite1_csid",
+                          "gcc_ahb",
+                          "gcc_axi_hf",
+                          "gcc_axi_sf";
+
+            interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+
+            interrupt-names = "vfe0",
+                              "csid0",
+                              "vfe1",
+                              "csid1",
+                              "vfe_lite0",
+                              "csid_lite0",
+                              "vfe_lite1",
+                              "csid_lite1";
+
+            power-domains = <&camcc IFE_0_GDSC>,
+                            <&camcc IFE_1_GDSC>,
+                            <&camcc TITAN_TOP_GDSC>;
+
+            power-domain-names = "ife0",
+                                 "ife1",
+                                 "top";
+
+            interconnects = <&gem_noc MASTER_AMPSS_M0 0
+                             &config_noc SLAVE_CAMERA_CFG 0>,
+                            <&mmss_noc MASTER_CAMNOC_HF0 0
+                             &mc_virt SLAVE_EBI_CH0 0>,
+                            <&mmss_noc MASTER_CAMNOC_SF 0
+                             &mc_virt SLAVE_EBI_CH0 0>,
+                            <&mmss_noc MASTER_CAMNOC_HF1 0
+                             &mc_virt SLAVE_EBI_CH0 0>;
+
+            interconnect-names = "cam_ahb",
+                                 "cam_hf_0_mnoc",
+                                 "cam_sf_0_mnoc",
+                                 "cam_hf_1_mnoc";
+
+            iommus = <&apps_smmu 0x840 0x620>,
+                     <&apps_smmu 0x860 0x620>,
+                     <&apps_smmu 0xa40 0x620>,
+                     <&apps_smmu 0xa60 0x620>,
+                     <&apps_smmu 0xc40 0x620>,
+                     <&apps_smmu 0xc60 0x620>,
+                     <&apps_smmu 0xe40 0x620>,
+                     <&apps_smmu 0xe60 0x620>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+
+                    endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                        data-lanes = <1 2 3 4>;
+                        remote-endpoint = <&csiphy0_out>;
+                    };
+                };
+            };
+        };
+    };
Signature · 1 line
2.56.0
#5 lore raw

Re: [PATCH v3 2/7] dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS

Quoted 48 lines · On 11/6/26 20:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Document the Qualcomm SM8150 Camera Subsystem. The IP integrates four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances, with 19 clocks, 8 interrupts, eight IOMMU streams, four interconnect paths and three power domains.

The CSIPHY I/O spaces are not part of the CAMSS container device: each CSIPHY is driven by the dedicated qcom,sm8150-csi2-phy driver, so this binding only describes the VFE and CSID resources. Each CSI input port is described with data lanes starting at 1, as required by the CAMSS PHY mode.

Describe SM8150 in a dedicated schema instead of reusing another SoC's schema.

---
  .../bindings/media/qcom,sm8150-camss.yaml          | 285 +++++++++++++++++++++
  1 file changed, 285 insertions(+)
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +21 -0
new file mode 100644
index 000000000000..371ff1ce0bd2
@@ -0,0 +1,285 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sm8150-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 Camera Subsystem (CAMSS)
+
+maintainers:
+  - Andrew Gigena <[email protected]>
+
+description:
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+  compatible:
+    const: qcom,sm8150-camss
+
+  reg:
+    maxItems: 8
+

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 31

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+  reg-names:
+    items:
+      - const: vfe0
+      - const: csid0
+      - const: vfe1
+      - const: csid1
+      - const: vfe_lite0
+      - const: csid_lite0
+      - const: vfe_lite1
+      - const: csid_lite1

That's an intermix of names, and you will get a review comment from Krzysztof about it, I stand aside.

Quoted 15 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +15 -0
+
+  clocks:
+    maxItems: 19
+
+  clock-names:
+    items:
+      - const: camnoc_axi
+      - const: cpas_ahb
+      - const: vfe0_axi
+      - const: vfe0
+      - const: vfe0_cphy_rx
+      - const: vfe0_csid
+      - const: vfe1_axi
+      - const: vfe1
+      - const: vfe1_cphy_rx

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 56

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+      - const: vfe1_csid
+      - const: vfe_lite0
+      - const: vfe_lite0_cphy_rx
+      - const: vfe_lite0_csid
+      - const: vfe_lite1
+      - const: vfe_lite1_cphy_rx
+      - const: vfe_lite1_csid
+      - const: gcc_ahb
+      - const: gcc_axi_hf
+      - const: gcc_axi_sf

Drop 'gcc_axi_sf'.

Quoted 4 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +4 -0
+
+  interrupts:
+    maxItems: 8
+

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 70

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+  interrupt-names:
+    items:
+      - const: vfe0
+      - const: csid0
+      - const: vfe1
+      - const: csid1
+      - const: vfe_lite0
+      - const: csid_lite0
+      - const: vfe_lite1
+      - const: csid_lite1

Here too.

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 80

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+
+  interconnects:
+    maxItems: 4
+
+  interconnect-names:
+    items:
+      - const: cam_ahb
+      - const: cam_hf_0_mnoc
+      - const: cam_sf_0_mnoc
+      - const: cam_hf_1_mnoc

Drop 'cam_' prefix and 'cam_sf_0_mnoc' also.

Quoted 36 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +36 -0
+
+  iommus:
+    maxItems: 8
+
+  power-domains:
+    items:
+      - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller.
+      - description: Titan Top GDSC - Titan ISP Block, Global Distributed Switch Controller.
+
+  power-domain-names:
+    items:
+      - const: ife0
+      - const: ife1
+      - const: top
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    description:
+      CSI input ports, one per CSI2 PHY instance.
+
+    patternProperties:
+      "^port@[0-3]$":
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+
+        description:
+          Input port for receiving CSI data from a CSIPHY.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 126

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  minimum: 1
+                  maximum: 4
+
+              bus-type:
+                enum:
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY

Or C-PHY, right?..

In fact you shall drop bus-type from here, because the link between CAMSS and PHY's output is not a CSI-2 bus, it makes it inapplicable.

'bus-type' is needed only between CSIPHY and a sensor connected to it.

Quoted 160 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +159 -0
+
+            required:
+              - data-lanes
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - interconnects
+  - interconnect-names
+  - interrupts
+  - interrupt-names
+  - iommus
+  - power-domains
+  - power-domain-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/qcom,gcc-sm8150.h>
+    #include <dt-bindings/clock/qcom,sm8150-camcc.h>
+    #include <dt-bindings/interconnect/qcom,sm8150.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        isp@acaf000 {
+            compatible = "qcom,sm8150-camss";
+
+            reg = <0 0xacaf000 0 0x4000>,
+                  <0 0xacb3000 0 0x1000>,
+                  <0 0xacb6000 0 0x4000>,
+                  <0 0xacba000 0 0x1000>,
+                  <0 0xacc4000 0 0x4000>,
+                  <0 0xacc8000 0 0x1000>,
+                  <0 0xaccb000 0 0x4000>,
+                  <0 0xaccf000 0 0x1000>;
+
+            reg-names = "vfe0",
+                        "csid0",
+                        "vfe1",
+                        "csid1",
+                        "vfe_lite0",
+                        "csid_lite0",
+                        "vfe_lite1",
+                        "csid_lite1";
+
+            clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+                     <&camcc CAM_CC_CPAS_AHB_CLK>,
+                     <&camcc CAM_CC_IFE_0_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_0_CLK>,
+                     <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_1_AXI_CLK>,
+                     <&camcc CAM_CC_IFE_1_CLK>,
+                     <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_1_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+                     <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+                     <&gcc GCC_CAMERA_AHB_CLK>,
+                     <&gcc GCC_CAMERA_HF_AXI_CLK>,
+                     <&gcc GCC_CAMERA_SF_AXI_CLK>;
+
+            clock-names = "camnoc_axi",
+                          "cpas_ahb",
+                          "vfe0_axi",
+                          "vfe0",
+                          "vfe0_cphy_rx",
+                          "vfe0_csid",
+                          "vfe1_axi",
+                          "vfe1",
+                          "vfe1_cphy_rx",
+                          "vfe1_csid",
+                          "vfe_lite0",
+                          "vfe_lite0_cphy_rx",
+                          "vfe_lite0_csid",
+                          "vfe_lite1",
+                          "vfe_lite1_cphy_rx",
+                          "vfe_lite1_csid",
+                          "gcc_ahb",
+                          "gcc_axi_hf",
+                          "gcc_axi_sf";
+
+            interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
+                         <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+
+            interrupt-names = "vfe0",
+                              "csid0",
+                              "vfe1",
+                              "csid1",
+                              "vfe_lite0",
+                              "csid_lite0",
+                              "vfe_lite1",
+                              "csid_lite1";
+
+            power-domains = <&camcc IFE_0_GDSC>,
+                            <&camcc IFE_1_GDSC>,
+                            <&camcc TITAN_TOP_GDSC>;
+
+            power-domain-names = "ife0",
+                                 "ife1",
+                                 "top";
+
+            interconnects = <&gem_noc MASTER_AMPSS_M0 0
+                             &config_noc SLAVE_CAMERA_CFG 0>,
+                            <&mmss_noc MASTER_CAMNOC_HF0 0
+                             &mc_virt SLAVE_EBI_CH0 0>,
+                            <&mmss_noc MASTER_CAMNOC_SF 0
+                             &mc_virt SLAVE_EBI_CH0 0>,
+                            <&mmss_noc MASTER_CAMNOC_HF1 0
+                             &mc_virt SLAVE_EBI_CH0 0>;
+
+            interconnect-names = "cam_ahb",
+                                 "cam_hf_0_mnoc",
+                                 "cam_sf_0_mnoc",
+                                 "cam_hf_1_mnoc";
+
+            iommus = <&apps_smmu 0x840 0x620>,
+                     <&apps_smmu 0x860 0x620>,
+                     <&apps_smmu 0xa40 0x620>,
+                     <&apps_smmu 0xa60 0x620>,
+                     <&apps_smmu 0xc40 0x620>,
+                     <&apps_smmu 0xc60 0x620>,
+                     <&apps_smmu 0xe40 0x620>,
+                     <&apps_smmu 0xe60 0x620>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port@0 {
+                    reg = <0>;
+
+                    endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                        data-lanes = <1 2 3 4>;
+                        remote-endpoint = <&csiphy0_out>;
+                    };
+                };
+            };
+        };
+    };
Signature · 2 lines
Best wishes,
Vladimir
#6 lore raw

Re: [PATCH v3 2/7] dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS

Hi Vladimir,

Quoted 4 lines

That's an intermix of names, and you will get a review comment from Krzysztof about it, I stand aside.

Here too.

Krzysztof did comment. I kept the vfe0/csid0/vfe1/csid1 order from sc8280xp-camss.yaml in reg-names and interrupt-names, and asked him if he prefers another grouping.

Quoted 1 line

Drop 'gcc_axi_sf'.

Downstream sm8150-camera.dtsi feeds GCC_CAMERA_SF_AXI_CLK to CPAS and x1e80100-camss.yaml has gcc_axi_sf, so it is used. Can you explain why it should go?

Quoted 1 line

Drop 'cam_' prefix and 'cam_sf_0_mnoc' also.

Prefix dropped. I kept sf_0_mnoc because SM8150 has a CAMNOC SF path. Should I remove it too?

Quoted 3 lines

Or C-PHY, right?..
In fact you shall drop bus-type from here, because the link between CAMSS and PHY's output is not a CSI-2 bus, it makes it inapplicable.

Agreed, bus-type is gone from the CAMSS ports. It only exists on the PHY sensor input now.

Best regards,
Andrew

#7 lore raw

Re: [PATCH v3 2/7] dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS

In reply to Andrew Gigena
Quoted 46 lines · Andrew Gigena

Document the Qualcomm SM8150 Camera Subsystem. The IP integrates four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances, with 19 clocks, 8 interrupts, eight IOMMU streams, four interconnect paths and three power domains.

The CSIPHY I/O spaces are not part of the CAMSS container device: each CSIPHY is driven by the dedicated qcom,sm8150-csi2-phy driver, so this binding only describes the VFE and CSID resources. Each CSI input port is described with data lanes starting at 1, as required by the CAMSS PHY mode.

Describe SM8150 in a dedicated schema instead of reusing another SoC's schema.

---
 .../bindings/media/qcom,sm8150-camss.yaml          | 285 +++++++++++++++++++++
 1 file changed, 285 insertions(+)
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +21 -0
new file mode 100644
index 000000000000..371ff1ce0bd2
@@ -0,0 +1,285 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/qcom,sm8150-camss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 Camera Subsystem (CAMSS)
+
+maintainers:
+  - Andrew Gigena <[email protected]>
+
+description:
+  The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms.
+
+properties:
+  compatible:
+    const: qcom,sm8150-camss
+
+  reg:
+    maxItems: 8
+

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml line 31

Quoted 10 lines
Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml new file +10 -0
+  reg-names:
+    items:
+      - const: vfe0
+      - const: csid0
+      - const: vfe1
+      - const: csid1
+      - const: vfe_lite0
+      - const: csid_lite0
+      - const: vfe_lite1
+      - const: csid_lite1

Seems you ignored my last review, so repeating:

From which binding did you copy such order of entries?

Best regards,
Krzysztof

#8 lore raw

Re: [PATCH v3 2/7] dt-bindings: media: qcom,sm8150-camss: Add SM8150 CAMSS

Hi Krzysztof,

First of all, apologies for the late reply and for not following your review advice earlier - that was my mistake, and I should have responded to your v2 comments individually instead of letting them carry over.

I have now gone through your v2 and v3 comments again and addressed most of them locally in a v4:
- reg/reg-names moved to the top, redundant minItems dropped, property order aligned with writing-schema.rst, example cleaned up, ports use patternProperties, bus-type dropped from the CAMSS binding, etc.

Regarding your v3 question about the order of reg/reg-names/interrupt-names (vfe0, csid0, vfe1, csid1, ...): I took it from qcom,sc8280xp-camss.yaml, which uses the same paired VFE/CSID layout and is the closest reference for SM8150. The entries are also in ascending register-address order in the SoC DTS.

If you would prefer a different grouping (e.g. all CSIDs then all VFEs, as in sm8250), I can reorder the binding, DTS and driver resource table. Please let me know which ordering you prefer. I would like to hear your feedback first so I can adjust anything needed before sending v4.

Best regards,
Andrew

#9 lore raw

PATCH v3 3/7 dt-bindings: phy: qcom,sm8150-csi2-phy: Add SM8150 CSI2 PHY

In reply to Andrew Gigena

Document the Qualcomm SM8150 MIPI CSI2 D-PHY. The PHY sits between the CSI2 sensor and the CAMSS CSI decoder and is fed by the CSIPHY "core" and "timer" clocks, the TITAN top power domain and the vdda-phy/vdda-pll supplies.

Unlike the X1E80100 C-PHY/D-PHY combo PHY, SM8150 only has a D-PHY, has no separate AHB clock and no MMCX/MX power domains, so describe it in a dedicated schema.

---
 .../bindings/phy/qcom,sm8150-csi2-phy.yaml         | 163 +++++++++++++++++++++
 1 file changed, 163 insertions(+)
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +163 -0
new file mode 100644
index 000000000000..86d8970d1119
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,sm8150-csi2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 SoC CSI2 PHY
+
+maintainers:
+  - Andrew Gigena <[email protected]>
+
+description:
+  Qualcomm MIPI CSI2 D-PHY. Connects MIPI CSI2 sensors to Qualcomm's Camera
+  CSI decoder (CAMSS).
+
+properties:
+  compatible:
+    const: qcom,sm8150-csi2-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: core
+      - const: timer
+
+  interrupts:
+    maxItems: 1
+
+  operating-points-v2: true
+
+  opp-table:
+    type: object
+
+  power-domains:
+    maxItems: 1
+
+  power-domain-names:
+    items:
+      - const: top
+
+  vdda-phy-supply:
+    description: Phandle to a 0.88V regulator supply to a PHY.
+
+  vdda-pll-supply:
+    description: Phandle to a 1.2V regulator supply to a PHY PLL.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Sensor input. A single sensor is described by a single endpoint with
+          one to four data lanes, numbered 1-4. The clock lane is position 0.
+
+        properties:
+          endpoint:
+            $ref: /schemas/media/video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+                default: 4
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  minimum: 1
+                  maximum: 4
+
+            required:
+              - data-lanes
+              - remote-endpoint
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output to the CAMSS CSI input port.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - operating-points-v2
+  - power-domains
+  - power-domain-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,sm8150-camcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    phy@ac65000 {
+        compatible = "qcom,sm8150-csi2-phy";
+        reg = <0xac65000 0x1000>;
+
+        clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
+                 <&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+        clock-names = "core",
+                      "timer";
+
+        interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+
+        operating-points-v2 = <&csiphy0_opp_table>;
+
+        power-domains = <&camcc TITAN_TOP_GDSC>;
+        power-domain-names = "top";
+
+        vdda-phy-supply = <&vreg_l5a_0p88>;
+        vdda-pll-supply = <&vreg_l12a_1p2>;
+
+        csiphy0_opp_table: opp-table {
+            compatible = "operating-points-v2";
+
+            opp-400000000 {
+                opp-hz = /bits/ 64 <400000000>;
+            };
+        };
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                endpoint {
+                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                    data-lanes = <1 2 3 4>;
+                    remote-endpoint = <&sensor_out>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+
+                endpoint {
+                    remote-endpoint = <&camss_csi0_in>;
+                };
+            };
+        };
+    };
Signature · 1 line
2.56.0
#10 lore raw

Re: [PATCH v3 3/7] dt-bindings: phy: qcom,sm8150-csi2-phy: Add SM8150 CSI2 PHY

Hi Andrew,

Quoted 11 lines · On 11/6/26 20:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Document the Qualcomm SM8150 MIPI CSI2 D-PHY. The PHY sits between the CSI2 sensor and the CAMSS CSI decoder and is fed by the CSIPHY "core" and "timer" clocks, the TITAN top power domain and the vdda-phy/vdda-pll supplies.

Unlike the X1E80100 C-PHY/D-PHY combo PHY, SM8150 only has a D-PHY, has no separate AHB clock and no MMCX/MX power domains, so describe it in a dedicated schema.

very much appreciated for changing the CAMSS phys to this format.

Please double check if SM8150 CSIPHY v1.1 is capable of C-PHY:

* https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.1.r1-16600-sm8150.0/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c#L239-256

D-PHY combo mode is also supported on the CSIPHY apparently.

Likely these features are supported on SM8150.

Quoted 45 lines
---
  .../bindings/phy/qcom,sm8150-csi2-phy.yaml         | 163 +++++++++++++++++++++
  1 file changed, 163 insertions(+)
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +34 -0
new file mode 100644
index 000000000000..86d8970d1119
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/qcom,sm8150-csi2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM8150 SoC CSI2 PHY
+
+maintainers:
+  - Andrew Gigena <[email protected]>
+
+description:
+  Qualcomm MIPI CSI2 D-PHY. Connects MIPI CSI2 sensors to Qualcomm's Camera
+  CSI decoder (CAMSS).
+
+properties:
+  compatible:
+    const: qcom,sm8150-csi2-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: core
+      - const: timer
+
+  interrupts:
+    maxItems: 1
+
+  operating-points-v2: true

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 44

Quoted 10 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +10 -0
+
+  opp-table:
+    type: object
+
+  power-domains:
+    maxItems: 1
+
+  power-domain-names:
+    items:
+      - const: top

In downstream camcc-sm8150.c, PLL0 is on MX, and PLL0 supplies CSIPHY clocks. I believe MX shall be added to the list of 'power-domains'.

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 50

Quoted 6 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +6 -0
+
+  vdda-phy-supply:
+    description: Phandle to a 0.88V regulator supply to a PHY.
+
+  vdda-pll-supply:
+    description: Phandle to a 1.2V regulator supply to a PHY PLL.

Still it would be preferred to get 'vdda-0p9-supply' and 'vdda-1p2-supply' properties.

Quoted 4 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +4 -0
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 64

Quoted 10 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +10 -0
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Sensor input. A single sensor is described by a single endpoint with
+          one to four data lanes, numbered 1-4. The clock lane is position 0.
+
+        properties:
+          endpoint:

Back to downstream

* https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.1.r1-16600-sm8150.0/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c#L239-256

D-PHY combo mode is also supported on the SM8150 CSIPHY apparently, it shall be reflected in a way that two endpoints could be present.

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 72

Quoted 8 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +8 -0
+            $ref: /schemas/media/video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+                default: 4

Please double check if SM8150 CSIPHY v1.1 is capable of C-PHY:

* https://git.codelinaro.org/clo/la/kernel/msm-4.14/-/blob/LA.UM.8.1.r1-16600-sm8150.0/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c#L239-256

Quoted 82 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +81 -0
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:
+                  minimum: 1
+                  maximum: 4
+
+            required:
+              - data-lanes
+              - remote-endpoint
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output to the CAMSS CSI input port.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - operating-points-v2
+  - power-domains
+  - power-domain-names
+  - vdda-phy-supply
+  - vdda-pll-supply
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,sm8150-camcc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    phy@ac65000 {
+        compatible = "qcom,sm8150-csi2-phy";
+        reg = <0xac65000 0x1000>;
+
+        clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
+                 <&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+        clock-names = "core",
+                      "timer";
+
+        interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+
+        operating-points-v2 = <&csiphy0_opp_table>;
+
+        power-domains = <&camcc TITAN_TOP_GDSC>;
+        power-domain-names = "top";
+
+        vdda-phy-supply = <&vreg_l5a_0p88>;
+        vdda-pll-supply = <&vreg_l12a_1p2>;
+
+        csiphy0_opp_table: opp-table {
+            compatible = "operating-points-v2";
+
+            opp-400000000 {
+                opp-hz = /bits/ 64 <400000000>;
+            };
+        };
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                endpoint {
+                    bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                    data-lanes = <1 2 3 4>;
+                    remote-endpoint = <&sensor_out>;
+                };
+            };

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 163

Quoted 10 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +10 -0
+
+            port@1 {
+                reg = <1>;
+
+                endpoint {
+                    remote-endpoint = <&camss_csi0_in>;
+                };
+            };
+        };
+    };

In general the change looks good, thank you, but likely it can be embedded into the scheme for X1E.

Signature · 2 lines
Best wishes,
Vladimir
#11 lore raw

Re: [PATCH v3 3/7] dt-bindings: phy: qcom,sm8150-csi2-phy: Add SM8150 CSI2 PHY

Hi Vladimir,

Thanks for the review, replies below.

Quoted 1 line

Please double check if SM8150 CSIPHY v1.1 is capable of C-PHY:

The hardware can do combo mode, but the driver only implements D-PHY and returns -EOPNOTSUPP for C-PHY, so the binding stays D-PHY. Would you like it documented as "not yet supported" anyway?

Quoted 2 lines

D-PHY combo mode is also supported on the SM8150 CSIPHY apparently, it shall be reflected in a way that two endpoints could be present.

Split mode is described in the binding, but the driver rejects it, so it cannot be used today. Is it fine to keep it out until the driver supports it?

Quoted 2 lines

In downstream camcc-sm8150.c, PLL0 is on MX, and PLL0 supplies CSIPHY clocks. I believe MX shall be added to the list of 'power-domains'.

You are right that PLL0 uses the MX corner in camcc, but that corner is internal to the clock controller, not a power domain of the CSIPHY. The PHY only consumes the top GDSC; SM8150 uses legacy GDSCs, while on X1E MX is a real power domain attached by the PHY driver.

Quoted 2 lines

Still it would be preferred to get 'vdda-0p9-supply' and 'vdda-1p2-supply' properties.

Renamed in the binding on v4, the driver and the DTS, matching the X1E naming.

Quoted 2 lines

In general the change looks good, thank you, but likely it can be embedded into the scheme for X1E.

Clocks, register offset, power domains, lane table and timer all differ, so folding it in would need if/then blocks for almost every property. Would you still prefer that, or is a separate schema acceptable?

Best regards,
Andrew

maintainer
#12 lore raw

Re: [PATCH v3 3/7] dt-bindings: phy: qcom,sm8150-csi2-phy: Add SM8150 CSI2 PHY

In reply to Andrew Gigena

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 50

Quoted 5 lines · On 06/11/2026 18:35, Andrew Gigena via B4 Relay wrote:
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +5 -0
+  vdda-phy-supply:
+    description: Phandle to a 0.88V regulator supply to a PHY.
+
+  vdda-pll-supply:
+    description: Phandle to a 1.2V regulator supply to a PHY PLL.

Wrong names.

Quoted 26 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +26 -0
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description:
+          Sensor input. A single sensor is described by a single endpoint with
+          one to four data lanes, numbered 1-4. The clock lane is position 0.
+
+        properties:
+          endpoint:
+            $ref: /schemas/media/video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+                default: 4
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+                items:

Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml line 87

Quoted 10 lines
Documentation/devicetree/bindings/phy/qcom,sm8150-csi2-phy.yaml new file +10 -0
+                  minimum: 1
+                  maximum: 4
+
+            required:
+              - data-lanes
+              - remote-endpoint
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output to the CAMSS CSI input port.

missing split-mode base case definition.

---
bod

#13 lore raw

PATCH v3 4/7 media: qcom: camss: Match VFE lite clocks by name prefix

In reply to Andrew Gigena

vfe_match_clock_names() builds the expected lite clock name from vfe->id, but vfe->id is the index of the VFE in the resources array. On SoCs where the lite VFEs come after the full VFEs, the generated name is vfe_lite2, vfe_lite3, ... and never matches the actual vfe_lite0/vfe_lite1 clocks, so their rates are never programmed.

Restrict the new prefix match to numbered "vfe_liteN" clocks (digit check) to avoid matching aux clocks, leaving the pre-existing vfe_lite_name and bare "vfe_lite" matches unchanged.

This affects SM8150, SC7280 and SC8280XP. On a Pixel 4 (SM8150), streaming through VFE-lite0 left cam_cc_ife_lite_0_clk at 19.2 MHz and failed with "VFE reset timeout".

---
 drivers/media/platform/qcom/camss/camss-vfe.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/media/platform/qcom/camss/camss-vfe.c +6 -0
index 2680a9914765..29e04d097116 100644
@@ -9,6 +9,7 @@
  */
 #include <linux/clk.h>
 #include <linux/completion.h>
+#include <linux/ctype.h>
 #include <linux/interrupt.h>
 #include <linux/iommu.h>
 #include <linux/mutex.h>
@@ -346,6 +347,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 	case CAMSS_6350:
 	case CAMSS_7280:
 	case CAMSS_8x96:
+	case CAMSS_8150:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_8300:
@@ -914,6 +916,9 @@ static int vfe_match_clock_names(struct vfe_device *vfe,
 	return (!strcmp(clock->name, vfe_name) ||
 		!strcmp(clock->name, vfe_lite_name) ||
 		!strcmp(clock->name, "vfe_lite") ||
+		(vfe->res->is_lite &&
+		 !strncmp(clock->name, "vfe_lite", 8) &&
+		 isdigit((unsigned char)clock->name[8])) ||
 		!strcmp(clock->name, "camnoc_axi") ||
 		!strcmp(clock->name, "camnoc_rt_axi"));
 }
@@ -2006,6 +2011,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
 	case CAMSS_6150:
 	case CAMSS_6350:
 	case CAMSS_7280:
+	case CAMSS_8150:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_8300:
Signature · 1 line
2.56.0
#14 lore raw

Re: [PATCH v3 4/7] media: qcom: camss: Match VFE lite clocks by name prefix

Thank you for your contribution! Sashiko AI review found 3 potential issues to consider: - [High] media: qcom: camss: undeclared CAMSS_8150 in camss-vfe.c breaks build - [Low] media: qcom: camss…

Thank you for your contribution! Sashiko AI review found 3 potential issues to consider:
- [High] media: qcom: camss: undeclared CAMSS_8150 in camss-vfe.c breaks build
- [Low] media: qcom: camss: missing Fixes trailer for vfe_match_clock_names() bug
- [Low] media: camss: unguarded lite clock checks in vfe_match_clock_names()
--

commit 304a59495a7a3eb87dc5d254ba4381a9abf0957b
Author: Andrew Gigena <[email protected]>

Quoted 12 lines

media: qcom: camss: Match VFE lite clocks by name prefix

vfe_match_clock_names() builds the expected lite clock name from vfe->id, but vfe->id is the index of the VFE in the resources array. On SoCs where the lite VFEs come after the full VFEs, the generated name is vfe_lite2, vfe_lite3, ... and never matches the actual vfe_lite0/vfe_lite1 clocks, so their rates are never programmed.

Restrict the new prefix match to numbered "vfe_liteN" clocks (digit check) to avoid matching aux clocks, leaving the pre-existing vfe_lite_name and bare "vfe_lite" matches unchanged.

Quoted 5 lines

This affects SM8150, SC7280 and SC8280XP. On a Pixel 4 (SM8150), streaming through VFE-lite0 left cam_cc_ife_lite_0_clk at 19.2 MHz and failed with "VFE reset timeout".

[Severity: Low]
This fixes VFE lite clock matching on existing platforms such as SC7280 and SC8280XP. Should this include:

Fixes bcd2adfef23a ("media: qcom: camss: Allow clocks vfeN vfe_liteN or vfe_lite")
Quoted 4 lines
drivers/media/platform/qcom/camss/camss-vfe.c +0 -0
index 2680a9914765f..29e04d0971163 100644

[ ... ]

drivers/media/platform/qcom/camss/camss-vfe.c static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, · line 353

Quoted 8 lines
drivers/media/platform/qcom/camss/camss-vfe.c +1 -0
@@ -346,6 +347,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 	case CAMSS_6350:
 	case CAMSS_7280:
 	case CAMSS_8x96:
+	case CAMSS_8150:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_8300:

[Severity: High]
Does adding case CAMSS_8150 here and in vfe_bpl_align_rdi() break the build at this commit? CAMSS_8150 is not declared in enum camss_version in drivers/media/platform/qcom/camss/camss.h until the following commit "media:
qcom: camss: Add support for SM8150", where these two hunks belong.

drivers/media/platform/qcom/camss/camss-vfe.c static int vfe_match_clock_names(struct vfe_device *vfe, · line 924

Quoted 10 lines
drivers/media/platform/qcom/camss/camss-vfe.c +3 -0
@@ -914,6 +916,9 @@ static int vfe_match_clock_names(struct vfe_device *vfe,
 	return (!strcmp(clock->name, vfe_name) ||
 		!strcmp(clock->name, vfe_lite_name) ||
 		!strcmp(clock->name, "vfe_lite") ||
+		(vfe->res->is_lite &&
+		 !strncmp(clock->name, "vfe_lite", 8) &&
+		 isdigit((unsigned char)clock->name[8])) ||
 		!strcmp(clock->name, "camnoc_axi") ||
 		!strcmp(clock->name, "camnoc_rt_axi"));
 }

[Severity: Low]
As reported by Bryan O'Donoghue on v2 [1], should all lite clock checks in vfe_match_clock_names() be gated on vfe->res->is_lite? Only lite VFE resource entries use vfe_lite or vfe_liteN clocks, and once gated on vfe->res->is_lite, the vfe_lite_name buffer and its snprintf() call are already covered by the numbered "vfe_lite" prefix check and can be dropped.

[1] https://lore.kernel.org/r/[email protected]

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-sm8150-v7.4-rc1-camss-v3-0-0103e8a0bbcd@andrewgigena.dev?part=4
maintainer
#15 lore raw

Re: [PATCH v3 4/7] media: qcom: camss: Match VFE lite clocks by name prefix

In reply to Andrew Gigena
Quoted 19 lines · On 06/11/2026 18:35, Andrew Gigena via B4 Relay wrote:
drivers/media/platform/qcom/camss/camss-vfe.c +4 -0
@@ -346,6 +347,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
  	case CAMSS_6350:
  	case CAMSS_7280:
  	case CAMSS_8x96:
+	case CAMSS_8150:
  	case CAMSS_8250:
  	case CAMSS_8280XP:
  	case CAMSS_8300:
@@ -914,6 +916,9 @@ static int vfe_match_clock_names(struct vfe_device *vfe,
  	return (!strcmp(clock->name, vfe_name) ||
  		!strcmp(clock->name, vfe_lite_name) ||
  		!strcmp(clock->name, "vfe_lite") ||
+		(vfe->res->is_lite &&
+		 !strncmp(clock->name, "vfe_lite", 8) &&
+		 isdigit((unsigned char)clock->name[8])) ||
  		!strcmp(clock->name, "camnoc_axi") ||
  		!strcmp(clock->name, "camnoc_rt_axi"));
  }

drivers/media/platform/qcom/camss/camss-vfe.c static int vfe_bpl_align_rdi(struct vfe_device *vfe) · line 2017

Quoted 7 lines
drivers/media/platform/qcom/camss/camss-vfe.c +1 -0
@@ -2006,6 +2011,7 @@ static int vfe_bpl_align_rdi(struct vfe_device *vfe)
  	case CAMSS_6150:
  	case CAMSS_6350:
  	case CAMSS_7280:
+	case CAMSS_8150:
  	case CAMSS_8250:
  	case CAMSS_8280XP:
  	case CAMSS_8300:

This patch mangles the thing the patch title does with switch additions for src_pad_code and bpl_align_rdi.

Please separate.

---
bod

#16 lore raw

PATCH v3 5/7 media: qcom: camss: Add support for SM8150

In reply to Andrew Gigena

Add CAMSS platform data for the Qualcomm SM8150 SoC. The camera subsystem contains four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances.

The hardware reuses the existing 3-phase 1.0 CSIPHY, Gen2 CSID and VFE 17x implementations; the CSIPHY uses the SC8280XP lane register layout. Add CAMSS_8150 to the version enum and to the shared code paths, then add the per-block clock, regulator, power domain, interrupt and interconnect resources.

The CSIPHY resources are reduced to id/hw_ops/formats only; clocks, regulators, registers and interrupts are owned by the dedicated CSI2 PHY driver.

---
 .../platform/qcom/camss/camss-csiphy-3ph-1-0.c     |   2 +
 drivers/media/platform/qcom/camss/camss.c          | 231 +++++++++++++++++++++
 drivers/media/platform/qcom/camss/camss.h          |   1 +
 3 files changed, 234 insertions(+)
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +2 -0
index dac8d2ecf799..5e7c2e67ae88 100644
@@ -1133,6 +1133,7 @@ static bool csiphy_is_gen2(u32 version)
 	case CAMSS_6150:
 	case CAMSS_6350:
 	case CAMSS_7280:
+	case CAMSS_8150:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_8300:
@@ -1235,6 +1236,7 @@ static int csiphy_init(struct csiphy_device *csiphy)
 		regs->lane_regs = &lane_regs_sm8250[0];
 		regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
 		break;
+	case CAMSS_8150:
 	case CAMSS_8280XP:
 		regs->lane_regs = &lane_regs_sc8280xp[0];
 		regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp);
drivers/media/platform/qcom/camss/camss.c +231 -0

249 lines not on this page · raw message

drivers/media/platform/qcom/camss/camss.h +1 -0
index 7dc2fd9f03e0..74d8cc2921be 100644
@@ -89,6 +89,7 @@ enum camss_version {
 	CAMSS_8x39,
 	CAMSS_8x53,
 	CAMSS_8x96,
+	CAMSS_8150,
 	CAMSS_8250,
 	CAMSS_8280XP,
 	CAMSS_8300,
Signature · 1 line
2.56.0
#17 lore raw

Re: [PATCH v3 5/7] media: qcom: camss: Add support for SM8150

Thank you for your contribution! Sashiko AI review found 2 potential issues to consider: - [Medium] media: qcom: camss: NULL deref and dead code in csiphy_res_sm8150 - [Medium] media: qcom: camss…

Thank you for your contribution! Sashiko AI review found 2 potential issues to consider:
- [Medium] media: qcom: camss: NULL deref and dead code in csiphy_res_sm8150
- [Medium] media: qcom: camss: CAMSS_8150 used in parent commit before definition
--

commit debc7cc0585d6af1f184ab66cdb3fb1863bba5d6
Author: Andrew Gigena <[email protected]>

media: qcom: camss: Add support for SM8150

This commit adds CAMSS platform data, resource definitions, and version handling to support the Qualcomm SM8150 SoC.

Quoted 27 lines
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +2 -0
index dac8d2ecf7995..5e7c2e67ae887 100644
@@ -1133,6 +1133,7 @@ static bool csiphy_is_gen2(u32 version)
 	case CAMSS_6150:
 	case CAMSS_6350:
 	case CAMSS_7280:
+	case CAMSS_8150:
 	case CAMSS_8250:
 	case CAMSS_8280XP:
 	case CAMSS_8300:
@@ -1235,6 +1236,7 @@ static int csiphy_init(struct csiphy_device *csiphy)
 		regs->lane_regs = &lane_regs_sm8250[0];
 		regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
 		break;
+	case CAMSS_8150:
 	case CAMSS_8280XP:
 		regs->lane_regs = &lane_regs_sc8280xp[0];
 		regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp);
drivers/media/platform/qcom/camss/camss.c +0 -0
index c54185c93a8a9..da4d2213fd3dc 100644
@@ -1940,6 +1940,223 @@ static const struct resources_icc icc_res_sm6350[] = {
 	},
 };

drivers/media/platform/qcom/camss/camss.c static const struct resources_icc icc_res_sm6350[] = { · line 1951

Quoted 10 lines
drivers/media/platform/qcom/camss/camss.c +9 -0
 
+static const struct camss_subdev_resources csiphy_res_sm8150[] = {
+	/* CSIPHY0 - clocks/regs/supplies owned by PHY driver */
+	{
+		.csiphy = {
+			.id = 0,
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},

[Severity: Medium]
Can csiphy_res_sm8150 cause a NULL pointer dereference in platform_get_resource_byname() when no remote PHY endpoints are connected in Device Tree?

camss_detect_legacy_phy() defaults camss->legacy_phy to true and only clears it when it finds an endpoint whose remote parent node is named "phy". If the CSIPHY ports are omitted in DT, camss_init_subdevices() takes the legacy path and calls msm_csiphy_subdev_init_legacy(), which passes res->reg[0] (NULL here) to devm_platform_ioremap_resource_byname().

Conversely, when camss->legacy_phy is false, msm_csiphy_subdev_init() and csiphy_v4l2_ops never use csiphy->res->hw_ops, making .hw_ops = &csiphy_ops_3ph_1_0 and the CAMSS_8150 additions in camss-csiphy-3ph-1-0.c unreachable dead code.

[ ... ]

drivers/media/platform/qcom/camss/camss.h enum camss_version { · line 95

Quoted 12 lines
drivers/media/platform/qcom/camss/camss.h +1 -0
index 7dc2fd9f03e0d..74d8cc2921be9 100644
@@ -89,6 +89,7 @@ enum camss_version {
 	CAMSS_8x39,
 	CAMSS_8x53,
 	CAMSS_8x96,
+	CAMSS_8150,
 	CAMSS_8250,
 	CAMSS_8280XP,
 	CAMSS_8300,

[Severity: Medium]
Does defining CAMSS_8150 here break the build on the preceding commit "media: qcom: camss: Match VFE lite clocks by name prefix"?

That earlier commit already adds case CAMSS_8150: in vfe_src_pad_code() and vfe_bpl_align_rdi() in drivers/media/platform/qcom/camss/camss-vfe.c before CAMSS_8150 is added to enum camss_version, causing an undeclared identifier error during git bisect. Moving those two switch cases into this patch keeps both commits buildable.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-sm8150-v7.4-rc1-camss-v3-0-0103e8a0bbcd@andrewgigena.dev?part=5
#18 lore raw

Re: [PATCH v3 5/7] media: qcom: camss: Add support for SM8150

In reply to Andrew Gigena
Quoted 48 lines · On 11/6/26 20:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Add CAMSS platform data for the Qualcomm SM8150 SoC. The camera subsystem contains four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances.

The hardware reuses the existing 3-phase 1.0 CSIPHY, Gen2 CSID and VFE 17x implementations; the CSIPHY uses the SC8280XP lane register layout. Add CAMSS_8150 to the version enum and to the shared code paths, then add the per-block clock, regulator, power domain, interrupt and interconnect resources.

The CSIPHY resources are reduced to id/hw_ops/formats only; clocks, regulators, registers and interrupts are owned by the dedicated CSI2 PHY driver.

---
  .../platform/qcom/camss/camss-csiphy-3ph-1-0.c     |   2 +
  drivers/media/platform/qcom/camss/camss.c          | 231 +++++++++++++++++++++
  drivers/media/platform/qcom/camss/camss.h          |   1 +
  3 files changed, 234 insertions(+)
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +2 -0
index dac8d2ecf799..5e7c2e67ae88 100644
@@ -1133,6 +1133,7 @@ static bool csiphy_is_gen2(u32 version)
  	case CAMSS_6150:
  	case CAMSS_6350:
  	case CAMSS_7280:
+	case CAMSS_8150:
  	case CAMSS_8250:
  	case CAMSS_8280XP:
  	case CAMSS_8300:
@@ -1235,6 +1236,7 @@ static int csiphy_init(struct csiphy_device *csiphy)
  		regs->lane_regs = &lane_regs_sm8250[0];
  		regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8250);
  		break;
+	case CAMSS_8150:
  	case CAMSS_8280XP:
  		regs->lane_regs = &lane_regs_sc8280xp[0];
  		regs->lane_array_size = ARRAY_SIZE(lane_regs_sc8280xp);
drivers/media/platform/qcom/camss/camss.c +0 -0
index c54185c93a8a..da4d2213fd3d 100644

drivers/media/platform/qcom/camss/camss.c static const struct resources_icc icc_res_sm6350[] = { · line 1943

Quoted 4 lines
drivers/media/platform/qcom/camss/camss.c +1 -0
@@ -1940,6 +1940,223 @@ static const struct resources_icc icc_res_sm6350[] = {
  	},
  };
 
+static const struct camss_subdev_resources csiphy_res_sm8150[] = {

Drop csiphy_res_sm8150[], and pull this:

* https://lore.kernel.org/all/[email protected]/

Quoted 260 lines
drivers/media/platform/qcom/camss/camss.c +230 -0
+	/* CSIPHY0 - clocks/regs/supplies owned by PHY driver */
+	{
+		.csiphy = {
+			.id = 0,
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY1 - clocks/regs/supplies owned by PHY driver */
+	{
+		.csiphy = {
+			.id = 1,
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY2 - clocks/regs/supplies owned by PHY driver */
+	{
+		.csiphy = {
+			.id = 2,
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY3 - clocks/regs/supplies owned by PHY driver */
+	{
+		.csiphy = {
+			.id = 3,
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_sm8150[] = {
+	/* CSID0 */
+	{
+		.regulators = {},
+		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid0" },
+		.interrupt = { "csid0" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = {},
+		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid1" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE0 */
+	{
+		.regulators = {},
+		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid_lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE1 */
+	{
+		.regulators = {},
+		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid_lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	}
+};
+
+/*
+ * cpas_ahb is left at the CAMCC default 80 MHz; it is not matched by
+ * vfe_match_clock_names(). The VFE/VFE-Lite rates are set from the
+ * remaining clock-rate tables.
+ */
+static const struct camss_subdev_resources vfe_res_sm8150[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi",
+			   "vfe0", "vfe0_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 0 },
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 847000000, 950000000 },
+				{ 0 }, },
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi",
+			   "vfe1", "vfe1_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 0 },
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 847000000, 950000000 },
+				{ 0 }, },
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_0 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 0 },
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000 }, },
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_1 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 0 },
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000 }, },
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	}
+};
+
+static const struct resources_icc icc_res_sm8150[] = {
+	{
+		.name = "cam_ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "cam_hf_0_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+	{
+		.name = "cam_hf_1_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+	{
+		.name = "cam_sf_0_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
  static const struct camss_subdev_resources csiphy_res_8250[] = {
  	/* CSIPHY0 */
  	{
@@ -5725,6 +5942,19 @@ static const struct camss_resources sm6350_resources = {
  	.vfe_num = ARRAY_SIZE(vfe_res_sm6350),
  };
 
+static const struct camss_resources sm8150_resources = {
+	.version = CAMSS_8150,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_sm8150,
+	.csid_res = csid_res_sm8150,
+	.vfe_res = vfe_res_sm8150,
+	.icc_res = icc_res_sm8150,
+	.icc_path_num = ARRAY_SIZE(icc_res_sm8150),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_sm8150),
+	.csid_num = ARRAY_SIZE(csid_res_sm8150),
+	.vfe_num = ARRAY_SIZE(vfe_res_sm8150),
+};
+
  static const struct camss_resources sm8250_resources = {
  	.version = CAMSS_8250,
  	.pd_name = "top",
@@ -5824,6 +6054,7 @@ static const struct of_device_id camss_dt_match[] = {
  	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
  	{ .compatible = "qcom,sm6150-camss", .data = &sm6150_resources },
  	{ .compatible = "qcom,sm6350-camss", .data = &sm6350_resources },
+	{ .compatible = "qcom,sm8150-camss", .data = &sm8150_resources },
  	{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
  	{ .compatible = "qcom,sm8550-camss", .data = &sm8550_resources },
  	{ .compatible = "qcom,sm8650-camss", .data = &sm8650_resources },
drivers/media/platform/qcom/camss/camss.h +1 -0
index 7dc2fd9f03e0..74d8cc2921be 100644
@@ -89,6 +89,7 @@ enum camss_version {
  	CAMSS_8x39,
  	CAMSS_8x53,
  	CAMSS_8x96,
+	CAMSS_8150,
  	CAMSS_8250,
  	CAMSS_8280XP,
  	CAMSS_8300,
Signature · 2 lines
Best wishes,
Vladimir
#19 lore raw

Re: [PATCH v3 5/7] media: qcom: camss: Add support for SM8150

Hi Vladimir,

Quoted 3 lines

Drop csiphy_res_sm8150[], and pull this:

* https://lore.kernel.org/all/[email protected]/

Done in v4: csiphy_res_sm8150[] is gone and sm8150_resources.csiphy_res is NULL, so SM8150 goes through the PHY-API path and clocks, regulators, registers and interrupts are owned by the dedicated CSI2 PHY driver.

I folded your change into this patch instead of carrying it as a separate commit, and credited you with

ahead of my own Signed-off-by, plus a line in the changelog saying the fallback comes from your patch. If you would rather have it as a separate commit, or want the attribution worded differently, tell me and I will adjust before resending. I am not enterely sure if this is the correct way to cherry-pick commits since this is my first kernel contribution.

Best regards,
Andrew

maintainer
#20 lore raw

Re: [PATCH v3 5/7] media: qcom: camss: Add support for SM8150

In reply to Andrew Gigena
Quoted 12 lines · On 06/11/2026 18:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Add CAMSS platform data for the Qualcomm SM8150 SoC. The camera subsystem contains four CSIPHY, four CSID (two full and two lite), two VFE and two VFE-Lite instances.

The hardware reuses the existing 3-phase 1.0 CSIPHY, Gen2 CSID and VFE 17x implementations; the CSIPHY uses the SC8280XP lane register layout. Add CAMSS_8150 to the version enum and to the shared code paths, then add the per-block clock, regulator, power domain, interrupt and interconnect resources.

Quoted 5 lines

The CSIPHY resources are reduced to id/hw_ops/formats only; clocks, regulators, registers and interrupts are owned by the dedicated CSI2 PHY driver.

You could add your bpl and src_pad stuff in here.

---
bod

#21 lore raw

PATCH v3 6/7 phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

In reply to Andrew Gigena

Add SM8150 platform data to the CSI2 DPHY driver so that SM8150 can use the dedicated PHY driver instead of the CAMSS-integrated CSIPHY.

The SM8150 CSIPHY uses the SC8280XP lane register layout, as already used by the CAMSS driver, so reuse that table, dropping the DNP entries, which the new PHY driver does not program. The PHY is fed by the "core" and "timer" clocks, the vdda-phy and vdda-pll supplies, and the Titan top power domain, which is not scaled.

The timer clock is pinned to 300 MHz via a new timer_rate_hz soc field (SM8150 timer only supports 19.2/300 MHz). SM8150 is ordered before X1E80100 as it predates it (7 nm vs 4 nm). A detach of the platform-attached single power domain is done before attaching by name, so single-domain SoCs do not fail with -EEXIST.

---
 drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 97 ++++++++++++++++++++++
 drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c     | 16 +++-
 drivers/phy/qualcomm/phy-qcom-mipi-csi2.h          |  4 +
 3 files changed, 116 insertions(+), 1 deletion(-)
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +97 -0
index 966d79c98f9b..b8b6589cee35 100644
@@ -45,6 +45,73 @@
 #define CSIPHY_SETTLE_CNT_LOWER_BYTE			2
 #define CSIPHY_SKEW_CAL					7
 
+/* 7nm 2PH v 1.1 2p5Gbps 4 lane DPHY mode */
+static const struct
+mipi_csi2phy_lane_regs lane_regs_sm8150[] = {
+	{.reg_addr = 0x0004, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x002c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0034, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x001c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0014, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x003c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0000, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0008, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0010, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0038, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0060, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0064, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0704, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x072c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0734, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x071c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0714, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0728, .reg_data = 0x04, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x073c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0700, .reg_data = 0x80, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0708, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x070c, .reg_data = 0xa5, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0710, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0738, .reg_data = 0x1f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0760, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0764, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0204, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x022c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0234, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x021c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0214, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x023c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0200, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0208, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0210, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0238, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0260, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0264, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0404, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x042c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0434, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x041c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0414, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x043c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0400, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0408, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0410, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0438, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0460, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0464, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0604, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x062c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0634, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x061c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0614, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x063c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0600, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0608, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0610, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0638, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0660, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0664, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+};
+
 /* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */
 static const struct
 mipi_csi2phy_lane_regs lane_regs_x1e80100[] = {
@@ -352,6 +419,36 @@ static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = {
 	.lanes_disable = phy_qcom_mipi_csi2_lanes_disable,
 };
 
+static const char * const sm8150_clks[] = {
+	"core",
+	"timer"
+};
+
+static const char * const sm8150_supplies[] = {
+	"vdda-phy",
+	"vdda-pll"
+};
+
+static struct mipi_csi2_genpd sm8150_genpds[] = {
+	{ .name = "top", .scaled = false },
+};
+
+const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_sm8150 = {
+	.ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
+	.reg_info = {
+		.init_seq = lane_regs_sm8150,
+		.lane_array_size = ARRAY_SIZE(lane_regs_sm8150),
+		.common_regs_offset = 0x800,
+	},
+	.supply_names = (const char **)sm8150_supplies,
+	.num_supplies = ARRAY_SIZE(sm8150_supplies),
+	.clk_names = (const char **)sm8150_clks,
+	.num_clk = ARRAY_SIZE(sm8150_clks),
+	.timer_rate_hz = 300000000,
+	.genpds = sm8150_genpds,
+	.num_genpds = ARRAY_SIZE(sm8150_genpds),
+};
+
 static const char * const x1e_clks[] = {
 	"core",
 	"timer",
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +15 -1
index c0a4fa20eaf0..3a45b8766311 100644
@@ -68,7 +68,11 @@ phy_qcom_mipi_csi2_set_clock_rates(struct mipi_csi2phy_device *csi2phy,
 		goto unset_opp_rate;
 	}
 
-	timer_rate = clk_round_rate(csi2phy->timer_clk, link_freq / 4);
+	if (csi2phy->soc_cfg->timer_rate_hz)
+		timer_rate = clk_round_rate(csi2phy->timer_clk,
+					    csi2phy->soc_cfg->timer_rate_hz);
+	else
+		timer_rate = clk_round_rate(csi2phy->timer_clk, link_freq / 4);
 	if (timer_rate <= 0) {
 		ret = -ENODEV;
 		goto unset_opp_rate;
@@ -233,6 +237,15 @@ static int phy_qcom_mipi_csi2_attach_pm_domains(struct mipi_csi2phy_device *csi2
 	const char **pd_names;
 	int i;
 
+	/*
+	 * platform_probe() auto-attaches a single power domain during probe.
+	 * Detach it first so devm_pm_domain_attach_list() can attach all
+	 * domains by name (otherwise it returns -EEXIST for single-domain
+	 * SoCs such as SM8150).
+	 */
+	if (csi2phy->dev->pm_domain)
+		dev_pm_domain_detach(csi2phy->dev, false);
+
 	pd_names = devm_kzalloc(csi2phy->dev,
 				sizeof(char *) * csi2phy->soc_cfg->num_genpds,
 				GFP_KERNEL);
@@ -443,6 +456,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,sm8150-csi2-phy", .data = &mipi_csi2_dphy_sm8150 },
 	{ .compatible	= "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
 	{ }
 };
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h +4 -0
index 7e55ae007370..4da9f12d4f8d 100644
@@ -68,6 +68,9 @@ struct mipi_csi2phy_soc_cfg {
 	const char ** const clk_names;
 	const unsigned int num_clk;
 
+	/* 0 = derive timer rate from link_freq/4; non-zero = fixed rate */
+	unsigned long timer_rate_hz;
+
 	const struct mipi_csi2_genpd *genpds;
 	const unsigned int num_genpds;
 };
@@ -92,6 +95,7 @@ struct mipi_csi2phy_device {
 	u32 hw_version;
 };
 
+extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_sm8150;
 extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e;
 
 #endif /* __PHY_QCOM_MIPI_CSI2_H__ */
Signature · 1 line
2.56.0
#22 lore raw

Re: [PATCH v3 6/7] phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

Thank you for your contribution! Sashiko AI review found 1 potential issue to consider: - [Medium] phy: qcom-mipi-csi2: wrong SM8150 lane polarity offsets in lanes_enable() --

Thank you for your contribution! Sashiko AI review found 1 potential issue to consider:
- [Medium] phy: qcom-mipi-csi2: wrong SM8150 lane polarity offsets in lanes_enable()
--

commit 8f49680e61ed7e381ce9eb5db34d5783dd1ae930
Author: Andrew Gigena <[email protected]>

phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

This commit adds SM8150 platform configuration and lane initialization tables to the Qualcomm MIPI CSI2 DPHY driver, along with support for a fixed timer clock rate and single power domain attachment.

Quoted 4 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +0 -0
index 966d79c98f9b2..b8b6589cee35d 100644

[ ... ]

Quoted 15 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +11 -0
@@ -352,6 +419,36 @@ static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = {
 	.lanes_disable = phy_qcom_mipi_csi2_lanes_disable,
 };
 
+static const char * const sm8150_clks[] = {
+	"core",
+	"timer"
+};
+
+static const char * const sm8150_supplies[] = {
+	"vdda-phy",
+	"vdda-pll"
+};
+
+static struct mipi_csi2_genpd sm8150_genpds[] = {

drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = { · line 442

Quoted 10 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +10 -0
+	{ .name = "top", .scaled = false },
+};
+
+const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_sm8150 = {
+	.ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
+	.reg_info = {
+		.init_seq = lane_regs_sm8150,
+		.lane_array_size = ARRAY_SIZE(lane_regs_sm8150),
+		.common_regs_offset = 0x800,
+	},

[Severity: Medium]
Does phy_qcom_mipi_csi2_lanes_enable() write lane polarity inversion to the wrong register offsets on SM8150?

In lane_regs_sm8150[], the physical lane register blocks use a 0x100-byte stride (data lanes at 0x0000, 0x0200, 0x0400, 0x0600 and the clock lane at 0x0700) with common registers starting at 0x0800. However, phy_qcom_mipi_csi2_lanes_enable() programs CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(), which hardcodes X1E80100's 0x200-byte per-lane stride:

drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c:

    #define CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(n)		((0x200 * (n)) + 0x24)
    ...
    phy_qcom_mipi_csi2_lanes_enable() {
        ...
	/* Lane configuration for polarity @ CSIPHY-base + CTRL9 */
	for (i = 0; i < cfg->num_data_lanes; i++) {
		if (lane_cfg->data[i].pol) {
			u8 pos = lane_cfg->data[i].pos;

			writel(BIT(2), csi2phy->base + CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(pos * 2));
		}
	}

	if (lane_cfg->clk.pol)
		writel(BIT(2), csi2phy->base + CSIPHY_2PH_LN_CSI_2PHASE_CTRL9n(lane_cfg->clk.pos));

When a board configures non-zero lane-polarities on SM8150, data lanes 1..3 and the clock lane write to 0x0424, 0x0824, 0x0c24, and 0x0e24 instead of 0x0224, 0x0424, 0x0624, and 0x0724, leaving those lanes uninverted and overwriting CSI_COMMON_CTRL9 at 0x0824 when data lane 2 is inverted.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-sm8150-v7.4-rc1-camss-v3-0-0103e8a0bbcd@andrewgigena.dev?part=6
maintainer
#23 lore raw

Re: [PATCH v3 6/7] phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

In reply to Andrew Gigena
Quoted 103 lines · On 06/11/2026 18:35, Andrew Gigena via B4 Relay wrote:

From: Andrew Gigena <[email protected]>

Add SM8150 platform data to the CSI2 DPHY driver so that SM8150 can use the dedicated PHY driver instead of the CAMSS-integrated CSIPHY.

The SM8150 CSIPHY uses the SC8280XP lane register layout, as already used by the CAMSS driver, so reuse that table, dropping the DNP entries, which the new PHY driver does not program. The PHY is fed by the "core" and "timer" clocks, the vdda-phy and vdda-pll supplies, and the Titan top power domain, which is not scaled.

The timer clock is pinned to 300 MHz via a new timer_rate_hz soc field (SM8150 timer only supports 19.2/300 MHz). SM8150 is ordered before X1E80100 as it predates it (7 nm vs 4 nm). A detach of the platform-attached single power domain is done before attaching by name, so single-domain SoCs do not fail with -EEXIST.

---
  drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c | 97 ++++++++++++++++++++++
  drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c     | 16 +++-
  drivers/phy/qualcomm/phy-qcom-mipi-csi2.h          |  4 +
  3 files changed, 116 insertions(+), 1 deletion(-)
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +67 -0
index 966d79c98f9b..b8b6589cee35 100644
@@ -45,6 +45,73 @@
  #define CSIPHY_SETTLE_CNT_LOWER_BYTE			2
  #define CSIPHY_SKEW_CAL					7
 
+/* 7nm 2PH v 1.1 2p5Gbps 4 lane DPHY mode */
+static const struct
+mipi_csi2phy_lane_regs lane_regs_sm8150[] = {
+	{.reg_addr = 0x0004, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x002c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0034, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x001c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0014, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x003c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0000, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0008, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0010, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0038, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0060, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0064, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0704, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x072c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0734, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x071c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0714, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0728, .reg_data = 0x04, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x073c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0700, .reg_data = 0x80, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0708, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x070c, .reg_data = 0xa5, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0710, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0738, .reg_data = 0x1f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0760, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0764, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0204, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x022c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0234, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x021c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0214, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x023c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0200, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0208, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0210, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0238, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0260, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0264, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0404, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x042c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0434, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x041c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0414, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x043c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0400, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0408, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0410, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0438, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0460, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0464, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0604, .reg_data = 0x0c, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x062c, .reg_data = 0x01, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0634, .reg_data = 0x0f, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x061c, .reg_data = 0x0a, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0614, .reg_data = 0x60, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x063c, .reg_data = 0xb8, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0600, .reg_data = 0x90, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0608, .reg_data = 0x0e, .param_type = CSIPHY_SETTLE_CNT_LOWER_BYTE},
+	{.reg_addr = 0x0610, .reg_data = 0x52, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0638, .reg_data = 0xfe, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0660, .reg_data = 0x00, .param_type = CSIPHY_DEFAULT_PARAMS},
+	{.reg_addr = 0x0664, .reg_data = 0x7f, .param_type = CSIPHY_DEFAULT_PARAMS},
+};
+
  /* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */
  static const struct
  mipi_csi2phy_lane_regs lane_regs_x1e80100[] = {

drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = { · line 425

Quoted 7 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +4 -0
@@ -352,6 +419,36 @@ static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = {
  	.lanes_disable = phy_qcom_mipi_csi2_lanes_disable,
  };
 
+static const char * const sm8150_clks[] = {
+	"core",
+	"timer"
+};

Is there really no AHB clock to be listed here ? Seems again suspect.

drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c static const struct mipi_csi2phy_hw_ops phy_qcom_mipi_csi2_ops_3ph_1_0 = { · line 430

Quoted 5 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +5 -0
+
+static const char * const sm8150_supplies[] = {
+	"vdda-phy",
+	"vdda-pll"
+};

These are not the correct names

Quoted 29 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-3ph-dphy.c +21 -0
+
+static struct mipi_csi2_genpd sm8150_genpds[] = {
+	{ .name = "top", .scaled = false },
+};
+
+const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_sm8150 = {
+	.ops = &phy_qcom_mipi_csi2_ops_3ph_1_0,
+	.reg_info = {
+		.init_seq = lane_regs_sm8150,
+		.lane_array_size = ARRAY_SIZE(lane_regs_sm8150),
+		.common_regs_offset = 0x800,
+	},
+	.supply_names = (const char **)sm8150_supplies,
+	.num_supplies = ARRAY_SIZE(sm8150_supplies),
+	.clk_names = (const char **)sm8150_clks,
+	.num_clk = ARRAY_SIZE(sm8150_clks),
+	.timer_rate_hz = 300000000,
+	.genpds = sm8150_genpds,
+	.num_genpds = ARRAY_SIZE(sm8150_genpds),
+};
+
  static const char * const x1e_clks[] = {
  	"core",
  	"timer",
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +0 -0
index c0a4fa20eaf0..3a45b8766311 100644

drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c phy_qcom_mipi_csi2_set_clock_rates(struct mipi_csi2phy_device *csi2phy, · line 75

Quoted 9 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +5 -1
@@ -68,7 +68,11 @@ phy_qcom_mipi_csi2_set_clock_rates(struct mipi_csi2phy_device *csi2phy,
  		goto unset_opp_rate;
  	}
 
-	timer_rate = clk_round_rate(csi2phy->timer_clk, link_freq / 4);
+	if (csi2phy->soc_cfg->timer_rate_hz)
+		timer_rate = clk_round_rate(csi2phy->timer_clk,
+					    csi2phy->soc_cfg->timer_rate_hz);
+	else
+		timer_rate = clk_round_rate(csi2phy->timer_clk, link_freq / 4);

But why ?

Quoted 6 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +0 -0
  	if (timer_rate <= 0) {
  		ret = -ENODEV;
  		goto unset_opp_rate;
@@ -233,6 +237,15 @@ static int phy_qcom_mipi_csi2_attach_pm_domains(struct mipi_csi2phy_device *csi2
  	const char **pd_names;
  	int i;

drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c static int phy_qcom_mipi_csi2_attach_pm_domains(struct mipi_csi2phy_device *csi2 · line 248

Quoted 10 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +9 -0
 
+	/*
+	 * platform_probe() auto-attaches a single power domain during probe.
+	 * Detach it first so devm_pm_domain_attach_list() can attach all
+	 * domains by name (otherwise it returns -EEXIST for single-domain
+	 * SoCs such as SM8150).
+	 */
+	if (csi2phy->dev->pm_domain)
+		dev_pm_domain_detach(csi2phy->dev, false);
+

No, there's something in the CPHY series for this already. You'll either have to absorb that patch or apply those changes to your tree and base your stuff off of that, and orchestrate landing this series on top of that series.

Quoted 36 lines
drivers/phy/qualcomm/phy-qcom-mipi-csi2-core.c +1 -0
  	pd_names = devm_kzalloc(csi2phy->dev,
  				sizeof(char *) * csi2phy->soc_cfg->num_genpds,
  				GFP_KERNEL);
@@ -443,6 +456,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,sm8150-csi2-phy", .data = &mipi_csi2_dphy_sm8150 },
  	{ .compatible	= "qcom,x1e80100-csi2-phy", .data = &mipi_csi2_dphy_4nm_x1e },
  	{ }
  };
drivers/phy/qualcomm/phy-qcom-mipi-csi2.h +4 -1
index 7e55ae007370..4da9f12d4f8d 100644
@@ -68,6 +68,9 @@ struct mipi_csi2phy_soc_cfg {
  	const char ** const clk_names;
  	const unsigned int num_clk;
 
+	/* 0 = derive timer rate from link_freq/4; non-zero = fixed rate */
+	unsigned long timer_rate_hz;
+
  	const struct mipi_csi2_genpd *genpds;
  	const unsigned int num_genpds;
  };
@@ -92,6 +95,7 @@ struct mipi_csi2phy_device {
  	u32 hw_version;
  };
 
+extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_sm8150;
  extern const struct mipi_csi2phy_soc_cfg mipi_csi2_dphy_4nm_x1e;
 
  #endif /* __PHY_QCOM_MIPI_CSI2_H__ */
 
--

2.56.0

maintainer
#24 lore raw

Re: [PATCH v3 6/7] phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

Quoted 12 lines · Bryan O'Donoghue
Quoted 11 lines

+    /*
+     * platform_probe() auto-attaches a single power domain during probe.
+     * Detach it first so devm_pm_domain_attach_list() can attach all +     * domains by name (otherwise it returns -EEXIST for single-domain +     * SoCs such as SM8150).
+     */
+    if (csi2phy->dev->pm_domain)
+        dev_pm_domain_detach(csi2phy->dev, false);
+

Quoted 1 line

No, there's something in the CPHY series for this already. You'll either have to absorb that patch or apply those changes to your tree and base your stuff off of that, and orchestrate landing this series on top of that series.

What you could do to unblock your series and not have a dependency on another series is cherry-pick the necessary patch.

https://patchwork.linuxtv.org/project/linux-media/patch/[email protected]/

If you do that you can drop the above change and resend your series with indicated changes.

---
bod

#25 lore raw

Re: [PATCH v3 6/7] phy: qcom-mipi-csi2: Add SM8150 CSI2 DPHY support

Hi Bryan,

Quoted 4 lines

What you could do to unblock your series and not have a dependency on another series is cherry-pick the necessary patch.

https://patchwork.linuxtv.org/project/linux-media/patch/[email protected]/

I took Anusha's approach and dropped the dev_pm_domain_detach() hack. Single power-domain SoCs now use dev_pm_domain_attach(dev, 0) and the loops check for a NULL pd_list. I folded it into the PHY patch with Co-developed-by and Signed-off-by for Anusha, so the series has no dependency on another series.

On your other points:

Quoted 1 line

Is there really no AHB clock to be listed here ? Seems again suspect.

There is no separate AHB clock. The "core" clock is cam_cc_csiphyN_clk, whose parent is cam_cc_cphy_rx_clk_src at 400 MHz, and the second clock is the CSI PHY timer.

Quoted 1 line

These are not the correct names

Renamed to vdda-0p9 and vdda-1p2 in the binding, the driver and the DTS.

Quoted 1 line

But why ?

The SM8150 timer RCG only has 19.2 MHz and 300 MHz. link_freq / 4 rounds down to 19.2 MHz and the settle count comes out zero, so the rate is pinned to 300 MHz through timer_rate_hz.

Best regards,
Andrew

#26 lore raw

PATCH v3 7/7 arm64: dts: qcom: sm8150: Add CAMSS and CCI nodes

In reply to Andrew Gigena

Describe the SM8150 CAMSS block and its CSID, VFE and VFE-Lite instances, together with the four dedicated CSI2 PHYs, the two CCI controllers and their I2C buses.

The CAMSS node exposes four CSI input ports, each linked to one CSI2 PHY output port, and references the CAMCC clocks and GDSCs, the interconnects and the IOMMU streams. Each of the four CSIPHY I/O spaces is described by its own qcom,sm8150-csi2-phy node, fed by the CSIPHY clocks and the Titan top power domain; the vdda-phy and vdda-pll supplies are board-specific. The CCI nodes describe the CCI0/CCI1 I2C buses, and the TLMM pinctrl states for their clock and data lines are added to the existing pin controller node.

All new nodes are left disabled. The PHY supplies and the sensor wiring are board-specific, so they belong in the board DTS that enables the controller.

---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 488 +++++++++++++++++++++++++++++++++++
 1 file changed, 488 insertions(+)
arch/arm64/boot/dts/qcom/sm8150.dtsi +488 -0
index 293fcbacff34..008f787235b8 100644
@@ -2736,6 +2736,86 @@ wake-pins {
 					bias-pull-up;
 				};
 			};
+
+			cci0_default: cci0-default-state {
+				cci0_i2c0_default: cci0-i2c0-default-pins {
+					/* SDA, SCL */
+					pins = "gpio17", "gpio18";
+					function = "cci_i2c";
+
+					bias-pull-up;
+					drive-strength = <2>; /* 2 mA */
+				};
+
+				cci0_i2c1_default: cci0-i2c1-default-pins {
+					/* SDA, SCL */
+					pins = "gpio19", "gpio20";
+					function = "cci_i2c";
+
+					bias-pull-up;
+					drive-strength = <2>; /* 2 mA */
+				};
+			};
+
+			cci0_sleep: cci0-sleep-state {
+				cci0_i2c0_sleep: cci0-i2c0-sleep-pins {
+					/* SDA, SCL */
+					pins = "gpio17", "gpio18";
+					function = "cci_i2c";
+
+					drive-strength = <2>; /* 2 mA */
+					bias-pull-down;
+				};
+
+				cci0_i2c1_sleep: cci0-i2c1-sleep-pins {
+					/* SDA, SCL */
+					pins = "gpio19", "gpio20";
+					function = "cci_i2c";
+
+					drive-strength = <2>; /* 2 mA */
+					bias-pull-down;
+				};
+			};
+
+			cci1_default: cci1-default-state {
+				cci1_i2c0_default: cci1-i2c0-default-pins {
+					/* SDA, SCL */
+					pins = "gpio31", "gpio32";
+					function = "cci_i2c";
+
+					bias-pull-up;
+					drive-strength = <2>; /* 2 mA */
+				};
+
+				cci1_i2c1_default: cci1-i2c1-default-pins {
+					/* SDA, SCL */
+					pins = "gpio33", "gpio34";
+					function = "cci_i2c";
+
+					bias-pull-up;
+					drive-strength = <2>; /* 2 mA */
+				};
+			};
+
+			cci1_sleep: cci1-sleep-state {
+				cci1_i2c0_sleep: cci1-i2c0-sleep-pins {
+					/* SDA, SCL */
+					pins = "gpio31", "gpio32";
+					function = "cci_i2c";
+
+					bias-pull-down;
+					drive-strength = <2>; /* 2 mA */
+				};
+
+				cci1_i2c1_sleep: cci1-i2c1-sleep-pins {
+					/* SDA, SCL */
+					pins = "gpio33", "gpio34";
+					function = "cci_i2c";
+
+					bias-pull-down;
+					drive-strength = <2>; /* 2 mA */
+				};
+			};
 		};
 
 		remoteproc_mpss: remoteproc@4080000 {
@@ -3782,6 +3862,414 @@ camnoc_virt: interconnect@ac00000 {
 			qcom,bcm-voters = <&apps_bcm_voter>;
 		};
 
+		cci0: cci@ac4a000 {
+			compatible = "qcom,sm8150-cci", "qcom,msm8996-cci";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			reg = <0 0xac4a000 0 0x1000>;
+			interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CCI_0_CLK>,
+				 <&camcc CAM_CC_CCI_0_CLK_SRC>;
+			clock-names = "camnoc_axi",
+				      "slow_ahb_src",
+				      "cpas_ahb",
+				      "cci",
+				      "cci_src";
+
+			pinctrl-0 = <&cci0_default>;
+			pinctrl-1 = <&cci0_sleep>;
+			pinctrl-names = "default", "sleep";
+
+			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@ac4b000 {
+			compatible = "qcom,sm8150-cci", "qcom,msm8996-cci";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			reg = <0 0xac4b000 0 0x1000>;
+			interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CCI_1_CLK>,
+				 <&camcc CAM_CC_CCI_1_CLK_SRC>;
+			clock-names = "camnoc_axi",
+				      "slow_ahb_src",
+				      "cpas_ahb",
+				      "cci",
+				      "cci_src";
+
+			pinctrl-0 = <&cci1_default>;
+			pinctrl-1 = <&cci1_sleep>;
+			pinctrl-names = "default", "sleep";
+
+			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>;
+			};
+		};
+
+		camss: isp@acaf000 {
+			compatible = "qcom,sm8150-camss";
+			status = "disabled";
+
+			reg = <0 0xacaf000 0 0x4000>,
+			      <0 0xacb3000 0 0x1000>,
+			      <0 0xacb6000 0 0x4000>,
+			      <0 0xacba000 0 0x1000>,
+			      <0 0xacc4000 0 0x4000>,
+			      <0 0xacc8000 0 0x1000>,
+			      <0 0xaccb000 0 0x4000>,
+			      <0 0xaccf000 0 0x1000>;
+
+			reg-names = "vfe0",
+				    "csid0",
+				    "vfe1",
+				    "csid1",
+				    "vfe_lite0",
+				    "csid_lite0",
+				    "vfe_lite1",
+				    "csid_lite1";
+
+			interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+
+			interrupt-names = "vfe0",
+					  "csid0",
+					  "vfe1",
+					  "csid1",
+					  "vfe_lite0",
+					  "csid_lite0",
+					  "vfe_lite1",
+					  "csid_lite1";
+
+			power-domains = <&camcc IFE_0_GDSC>,
+					<&camcc IFE_1_GDSC>,
+					<&camcc TITAN_TOP_GDSC>;
+			power-domain-names = "ife0",
+					     "ife1",
+					     "top";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+				 <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&gcc GCC_CAMERA_SF_AXI_CLK>;
+			clock-names = "camnoc_axi",
+				      "cpas_ahb",
+				      "vfe0_axi",
+				      "vfe0",
+				      "vfe0_cphy_rx",
+				      "vfe0_csid",
+				      "vfe1_axi",
+				      "vfe1",
+				      "vfe1_cphy_rx",
+				      "vfe1_csid",
+				      "vfe_lite0",
+				      "vfe_lite0_cphy_rx",
+				      "vfe_lite0_csid",
+				      "vfe_lite1",
+				      "vfe_lite1_cphy_rx",
+				      "vfe_lite1_csid",
+				      "gcc_ahb",
+				      "gcc_axi_hf",
+				      "gcc_axi_sf";
+
+			iommus = <&apps_smmu 0x840 0x620>,
+				 <&apps_smmu 0x860 0x620>,
+				 <&apps_smmu 0xa40 0x620>,
+				 <&apps_smmu 0xa60 0x620>,
+				 <&apps_smmu 0xc40 0x620>,
+				 <&apps_smmu 0xc60 0x620>,
+				 <&apps_smmu 0xe40 0x620>,
+				 <&apps_smmu 0xe60 0x620>;
+
+			interconnects = <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_CAMERA_CFG 0>,
+					<&mmss_noc MASTER_CAMNOC_HF0 0 &mc_virt SLAVE_EBI_CH0 0>,
+					<&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI_CH0 0>,
+					<&mmss_noc MASTER_CAMNOC_HF1 0 &mc_virt SLAVE_EBI_CH0 0>;
+			interconnect-names = "cam_ahb",
+					     "cam_hf_0_mnoc",
+					     "cam_sf_0_mnoc",
+					     "cam_hf_1_mnoc";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					camss_csi0_in: endpoint {
+						remote-endpoint = <&csiphy0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					camss_csi1_in: endpoint {
+						remote-endpoint = <&csiphy1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					camss_csi2_in: endpoint {
+						remote-endpoint = <&csiphy2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+
+					camss_csi3_in: endpoint {
+						remote-endpoint = <&csiphy3_out>;
+					};
+				};
+			};
+		};
+
+		csiphy0: phy@ac65000 {
+			compatible = "qcom,sm8150-csi2-phy";
+			reg = <0 0xac65000 0 0x1000>;
+			status = "disabled";
+
+			clocks = <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+			clock-names = "core",
+				      "timer";
+
+			interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+
+			operating-points-v2 = <&csiphy0_opp_table>;
+
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					csiphy0_in: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					csiphy0_out: endpoint {
+						remote-endpoint = <&camss_csi0_in>;
+					};
+				};
+			};
+
+			csiphy0_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+				};
+			};
+		};
+
+		csiphy1: phy@ac66000 {
+			compatible = "qcom,sm8150-csi2-phy";
+			reg = <0 0xac66000 0 0x1000>;
+			status = "disabled";
+
+			clocks = <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+			clock-names = "core",
+				      "timer";
+
+			interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+
+			operating-points-v2 = <&csiphy1_opp_table>;
+
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					csiphy1_in: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					csiphy1_out: endpoint {
+						remote-endpoint = <&camss_csi1_in>;
+					};
+				};
+			};
+
+			csiphy1_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+				};
+			};
+		};
+
+		csiphy2: phy@ac67000 {
+			compatible = "qcom,sm8150-csi2-phy";
+			reg = <0 0xac67000 0 0x1000>;
+			status = "disabled";
+
+			clocks = <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+			clock-names = "core",
+				      "timer";
+
+			interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+
+			operating-points-v2 = <&csiphy2_opp_table>;
+
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					csiphy2_in: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					csiphy2_out: endpoint {
+						remote-endpoint = <&camss_csi2_in>;
+					};
+				};
+			};
+
+			csiphy2_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+				};
+			};
+		};
+
+		csiphy3: phy@ac68000 {
+			compatible = "qcom,sm8150-csi2-phy";
+			reg = <0 0xac68000 0 0x1000>;
+			status = "disabled";
+
+			clocks = <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+			clock-names = "core",
+				      "timer";
+
+			interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+
+			operating-points-v2 = <&csiphy3_opp_table>;
+
+			power-domains = <&camcc TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					csiphy3_in: endpoint {
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					csiphy3_out: endpoint {
+						remote-endpoint = <&camss_csi3_in>;
+					};
+				};
+			};
+
+			csiphy3_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+				};
+			};
+		};
+
 		camcc: clock-controller@ad00000 {
 			compatible = "qcom,sm8150-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
Signature · 1 line
2.56.0
#27 lore raw

Re: [PATCH v3 7/7] arm64: dts: qcom: sm8150: Add CAMSS and CCI nodes

Thank you for your contribution! Sashiko AI review found 2 potential issues to consider: - [Medium] arm64: dts: qcom: sm8150: camss endpoints omit required data-lanes - [Low] arm64: dts: qcom…

Thank you for your contribution! Sashiko AI review found 2 potential issues to consider:
- [Medium] arm64: dts: qcom: sm8150: camss endpoints omit required data-lanes
- [Low] arm64: dts: qcom: sm8150: camss placed before csiphy0..3 out of address order
--

commit c52d60a765d4e993fcd753e18db2ef2055f389e5
Author: Andrew Gigena <[email protected]>

arm64: dts: qcom: sm8150: Add CAMSS and CCI nodes

This commit adds Devicetree nodes for the SM8150 CAMSS ISP, four CSI2 PHYs, and two CCI I2C controllers along with their TLMM pin configurations.

Quoted 4 lines
arch/arm64/boot/dts/qcom/sm8150.dtsi +0 -0
index 293fcbacff346..008f787235b86 100644

[ ... ]

Quoted 1 line
arch/arm64/boot/dts/qcom/sm8150.dtsi +0 -0
@@ -3782,6 +3862,414 @@ camnoc_virt: interconnect@ac00000 {

[ ... ]

Quoted 3 lines
arch/arm64/boot/dts/qcom/sm8150.dtsi +3 -0
+		camss: isp@acaf000 {
+			compatible = "qcom,sm8150-camss";
+			status = "disabled";

[ ... ]

Quoted 27 lines
arch/arm64/boot/dts/qcom/sm8150.dtsi +27 -0
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					camss_csi0_in: endpoint {
+						remote-endpoint = <&csiphy0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					camss_csi1_in: endpoint {
+						remote-endpoint = <&csiphy1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					camss_csi2_in: endpoint {
+						remote-endpoint = <&csiphy2_out>;
+					};
+				};

arch/arm64/boot/dts/qcom/sm8150.dtsi camnoc_virt: interconnect@ac00000 { · line 4087

Quoted 10 lines
arch/arm64/boot/dts/qcom/sm8150.dtsi +10 -0
+
+				port@3 {
+					reg = <3>;
+
+					camss_csi3_in: endpoint {
+						remote-endpoint = <&csiphy3_out>;
+					};
+				};
+			};
+		};

[Severity: Medium]
Should port@0 through port@3 in camss omit the pre-populated camss_csi0_in..camss_csi3_in endpoint nodes here so that board DTS files instantiate only the active endpoints with their data-lanes?

Documentation/devicetree/bindings/media/qcom,sm8150-camss.yaml requires data-lanes on every endpoint under port@[0-3], so enabling camss on a board that uses fewer than all four CSI2 PHYs leaves the unused endpoints without data-lanes and fails dtbs_check. At runtime, if a board DTS only sets data-lanes on the sensor-facing csiphyN_in endpoint, camss_parse_ports() -> camss_parse_endpoint_node() parses camss_csiN_in without data-lanes, does not select V4L2_MBUS_CSI2_DPHY in v4l2_fwnode_endpoint_parse(), and fails probe with -EINVAL:

drivers/media/platform/qcom/camss/camss.c:camss_parse_endpoint_node() {
    ...
	v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
	if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) {
		dev_err(dev, "Unsupported bus type %d\n", vep.bus_type);
		return -EINVAL;
	}
    ...
}

arch/arm64/boot/dts/qcom/sm8150.dtsi camnoc_virt: interconnect@ac00000 { · line 4092

Quoted 5 lines
arch/arm64/boot/dts/qcom/sm8150.dtsi +5 -0
+
+		csiphy0: phy@ac65000 {
+			compatible = "qcom,sm8150-csi2-phy";
+			reg = <0 0xac65000 0 0x1000>;
+			status = "disabled";

[Severity: Low]
Should csiphy0..csiphy3 ([email protected]@ac68000) be placed before camss (isp@acaf000) to keep /soc@0 child nodes in ascending unit-address order?

Because of_platform_populate() registers devices in node order, placing isp@acaf000 before [email protected]@ac68000 also causes camss_probe() -> camss_init_subdevices() -> msm_csiphy_subdev_init() to run before the PHY providers are registered when built-in, hitting -EPROBE_DEFER from devm_phy_get_by_of_node() and logging a spurious dev_err("csiphy %d init fail\n"). In addition, status = "disabled" in camss and csiphy0..csiphy3 should sit after the standard device properties (before child nodes), and the reg addresses in these nodes should be zero-padded to 8 hex digits (such as 0x0ac4a000) to match surrounding /soc@0 nodes.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-sm8150-v7.4-rc1-camss-v3-0-0103e8a0bbcd@andrewgigena.dev?part=7