| # SPDX-License-Identifier: GPL-2.0-only |
| %YAML 1.2 |
| --- |
| $id: http://devicetree.org/schemas/iommu/arm,smmu.yaml# |
| $schema: http://devicetree.org/meta-schemas/core.yaml# |
| |
| title: ARM System MMU Architecture Implementation |
| |
| maintainers: |
| - Will Deacon <will@kernel.org> |
| - Robin Murphy <Robin.Murphy@arm.com> |
| |
| description: |+ |
| ARM SoCs may contain an implementation of the ARM System Memory |
| Management Unit Architecture, which can be used to provide 1 or 2 stages |
| of address translation to bus masters external to the CPU. |
| |
| The SMMU may also raise interrupts in response to various fault |
| conditions. |
| |
| properties: |
| $nodename: |
| pattern: "^iommu@[0-9a-f]*" |
| compatible: |
| oneOf: |
| - description: Qcom SoCs implementing "arm,smmu-v2" |
| items: |
| - enum: |
| - qcom,msm8996-smmu-v2 |
| - qcom,msm8998-smmu-v2 |
| - qcom,sdm630-smmu-v2 |
| - qcom,sm6375-smmu-v2 |
| - const: qcom,smmu-v2 |
| |
| - description: Qcom SoCs implementing "qcom,smmu-500" and "arm,mmu-500" |
| items: |
| - enum: |
| - qcom,qcm2290-smmu-500 |
| - qcom,qdu1000-smmu-500 |
| - qcom,sa8775p-smmu-500 |
| - qcom,sc7180-smmu-500 |
| - qcom,sc7280-smmu-500 |
| - qcom,sc8180x-smmu-500 |
| - qcom,sc8280xp-smmu-500 |
| - qcom,sdm670-smmu-500 |
| - qcom,sdm845-smmu-500 |
| - qcom,sdx55-smmu-500 |
| - qcom,sdx65-smmu-500 |
| - qcom,sdx75-smmu-500 |
| - qcom,sm6115-smmu-500 |
| - qcom,sm6125-smmu-500 |
| - qcom,sm6350-smmu-500 |
| - qcom,sm6375-smmu-500 |
| - qcom,sm8150-smmu-500 |
| - qcom,sm8250-smmu-500 |
| - qcom,sm8350-smmu-500 |
| - qcom,sm8450-smmu-500 |
| - qcom,sm8550-smmu-500 |
| - qcom,sm8650-smmu-500 |
| - qcom,x1e80100-smmu-500 |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| |
| - description: Qcom SoCs implementing "arm,mmu-500" (legacy binding) |
| deprecated: true |
| items: |
| # Do not add additional SoC to this list. Instead use two previous lists. |
| - enum: |
| - qcom,qcm2290-smmu-500 |
| - qcom,sc7180-smmu-500 |
| - qcom,sc7280-smmu-500 |
| - qcom,sc8180x-smmu-500 |
| - qcom,sc8280xp-smmu-500 |
| - qcom,sdm845-smmu-500 |
| - qcom,sm6115-smmu-500 |
| - qcom,sm6350-smmu-500 |
| - qcom,sm6375-smmu-500 |
| - qcom,sm8150-smmu-500 |
| - qcom,sm8250-smmu-500 |
| - qcom,sm8350-smmu-500 |
| - qcom,sm8450-smmu-500 |
| - const: arm,mmu-500 |
| - description: Qcom Adreno GPUs implementing "qcom,smmu-500" and "arm,mmu-500" |
| items: |
| - enum: |
| - qcom,qcm2290-smmu-500 |
| - qcom,sa8775p-smmu-500 |
| - qcom,sc7280-smmu-500 |
| - qcom,sc8280xp-smmu-500 |
| - qcom,sm6115-smmu-500 |
| - qcom,sm6125-smmu-500 |
| - qcom,sm8150-smmu-500 |
| - qcom,sm8250-smmu-500 |
| - qcom,sm8350-smmu-500 |
| - qcom,sm8450-smmu-500 |
| - qcom,sm8550-smmu-500 |
| - qcom,sm8650-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| - description: Qcom Adreno GPUs implementing "arm,mmu-500" (legacy binding) |
| deprecated: true |
| items: |
| # Do not add additional SoC to this list. Instead use previous list. |
| - enum: |
| - qcom,sc7280-smmu-500 |
| - qcom,sm8150-smmu-500 |
| - qcom,sm8250-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: arm,mmu-500 |
| - description: Qcom Adreno GPUs implementing "arm,smmu-v2" |
| items: |
| - enum: |
| - qcom,msm8996-smmu-v2 |
| - qcom,sc7180-smmu-v2 |
| - qcom,sdm630-smmu-v2 |
| - qcom,sdm845-smmu-v2 |
| - qcom,sm6350-smmu-v2 |
| - qcom,sm7150-smmu-v2 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-v2 |
| - description: Qcom Adreno GPUs on Google Cheza platform |
| items: |
| - const: qcom,sdm845-smmu-v2 |
| - const: qcom,smmu-v2 |
| - description: Marvell SoCs implementing "arm,mmu-500" |
| items: |
| - const: marvell,ap806-smmu-500 |
| - const: arm,mmu-500 |
| - description: NVIDIA SoCs that require memory controller interaction |
| and may program multiple ARM MMU-500s identically with the memory |
| controller interleaving translations between multiple instances |
| for improved performance. |
| items: |
| - enum: |
| - nvidia,tegra186-smmu |
| - nvidia,tegra194-smmu |
| - nvidia,tegra234-smmu |
| - const: nvidia,smmu-500 |
| - items: |
| - const: arm,mmu-500 |
| - const: arm,smmu-v2 |
| - items: |
| - enum: |
| - arm,mmu-400 |
| - arm,mmu-401 |
| - const: arm,smmu-v1 |
| - enum: |
| - arm,smmu-v1 |
| - arm,smmu-v2 |
| - arm,mmu-400 |
| - arm,mmu-401 |
| - arm,mmu-500 |
| - cavium,smmu-v2 |
| |
| reg: |
| minItems: 1 |
| maxItems: 2 |
| |
| '#global-interrupts': |
| description: The number of global interrupts exposed by the device. |
| $ref: /schemas/types.yaml#/definitions/uint32 |
| minimum: 0 |
| maximum: 260 # 2 secure, 2 non-secure, and up to 256 perf counters |
| |
| '#iommu-cells': |
| enum: [ 1, 2 ] |
| description: | |
| See Documentation/devicetree/bindings/iommu/iommu.txt for details. With a |
| value of 1, each IOMMU specifier represents a distinct stream ID emitted |
| by that device into the relevant SMMU. |
| |
| SMMUs with stream matching support and complex masters may use a value of |
| 2, where the second cell of the IOMMU specifier represents an SMR mask to |
| combine with the ID in the first cell. Care must be taken to ensure the |
| set of matched IDs does not result in conflicts. |
| |
| interrupts: |
| minItems: 1 |
| maxItems: 388 # 260 plus 128 contexts |
| description: | |
| Interrupt list, with the first #global-interrupts entries corresponding to |
| the global interrupts and any following entries corresponding to context |
| interrupts, specified in order of their indexing by the SMMU. |
| |
| For SMMUv2 implementations, there must be exactly one interrupt per |
| context bank. In the case of a single, combined interrupt, it must be |
| listed multiple times. |
| |
| dma-coherent: |
| description: | |
| Present if page table walks made by the SMMU are cache coherent with the |
| CPU. |
| |
| NOTE: this only applies to the SMMU itself, not masters connected |
| upstream of the SMMU. |
| |
| calxeda,smmu-secure-config-access: |
| type: boolean |
| description: |
| Enable proper handling of buggy implementations that always use secure |
| access to SMMU configuration registers. In this case non-secure aliases of |
| secure registers have to be used during SMMU configuration. |
| |
| stream-match-mask: |
| $ref: /schemas/types.yaml#/definitions/uint32 |
| description: | |
| For SMMUs supporting stream matching and using #iommu-cells = <1>, |
| specifies a mask of bits to ignore when matching stream IDs (e.g. this may |
| be programmed into the SMRn.MASK field of every stream match register |
| used). For cases where it is desirable to ignore some portion of every |
| Stream ID (e.g. for certain MMU-500 configurations given globally unique |
| input IDs). This property is not valid for SMMUs using stream indexing, or |
| using stream matching with #iommu-cells = <2>, and may be ignored if |
| present in such cases. |
| |
| clock-names: |
| minItems: 1 |
| maxItems: 7 |
| |
| clocks: |
| minItems: 1 |
| maxItems: 7 |
| |
| power-domains: |
| minItems: 1 |
| maxItems: 3 |
| |
| nvidia,memory-controller: |
| description: | |
| A phandle to the memory controller on NVIDIA Tegra186 and later SoCs. |
| The memory controller needs to be programmed with a mapping of memory |
| client IDs to ARM SMMU stream IDs. |
| |
| If this property is absent, the mapping programmed by early firmware |
| will be used and it is not guaranteed that IOMMU translations will be |
| enabled for any given device. |
| $ref: /schemas/types.yaml#/definitions/phandle |
| |
| required: |
| - compatible |
| - reg |
| - '#global-interrupts' |
| - '#iommu-cells' |
| - interrupts |
| |
| additionalProperties: false |
| |
| allOf: |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - nvidia,tegra186-smmu |
| - nvidia,tegra194-smmu |
| - nvidia,tegra234-smmu |
| then: |
| properties: |
| reg: |
| minItems: 1 |
| maxItems: 2 |
| |
| # The reference to the memory controller is required to ensure that the |
| # memory client to stream ID mapping can be done synchronously with the |
| # IOMMU attachment. |
| required: |
| - nvidia,memory-controller |
| else: |
| properties: |
| reg: |
| maxItems: 1 |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - qcom,msm8998-smmu-v2 |
| - qcom,sdm630-smmu-v2 |
| then: |
| anyOf: |
| - properties: |
| clock-names: |
| items: |
| - const: bus |
| clocks: |
| items: |
| - description: bus clock required for downstream bus access and for |
| the smmu ptw |
| - properties: |
| clock-names: |
| items: |
| - const: iface |
| - const: mem |
| - const: mem_iface |
| clocks: |
| items: |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| - description: bus clock required for memory access |
| - description: bus clock required for GPU memory access |
| - properties: |
| clock-names: |
| items: |
| - const: iface-mm |
| - const: iface-smmu |
| - const: bus-smmu |
| clocks: |
| items: |
| - description: interface clock required to access mnoc's registers |
| through the TCU's programming interface. |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| - description: bus clock required for the smmu ptw |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - qcom,sm6375-smmu-v2 |
| then: |
| anyOf: |
| - properties: |
| clock-names: |
| items: |
| - const: bus |
| clocks: |
| items: |
| - description: bus clock required for downstream bus access and for |
| the smmu ptw |
| - properties: |
| clock-names: |
| items: |
| - const: iface |
| - const: mem |
| - const: mem_iface |
| clocks: |
| items: |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| - description: bus clock required for memory access |
| - description: bus clock required for GPU memory access |
| - properties: |
| clock-names: |
| items: |
| - const: iface-mm |
| - const: iface-smmu |
| - const: bus-mm |
| - const: bus-smmu |
| clocks: |
| items: |
| - description: interface clock required to access mnoc's registers |
| through the TCU's programming interface. |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| - description: bus clock required for downstream bus access |
| - description: bus clock required for the smmu ptw |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - qcom,msm8996-smmu-v2 |
| - qcom,sc7180-smmu-v2 |
| - qcom,sdm845-smmu-v2 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: bus |
| - const: iface |
| |
| clocks: |
| items: |
| - description: bus clock required for downstream bus access and for |
| the smmu ptw |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - qcom,sa8775p-smmu-500 |
| - qcom,sc7280-smmu-500 |
| - qcom,sc8280xp-smmu-500 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: gcc_gpu_memnoc_gfx_clk |
| - const: gcc_gpu_snoc_dvm_gfx_clk |
| - const: gpu_cc_ahb_clk |
| - const: gpu_cc_hlos1_vote_gpu_smmu_clk |
| - const: gpu_cc_cx_gmu_clk |
| - const: gpu_cc_hub_cx_int_clk |
| - const: gpu_cc_hub_aon_clk |
| |
| clocks: |
| items: |
| - description: GPU memnoc_gfx clock |
| - description: GPU snoc_dvm_gfx clock |
| - description: GPU ahb clock |
| - description: GPU hlos1_vote_GPU smmu clock |
| - description: GPU cx_gmu clock |
| - description: GPU hub_cx_int clock |
| - description: GPU hub_aon clock |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - qcom,sm6350-smmu-v2 |
| - qcom,sm7150-smmu-v2 |
| - qcom,sm8150-smmu-500 |
| - qcom,sm8250-smmu-500 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: ahb |
| - const: bus |
| - const: iface |
| |
| clocks: |
| items: |
| - description: bus clock required for AHB bus access |
| - description: bus clock required for downstream bus access and for |
| the smmu ptw |
| - description: interface clock required to access smmu's registers |
| through the TCU's programming interface. |
| |
| - if: |
| properties: |
| compatible: |
| items: |
| - enum: |
| - qcom,sm8350-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: bus |
| - const: iface |
| - const: ahb |
| - const: hlos1_vote_gpu_smmu |
| - const: cx_gmu |
| - const: hub_cx_int |
| - const: hub_aon |
| clocks: |
| minItems: 7 |
| maxItems: 7 |
| |
| - if: |
| properties: |
| compatible: |
| items: |
| - enum: |
| - qcom,qcm2290-smmu-500 |
| - qcom,sm6115-smmu-500 |
| - qcom,sm6125-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: mem |
| - const: hlos |
| - const: iface |
| |
| clocks: |
| items: |
| - description: GPU memory bus clock |
| - description: Voter clock required for HLOS SMMU access |
| - description: Interface clock required for register access |
| |
| - if: |
| properties: |
| compatible: |
| items: |
| - const: qcom,sm8450-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: gmu |
| - const: hub |
| - const: hlos |
| - const: bus |
| - const: iface |
| - const: ahb |
| |
| clocks: |
| items: |
| - description: GMU clock |
| - description: GPU HUB clock |
| - description: HLOS vote clock |
| - description: GPU memory bus clock |
| - description: GPU SNoC bus clock |
| - description: GPU AHB clock |
| |
| - if: |
| properties: |
| compatible: |
| items: |
| - enum: |
| - qcom,sm8550-smmu-500 |
| - qcom,sm8650-smmu-500 |
| - const: qcom,adreno-smmu |
| - const: qcom,smmu-500 |
| - const: arm,mmu-500 |
| then: |
| properties: |
| clock-names: |
| items: |
| - const: hlos |
| - const: bus |
| - const: iface |
| - const: ahb |
| |
| clocks: |
| items: |
| - description: HLOS vote clock |
| - description: GPU memory bus clock |
| - description: GPU SNoC bus clock |
| - description: GPU AHB clock |
| |
| # Disallow clocks for all other platforms with specific compatibles |
| - if: |
| properties: |
| compatible: |
| contains: |
| enum: |
| - cavium,smmu-v2 |
| - marvell,ap806-smmu-500 |
| - nvidia,smmu-500 |
| - qcom,qdu1000-smmu-500 |
| - qcom,sc7180-smmu-500 |
| - qcom,sc8180x-smmu-500 |
| - qcom,sdm670-smmu-500 |
| - qcom,sdm845-smmu-500 |
| - qcom,sdx55-smmu-500 |
| - qcom,sdx65-smmu-500 |
| - qcom,sm6350-smmu-500 |
| - qcom,sm6375-smmu-500 |
| - qcom,x1e80100-smmu-500 |
| then: |
| properties: |
| clock-names: false |
| clocks: false |
| |
| - if: |
| properties: |
| compatible: |
| contains: |
| const: qcom,sm6375-smmu-500 |
| then: |
| properties: |
| power-domains: |
| items: |
| - description: SNoC MMU TBU RT GDSC |
| - description: SNoC MMU TBU NRT GDSC |
| - description: SNoC TURING MMU TBU0 GDSC |
| |
| required: |
| - power-domains |
| else: |
| properties: |
| power-domains: |
| maxItems: 1 |
| |
| examples: |
| - |+ |
| /* SMMU with stream matching or stream indexing */ |
| smmu1: iommu@ba5e0000 { |
| compatible = "arm,smmu-v1"; |
| reg = <0xba5e0000 0x10000>; |
| #global-interrupts = <2>; |
| interrupts = <0 32 4>, |
| <0 33 4>, |
| <0 34 4>, /* This is the first context interrupt */ |
| <0 35 4>, |
| <0 36 4>, |
| <0 37 4>; |
| #iommu-cells = <1>; |
| }; |
| |
| /* device with two stream IDs, 0 and 7 */ |
| master1 { |
| iommus = <&smmu1 0>, |
| <&smmu1 7>; |
| }; |
| |
| |
| /* SMMU with stream matching */ |
| smmu2: iommu@ba5f0000 { |
| compatible = "arm,smmu-v1"; |
| reg = <0xba5f0000 0x10000>; |
| #global-interrupts = <2>; |
| interrupts = <0 38 4>, |
| <0 39 4>, |
| <0 40 4>, /* This is the first context interrupt */ |
| <0 41 4>, |
| <0 42 4>, |
| <0 43 4>; |
| #iommu-cells = <2>; |
| }; |
| |
| /* device with stream IDs 0 and 7 */ |
| master2 { |
| iommus = <&smmu2 0 0>, |
| <&smmu2 7 0>; |
| }; |
| |
| /* device with stream IDs 1, 17, 33 and 49 */ |
| master3 { |
| iommus = <&smmu2 1 0x30>; |
| }; |
| |
| |
| /* ARM MMU-500 with 10-bit stream ID input configuration */ |
| smmu3: iommu@ba600000 { |
| compatible = "arm,mmu-500", "arm,smmu-v2"; |
| reg = <0xba600000 0x10000>; |
| #global-interrupts = <2>; |
| interrupts = <0 44 4>, |
| <0 45 4>, |
| <0 46 4>, /* This is the first context interrupt */ |
| <0 47 4>, |
| <0 48 4>, |
| <0 49 4>; |
| #iommu-cells = <1>; |
| /* always ignore appended 5-bit TBU number */ |
| stream-match-mask = <0x7c00>; |
| }; |
| |
| bus { |
| /* bus whose child devices emit one unique 10-bit stream |
| ID each, but may master through multiple SMMU TBUs */ |
| iommu-map = <0 &smmu3 0 0x400>; |
| |
| |
| }; |
| |
| - |+ |
| /* Qcom's arm,smmu-v2 implementation */ |
| #include <dt-bindings/interrupt-controller/arm-gic.h> |
| #include <dt-bindings/interrupt-controller/irq.h> |
| smmu4: iommu@d00000 { |
| compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; |
| reg = <0xd00000 0x10000>; |
| |
| #global-interrupts = <1>; |
| interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, |
| <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>, |
| <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>; |
| #iommu-cells = <1>; |
| power-domains = <&mmcc 0>; |
| |
| clocks = <&mmcc 123>, |
| <&mmcc 124>; |
| clock-names = "bus", "iface"; |
| }; |