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

title: NVIDIA Tegra194 (and later) PCIe controller (Synopsys DesignWare Core based)

maintainers:
  - Thierry Reding <thierry.reding@gmail.com>
  - Jon Hunter <jonathanh@nvidia.com>
  - Vidya Sagar <vidyas@nvidia.com>

description: |
  This PCIe controller is based on the Synopsys DesignWare PCIe IP and thus
  inherits all the common properties defined in snps,dw-pcie.yaml. Some of
  the controller instances are dual mode where in they can work either in
  Root Port mode or Endpoint mode but one at a time.

  See nvidia,tegra194-pcie-ep.yaml for details on the Endpoint mode device
  tree bindings.

properties:
  compatible:
    enum:
      - nvidia,tegra194-pcie
      - nvidia,tegra234-pcie

  reg:
    minItems: 4
    items:
      - description: controller's application logic registers
      - description: configuration registers
      - description: iATU and DMA registers. This is where the iATU (internal
          Address Translation Unit) registers of the PCIe core are made
          available for software access.
      - description: aperture where the Root Port's own configuration
          registers are available.
      - description: aperture to access the configuration space through ECAM.

  reg-names:
    minItems: 4
    items:
      - const: appl
      - const: config
      - const: atu_dma
      - const: dbi
      - const: ecam

  interrupts:
    items:
      - description: controller interrupt
      - description: MSI interrupt

  interrupt-names:
    items:
      - const: intr
      - const: msi

  clocks:
    items:
      - description: module clock

  clock-names:
    items:
      - const: core

  resets:
    items:
      - description: APB bus interface reset
      - description: module reset

  reset-names:
    items:
      - const: apb
      - const: core

  phys:
    minItems: 1
    maxItems: 8

  phy-names:
    minItems: 1
    items:
      - const: p2u-0
      - const: p2u-1
      - const: p2u-2
      - const: p2u-3
      - const: p2u-4
      - const: p2u-5
      - const: p2u-6
      - const: p2u-7

  power-domains:
    maxItems: 1
    description: |
      A phandle to the node that controls power to the respective PCIe
      controller and a specifier name for the PCIe controller.

      Tegra194 specifiers defined in "include/dt-bindings/power/tegra194-powergate.h"
      Tegra234 specifiers defined in "include/dt-bindings/power/tegra234-powergate.h"

  interconnects:
    items:
      - description: memory read client
      - description: memory write client

  interconnect-names:
    items:
      - const: dma-mem # read
      - const: write

  dma-coherent: true

  nvidia,bpmp:
    $ref: /schemas/types.yaml#/definitions/phandle-array
    description: |
      Must contain a pair of phandles to BPMP controller node followed by
      controller ID. Following are the controller IDs for each controller:

      Tegra194

        0: C0
        1: C1
        2: C2
        3: C3
        4: C4
        5: C5

      Tegra234

        0 : C0
        1 : C1
        2 : C2
        3 : C3
        4 : C4
        5 : C5
        6 : C6
        7 : C7
        8 : C8
        9 : C9
        10: C10

    items:
      - items:
          - description: phandle to BPMP controller node
          - description: PCIe controller ID
            maximum: 10

  nvidia,update-fc-fixup:
    description: |
      This is a boolean property and needs to be present to improve performance
      when a platform is designed in such a way that it satisfies at least one
      of the following conditions thereby enabling Root Port to exchange
      optimum number of FC (Flow Control) credits with downstream devices:

      NOTE: This is applicable only for Tegra194.

        1. If C0/C4/C5 run at x1/x2 link widths (irrespective of speed and MPS)
        2. If C0/C1/C2/C3/C4/C5 operate at their respective max link widths and
          a) speed is Gen-2 and MPS is 256B
          b) speed is >= Gen-3 with any MPS

    $ref: /schemas/types.yaml#/definitions/flag

  nvidia,aspm-cmrt-us:
    description: Common Mode Restore Time for proper operation of ASPM to be
      specified in microseconds

  nvidia,aspm-pwr-on-t-us:
    description: Power On time for proper operation of ASPM to be specified in
      microseconds

  nvidia,aspm-l0s-entrance-latency-us:
    description: ASPM L0s entrance latency to be specified in microseconds

  vddio-pex-ctl-supply:
    description: A phandle to the regulator supply for PCIe side band signals.

  vpcie3v3-supply:
    description: A phandle to the regulator node that supplies 3.3V to the slot
      if the platform has one such slot, e.g., x16 slot owned by C5 controller
      in p2972-0000 platform.

  vpcie12v-supply:
    description: A phandle to the regulator node that supplies 12V to the slot
      if the platform has one such slot, e.g., x16 slot owned by C5 controller
      in p2972-0000 platform.

  nvidia,enable-srns:
    description: |
      This boolean property needs to be present if the controller is
      configured to operate in SRNS (Separate Reference Clocks with No
      Spread-Spectrum Clocking).  NOTE: This is applicable only for
      Tegra234.

    $ref: /schemas/types.yaml#/definitions/flag

  nvidia,enable-ext-refclk:
    description: |
      This boolean property needs to be present if the controller is
      configured to use the reference clocking coming in from an external
      clock source instead of using the internal clock source.

    $ref: /schemas/types.yaml#/definitions/flag

allOf:
  - $ref: /schemas/pci/snps,dw-pcie.yaml#
  - if:
      properties:
        compatible:
          contains:
            enum:
              - nvidia,tegra194-pcie
    then:
      properties:
        reg:
          maxItems: 4
        reg-names:
          maxItems: 4

  - if:
      properties:
        compatible:
          contains:
            enum:
              - nvidia,tegra234-pcie
    then:
      properties:
        reg:
          minItems: 5
        reg-names:
          minItems: 5

unevaluatedProperties: false

required:
  - interrupts
  - interrupt-names
  - interrupt-map
  - interrupt-map-mask
  - clocks
  - clock-names
  - resets
  - reset-names
  - power-domains
  - vddio-pex-ctl-supply
  - num-lanes
  - phys
  - phy-names
  - nvidia,bpmp

examples:
  - |
    #include <dt-bindings/clock/tegra194-clock.h>
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/power/tegra194-powergate.h>
    #include <dt-bindings/reset/tegra194-reset.h>

    bus@0 {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges = <0x0 0x0 0x0 0x8 0x0>;

        pcie@14180000 {
            compatible = "nvidia,tegra194-pcie";
            power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>;
            reg = <0x0 0x14180000 0x0 0x00020000>, /* appl registers (128K)      */
                  <0x0 0x38000000 0x0 0x00040000>, /* configuration space (256K) */
                  <0x0 0x38040000 0x0 0x00040000>, /* iATU_DMA reg space (256K)  */
                  <0x0 0x38080000 0x0 0x00040000>; /* DBI reg space (256K)       */
            reg-names = "appl", "config", "atu_dma", "dbi";

            #address-cells = <3>;
            #size-cells = <2>;
            device_type = "pci";
            num-lanes = <8>;
            linux,pci-domain = <0>;

            pinctrl-names = "default";
            pinctrl-0 = <&pex_rst_c5_out_state>, <&clkreq_c5_bi_dir_state>;

            clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>;
            clock-names = "core";

            resets = <&bpmp TEGRA194_RESET_PEX0_CORE_0_APB>,
                     <&bpmp TEGRA194_RESET_PEX0_CORE_0>;
            reset-names = "apb", "core";

            interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
                         <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
            interrupt-names = "intr", "msi";

            #interrupt-cells = <1>;
            interrupt-map-mask = <0 0 0 0>;
            interrupt-map = <0 0 0 0 &gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;

            nvidia,bpmp = <&bpmp 0>;

            supports-clkreq;
            nvidia,aspm-cmrt-us = <60>;
            nvidia,aspm-pwr-on-t-us = <20>;
            nvidia,aspm-l0s-entrance-latency-us = <3>;

            bus-range = <0x0 0xff>;
            ranges = <0x81000000 0x0  0x38100000 0x0  0x38100000 0x0 0x00100000>, /* downstream I/O */
                     <0x82000000 0x0  0x38200000 0x0  0x38200000 0x0 0x01e00000>, /* non-prefetch memory */
                     <0xc2000000 0x18 0x00000000 0x18 0x00000000 0x4 0x00000000>; /* prefetchable memory */

            vddio-pex-ctl-supply = <&vdd_1v8ao>;
            vpcie3v3-supply = <&vdd_3v3_pcie>;
            vpcie12v-supply = <&vdd_12v_pcie>;

            phys = <&p2u_hsio_2>, <&p2u_hsio_3>, <&p2u_hsio_4>,
                   <&p2u_hsio_5>;
            phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3";
        };
    };

  - |
    #include <dt-bindings/clock/tegra234-clock.h>
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/power/tegra234-powergate.h>
    #include <dt-bindings/reset/tegra234-reset.h>

    bus@0 {
        #address-cells = <2>;
        #size-cells = <2>;
        ranges = <0x0 0x0 0x0 0x8 0x0>;

        pcie@14160000 {
            compatible = "nvidia,tegra234-pcie";
            power-domains = <&bpmp TEGRA234_POWER_DOMAIN_PCIEX4BB>;
            reg = <0x00 0x14160000 0x0 0x00020000>, /* appl registers (128K)      */
                  <0x00 0x36000000 0x0 0x00040000>, /* configuration space (256K) */
                  <0x00 0x36040000 0x0 0x00040000>, /* iATU_DMA reg space (256K)  */
                  <0x00 0x36080000 0x0 0x00040000>, /* DBI reg space (256K)       */
                  <0x24 0x30000000 0x0 0x10000000>; /* ECAM (256MB)               */
            reg-names = "appl", "config", "atu_dma", "dbi", "ecam";

            #address-cells = <3>;
            #size-cells = <2>;
            device_type = "pci";
            num-lanes = <4>;
            num-viewport = <8>;
            linux,pci-domain = <4>;

            clocks = <&bpmp TEGRA234_CLK_PEX0_C4_CORE>;
            clock-names = "core";

            resets = <&bpmp TEGRA234_RESET_PEX0_CORE_4_APB>,
                     <&bpmp TEGRA234_RESET_PEX0_CORE_4>;
            reset-names = "apb", "core";

            interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
                         <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
            interrupt-names = "intr", "msi";

            #interrupt-cells = <1>;
            interrupt-map-mask = <0 0 0 0>;
            interrupt-map = <0 0 0 0 &gic GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;

            nvidia,bpmp = <&bpmp 4>;

            nvidia,aspm-cmrt-us = <60>;
            nvidia,aspm-pwr-on-t-us = <20>;
            nvidia,aspm-l0s-entrance-latency-us = <3>;

            bus-range = <0x0 0xff>;
            ranges = <0x43000000 0x21 0x40000000 0x21 0x40000000 0x2 0xe8000000>, /* prefetchable */
                     <0x02000000 0x0  0x40000000 0x24 0x28000000 0x0 0x08000000>, /* non-prefetchable */
                     <0x01000000 0x0  0x36100000 0x00 0x36100000 0x0 0x00100000>; /* downstream I/O */

            vddio-pex-ctl-supply = <&p3701_vdd_AO_1v8>;

            phys = <&p2u_hsio_4>, <&p2u_hsio_5>, <&p2u_hsio_6>,
                   <&p2u_hsio_7>;
            phy-names = "p2u-0", "p2u-1", "p2u-2", "p2u-3";
        };
    };


code:
NVIDIA Tegra PCIe controller

Required properties:
- compatible: Must be:
  - "nvidia,tegra20-pcie": for Tegra20
  - "nvidia,tegra30-pcie": for Tegra30
  - "nvidia,tegra124-pcie": for Tegra124 and Tegra132
  - "nvidia,tegra210-pcie": for Tegra210
  - "nvidia,tegra186-pcie": for Tegra186
- power-domains: To ungate power partition by BPMP powergate driver. Must
  contain BPMP phandle and PCIe power partition ID. This is required only
  for Tegra186.
- device_type: Must be "pci"
- reg: A list of physical base address and length for each set of controller
  registers. Must contain an entry for each entry in the reg-names property.
- reg-names: Must include the following entries:
  "pads": PADS registers
  "afi": AFI registers
  "cs": configuration space region
- interrupts: A list of interrupt outputs of the controller. Must contain an
  entry for each entry in the interrupt-names property.
- interrupt-names: Must include the following entries:
  "intr": The Tegra interrupt that is asserted for controller interrupts
  "msi": The Tegra interrupt that is asserted when an MSI is received
- bus-range: Range of bus numbers associated with this controller
- #address-cells: Address representation for root ports (must be 3)
  - cell 0 specifies the bus and device numbers of the root port:
    [23:16]: bus number
    [15:11]: device number
  - cell 1 denotes the upper 32 address bits and should be 0
  - cell 2 contains the lower 32 address bits and is used to translate to the
    CPU address space
- #size-cells: Size representation for root ports (must be 2)
- ranges: Describes the translation of addresses for root ports and standard
  PCI regions. The entries must be 6 cells each, where the first three cells
  correspond to the address as described for the #address-cells property
  above, the fourth cell is the physical CPU address to translate to and the
  fifth and six cells are as described for the #size-cells property above.
  - The first two entries are expected to translate the addresses for the root
    port registers, which are referenced by the assigned-addresses property of
    the root port nodes (see below).
  - The remaining entries setup the mapping for the standard I/O, memory and
    prefetchable PCI regions. The first cell determines the type of region
    that is setup:
    - 0x81000000: I/O memory region
    - 0x82000000: non-prefetchable memory region
    - 0xc2000000: prefetchable memory region
  Please refer to the standard PCI bus binding document for a more detailed
  explanation.
- #interrupt-cells: Size representation for interrupts (must be 1)
- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties
  Please refer to the standard PCI bus binding document for a more detailed
  explanation.
- clocks: Must contain an entry for each entry in clock-names.
  See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
  - pex
  - afi
  - pll_e
  - cml (not required for Tegra20)
- resets: Must contain an entry for each entry in reset-names.
  See ../reset/reset.txt for details.
- reset-names: Must include the following entries:
  - pex
  - afi
  - pcie_x

Optional properties:
- pinctrl-names: A list of pinctrl state names. Must contain the following
  entries:
  - "default": active state, puts PCIe I/O out of deep power down state
  - "idle": puts PCIe I/O into deep power down state
- pinctrl-0: phandle for the default/active state of pin configurations.
- pinctrl-1: phandle for the idle state of pin configurations.

Required properties on Tegra124 and later (deprecated):
- phys: Must contain an entry for each entry in phy-names.
- phy-names: Must include the following entries:
  - pcie

These properties are deprecated in favour of per-lane PHYs define in each of
the root ports (see below).

Power supplies for Tegra20:
- avdd-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
- vdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
- avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
  supply 1.05 V.
- avdd-plle-supply: Power supply for PLLE, which is shared with SATA. Must
  supply 1.05 V.
- vddio-pex-clk-supply: Power supply for PCIe clock. Must supply 3.3 V.

Power supplies for Tegra30:
- Required:
  - avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
    supply 1.05 V.
  - avdd-plle-supply: Power supply for PLLE, which is shared with SATA. Must
    supply 1.05 V.
  - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
    supply 1.8 V.
  - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
    Must supply 3.3 V.
- Optional:
  - If lanes 0 to 3 are used:
    - avdd-pexa-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
    - vdd-pexa-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
  - If lanes 4 or 5 are used:
    - avdd-pexb-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
    - vdd-pexb-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.

Power supplies for Tegra124:
- Required:
  - avddio-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
  - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
  - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
    Must supply 3.3 V.
  - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
    supply 2.8-3.3 V.

Power supplies for Tegra210:
- Required:
  - hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output
    clocks. Must supply 1.8 V.
  - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
  - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
    supply 1.8 V.

Power supplies for Tegra186:
- Required:
  - dvdd-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
  - hvdd-pex-pll-supply: High-voltage supply for PLLE (shared with USB3). Must
    supply 1.8 V.
  - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
    Must supply 1.8 V.
  - vddio-pexctl-aud-supply: Power supply for PCIe side band signals. Must
    supply 1.8 V.

Root ports are defined as subnodes of the PCIe controller node.

Required properties:
- device_type: Must be "pci"
- assigned-addresses: Address and size of the port configuration registers
- reg: PCI bus address of the root port
- #address-cells: Must be 3
- #size-cells: Must be 2
- ranges: Sub-ranges distributed from the PCIe controller node. An empty
  property is sufficient.
- nvidia,num-lanes: Number of lanes to use for this port. Valid combinations
  are:
  - Root port 0 uses 4 lanes, root port 1 is unused.
  - Both root ports use 2 lanes.

Required properties for Tegra124 and later:
- phys: Must contain an phandle to a PHY for each entry in phy-names.
- phy-names: Must include an entry for each active lane. Note that the number
  of entries does not have to (though usually will) be equal to the specified
  number of lanes in the nvidia,num-lanes property. Entries are of the form
  "pcie-N": where N ranges from 0 to the value specified in nvidia,num-lanes.

Examples:
=========

Tegra20:
--------

SoC DTSI:

	pcie-controller@80003000 {
		compatible = "nvidia,tegra20-pcie";
		device_type = "pci";
		reg = <0x80003000 0x00000800   /* PADS registers */
		       0x80003800 0x00000200   /* AFI registers */
		       0x90000000 0x10000000>; /* configuration space */
		reg-names = "pads", "afi", "cs";
		interrupts = <0 98 0x04   /* controller interrupt */
		              0 99 0x04>; /* MSI interrupt */
		interrupt-names = "intr", "msi";

		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;

		bus-range = <0x00 0xff>;
		#address-cells = <3>;
		#size-cells = <2>;

		ranges = <0x82000000 0 0x80000000 0x80000000 0 0x00001000   /* port 0 registers */
			  0x82000000 0 0x80001000 0x80001000 0 0x00001000   /* port 1 registers */
			  0x81000000 0 0          0x82000000 0 0x00010000   /* downstream I/O */
			  0x82000000 0 0xa0000000 0xa0000000 0 0x10000000   /* non-prefetchable memory */
			  0xc2000000 0 0xb0000000 0xb0000000 0 0x10000000>; /* prefetchable memory */

		clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 118>;
		clock-names = "pex", "afi", "pll_e";
		resets = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>;
		reset-names = "pex", "afi", "pcie_x";
		status = "disabled";

		pci@1,0 {
			device_type = "pci";
			assigned-addresses = <0x82000800 0 0x80000000 0 0x1000>;
			reg = <0x000800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges;

			nvidia,num-lanes = <2>;
		};

		pci@2,0 {
			device_type = "pci";
			assigned-addresses = <0x82001000 0 0x80001000 0 0x1000>;
			reg = <0x001000 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;

			ranges;

			nvidia,num-lanes = <2>;
		};
	};

Board DTS:

	pcie-controller@80003000 {
		status = "okay";

		vdd-supply = <&pci_vdd_reg>;
		pex-clk-supply = <&pci_clk_reg>;

		/* root port 00:01.0 */
		pci@1,0 {
			status = "okay";

			/* bridge 01:00.0 (optional) */
			pci@0,0 {
				reg = <0x010000 0 0 0 0>;

				#address-cells = <3>;
				#size-cells = <2>;

				device_type = "pci";

				/* endpoint 02:00.0 */
				pci@0,0 {
					reg = <0x020000 0 0 0 0>;
				};
			};
		};
	};

Note that devices on the PCI bus are dynamically discovered using PCI's bus
enumeration and therefore don't need corresponding device nodes in DT. However
if a device on the PCI bus provides a non-probeable bus such as I2C or SPI,
device nodes need to be added in order to allow the bus' children to be
instantiated at the proper location in the operating system's device tree (as
illustrated by the optional nodes in the example above).

Tegra30:
--------

SoC DTSI:

	pcie-controller@3000 {
		compatible = "nvidia,tegra30-pcie";
		device_type = "pci";
		reg = <0x00003000 0x00000800   /* PADS registers */
		       0x00003800 0x00000200   /* AFI registers */
		       0x10000000 0x10000000>; /* configuration space */
		reg-names = "pads", "afi", "cs";
		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH   /* controller interrupt */
			      GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
		interrupt-names = "intr", "msi";

		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &intc GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;

		bus-range = <0x00 0xff>;
		#address-cells = <3>;
		#size-cells = <2>;

		ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000   /* port 0 configuration space */
			  0x82000000 0 0x00001000 0x00001000 0 0x00001000   /* port 1 configuration space */
			  0x82000000 0 0x00004000 0x00004000 0 0x00001000   /* port 2 configuration space */
			  0x81000000 0 0          0x02000000 0 0x00010000   /* downstream I/O */
			  0x82000000 0 0x20000000 0x20000000 0 0x08000000   /* non-prefetchable memory */
			  0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */

		clocks = <&tegra_car TEGRA30_CLK_PCIE>,
			 <&tegra_car TEGRA30_CLK_AFI>,
			 <&tegra_car TEGRA30_CLK_PLL_E>,
			 <&tegra_car TEGRA30_CLK_CML0>;
		clock-names = "pex", "afi", "pll_e", "cml";
		resets = <&tegra_car 70>,
			 <&tegra_car 72>,
			 <&tegra_car 74>;
		reset-names = "pex", "afi", "pcie_x";
		status = "disabled";

		pci@1,0 {
			device_type = "pci";
			assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>;
			reg = <0x000800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <2>;
		};

		pci@2,0 {
			device_type = "pci";
			assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>;
			reg = <0x001000 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <2>;
		};

		pci@3,0 {
			device_type = "pci";
			assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>;
			reg = <0x001800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <2>;
		};
	};

Board DTS:

	pcie-controller@3000 {
		status = "okay";

		avdd-pexa-supply = <&ldo1_reg>;
		vdd-pexa-supply = <&ldo1_reg>;
		avdd-pexb-supply = <&ldo1_reg>;
		vdd-pexb-supply = <&ldo1_reg>;
		avdd-pex-pll-supply = <&ldo1_reg>;
		avdd-plle-supply = <&ldo1_reg>;
		vddio-pex-ctl-supply = <&sys_3v3_reg>;
		hvdd-pex-supply = <&sys_3v3_pexs_reg>;

		pci@1,0 {
			status = "okay";
		};

		pci@3,0 {
			status = "okay";
		};
	};

Tegra124:
---------

SoC DTSI:

	pcie-controller@1003000 {
		compatible = "nvidia,tegra124-pcie";
		device_type = "pci";
		reg = <0x0 0x01003000 0x0 0x00000800   /* PADS registers */
		       0x0 0x01003800 0x0 0x00000800   /* AFI registers */
		       0x0 0x02000000 0x0 0x10000000>; /* configuration space */
		reg-names = "pads", "afi", "cs";
		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
			     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
		interrupt-names = "intr", "msi";

		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;

		bus-range = <0x00 0xff>;
		#address-cells = <3>;
		#size-cells = <2>;

		ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000   /* port 0 configuration space */
			  0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000   /* port 1 configuration space */
			  0x81000000 0 0x0        0x0 0x12000000 0 0x00010000   /* downstream I/O (64 KiB) */
			  0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000   /* non-prefetchable memory (208 MiB) */
			  0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */

		clocks = <&tegra_car TEGRA124_CLK_PCIE>,
			 <&tegra_car TEGRA124_CLK_AFI>,
			 <&tegra_car TEGRA124_CLK_PLL_E>,
			 <&tegra_car TEGRA124_CLK_CML0>;
		clock-names = "pex", "afi", "pll_e", "cml";
		resets = <&tegra_car 70>,
			 <&tegra_car 72>,
			 <&tegra_car 74>;
		reset-names = "pex", "afi", "pcie_x";
		status = "disabled";

		pci@1,0 {
			device_type = "pci";
			assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
			reg = <0x000800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <2>;
		};

		pci@2,0 {
			device_type = "pci";
			assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
			reg = <0x001000 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <1>;
		};
	};

Board DTS:

	pcie-controller@1003000 {
		status = "okay";

		avddio-pex-supply = <&vdd_1v05_run>;
		dvddio-pex-supply = <&vdd_1v05_run>;
		avdd-pex-pll-supply = <&vdd_1v05_run>;
		hvdd-pex-supply = <&vdd_3v3_lp0>;
		hvdd-pex-pll-e-supply = <&vdd_3v3_lp0>;
		vddio-pex-ctl-supply = <&vdd_3v3_lp0>;
		avdd-pll-erefe-supply = <&avdd_1v05_run>;

		/* Mini PCIe */
		pci@1,0 {
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
			phy-names = "pcie-0";
			status = "okay";
		};

		/* Gigabit Ethernet */
		pci@2,0 {
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>;
			phy-names = "pcie-0";
			status = "okay";
		};
	};

Tegra210:
---------

SoC DTSI:

	pcie-controller@1003000 {
		compatible = "nvidia,tegra210-pcie";
		device_type = "pci";
		reg = <0x0 0x01003000 0x0 0x00000800   /* PADS registers */
		       0x0 0x01003800 0x0 0x00000800   /* AFI registers */
		       0x0 0x02000000 0x0 0x10000000>; /* configuration space */
		reg-names = "pads", "afi", "cs";
		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
			     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
		interrupt-names = "intr", "msi";

		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;

		bus-range = <0x00 0xff>;
		#address-cells = <3>;
		#size-cells = <2>;

		ranges = <0x82000000 0 0x01000000 0x0 0x01000000 0 0x00001000   /* port 0 configuration space */
			  0x82000000 0 0x01001000 0x0 0x01001000 0 0x00001000   /* port 1 configuration space */
			  0x81000000 0 0x0        0x0 0x12000000 0 0x00010000   /* downstream I/O (64 KiB) */
			  0x82000000 0 0x13000000 0x0 0x13000000 0 0x0d000000   /* non-prefetchable memory (208 MiB) */
			  0xc2000000 0 0x20000000 0x0 0x20000000 0 0x20000000>; /* prefetchable memory (512 MiB) */

		clocks = <&tegra_car TEGRA210_CLK_PCIE>,
			 <&tegra_car TEGRA210_CLK_AFI>,
			 <&tegra_car TEGRA210_CLK_PLL_E>,
			 <&tegra_car TEGRA210_CLK_CML0>;
		clock-names = "pex", "afi", "pll_e", "cml";
		resets = <&tegra_car 70>,
			 <&tegra_car 72>,
			 <&tegra_car 74>;
		reset-names = "pex", "afi", "pcie_x";
		status = "disabled";

		pci@1,0 {
			device_type = "pci";
			assigned-addresses = <0x82000800 0 0x01000000 0 0x1000>;
			reg = <0x000800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <4>;
		};

		pci@2,0 {
			device_type = "pci";
			assigned-addresses = <0x82001000 0 0x01001000 0 0x1000>;
			reg = <0x001000 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <1>;
		};
	};

Board DTS:

	pcie-controller@1003000 {
		status = "okay";

		avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
		hvddio-pex-supply = <&vdd_1v8>;
		dvddio-pex-supply = <&vdd_pex_1v05>;
		dvdd-pex-pll-supply = <&vdd_pex_1v05>;
		hvdd-pex-pll-e-supply = <&vdd_1v8>;
		vddio-pex-ctl-supply = <&vdd_1v8>;

		pci@1,0 {
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-0}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-1}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-2}>,
			       <&{/padctl@7009f000/pads/pcie/lanes/pcie-3}>;
			phy-names = "pcie-0", "pcie-1", "pcie-2", "pcie-3";
			status = "okay";
		};

		pci@2,0 {
			phys = <&{/padctl@7009f000/pads/pcie/lanes/pcie-4}>;
			phy-names = "pcie-0";
			status = "okay";
		};
	};

Tegra186:
---------

SoC DTSI:

	pcie@10003000 {
		compatible = "nvidia,tegra186-pcie";
		power-domains = <&bpmp TEGRA186_POWER_DOMAIN_PCX>;
		device_type = "pci";
		reg = <0x0 0x10003000 0x0 0x00000800   /* PADS registers */
		       0x0 0x10003800 0x0 0x00000800   /* AFI registers */
		       0x0 0x40000000 0x0 0x10000000>; /* configuration space */
		reg-names = "pads", "afi", "cs";

		interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, /* controller interrupt */
			     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
		interrupt-names = "intr", "msi";

		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;

		bus-range = <0x00 0xff>;
		#address-cells = <3>;
		#size-cells = <2>;

		ranges = <0x82000000 0 0x10000000 0x0 0x10000000 0 0x00001000   /* port 0 configuration space */
			  0x82000000 0 0x10001000 0x0 0x10001000 0 0x00001000   /* port 1 configuration space */
			  0x82000000 0 0x10004000 0x0 0x10004000 0 0x00001000   /* port 2 configuration space */
			  0x81000000 0 0x0        0x0 0x50000000 0 0x00010000   /* downstream I/O (64 KiB) */
			  0x82000000 0 0x50100000 0x0 0x50100000 0 0x07F00000   /* non-prefetchable memory (127 MiB) */
			  0xc2000000 0 0x58000000 0x0 0x58000000 0 0x28000000>; /* prefetchable memory (640 MiB) */

		clocks = <&bpmp TEGRA186_CLK_AFI>,
			 <&bpmp TEGRA186_CLK_PCIE>,
			 <&bpmp TEGRA186_CLK_PLLE>;
		clock-names = "afi", "pex", "pll_e";

		resets = <&bpmp TEGRA186_RESET_AFI>,
			 <&bpmp TEGRA186_RESET_PCIE>,
			 <&bpmp TEGRA186_RESET_PCIEXCLK>;
		reset-names = "afi", "pex", "pcie_x";

		status = "disabled";

		pci@1,0 {
			device_type = "pci";
			assigned-addresses = <0x82000800 0 0x10000000 0 0x1000>;
			reg = <0x000800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <2>;
		};

		pci@2,0 {
			device_type = "pci";
			assigned-addresses = <0x82001000 0 0x10001000 0 0x1000>;
			reg = <0x001000 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <1>;
		};

		pci@3,0 {
			device_type = "pci";
			assigned-addresses = <0x82001800 0 0x10004000 0 0x1000>;
			reg = <0x001800 0 0 0 0>;
			status = "disabled";

			#address-cells = <3>;
			#size-cells = <2>;
			ranges;

			nvidia,num-lanes = <1>;
		};
	};

Board DTS:

	pcie@10003000 {
		status = "okay";

		dvdd-pex-supply = <&vdd_pex>;
		hvdd-pex-pll-supply = <&vdd_1v8>;
		hvdd-pex-supply = <&vdd_1v8>;
		vddio-pexctl-aud-supply = <&vdd_1v8>;

		pci@1,0 {
			nvidia,num-lanes = <4>;
			status = "okay";
		};

		pci@2,0 {
			nvidia,num-lanes = <0>;
			status = "disabled";
		};

		pci@3,0 {
			nvidia,num-lanes = <1>;
			status = "disabled";
		};
	};

repo_name: angery/linux


code:
* Marvell Armada 7K/8K PCIe interface

This PCIe host controller is based on the Synopsys DesignWare PCIe IP
and thus inherits all the common properties defined in snps,dw-pcie.yaml.

Required properties:
- compatible: "marvell,armada8k-pcie"
- reg: must contain two register regions
   - the control register region
   - the config space region
- reg-names:
   - "ctrl" for the control register region
   - "config" for the config space region
- interrupts: Interrupt specifier for the PCIe controller
- clocks: reference to the PCIe controller clocks
- clock-names: mandatory if there is a second clock, in this case the
   name must be "core" for the first clock and "reg" for the second
   one

Optional properties:
- phys: phandle(s) to PHY node(s) following the generic PHY bindings.
	Either 1, 2 or 4 PHYs might be needed depending on the number of
	PCIe lanes.
- phy-names: names of the PHYs corresponding to the number of lanes.
	Must be "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy" for
	2 PHYs.

Example:

	pcie@f2600000 {
		compatible = "marvell,armada8k-pcie", "snps,dw-pcie";
		reg = <0 0xf2600000 0 0x10000>, <0 0xf6f00000 0 0x80000>;
		reg-names = "ctrl", "config";
		#address-cells = <3>;
		#size-cells = <2>;
		#interrupt-cells = <1>;
		device_type = "pci";
		dma-coherent;

		bus-range = <0 0xff>;
		ranges = <0x81000000 0 0xf9000000 0  0xf9000000 0 0x10000	/* downstream I/O */
			  0x82000000 0 0xf6000000 0  0xf6000000 0 0xf00000>;	/* non-prefetchable memory */
		interrupt-map-mask = <0 0 0 0>;
		interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
		num-lanes = <1>;
		clocks = <&cpm_syscon0 1 13>;
	};


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

title: PCI Endpoint Controller Schema

description: |
  Common properties for PCI Endpoint Controller Nodes.

maintainers:
  - Kishon Vijay Abraham I <kishon@ti.com>

properties:
  $nodename:
    pattern: "^pcie-ep@"

  max-functions:
    description: Maximum number of functions that can be configured
    $ref: /schemas/types.yaml#/definitions/uint8
    minimum: 1
    default: 1
    maximum: 255

  max-virtual-functions:
    description: Array representing the number of virtual functions corresponding to each physical
      function
    $ref: /schemas/types.yaml#/definitions/uint8-array
    minItems: 1
    maxItems: 255

  max-link-speed:
    $ref: /schemas/types.yaml#/definitions/uint32
    enum: [ 1, 2, 3, 4 ]

  num-lanes:
    description: maximum number of lanes
    $ref: /schemas/types.yaml#/definitions/uint32
    minimum: 1
    default: 1
    maximum: 16

required:
  - compatible

additionalProperties: true


code:
This document describes the generic device tree binding for describing the
relationship between PCI(e) devices and IOMMU(s).

Each PCI(e) device under a root complex is uniquely identified by its Requester
ID (AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
Function number.

For the purpose of this document, when treated as a numeric value, a RID is
formatted such that:

* Bits [15:8] are the Bus number.
* Bits [7:3] are the Device number.
* Bits [2:0] are the Function number.
* Any other bits required for padding must be zero.

IOMMUs may distinguish PCI devices through sideband data derived from the
Requester ID. While a given PCI device can only master through one IOMMU, a
root complex may split masters across a set of IOMMUs (e.g. with one IOMMU per
bus).

The generic 'iommus' property is insufficient to describe this relationship,
and a mechanism is required to map from a PCI device to its IOMMU and sideband
data.

For generic IOMMU bindings, see
Documentation/devicetree/bindings/iommu/iommu.txt.

PCI root complex
================

Optional properties
-------------------

- iommu-map: Maps a Requester ID to an IOMMU and associated IOMMU specifier
  data.

  The property is an arbitrary number of tuples of
  (rid-base,iommu,iommu-base,length).

  Any RID r in the interval [rid-base, rid-base + length) is associated with
  the listed IOMMU, with the IOMMU specifier (r - rid-base + iommu-base).

- iommu-map-mask: A mask to be applied to each Requester ID prior to being
  mapped to an IOMMU specifier per the iommu-map property.

Example (1)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	iommu: iommu@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the IOMMU is the RID,
		 * identity-mapped.
		 */
		iommu-map = <0x0 &iommu 0x0 0x10000>;
	};
};

Example (2)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	iommu: iommu@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the IOMMU is the RID with the
		 * function bits masked out.
		 */
		iommu-map = <0x0 &iommu 0x0 0x10000>;
		iommu-map-mask = <0xfff8>;
	};
};

Example (3)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	iommu: iommu@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the IOMMU is the RID,
		 * but the high bits of the bus number are flipped.
		 */
		iommu-map = <0x0000 &iommu 0x8000 0x8000>,
			    <0x8000 &iommu 0x0000 0x8000>;
	};
};

Example (4)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	iommu_a: iommu@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	iommu_b: iommu@b {
		reg = <0xb 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	iommu_c: iommu@c {
		reg = <0xc 0x1>;
		compatible = "vendor,some-iommu";
		#iommu-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * Devices with bus number 0-127 are mastered via IOMMU
		 * a, with sideband data being RID[14:0].
		 * Devices with bus number 128-255 are mastered via
		 * IOMMU b, with sideband data being RID[14:0].
		 * No devices master via IOMMU c.
		 */
		iommu-map = <0x0000 &iommu_a 0x0000 0x8000>,
			    <0x8000 &iommu_b 0x0000 0x8000>;
	};
};


code:
This document describes the generic device tree binding for describing the
relationship between PCI devices and MSI controllers.

Each PCI device under a root complex is uniquely identified by its Requester ID
(AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
Function number.

For the purpose of this document, when treated as a numeric value, a RID is
formatted such that:

* Bits [15:8] are the Bus number.
* Bits [7:3] are the Device number.
* Bits [2:0] are the Function number.
* Any other bits required for padding must be zero.

MSIs may be distinguished in part through the use of sideband data accompanying
writes. In the case of PCI devices, this sideband data may be derived from the
Requester ID. A mechanism is required to associate a device with both the MSI
controllers it can address, and the sideband data that will be associated with
its writes to those controllers.

For generic MSI bindings, see
Documentation/devicetree/bindings/interrupt-controller/msi.txt.

PCI root complex
================

Optional properties
-------------------

- msi-map: Maps a Requester ID to an MSI controller and associated
  msi-specifier data. The property is an arbitrary number of tuples of
  (rid-base,msi-controller,msi-base,length), where:

  * rid-base is a single cell describing the first RID matched by the entry.

  * msi-controller is a single phandle to an MSI controller

  * msi-base is an msi-specifier describing the msi-specifier produced for the
    first RID matched by the entry.

  * length is a single cell describing how many consecutive RIDs are matched
    following the rid-base.

  Any RID r in the interval [rid-base, rid-base + length) is associated with
  the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).

- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
  to an msi-specifier per the msi-map property.

- msi-parent: Describes the MSI parent of the root complex itself. Where
  the root complex and MSI controller do not pass sideband data with MSI
  writes, this property may be used to describe the MSI controller(s)
  used by PCI devices under the root complex, if defined as such in the
  binding for the root complex.

Example (1)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	msi: msi-controller@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the MSI controller is
		 * the RID, identity-mapped.
		 */
		msi-map = <0x0 &msi_a 0x0 0x10000>,
	};
};

Example (2)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	msi: msi-controller@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the MSI controller is
		 * the RID, masked to only the device and function bits.
		 */
		msi-map = <0x0 &msi_a 0x0 0x100>,
		msi-map-mask = <0xff>
	};
};

Example (3)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	msi: msi-controller@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the MSI controller is
		 * the RID, but the high bit of the bus number is
		 * ignored.
		 */
		msi-map = <0x0000 &msi 0x0000 0x8000>,
			  <0x8000 &msi 0x0000 0x8000>;
	};
};

Example (4)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	msi: msi-controller@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to the MSI controller is
		 * the RID, but the high bit of the bus number is
		 * negated.
		 */
		msi-map = <0x0000 &msi 0x8000 0x8000>,
			  <0x8000 &msi 0x0000 0x8000>;
	};
};

Example (5)
===========

/ {
	#address-cells = <1>;
	#size-cells = <1>;

	msi_a: msi-controller@a {
		reg = <0xa 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	msi_b: msi-controller@b {
		reg = <0xb 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	msi_c: msi-controller@c {
		reg = <0xc 0x1>;
		compatible = "vendor,some-controller";
		msi-controller;
		#msi-cells = <1>;
	};

	pci: pci@f {
		reg = <0xf 0x1>;
		compatible = "vendor,pcie-root-complex";
		device_type = "pci";

		/*
		 * The sideband data provided to MSI controller a is the
		 * RID, but the high bit of the bus number is negated.
		 * The sideband data provided to MSI controller b is the
		 * RID, identity-mapped.
		 * MSI controller c is not addressable.
		 */
		msi-map = <0x0000 &msi_a 0x8000 0x08000>,
			  <0x8000 &msi_a 0x0000 0x08000>,
			  <0x0000 &msi_b 0x0000 0x10000>;
	};
};


code:
PCI bus bridges have standardized Device Tree bindings:

PCI Bus Binding to: IEEE Std 1275-1994
https://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf

And for the interrupt mapping part:

Open Firmware Recommended Practice: Interrupt Mapping
https://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf

Additionally to the properties specified in the above standards a host bridge
driver implementation may support the following properties:

- linux,pci-domain:
   If present this property assigns a fixed PCI domain number to a host bridge,
   otherwise an unstable (across boots) unique number will be assigned.
   It is required to either not set this property at all or set it for all
   host bridges in the system, otherwise potentially conflicting domain numbers
   may be assigned to root buses behind different host bridges.  The domain
   number for each host bridge in the system must be unique.
- max-link-speed:
   If present this property specifies PCI gen for link capability.  Host
   drivers could add this as a strategy to avoid unnecessary operation for
   unsupported link speed, for instance, trying to do training for
   unsupported link speed, etc.  Must be '4' for gen4, '3' for gen3, '2'
   for gen2, and '1' for gen1. Any other values are invalid.
- reset-gpios:
   If present this property specifies PERST# GPIO. Host drivers can parse the
   GPIO and apply fundamental reset to endpoints.
- supports-clkreq:
   If present this property specifies that CLKREQ signal routing exists from
   root port to downstream device and host bridge drivers can do programming
   which depends on CLKREQ signal existence. For example, programming root port
   not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.

PCI-PCI Bridge properties
-------------------------

PCIe root ports and switch ports may be described explicitly in the device
tree, as children of the host bridge node. Even though those devices are
discoverable by probing, it might be necessary to describe properties that
aren't provided by standard PCIe capabilities.

Required properties:

- reg:
   Identifies the PCI-PCI bridge. As defined in the IEEE Std 1275-1994
   document, it is a five-cell address encoded as (phys.hi phys.mid
   phys.lo size.hi size.lo). phys.hi should contain the device's BDF as
   0b00000000 bbbbbbbb dddddfff 00000000. The other cells should be zero.

   The bus number is defined by firmware, through the standard bridge
   configuration mechanism. If this port is a switch port, then firmware
   allocates the bus number and writes it into the Secondary Bus Number
   register of the bridge directly above this port. Otherwise, the bus
   number of a root port is the first number in the bus-range property,
   defaulting to zero.

   If firmware leaves the ARI Forwarding Enable bit set in the bridge
   above this port, then phys.hi contains the 8-bit function number as
   0b00000000 bbbbbbbb ffffffff 00000000. Note that the PCIe specification
   recommends that firmware only leaves ARI enabled when it knows that the
   OS is ARI-aware.

Optional properties:

- external-facing:
   When present, the port is external-facing. All bridges and endpoints
   downstream of this port are external to the machine. The OS can, for
   example, use this information to identify devices that cannot be
   trusted with relaxed DMA protection, as users could easily attach
   malicious devices to this port.

Example:

pcie@10000000 {
	compatible = "pci-host-ecam-generic";
	...
	pcie@0008 {
		/* Root port 00:01.0 is external-facing */
		reg = <0x00000800 0 0 0 0>;
		external-facing;
	};
};


code:
* Amazon Annapurna Labs PCIe host bridge

Amazon's Annapurna Labs PCIe Host Controller is based on the Synopsys DesignWare
PCI core. It inherits common properties defined in
Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml.

Properties of the host controller node that differ from it are:

- compatible:
	Usage: required
	Value type: <stringlist>
	Definition: Value should contain
			- "amazon,al-alpine-v2-pcie" for alpine_v2
			- "amazon,al-alpine-v3-pcie" for alpine_v3

- reg:
	Usage: required
	Value type: <prop-encoded-array>
	Definition: Register ranges as listed in the reg-names property

- reg-names:
	Usage: required
	Value type: <stringlist>
	Definition: Must include the following entries
			- "config"	PCIe ECAM space
			- "controller"	AL proprietary registers
			- "dbi"		Designware PCIe registers

Example:

	pcie-external0: pcie@fb600000 {
		compatible = "amazon,al-alpine-v3-pcie";
		reg = <0x0 0xfb600000 0x0 0x00100000
		       0x0 0xfd800000 0x0 0x00010000
		       0x0 0xfd810000 0x0 0x00001000>;
		reg-names = "config", "controller", "dbi";
		bus-range = <0 255>;
		device_type = "pci";
		#address-cells = <3>;
		#size-cells = <2>;
		#interrupt-cells = <1>;
		interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
		interrupt-map-mask = <0x00 0 0 7>;
		interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; /* INTa */
		ranges = <0x02000000 0x0 0xc0010000 0x0 0xc0010000 0x0 0x07ff0000>;
	};


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

title: Qualcomm PCIe Endpoint Controller binding

maintainers:
  - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

properties:
  compatible:
    enum:
      - qcom,sdx55-pcie-ep
      - qcom,sm8450-pcie-ep

  reg:
    items:
      - description: Qualcomm-specific PARF configuration registers
      - description: DesignWare PCIe registers
      - description: External local bus interface registers
      - description: Address Translation Unit (ATU) registers
      - description: Memory region used to map remote RC address space
      - description: BAR memory region

  reg-names:
    items:
      - const: parf
      - const: dbi
      - const: elbi
      - const: atu
      - const: addr_space
      - const: mmio

  clocks:
    minItems: 7
    maxItems: 8

  clock-names:
    minItems: 7
    maxItems: 8

  qcom,perst-regs:
    description: Reference to a syscon representing TCSR followed by the two
                 offsets within syscon for Perst enable and Perst separation
                 enable registers
    $ref: "/schemas/types.yaml#/definitions/phandle-array"
    items:
      minItems: 3
      maxItems: 3

  interrupts:
    items:
      - description: PCIe Global interrupt
      - description: PCIe Doorbell interrupt

  interrupt-names:
    items:
      - const: global
      - const: doorbell

  reset-gpios:
    description: GPIO used as PERST# input signal
    maxItems: 1

  wake-gpios:
    description: GPIO used as WAKE# output signal
    maxItems: 1

  resets:
    maxItems: 1

  reset-names:
    const: core

  power-domains:
    maxItems: 1

  phys:
    maxItems: 1

  phy-names:
    const: pciephy

  num-lanes:
    default: 2

required:
  - compatible
  - reg
  - reg-names
  - clocks
  - clock-names
  - interrupts
  - interrupt-names
  - reset-gpios
  - resets
  - reset-names
  - power-domains

allOf:
  - $ref: pci-ep.yaml#
  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sdx55-pcie-ep
    then:
      properties:
        clocks:
          items:
            - description: PCIe Auxiliary clock
            - description: PCIe CFG AHB clock
            - description: PCIe Master AXI clock
            - description: PCIe Slave AXI clock
            - description: PCIe Slave Q2A AXI clock
            - description: PCIe Sleep clock
            - description: PCIe Reference clock
        clock-names:
          items:
            - const: aux
            - const: cfg
            - const: bus_master
            - const: bus_slave
            - const: slave_q2a
            - const: sleep
            - const: ref

  - if:
      properties:
        compatible:
          contains:
            enum:
              - qcom,sm8450-pcie-ep
    then:
      properties:
        clocks:
          items:
            - description: PCIe Auxiliary clock
            - description: PCIe CFG AHB clock
            - description: PCIe Master AXI clock
            - description: PCIe Slave AXI clock
            - description: PCIe Slave Q2A AXI clock
            - description: PCIe Reference clock
            - description: PCIe DDRSS SF TBU clock
            - description: PCIe AGGRE NOC AXI clock
        clock-names:
          items:
            - const: aux
            - const: cfg
            - const: bus_master
            - const: bus_slave
            - const: slave_q2a
            - const: ref
            - const: ddrss_sf_tbu
            - const: aggre_noc_axi

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/clock/qcom,gcc-sdx55.h>
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    pcie_ep: pcie-ep@40000000 {
        compatible = "qcom,sdx55-pcie-ep";
        reg = <0x01c00000 0x3000>,
              <0x40000000 0xf1d>,
              <0x40000f20 0xc8>,
              <0x40001000 0x1000>,
              <0x40002000 0x1000>,
              <0x01c03000 0x3000>;
        reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
                    "mmio";

        clocks = <&gcc GCC_PCIE_AUX_CLK>,
             <&gcc GCC_PCIE_CFG_AHB_CLK>,
             <&gcc GCC_PCIE_MSTR_AXI_CLK>,
             <&gcc GCC_PCIE_SLV_AXI_CLK>,
             <&gcc GCC_PCIE_SLV_Q2A_AXI_CLK>,
             <&gcc GCC_PCIE_SLEEP_CLK>,
             <&gcc GCC_PCIE_0_CLKREF_CLK>;
        clock-names = "aux", "cfg", "bus_master", "bus_slave",
                      "slave_q2a", "sleep", "ref";

        qcom,perst-regs = <&tcsr 0xb258 0xb270>;

        interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
                     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-names = "global", "doorbell";
        reset-gpios = <&tlmm 57 GPIO_ACTIVE_LOW>;
        wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>;
        resets = <&gcc GCC_PCIE_BCR>;
        reset-names = "core";
        power-domains = <&gcc PCIE_GDSC>;
        phys = <&pcie0_lane>;
        phy-names = "pciephy";
        max-link-speed = <3>;
        num-lanes = <2>;
    };


code:
# 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

  dma-coherent: true

  interconnects:
    maxItems: 2

  interconnect-names:
    items:
      - const: pcie-mem
      - const: cpu-pcie

  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:
      properties:
        compatible:
          contains:
            enum:
              - qcom,pcie-sa8540p
              - qcom,pcie-sc8280xp
    then:
      required:
        - interconnects
        - interconnect-names

  - 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";
    };
...


code:
* Mediatek/Ralink RT3883 PCI controller

1) Main node

   Required properties:

   - compatible: must be "ralink,rt3883-pci"

   - reg: specifies the physical base address of the controller and
     the length of the memory mapped region.

   - #address-cells: specifies the number of cells needed to encode an
     address. The value must be 1.

   - #size-cells: specifies the number of cells used to represent the size
     of an address. The value must be 1.

   - ranges: specifies the translation between child address space and parent
     address space

  Optional properties:

   - status: indicates the operational status of the device.
     Value must be either "disabled" or "okay".

2) Child nodes

   The main node must have two child nodes which describes the built-in
   interrupt controller and the PCI host bridge.

   a) Interrupt controller:

   Required properties:

   - interrupt-controller: identifies the node as an interrupt controller

   - #address-cells: specifies the number of cells needed to encode an
     address. The value must be 0. As such, 'interrupt-map' nodes do not
     have to specify a parent unit address.

   - #interrupt-cells: specifies the number of cells needed to encode an
     interrupt source. The value must be 1.

   - interrupts: specifies the interrupt source of the parent interrupt
     controller. The format of the interrupt specifier depends on the
     parent interrupt controller.

   b) PCI host bridge:

   Required properties:

   - #address-cells: specifies the number of cells needed to encode an
     address. The value must be 0.

   - #size-cells: specifies the number of cells used to represent the size
     of an address. The value must be 2.

   - #interrupt-cells: specifies the number of cells needed to encode an
     interrupt source. The value must be 1.

   - device_type: must be "pci"

   - bus-range: PCI bus numbers covered

   - ranges: specifies the ranges for the PCI memory and I/O regions

   - interrupt-map-mask,
   - interrupt-map: standard PCI properties to define the mapping of the
     PCI interface to interrupt numbers.

   The PCI host bridge node might have additional sub-nodes representing
   the onboard PCI devices/PCI slots. Each such sub-node must have the
   following mandatory properties:

     - reg: used only for interrupt mapping, so only the first four bytes
       are used to refer to the correct bus number and device number.

     - device_type: must be "pci"

   If a given sub-node represents a PCI bridge it must have following
   mandatory properties as well:

     - #address-cells: must be set to <3>

     - #size-cells: must set to <2>

     - #interrupt-cells: must be set to <1>

     - interrupt-map-mask,
     - interrupt-map: standard PCI properties to define the mapping of the
       PCI interface to interrupt numbers.

   Besides the required properties the sub-nodes may have these optional
   properties:

     - status: indicates the operational status of the sub-node.
       Value must be either "disabled" or "okay".

3) Example:

   a) SoC specific dtsi file:

	pci@10140000 {
		compatible = "ralink,rt3883-pci";
		reg = <0x10140000 0x20000>;
		#address-cells = <1>;
		#size-cells = <1>;
		ranges; /* direct mapping */

		status = "disabled";

		pciintc: interrupt-controller {
			interrupt-controller;
			#address-cells = <0>;
			#interrupt-cells = <1>;

			interrupt-parent = <&cpuintc>;
			interrupts = <4>;
		};

		host-bridge {
			#address-cells = <3>;
			#size-cells = <2>;
			#interrupt-cells = <1>;

			device_type = "pci";

			bus-range = <0 255>;
			ranges = <
				0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
				0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
			>;

			interrupt-map-mask = <0xf800 0 0 7>;
			interrupt-map = <
				/* IDSEL 17 */
				0x8800 0 0 1 &pciintc 18
				0x8800 0 0 2 &pciintc 18
				0x8800 0 0 3 &pciintc 18
				0x8800 0 0 4 &pciintc 18
				/* IDSEL 18 */
				0x9000 0 0 1 &pciintc 19
				0x9000 0 0 2 &pciintc 19
				0x9000 0 0 3 &pciintc 19
				0x9000 0 0 4 &pciintc 19
			>;

			pci-bridge@1 {
				reg = <0x0800 0 0 0 0>;
				device_type = "pci";
				#interrupt-cells = <1>;
				#address-cells = <3>;
				#size-cells = <2>;

				interrupt-map-mask = <0x0 0 0 0>;
				interrupt-map = <0x0 0 0 0 &pciintc 20>;

				status = "disabled";
			};

			pci-slot@17 {
				reg = <0x8800 0 0 0 0>;
				device_type = "pci";

				status = "disabled";
			};

			pci-slot@18 {
				reg = <0x9000 0 0 0 0>;
				device_type = "pci";

				status = "disabled";
			};
		};
	};

   b) Board specific dts file:

	pci@10140000 {
		status = "okay";

		host-bridge {
			pci-bridge@1 {
				status = "okay";
			};
		};
	};


code:
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2020 Renesas Electronics Europe GmbH - https://www.renesas.com/eu/en/
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/rcar-pci-ep.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Renesas R-Car PCIe Endpoint

maintainers:
  - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
  - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

properties:
  compatible:
    items:
      - enum:
          - renesas,r8a774a1-pcie-ep     # RZ/G2M
          - renesas,r8a774b1-pcie-ep     # RZ/G2N
          - renesas,r8a774c0-pcie-ep     # RZ/G2E
          - renesas,r8a774e1-pcie-ep     # RZ/G2H
          - renesas,r8a7795-pcie-ep      # R-Car H3
      - const: renesas,rcar-gen3-pcie-ep # R-Car Gen3 and RZ/G2

  reg:
    maxItems: 5

  reg-names:
    items:
      - const: apb-base
      - const: memory0
      - const: memory1
      - const: memory2
      - const: memory3

  interrupts:
    minItems: 3
    maxItems: 3

  power-domains:
    maxItems: 1

  resets:
    maxItems: 1

  clocks:
    maxItems: 1

  clock-names:
    items:
      - const: pcie

  max-functions:
    minimum: 1
    maximum: 1

required:
  - compatible
  - reg
  - reg-names
  - interrupts
  - resets
  - power-domains
  - clocks
  - clock-names
  - max-functions

additionalProperties: false

examples:
  - |
    #include <dt-bindings/clock/r8a774c0-cpg-mssr.h>
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/power/r8a774c0-sysc.h>

     pcie0_ep: pcie-ep@fe000000 {
            compatible = "renesas,r8a774c0-pcie-ep",
                         "renesas,rcar-gen3-pcie-ep";
            reg = <0xfe000000 0x80000>,
                  <0xfe100000 0x100000>,
                  <0xfe200000 0x200000>,
                  <0x30000000 0x8000000>,
                  <0x38000000 0x8000000>;
            reg-names = "apb-base", "memory0", "memory1", "memory2", "memory3";
            interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                         <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                         <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
            resets = <&cpg 319>;
            power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
            clocks = <&cpg CPG_MOD 319>;
            clock-names = "pcie";
            max-functions = /bits/ 8 <1>;
    };


code:
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2020 Renesas Electronics Corp.
%YAML 1.2
---
$id: http://devicetree.org/schemas/pci/rcar-pci-host.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Renesas R-Car PCIe Host

maintainers:
  - Marek Vasut <marek.vasut+renesas@gmail.com>
  - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

allOf:
  - $ref: pci-bus.yaml#

properties:
  compatible:
    oneOf:
      - const: renesas,pcie-r8a7779       # R-Car H1
      - items:
          - enum:
              - renesas,pcie-r8a7742      # RZ/G1H
              - renesas,pcie-r8a7743      # RZ/G1M
              - renesas,pcie-r8a7744      # RZ/G1N
              - renesas,pcie-r8a7790      # R-Car H2
              - renesas,pcie-r8a7791      # R-Car M2-W
              - renesas,pcie-r8a7793      # R-Car M2-N
          - const: renesas,pcie-rcar-gen2 # R-Car Gen2 and RZ/G1
      - items:
          - enum:
              - renesas,pcie-r8a774a1     # RZ/G2M
              - renesas,pcie-r8a774b1     # RZ/G2N
              - renesas,pcie-r8a774c0     # RZ/G2E
              - renesas,pcie-r8a774e1     # RZ/G2H
              - renesas,pcie-r8a7795      # R-Car H3
              - renesas,pcie-r8a7796      # R-Car M3-W
              - renesas,pcie-r8a77961     # R-Car M3-W+
              - renesas,pcie-r8a77965     # R-Car M3-N
              - renesas,pcie-r8a77980     # R-Car V3H
              - renesas,pcie-r8a77990     # R-Car E3
          - const: renesas,pcie-rcar-gen3 # R-Car Gen3 and RZ/G2

  reg:
    maxItems: 1

  interrupts:
    minItems: 3
    maxItems: 3

  clocks:
    maxItems: 2

  clock-names:
    items:
      - const: pcie
      - const: pcie_bus

  power-domains:
    maxItems: 1

  resets:
    maxItems: 1

  phys:
    maxItems: 1

  phy-names:
    const: pcie

required:
  - compatible
  - reg
  - interrupts
  - clocks
  - clock-names
  - power-domains

if:
  not:
    properties:
      compatible:
        contains:
          const: renesas,pcie-r8a7779
then:
  required:
    - resets

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/clock/r8a7791-cpg-mssr.h>
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/power/r8a7791-sysc.h>

    soc {
        #address-cells = <2>;
        #size-cells = <2>;

        pcie: pcie@fe000000 {
            compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2";
            reg = <0 0xfe000000 0 0x80000>;
             #address-cells = <3>;
             #size-cells = <2>;
             bus-range = <0x00 0xff>;
             device_type = "pci";
             ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
                      <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
                      <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
                      <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
             dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x40000000>,
                          <0x42000000 2 0x00000000 2 0x00000000 0 0x40000000>;
             interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                          <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                          <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
             #interrupt-cells = <1>;
             interrupt-map-mask = <0 0 0 0>;
             interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
             clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
             clock-names = "pcie", "pcie_bus";
             power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
             resets = <&cpg 319>;
         };
    };


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

title: Renesas AHB to PCI bridge

maintainers:
  - Marek Vasut <marek.vasut+renesas@gmail.com>
  - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

description: |
  This is the bridge used internally to connect the USB controllers to the
  AHB. There is one bridge instance per USB port connected to the internal
  OHCI and EHCI controllers.

properties:
  compatible:
    oneOf:
      - items:
          - enum:
              - renesas,pci-r8a7742      # RZ/G1H
              - renesas,pci-r8a7743      # RZ/G1M
              - renesas,pci-r8a7744      # RZ/G1N
              - renesas,pci-r8a7745      # RZ/G1E
              - renesas,pci-r8a7790      # R-Car H2
              - renesas,pci-r8a7791      # R-Car M2-W
              - renesas,pci-r8a7793      # R-Car M2-N
              - renesas,pci-r8a7794      # R-Car E2
          - const: renesas,pci-rcar-gen2 # R-Car Gen2 and RZ/G1
      - items:
          - enum:
              - renesas,pci-r9a06g032     # RZ/N1D
          - const: renesas,pci-rzn1       # RZ/N1

  reg:
    items:
      - description: Operational registers for the OHCI/EHCI controllers.
      - description: Bridge configuration and control registers.

  interrupts:
    maxItems: 1

  clocks: true

  clock-names: true

  resets:
    maxItems: 1

  power-domains:
    maxItems: 1

  bus-range:
    description: |
      The PCI bus number range; as this is a single bus, the range
      should be specified as the same value twice.

  dma-ranges:
    description: |
      A single range for the inbound memory region. If not supplied,
      defaults to 1GiB at 0x40000000. Note there are hardware restrictions on
      the allowed combinations of address and size.
    maxItems: 1

patternProperties:
  '^usb@[0-1],0$':
    type: object

    description:
      This a USB controller PCI device

    properties:
      reg:
        description:
          Identify the correct bus, device and function number in the
          form <bdf 0 0 0 0>.

        items:
          minItems: 5
          maxItems: 5

      phys:
        description:
          Reference to the USB phy
        maxItems: 1

      phy-names:
        maxItems: 1

    required:
      - reg
      - phys
      - phy-names

    unevaluatedProperties: false

required:
  - compatible
  - reg
  - interrupts
  - interrupt-map
  - interrupt-map-mask
  - clocks
  - power-domains
  - bus-range
  - "#address-cells"
  - "#size-cells"
  - "#interrupt-cells"

allOf:
  - $ref: /schemas/pci/pci-bus.yaml#

  - if:
      properties:
        compatible:
          contains:
            enum:
              - renesas,pci-rzn1
    then:
      properties:
        clocks:
          items:
            - description: Internal bus clock (AHB) for HOST
            - description: Internal bus clock (AHB) Power Management
            - description: PCI clock for USB subsystem
        clock-names:
          items:
            - const: hclkh
            - const: hclkpm
            - const: pciclk
      required:
        - clock-names
    else:
      properties:
        clocks:
          items:
            - description: Device clock
        clock-names:
          items:
            - const: pclk
      required:
        - resets

unevaluatedProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/arm-gic.h>
    #include <dt-bindings/clock/r8a7790-cpg-mssr.h>
    #include <dt-bindings/power/r8a7790-sysc.h>

    pci@ee090000  {
        compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2";
        device_type = "pci";
        reg = <0xee090000 0xc00>,
              <0xee080000 0x1100>;
        clocks = <&cpg CPG_MOD 703>;
        power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
        resets = <&cpg 703>;
        interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;

        bus-range = <0 0>;
        #address-cells = <3>;
        #size-cells = <2>;
        #interrupt-cells = <1>;
        ranges = <0x02000000 0 0xee080000 0xee080000 0 0x00010000>;
        dma-ranges = <0x42000000 0 0x40000000 0x40000000 0 0x40000000>;
        interrupt-map-mask = <0xf800 0 0 0x7>;
        interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
                        <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
                        <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;

        usb@1,0 {
            reg = <0x800 0 0 0 0>;
            phys = <&usb0 0>;
            phy-names = "usb";
        };

        usb@2,0 {
            reg = <0x1000 0 0 0 0>;
            phys = <&usb0 0>;
            phy-names = "usb";
        };
    };


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

title: DesignWare based PCIe controller on Rockchip SoCs

maintainers:
  - Shawn Lin <shawn.lin@rock-chips.com>
  - Simon Xue <xxm@rock-chips.com>
  - Heiko Stuebner <heiko@sntech.de>

description: |+
  RK3568 SoC PCIe host controller is based on the Synopsys DesignWare
  PCIe IP and thus inherits all the common properties defined in
  snps,dw-pcie.yaml.

allOf:
  - $ref: /schemas/pci/snps,dw-pcie.yaml#

properties:
  compatible:
    items:
      - const: rockchip,rk3568-pcie

  reg:
    items:
      - description: Data Bus Interface (DBI) registers
      - description: Rockchip designed configuration registers
      - description: Config registers

  reg-names:
    items:
      - const: dbi
      - const: apb
      - const: config

  clocks:
    items:
      - description: AHB clock for PCIe master
      - description: AHB clock for PCIe slave
      - description: AHB clock for PCIe dbi
      - description: APB clock for PCIe
      - description: Auxiliary clock for PCIe

  clock-names:
    items:
      - const: aclk_mst
      - const: aclk_slv
      - const: aclk_dbi
      - const: pclk
      - const: aux

  msi-map: true

  num-lanes: true

  phys:
    maxItems: 1

  phy-names:
    const: pcie-phy

  power-domains:
    maxItems: 1

  ranges:
    maxItems: 2

  resets:
    maxItems: 1

  reset-names:
    const: pipe

  vpcie3v3-supply: true

required:
  - compatible
  - reg
  - reg-names
  - clocks
  - clock-names
  - msi-map
  - num-lanes
  - phys
  - phy-names
  - power-domains
  - resets
  - reset-names

unevaluatedProperties: false

examples:
  - |

    bus {
        #address-cells = <2>;
        #size-cells = <2>;

        pcie3x2: pcie@fe280000 {
            compatible = "rockchip,rk3568-pcie";
            reg = <0x3 0xc0800000 0x0 0x390000>,
                  <0x0 0xfe280000 0x0 0x10000>,
                  <0x3 0x80000000 0x0 0x100000>;
            reg-names = "dbi", "apb", "config";
            bus-range = <0x20 0x2f>;
            clocks = <&cru 143>, <&cru 144>,
                     <&cru 145>, <&cru 146>,
                     <&cru 147>;
            clock-names = "aclk_mst", "aclk_slv",
                          "aclk_dbi", "pclk",
                          "aux";
            device_type = "pci";
            linux,pci-domain = <2>;
            max-link-speed = <2>;
            msi-map = <0x2000 &its 0x2000 0x1000>;
            num-lanes = <2>;
            phys = <&pcie30phy>;
            phy-names = "pcie-phy";
            power-domains = <&power 15>;
            ranges = <0x81000000 0x0 0x80800000 0x3 0x80800000 0x0 0x100000>,
                     <0x83000000 0x0 0x80900000 0x3 0x80900000 0x0 0x3f700000>;
            resets = <&cru 193>;
            reset-names = "pipe";
            #address-cells = <3>;
            #size-cells = <2>;
        };
    };
...


code:
* Rockchip AXI PCIe Endpoint Controller DT description

Required properties:
- compatible: Should contain "rockchip,rk3399-pcie-ep"
- reg: Two register ranges as listed in the reg-names property
- reg-names: Must include the following names
	- "apb-base"
	- "mem-base"
- clocks: Must contain an entry for each entry in clock-names.
		See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
	- "aclk"
	- "aclk-perf"
	- "hclk"
	- "pm"
- resets: Must contain seven entries for each entry in reset-names.
	   See ../reset/reset.txt for details.
- reset-names: Must include the following names
	- "core"
	- "mgmt"
	- "mgmt-sticky"
	- "pipe"
	- "pm"
	- "aclk"
	- "pclk"
- pinctrl-names : The pin control state names
- pinctrl-0: The "default" pinctrl state
- phys: Must contain an phandle to a PHY for each entry in phy-names.
- phy-names: Must include 4 entries for all 4 lanes even if some of
  them won't be used for your cases. Entries are of the form "pcie-phy-N":
  where N ranges from 0 to 3.
  (see example below and you MUST also refer to ../phy/rockchip-pcie-phy.txt
  for changing the #phy-cells of phy node to support it)
- rockchip,max-outbound-regions: Maximum number of outbound regions

Optional Property:
- num-lanes: number of lanes to use
- max-functions: Maximum number of functions that can be configured (default 1).

pcie0-ep: pcie@f8000000 {
	compatible = "rockchip,rk3399-pcie-ep";
	#address-cells = <3>;
	#size-cells = <2>;
	rockchip,max-outbound-regions = <16>;
	clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
		 <&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
	clock-names = "aclk", "aclk-perf",
		      "hclk", "pm";
	max-functions = /bits/ 8 <8>;
	num-lanes = <4>;
	reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0x80000000 0x0 0x20000>;
	reg-names = "apb-base", "mem-base";
	resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>,
		 <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> ,
		 <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>;
	reset-names = "core", "mgmt", "mgmt-sticky", "pipe",
		      "pm", "pclk", "aclk";
	phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>;
	phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3";
	pinctrl-names = "default";
	pinctrl-0 = <&pcie_clkreq>;
};