162306a36Sopenharmony_ciThis document describes the generic device tree binding for describing the
262306a36Sopenharmony_cirelationship between PCI(e) devices and IOMMU(s).
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciEach PCI(e) device under a root complex is uniquely identified by its Requester
562306a36Sopenharmony_ciID (AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
662306a36Sopenharmony_ciFunction number.
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciFor the purpose of this document, when treated as a numeric value, a RID is
962306a36Sopenharmony_ciformatted such that:
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci* Bits [15:8] are the Bus number.
1262306a36Sopenharmony_ci* Bits [7:3] are the Device number.
1362306a36Sopenharmony_ci* Bits [2:0] are the Function number.
1462306a36Sopenharmony_ci* Any other bits required for padding must be zero.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciIOMMUs may distinguish PCI devices through sideband data derived from the
1762306a36Sopenharmony_ciRequester ID. While a given PCI device can only master through one IOMMU, a
1862306a36Sopenharmony_ciroot complex may split masters across a set of IOMMUs (e.g. with one IOMMU per
1962306a36Sopenharmony_cibus).
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ciThe generic 'iommus' property is insufficient to describe this relationship,
2262306a36Sopenharmony_ciand a mechanism is required to map from a PCI device to its IOMMU and sideband
2362306a36Sopenharmony_cidata.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciFor generic IOMMU bindings, see
2662306a36Sopenharmony_ciDocumentation/devicetree/bindings/iommu/iommu.txt.
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciPCI root complex
3062306a36Sopenharmony_ci================
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciOptional properties
3362306a36Sopenharmony_ci-------------------
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci- iommu-map: Maps a Requester ID to an IOMMU and associated IOMMU specifier
3662306a36Sopenharmony_ci  data.
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci  The property is an arbitrary number of tuples of
3962306a36Sopenharmony_ci  (rid-base,iommu,iommu-base,length).
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci  Any RID r in the interval [rid-base, rid-base + length) is associated with
4262306a36Sopenharmony_ci  the listed IOMMU, with the IOMMU specifier (r - rid-base + iommu-base).
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci- iommu-map-mask: A mask to be applied to each Requester ID prior to being
4562306a36Sopenharmony_ci  mapped to an IOMMU specifier per the iommu-map property.
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ciExample (1)
4962306a36Sopenharmony_ci===========
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/ {
5262306a36Sopenharmony_ci	#address-cells = <1>;
5362306a36Sopenharmony_ci	#size-cells = <1>;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	iommu: iommu@a {
5662306a36Sopenharmony_ci		reg = <0xa 0x1>;
5762306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
5862306a36Sopenharmony_ci		#iommu-cells = <1>;
5962306a36Sopenharmony_ci	};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	pci: pci@f {
6262306a36Sopenharmony_ci		reg = <0xf 0x1>;
6362306a36Sopenharmony_ci		compatible = "vendor,pcie-root-complex";
6462306a36Sopenharmony_ci		device_type = "pci";
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci		/*
6762306a36Sopenharmony_ci		 * The sideband data provided to the IOMMU is the RID,
6862306a36Sopenharmony_ci		 * identity-mapped.
6962306a36Sopenharmony_ci		 */
7062306a36Sopenharmony_ci		iommu-map = <0x0 &iommu 0x0 0x10000>;
7162306a36Sopenharmony_ci	};
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciExample (2)
7662306a36Sopenharmony_ci===========
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/ {
7962306a36Sopenharmony_ci	#address-cells = <1>;
8062306a36Sopenharmony_ci	#size-cells = <1>;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	iommu: iommu@a {
8362306a36Sopenharmony_ci		reg = <0xa 0x1>;
8462306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
8562306a36Sopenharmony_ci		#iommu-cells = <1>;
8662306a36Sopenharmony_ci	};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	pci: pci@f {
8962306a36Sopenharmony_ci		reg = <0xf 0x1>;
9062306a36Sopenharmony_ci		compatible = "vendor,pcie-root-complex";
9162306a36Sopenharmony_ci		device_type = "pci";
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci		/*
9462306a36Sopenharmony_ci		 * The sideband data provided to the IOMMU is the RID with the
9562306a36Sopenharmony_ci		 * function bits masked out.
9662306a36Sopenharmony_ci		 */
9762306a36Sopenharmony_ci		iommu-map = <0x0 &iommu 0x0 0x10000>;
9862306a36Sopenharmony_ci		iommu-map-mask = <0xfff8>;
9962306a36Sopenharmony_ci	};
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciExample (3)
10462306a36Sopenharmony_ci===========
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/ {
10762306a36Sopenharmony_ci	#address-cells = <1>;
10862306a36Sopenharmony_ci	#size-cells = <1>;
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	iommu: iommu@a {
11162306a36Sopenharmony_ci		reg = <0xa 0x1>;
11262306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
11362306a36Sopenharmony_ci		#iommu-cells = <1>;
11462306a36Sopenharmony_ci	};
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	pci: pci@f {
11762306a36Sopenharmony_ci		reg = <0xf 0x1>;
11862306a36Sopenharmony_ci		compatible = "vendor,pcie-root-complex";
11962306a36Sopenharmony_ci		device_type = "pci";
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci		/*
12262306a36Sopenharmony_ci		 * The sideband data provided to the IOMMU is the RID,
12362306a36Sopenharmony_ci		 * but the high bits of the bus number are flipped.
12462306a36Sopenharmony_ci		 */
12562306a36Sopenharmony_ci		iommu-map = <0x0000 &iommu 0x8000 0x8000>,
12662306a36Sopenharmony_ci			    <0x8000 &iommu 0x0000 0x8000>;
12762306a36Sopenharmony_ci	};
12862306a36Sopenharmony_ci};
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ciExample (4)
13262306a36Sopenharmony_ci===========
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/ {
13562306a36Sopenharmony_ci	#address-cells = <1>;
13662306a36Sopenharmony_ci	#size-cells = <1>;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	iommu_a: iommu@a {
13962306a36Sopenharmony_ci		reg = <0xa 0x1>;
14062306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
14162306a36Sopenharmony_ci		#iommu-cells = <1>;
14262306a36Sopenharmony_ci	};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	iommu_b: iommu@b {
14562306a36Sopenharmony_ci		reg = <0xb 0x1>;
14662306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
14762306a36Sopenharmony_ci		#iommu-cells = <1>;
14862306a36Sopenharmony_ci	};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	iommu_c: iommu@c {
15162306a36Sopenharmony_ci		reg = <0xc 0x1>;
15262306a36Sopenharmony_ci		compatible = "vendor,some-iommu";
15362306a36Sopenharmony_ci		#iommu-cells = <1>;
15462306a36Sopenharmony_ci	};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	pci: pci@f {
15762306a36Sopenharmony_ci		reg = <0xf 0x1>;
15862306a36Sopenharmony_ci		compatible = "vendor,pcie-root-complex";
15962306a36Sopenharmony_ci		device_type = "pci";
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci		/*
16262306a36Sopenharmony_ci		 * Devices with bus number 0-127 are mastered via IOMMU
16362306a36Sopenharmony_ci		 * a, with sideband data being RID[14:0].
16462306a36Sopenharmony_ci		 * Devices with bus number 128-255 are mastered via
16562306a36Sopenharmony_ci		 * IOMMU b, with sideband data being RID[14:0].
16662306a36Sopenharmony_ci		 * No devices master via IOMMU c.
16762306a36Sopenharmony_ci		 */
16862306a36Sopenharmony_ci		iommu-map = <0x0000 &iommu_a 0x0000 0x8000>,
16962306a36Sopenharmony_ci			    <0x8000 &iommu_b 0x0000 0x8000>;
17062306a36Sopenharmony_ci	};
17162306a36Sopenharmony_ci};
172