ArmSoM applicability and source scope
Platform reference for adapting ArmSoM systems, based on CN V1.2.0 baseline; EN V1.0.1 comparison. No board, SDK/BSP, kernel or wiring combination has been hardware-validated here. The source scope below is not a claim that every ArmSoM board or kernel supports these features. Check the exact SoC, board schematic, SDK/BSP, kernel driver and pinmux. Commands, patches, logs and measurements are source examples, not ArmSoM test results.
By user approval, all languages follow Chinese V1.2.0, including V2 layouts, RK3588 page dumps, system-heap mapping and FAQ 5.9–5.18 missing from EN V1.0.1. Additions retain Chinese source-page comments. English/Russian use matching English originals for the four common figures; the two V2 figures use Chinese originals because no English equivalent was supplied. The older English formulas use && where Chinese uses &; the baseline uses Chinese literals, with both variants recorded in the notes.
| Source SoC | Source kernel scope |
|---|---|
| ROCKCHIP | 4.4/4.19/5.10/6.1 |
IOMMU translates 32-bit virtual addresses to physical addresses, provides read/write permission bits and can raise page-fault and bus-exception interrupts.
Editorial notes · ArmSoM documentation · Rockchip Linux
1. IOMMU structure
A two-level page-table structure is used:

IOMMU two-level page-table structure — source EN PDF p.6.

32-bit IOMMU virtual address fields — source EN PDF p.6.
The 32-bit address contains a 10-bit first-level table offset, a 10-bit second-level table offset and a 12-bit offset within the page.
DTE structure:

IOMMU V1 DTE layout — source EN PDF p.6.
V2 DTE structure (Chinese V1.2.0 source):

IOMMU V2 DTE layout — source CN PDF p.4.
bit0: whether the next-level page table exists.
PTE structure:

IOMMU V1 PTE layout and permissions — source EN PDF p.7.
bit0: whether the physical page exists.
bit1: read permission.
bit2: write permission.
V2 PTE structure (Chinese V1.2.0 source):

IOMMU V2 PTE layout — source CN PDF p.5.
The preceding V1 text says bit1=read and bit2=write, but the V2 diagram labels bit2=read permission and bit1=write permission (bit0=page present). This version-specific discrepancy is preserved exactly as shown. Do not apply V1 permissions to V2 without checking the matching driver/TRM; no hardware validation was performed.
2. IOMMU driver
2.1 Driver file
Driver file location:
drivers/iommu/rockchip-iommu.c
2.2 DTS node configuration
Refer to Documentation/devicetree/bindings/iommu/rockchip,iommu.txt for DTS configuration. The main parameters are described below:
compatible = "rockchip,iommu";
compatible = "rockchip,iommu-v2"; — V2, from the Chinese V1.2.0 source.
The source states that the compatible value is shared by the IOMMUs of devices. It lists interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>; for exception interrupts such as page faults. Preserve this example and verify it against the actual DTS binding; the source has both V1 and V2 compatible strings above.
clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>;
clock-names = "aclk", "hclk"; — IOMMU and master share clocks; these entries allow the IOMMU driver to control the clocks independently.
power-domains = <&power RK3399_PD_VOPL>; — enables power-domain operations in the IOMMU driver.
iommu-cells = <0>; — the source requires 0; see iommu.txt. The missing # in this source spelling is retained and flagged in the editorial notes.
3. Using IOMMU
The Rockchip IOMMU driver depends on the IOMMU framework:
drivers/iommu/iommu.c
It mainly implements callbacks in:
struct iommu_ops rk_iommu_ops
The master invokes the framework APIs to operate the IOMMU, as follows:
1. iommu attach
iommu_attach_device -> rk_iommu_attach_device /* enable iommu */
2. iommu detach
iommu_detach_device -> rk_iommu_detach_device /* disable iommu */
3. iommu map
iommu_map -> rk_iommu_map
Create page tables and mappings between virtual and physical addresses. Enable the dbg output inside iommu_map during debugging to observe mapping.
4. iommu unmap
iommu_unmap -> rk_iommu_unmap
Remove virtual-to-physical mappings and free virtual address space. Enable dbg output inside iommu_unmap to observe unmapping.
5. domain alloc
iommu_domain_alloc -> rk_iommu_domain_alloc
Allocate the page-table base address used by attach/detach.
6. domain free
iommu_domain_free -> rk_iommu_domain_free
Free page-table space.
7. Dump IOMMU page tables. For RK3399 vopl_iommu and virtual address VA=0x00001000, use this sequence. a. Obtain the first-level table base DT:
io -4 0xff8f3f00
b. Calculate the first-level table offset:
index1 = VA >> 22
c. Calculate the physical address of the first-level entry DTE:
DTE = index1 * 4 + DT
d. Obtain the second-level table base PT:
PT = io -4 DTE
e. Calculate the second-level table offset:
index2 = VA & 0x3ff000
f. Calculate the physical address of the second-level entry PTE:
PTE = index2 * 4 + PT
g. Obtain the physical PAGE address, page:
page = io -4 PTE
h. Calculate the in-page offset, offset:
offset = page + (VA & 0xfff)
The source calls offset the physical address corresponding to virtual address 0x00001000; the master can inspect data there. For RK3588 vop_mmu with VA=0x00001000, the Chinese V1.2.0 source adds the following sequence. a. Obtain the first-level table base DT:
DT = io -4 0xfdd97e00
DT = ((DT & 0xf0) << 32) | ((DT & 0xf00) << 24) | (DT & 0xfffff000)
b. Calculate the first-level table offset:
index1 = VA >> 22
c. Calculate physical address DTE:
DTE = index1 * 4 + DT
d. Obtain second-level table base PT:
PT = io -4 DTE
PT = ((PT & 0xf0) << 32) | ((PT & 0xf00) << 24) | (PT & 0xfffff000)
e. Calculate the second-level table offset:
index2 = VA & 0x3ff000
f. Calculate physical address PTE:
PTE = index2 * 4 + PT
g. Obtain physical page address page:
page = io -4 PTE
page = ((page & 0xf0) << 32) | ((page & 0xf00) << 24) | (page & 0xfffff000)
h. Calculate offset:
offset = page + (VA & 0xfff)
The source calls offset the physical address corresponding to VA=0x00001000; the master can use it to inspect data. The formulas are reproduced literally and have not been validated on hardware.
8. dma-mapping. a. For a device without IOMMU:
ARM32: dev->dma_ops = arm_dma_ops;
ARM64: dev->dma_ops = arm64_swiotlb_dma_ops;
b. For an IOMMU device:
ARM32: dev->dma_ops = iommu_ops;
ARM64: dev->dma_ops = iommu_dma_ops;
Taking dma_alloc_attrs as an example:
1. For a non-IOMMU device, the alloc callback in the dma_ops from (a) allocates contiguous physical memory and a kernel virtual address.
2. For an IOMMU device, alloc in the dma_ops from (b) allocates physical memory and invokes iommu_map through the framework to create page tables and virtual-to-physical mappings. It returns the initial IOMMU virtual address and the kernel virtual address.
A minimal IOMMU usage sequence:
1. domain = iommu_domain_alloc(&platform_bus_type);
2. iommu_map(domain, iova, paddr, size, prot);
3. iommu_attach_device(domain, dev);
4. master启动访问iommu
IOMMU is a basic component that can be embedded in allocators such as ion/drm. In ARM64 DRM, a complete IOMMU buffer allocation and mapping sequence is:
rockchip_gem_alloc_buf ->
rockchip_gem_get_pages ->
rockchip_gem_iommu_map ->
iommu_map_sg ->
iommu_map
IOMMU mapping when passing an fd:
DRM path:
1. struct dma_buf *dmabuf = dma_buf_get(fd) ->
dma_buf_attach -> dma_buf_map_attachment ->
map_dma_buf -> drm_gem_map_dma_buf ->
dma_map_sg_attrs -> map_sg ->
__iommu_map_sg_attrs ->
iommu_dma_map_sg ->
iommu_map_sg ->
iommu_map
SYSTEM HEAP path:
2. struct dma_buf *dmabuf = dma_buf_get(fd) ->
dma_buf_attach -> dma_buf_map_attachment ->
map_dma_buf -> system_heap_map_dma_buf ->
dma_map_sgtable -> __dma_map_sg_attrs ->
map_sg -> iommu_dma_map_sg ->
iommu_map_sg_atomic ->
__iommu_map_sg ->
__iommu_map
4. Kernel configuration
Symbol: ROCKCHIP_IOMMU [=y]
Type : boolean
Prompt: Rockchip IOMMU Support
Location:
-> Device Drivers
-> IOMMU Hardware Support (IOMMU_SUPPORT [=y])
Defined at drivers/iommu/Kconfig:211
Depends on: IOMMU_SUPPORT [=y] && (ARM || ARM64 [=y]) && (ARCH_ROCKCHIP [=y] ||
COMPILE_TEST [=n])
Selects: IOMMU_API [=y] && ARM_DMA_USE_IOMMU
5. IOMMU frequently asked questions
5.1 Page-fault interrupt
A page-fault interrupt means that the virtual address currently accessed has no corresponding mapping. Three cases have occurred in masters: accessing an unmapped address, accessing out of bounds, or starting access before mapping.
5.2 IOMMU enable-stall failure
An IOMMU page fault may already have occurred and the master continues accessing without handling it; inspect the log.
Incorrect clock handling is another possibility. Temporarily keep PD and CLK enabled to rule out those causes.
5.3 Inaccessible IOMMU registers
The master’s power-domain handling may use pm_runtime_get_sync/pm_runtime_put_sync incorrectly, accessing IOMMU registers before enabling the IOMMU power domain.
5.4 Continuous IOMMU interrupts
The interrupt number in DTS may be wrong.
The master may continuously access unmapped IOVA; this often accompanies display failures.
5.5 Boot-time display flicker
Enabling IOMMU while VOP is displaying may disrupt data fetching. On chips without frame-effective switching, wait until VOP is not fetching before enabling IOMMU.
5.6 Abnormal IOMMU registers
Out-of-bounds master accesses to IOMMU registers can cause this problem.
Resetting the entire master IP also resets IOMMU, because IOMMU is integrated inside that IP.
After a master reset, restore the IOMMU register configuration.
5.7 IOMMU device-link integration
Power-domain control is handed to the master; ensure correct use of pm_runtime_get/pm_runtime_put.
Calling pm_runtime_get in the master enables IOMMU.
Calling pm_runtime_put in the master disables IOMMU.
5.8 Page-table maintenance
In ARM32, masters sharing IOMMU, such as vepu and vdpu, need separate page tables and must attach the appropriate table before every access. ARM64 shares page tables, so repeated attach is unnecessary.
5.9 Reset failure at high clock frequency
RK3288 reboot stress tests can trigger VOP page faults. If VOP is overclocked, force reset of VOP IOMMU may fail. The source workaround is to skip force reset when attaching VOP IOMMU.
5.10 Unreadable VOP IOMMU on RK3128/RK3126
These chips’ VOP IOMMU registers cannot be read. Add this workaround to the VOP IOMMU DTS configuration:
rockchip,skip-mmu-read
The driver skips the relevant reads; its flag is iommu->skip_read.
5.11 Reset operation
After resetting ISP IOMMU, its status register may not confirm completion even though reset succeeded. Add this workaround to the ISP IOMMU DTS node:
rockchip,disable-mmu-reset
This skips ISP IOMMU reset; the driver flag is iommu->reset_disabled.
5.12 Ensuring write commands take effect
The source names RK1126 and RV1109 rkvenc IOMMU as possibly losing write commands; repeat writes several times to avoid this. RK1126 is preserved as written and requires verification.
5.13 Disable automatic VOP IOMMU attach
From the 4.19 kernel onward, VOP explicitly attaches IOMMU rather than attaching automatically when the device node is registered, preventing display problems at the U-Boot-to-kernel handover.
5.14 Performance loss from IOMMU TLB flushing
Mapping requires TLB flushes. Fragmented buffers can cause many flushes and reduce performance; add a flag so the TLB is flushed only once.
5.15 One-to-one mapping for VOP IOMMU
One-to-one mapping avoids display faults caused by waiting for frame-effective updates at the U-Boot/kernel transition. For example, RK356X has more masters than IOMMUs, so waiting for frame-effective updates is unavailable; identity mapping avoids that problem.
5.16 One master with two IOMMUs
Unless special requirements apply, optimize the master driver so both IOMMUs use the same page table.
The source’s newer IOMMU driver automatically shares the same page table across multiple IOMMUs of one master; no master-driver intervention is needed.
5.17 PX30 H.264/H.265 switching
Use this switching order:
- Ensure all clocks are enabled.
- Ensure all power domains are enabled.
- Disable all IOMMUs.
- Switch GRF.
- Enable the current IOMMU.
5.18 RK3368 VPU and HEVC simultaneous-operation failures
RK3368 VPU and HEVC share an IOMMU TLB. Serialize TLB operations, and therefore mapping operations, to prevent failures.
