[PATCH v8] net: airoha: npu: use cacheline-sized buffers for mailbox DMA
Daniel Pawlik
pawlik.dan at gmail.com
Thu Aug 20 13:28:00 PDT 2026
Hi Kuba,
Fair point - the interesting part is the mechanism. I don't have the
EN7581 TRM, so I can't name the exact register. From ATF, DT, NPU
firmware, and the instrumented kernel path, the picture looks like this:
TL;DR: Sub-cacheline map length forces SWIOTLB on this non-coherent
arm64 setup. SWIOTLB sync/invalidation doesn't explain the failure -
the response never appears in the bounce buffer. Cache-line-aligned
streaming buffers avoid SWIOTLB entirely and the probe reads 0.1111. The
remaining question is why the NPU doesn't produce visible writes in
the bounce region (high phys ~0xFF6x vs vendor DMA pools ~0x84-0x91).
What's ruled out:
- No IOMMU/SMMU on this SoC; DMA addresses equal physical addresses.
- No EMI MPU - unlike MT7622/MT7986, the Airoha ATF [1] configures
only TZPC (secure/non-secure for NPU SRAM and EFUSE), not DMA
address ranges.
- No PMP in NPU firmware — disassembly of the RISC-V binary shows
zero accesses to pmpcfg*/pmpaddr* CSRs.
- No dma-ranges in DT - the soc node uses identity-mapped ranges;
the kernel sees no address translation for NPU DMA.
- set_memory_decrypted() on swiotlb pages is a no-op on standard
arm64 (no CCA/memory encryption on EN7581).
What the bus fabric looks like:
The ATF bus test code [2] reveals the internal topology. Each DMA
engine has a dedicated port through the R2C (RBUS-to-DRAM converter)
bridge:
port 0: GDMA/HSDMA
port 1: PPE
port 2: QDMA LAN (TX)
port 3: QDMA WAN (TX)
port 4: TDMA
port 5: NPU
The RBUS also has a "DMA block" mechanism (0x1FA000EC) that
serializes CPU writes against DMA reads within 64B/128B-masked
regions, with per-engine block counters at 0x1FA000F4-0x1FA00108.
All vendor DMA buffers sit in one contiguous region:
npu-binary: 0x84000000 (10MB)
qdma0-buf: 0x87000000 (32MB)
qdma1-buf: 0x89000000 (16MB)
npu-pkt: 0x8A000000 (44MB)
npu-txpkt: 0x8CC00000 (64MB)
npu-txbufid: 0x90C00000
npu-ba: 0x90C06800
The ATF bus test uses DRAM_TEST_BASE = 0x84000000 exclusively -
no test exercises DMA at high physical addresses.
The NPU reads the mailbox command from the swiotlb bounce address
(~0xFF6D0000) successfully - mbox_status returns success. But it
never writes the response back; the buffer stays zero, causing a
timeout.
Read-succeeds/write-fails at a high physical address, while all
production DMA stays in 0x84-0x91, points to the R2C bridge's
write path having a narrower address reach than the read path.
Whether that's an address decode window, a write-buffer range
check, or a port-specific routing constraint isn't visible in
the open-source ATF or kernel code - likely hardwired or set by
boot ROM before ATF runs.
So I suspect this is less "swiotlb unaligned-length sync is broken"
and more "this DMA master shouldn't be bounced to that DRAM region" -
but I can't prove the bridge/decode story without vendor docs.
Regards,
Dan
[1] https://github.com/Ansuel/atf-airoha
[2] atf-airoha/plat/ecnt/en7523/cpu_bus_bl2_test.c
czw., 20 sie 2026 o 19:18 Jakub Kicinski <kuba at kernel.org> napisał(a):
>
> On Thu, 20 Aug 2026 10:20:08 +0200 Daniel Pawlik wrote:
> > size=24 < cache_line=64 fails this regardless of address alignment.
> > The swiotlb sync code itself is fine, but the NPU cannot DMA-write to
> > the bounce buffer address range (it reads commands fine, never writes
> > responses back). This is probably an EN7581 platform limitation.
>
> Sure, that's pretty much what GPT told us some revisions ago.
> The question is why.
--
Z poważaniem,
Daniel Pawlik
More information about the Linux-mediatek
mailing list