# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/qcom,pcie.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Qualcomm PCI express root complex

maintainers:
  - Bjorn Andersson <bjorn.andersson@linaro.org>
  - Stanimir Varbanov <svarbanov@mm-sol.com>

description: |
  Qualcomm PCIe root complex controller is based on the Synopsys DesignWare
  PCIe IP.

properties:
  compatible:
    enum:
      - qcom,pcie-ipq8064
      - qcom,pcie-ipq8064-v2
      - qcom,pcie-apq8064
      - qcom,pcie-apq8084
      - qcom,pcie-msm8996
      - qcom,pcie-ipq4019
      - qcom,pcie-ipq8074
      - qcom,pcie-qcs404
      - qcom,pcie-sa8540p
      - qcom,pcie-sc7280
      - qcom,pcie-sc8180x
      - qcom,pcie-sc8280xp
      - qcom,pcie-sdm845
      - qcom,pcie-sm8150
      - qcom,pcie-sm8250
      - qcom,pcie-sm8450-pcie0
      - qcom,pcie-sm8450-pcie1
      - qcom,pcie-ipq6018

  reg:
    minItems: 4
    maxItems: 5

  reg-names:
    minItems: 4
    maxItems: 5

  interrupts:
    minItems: 1
    maxItems: 8

  interrupt-names:
    minItems: 1
    maxItems: 8

  # Common definitions for clocks, clock-names and reset.
  # Platform constraints are described later.
  clocks:
    minItems: 3
    maxItems: 13

  clock-names:
    minItems: 3
    maxItems: 13

  resets:
    minItems: 1
    maxItems: 12

  resets-names:
    minItems: 1
    maxItems: 12

  vdda-supply:
    description: A phandle to the core analog power supply

  vdda_phy-supply:
    description: A phandle to the core analog power supply for PHY

  vdda_refclk-supply:
    description: A phandle to the core analog power supply for IC which generates reference clock

  vddpe-3v3-supply:
    description: A phandle to the PCIe endpoint power supply

  phys:
    maxItems: 1

  phy-names:
    items:
      - const: pciephy

  power-domains:
    maxItems: 1

  perst-gpios:
    description: GPIO controlled connection to PERST# signal
    maxItems: 1

  wake-gpios:
    description: GPIO controlled connection to WAKE# signal
    maxItems: 1

required:
  - compatible
  - reg
  - reg-names
  - interrupts
  - interrupt-names
  - "#interrupt-cells"
  - interrupt-map-mask
  - interrupt-map
  - clocks
  - clock-names

allOf:
  - $ref: /schemas/pci/pci-bus.yaml#
  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8064
              - qcom,pcie-ipq4019
              - qcom,pcie-ipq8064
              - qcom,pcie-ipq8064v2
              - qcom,pcie-ipq8074
              - qcom,pcie-qcs404
    then:
      properties:
        reg:
          minItems: 4
          maxItems: 4
        reg-names:
          items:
            - const: dbi # DesignWare PCIe registers
            - const: elbi # External local bus interface registers
            - const: parf # Qualcomm specific registers
            - const: config # PCIe configuration space

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-ipq6018
    then:
      properties:
        reg:
          minItems: 5
          maxItems: 5
        reg-names:
          items:
            - const: dbi # DesignWare PCIe registers
            - const: elbi # External local bus interface registers
            - const: atu # ATU address space
            - const: parf # Qualcomm specific registers
            - const: config # PCIe configuration space

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8084
              - qcom,pcie-msm8996
              - qcom,pcie-sdm845
    then:
      properties:
        reg:
          minItems: 4
          maxItems: 4
        reg-names:
          items:
            - const: parf # Qualcomm specific registers
            - const: dbi # DesignWare PCIe registers
            - const: elbi # External local bus interface registers
            - const: config # PCIe configuration space

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sc7280
              - qcom,pcie-sc8180x
              - qcom,pcie-sc8280xp
              - qcom,pcie-sm8250
              - qcom,pcie-sm8450-pcie0
              - qcom,pcie-sm8450-pcie1
    then:
      properties:
        reg:
          minItems: 5
          maxItems: 5
        reg-names:
          items:
            - const: parf # Qualcomm specific registers
            - const: dbi # DesignWare PCIe registers
            - const: elbi # External local bus interface registers
            - const: atu # ATU address space
            - const: config # PCIe configuration space

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8064
              - qcom,pcie-ipq8064
              - qcom,pcie-ipq8064v2
    then:
      properties:
        clocks:
          minItems: 3
          maxItems: 5
        clock-names:
          minItems: 3
          items:
            - const: core # Clocks the pcie hw block
            - const: iface # Configuration AHB clock
            - const: phy # Clocks the pcie PHY block
            - const: aux # Clocks the pcie AUX block, not on apq8064
            - const: ref # Clocks the pcie ref block, not on apq8064
        resets:
          minItems: 5
          maxItems: 6
        reset-names:
          minItems: 5
          items:
            - const: axi # AXI reset
            - const: ahb # AHB reset
            - const: por # POR reset
            - const: pci # PCI reset
            - const: phy # PHY reset
            - const: ext # EXT reset, not on apq8064
      required:
        - vdda-supply
        - vdda_phy-supply
        - vdda_refclk-supply

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8084
    then:
      properties:
        clocks:
          minItems: 4
          maxItems: 4
        clock-names:
          items:
            - const: iface # Configuration AHB clock
            - const: master_bus # Master AXI clock
            - const: slave_bus # Slave AXI clock
            - const: aux # Auxiliary (AUX) clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: core # Core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-ipq4019
    then:
      properties:
        clocks:
          minItems: 3
          maxItems: 3
        clock-names:
          items:
            - const: aux # Auxiliary (AUX) clock
            - const: master_bus # Master AXI clock
            - const: slave_bus # Slave AXI clock
        resets:
          minItems: 12
          maxItems: 12
        reset-names:
          items:
            - const: axi_m # AXI master reset
            - const: axi_s # AXI slave reset
            - const: pipe # PIPE reset
            - const: axi_m_vmid # VMID reset
            - const: axi_s_xpu # XPU reset
            - const: parf # PARF reset
            - const: phy # PHY reset
            - const: axi_m_sticky # AXI sticky reset
            - const: pipe_sticky # PIPE sticky reset
            - const: pwr # PWR reset
            - const: ahb # AHB reset
            - const: phy_ahb # PHY AHB reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-msm8996
    then:
      oneOf:
        - properties:
            clock-names:
              items:
                - const: pipe # Pipe Clock driving internal logic
                - const: aux # Auxiliary (AUX) clock
                - const: cfg # Configuration clock
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
        - properties:
            clock-names:
              items:
                - const: pipe # Pipe Clock driving internal logic
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
                - const: cfg # Configuration clock
                - const: aux # Auxiliary (AUX) clock
      properties:
        clocks:
          minItems: 5
          maxItems: 5
        resets: false
        reset-names: false

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-ipq8074
    then:
      properties:
        clocks:
          minItems: 5
          maxItems: 5
        clock-names:
          items:
            - const: iface # PCIe to SysNOC BIU clock
            - const: axi_m # AXI Master clock
            - const: axi_s # AXI Slave clock
            - const: ahb # AHB clock
            - const: aux # Auxiliary clock
        resets:
          minItems: 7
          maxItems: 7
        reset-names:
          items:
            - const: pipe # PIPE reset
            - const: sleep # Sleep reset
            - const: sticky # Core Sticky reset
            - const: axi_m # AXI Master reset
            - const: axi_s # AXI Slave reset
            - const: ahb # AHB Reset
            - const: axi_m_sticky # AXI Master Sticky reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-ipq6018
    then:
      properties:
        clocks:
          minItems: 5
          maxItems: 5
        clock-names:
          items:
            - const: iface # PCIe to SysNOC BIU clock
            - const: axi_m # AXI Master clock
            - const: axi_s # AXI Slave clock
            - const: axi_bridge # AXI bridge clock
            - const: rchng
        resets:
          minItems: 8
          maxItems: 8
        reset-names:
          items:
            - const: pipe # PIPE reset
            - const: sleep # Sleep reset
            - const: sticky # Core Sticky reset
            - const: axi_m # AXI Master reset
            - const: axi_s # AXI Slave reset
            - const: ahb # AHB Reset
            - const: axi_m_sticky # AXI Master Sticky reset
            - const: axi_s_sticky # AXI Slave Sticky reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-qcs404
    then:
      properties:
        clocks:
          minItems: 4
          maxItems: 4
        clock-names:
          items:
            - const: iface # AHB clock
            - const: aux # Auxiliary clock
            - const: master_bus # AXI Master clock
            - const: slave_bus # AXI Slave clock
        resets:
          minItems: 6
          maxItems: 6
        reset-names:
          items:
            - const: axi_m # AXI Master reset
            - const: axi_s # AXI Slave reset
            - const: axi_m_sticky # AXI Master Sticky reset
            - const: pipe_sticky # PIPE sticky reset
            - const: pwr # PWR reset
            - const: ahb # AHB reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sc7280
    then:
      properties:
        clocks:
          minItems: 13
          maxItems: 13
        clock-names:
          items:
            - const: pipe # PIPE clock
            - const: pipe_mux # PIPE MUX
            - const: phy_pipe # PIPE output clock
            - const: ref # REFERENCE clock
            - const: aux # Auxiliary clock
            - const: cfg # Configuration clock
            - const: bus_master # Master AXI clock
            - const: bus_slave # Slave AXI clock
            - const: slave_q2a # Slave Q2A clock
            - const: tbu # PCIe TBU clock
            - const: ddrss_sf_tbu # PCIe SF TBU clock
            - const: aggre0 # Aggre NoC PCIe CENTER SF AXI clock
            - const: aggre1 # Aggre NoC PCIe1 AXI clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sdm845
    then:
      oneOf:
          # Unfortunately the "optional" ref clock is used in the middle of the list
        - properties:
            clocks:
              minItems: 8
              maxItems: 8
            clock-names:
              items:
                - const: pipe # PIPE clock
                - const: aux # Auxiliary clock
                - const: cfg # Configuration clock
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
                - const: slave_q2a # Slave Q2A clock
                - const: ref # REFERENCE clock
                - const: tbu # PCIe TBU clock
        - properties:
            clocks:
              minItems: 7
              maxItems: 7
            clock-names:
              items:
                - const: pipe # PIPE clock
                - const: aux # Auxiliary clock
                - const: cfg # Configuration clock
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
                - const: slave_q2a # Slave Q2A clock
                - const: tbu # PCIe TBU clock
      properties:
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sc8180x
              - qcom,pcie-sm8150
              - qcom,pcie-sm8250
    then:
      oneOf:
          # Unfortunately the "optional" ref clock is used in the middle of the list
        - properties:
            clocks:
              minItems: 9
              maxItems: 9
            clock-names:
              items:
                - const: pipe # PIPE clock
                - const: aux # Auxiliary clock
                - const: cfg # Configuration clock
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
                - const: slave_q2a # Slave Q2A clock
                - const: ref # REFERENCE clock
                - const: tbu # PCIe TBU clock
                - const: ddrss_sf_tbu # PCIe SF TBU clock
        - properties:
            clocks:
              minItems: 8
              maxItems: 8
            clock-names:
              items:
                - const: pipe # PIPE clock
                - const: aux # Auxiliary clock
                - const: cfg # Configuration clock
                - const: bus_master # Master AXI clock
                - const: bus_slave # Slave AXI clock
                - const: slave_q2a # Slave Q2A clock
                - const: tbu # PCIe TBU clock
                - const: ddrss_sf_tbu # PCIe SF TBU clock
      properties:
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sm8450-pcie0
    then:
      properties:
        clocks:
          minItems: 12
          maxItems: 12
        clock-names:
          items:
            - const: pipe # PIPE clock
            - const: pipe_mux # PIPE MUX
            - const: phy_pipe # PIPE output clock
            - const: ref # REFERENCE clock
            - const: aux # Auxiliary clock
            - const: cfg # Configuration clock
            - const: bus_master # Master AXI clock
            - const: bus_slave # Slave AXI clock
            - const: slave_q2a # Slave Q2A clock
            - const: ddrss_sf_tbu # PCIe SF TBU clock
            - const: aggre0 # Aggre NoC PCIe0 AXI clock
            - const: aggre1 # Aggre NoC PCIe1 AXI clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sm8450-pcie1
    then:
      properties:
        clocks:
          minItems: 11
          maxItems: 11
        clock-names:
          items:
            - const: pipe # PIPE clock
            - const: pipe_mux # PIPE MUX
            - const: phy_pipe # PIPE output clock
            - const: ref # REFERENCE clock
            - const: aux # Auxiliary clock
            - const: cfg # Configuration clock
            - const: bus_master # Master AXI clock
            - const: bus_slave # Slave AXI clock
            - const: slave_q2a # Slave Q2A clock
            - const: ddrss_sf_tbu # PCIe SF TBU clock
            - const: aggre1 # Aggre NoC PCIe1 AXI clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sa8540p
              - qcom,pcie-sc8280xp
    then:
      properties:
        clocks:
          minItems: 8
          maxItems: 9
        clock-names:
          minItems: 8
          items:
            - const: aux # Auxiliary clock
            - const: cfg # Configuration clock
            - const: bus_master # Master AXI clock
            - const: bus_slave # Slave AXI clock
            - const: slave_q2a # Slave Q2A clock
            - const: ddrss_sf_tbu # PCIe SF TBU clock
            - const: noc_aggr_4 # NoC aggregate 4 clock
            - const: noc_aggr_south_sf # NoC aggregate South SF clock
            - const: cnoc_qx # Configuration NoC QX clock
        resets:
          maxItems: 1
        reset-names:
          items:
            - const: pci # PCIe core reset

  - if:
      not:
        properties:
          compatible:
            contains:
              enum:
                - qcom,pcie-apq8064
                - qcom,pcie-ipq4019
                - qcom,pcie-ipq8064
                - qcom,pcie-ipq8064v2
                - qcom,pcie-ipq8074
                - qcom,pcie-qcs404
    then:
      required:
        - power-domains

  - if:
      not:
        properties:
          compatible:
            contains:
              enum:
                - qcom,pcie-msm8996
    then:
      required:
        - resets
        - reset-names

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-msm8996
              - qcom,pcie-sc7280
              - qcom,pcie-sc8180x
              - qcom,pcie-sdm845
              - qcom,pcie-sm8150
              - qcom,pcie-sm8250
              - qcom,pcie-sm8450-pcie0
              - qcom,pcie-sm8450-pcie1
    then:
      oneOf:
        - properties:
            interrupts:
              maxItems: 1
            interrupt-names:
              items:
                - const: msi
        - properties:
            interrupts:
              minItems: 8
            interrupt-names:
              items:
                - const: msi0
                - const: msi1
                - const: msi2
                - const: msi3
                - const: msi4
                - const: msi5
                - const: msi6
                - const: msi7

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sc8280xp
    then:
      properties:
        interrupts:
          minItems: 4
          maxItems: 4
        interrupt-names:
          items:
            - const: msi0
            - const: msi1
            - const: msi2
            - const: msi3

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-apq8064
              - qcom,pcie-apq8084
              - qcom,pcie-ipq4019
              - qcom,pcie-ipq6018
              - qcom,pcie-ipq8064
              - qcom,pcie-ipq8064-v2
              - qcom,pcie-ipq8074
              - qcom,pcie-qcs404
              - qcom,pcie-sa8540p
    then:
      properties:
        interrupts:
          maxItems: 1
        interrupt-names:
          items:
            - const: msi

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    pcie@1b500000 {
      compatible = "qcom,pcie-ipq8064";
      reg = <0x1b500000 0x1000>,
            <0x1b502000 0x80>,
            <0x1b600000 0x100>,
            <0x0ff00000 0x100000>;
      reg-names = "dbi", "elbi", "parf", "config";
      device_type = "pci";
      linux,pci-domain = <0>;
      bus-range = <0x00 0xff>;
      num-lanes = <1>;
      #address-cells = <3>;
      #size-cells = <2>;
      ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000>,
               <0x82000000 0 0 0x08000000 0 0x07e00000>;
      interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
      interrupt-names = "msi";
      #interrupt-cells = <1>;
      interrupt-map-mask = <0 0 0 0x7>;
      interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>;
      clocks = <&gcc 41>,
               <&gcc 43>,
               <&gcc 44>,
               <&gcc 42>,
               <&gcc 248>;
      clock-names = "core", "iface", "phy", "aux", "ref";
      resets = <&gcc 27>,
               <&gcc 26>,
               <&gcc 25>,
               <&gcc 24>,
               <&gcc 23>,
               <&gcc 22>;
      reset-names = "axi", "ahb", "por", "pci", "phy", "ext";
      pinctrl-0 = <&pcie_pins_default>;
      pinctrl-names = "default";
      vdda-supply = <&pm8921_s3>;
      vdda_phy-supply = <&pm8921_lvs6>;
      vdda_refclk-supply = <&ext_3p3v>;
    };
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/gpio/gpio.h>
    pcie@fc520000 {
      compatible = "qcom,pcie-apq8084";
      reg = <0xfc520000 0x2000>,
            <0xff000000 0x1000>,
            <0xff001000 0x1000>,
            <0xff002000 0x2000>;
      reg-names = "parf", "dbi", "elbi", "config";
      device_type = "pci";
      linux,pci-domain = <0>;
      bus-range = <0x00 0xff>;
      num-lanes = <1>;
      #address-cells = <3>;
      #size-cells = <2>;
      ranges = <0x81000000 0 0          0xff200000 0 0x00100000>,
               <0x82000000 0 0x00300000 0xff300000 0 0x00d00000>;
      interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
      interrupt-names = "msi";
      #interrupt-cells = <1>;
      interrupt-map-mask = <0 0 0 0x7>;
      interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>,
                      <0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>;
      clocks = <&gcc 324>,
               <&gcc 325>,
               <&gcc 327>,
               <&gcc 323>;
      clock-names = "iface", "master_bus", "slave_bus", "aux";
      resets = <&gcc 81>;
      reset-names = "core";
      power-domains = <&gcc 1>;
      vdda-supply = <&pma8084_l3>;
      phys = <&pciephy0>;
      phy-names = "pciephy";
      perst-gpios = <&tlmm 70 GPIO_ACTIVE_LOW>;
      pinctrl-0 = <&pcie0_pins_default>;
      pinctrl-names = "default";
    };
...
