Hi Chaoyi, > As I said, it is v2. Could you please try using the code below instead and > see if it works? > [ auto_gate = read(RK_MMU_AUTO_GATING); auto_gate |= BIT(31); write(...) ]
Thanks -- that's clearly the right shape (read-modify-write, before paging is enabled, keeping the reset value instead of my clobbering 0x2). I rebuilt v7.1-rc6 (with the rocket RK3568 series + your per-device-ops work) using your bit-31 version and tested it on a ROCK 3B: the NPU IOMMU comes up and services the NPU's DMA cleanly -- the NPU probes, attaches its domain, and runs repeated conv submissions with no DMA_READ_ERROR and no page-walk stall. No regression from the write. To be precise about what I can and can't show: I tested both ways on v7.1-rc6 -- with your bit-31 write, and on the reset value (0x3) -- and the NPU IOMMU services the NPU's reads with zero faults in both cases (no DMA_READ_ERROR, no page-walk stall). So I don't have a failing baseline here that bit-31 visibly fixes. Is the AUTO_GATING write needed on current mainline, or only under conditions I'm not reproducing (a particular traffic pattern / silicon rev)? I'll keep the patch in your form unless you'd prefer to drop it. One question so I document it correctly: what does bit 31 of RK_MMU_AUTO_GATING control on the v2 block -- is it a master "disable internal auto clock-gating" for the page-table walker (i.e. so a TLB-miss walk's AXI master keeps its clock to completion)? The RK3568 TRM I have doesn't cover the IOMMU registers, so a one-line description would let me write an accurate comment. Kind regards, Midgy Le ven. 5 juin 2026 à 03:59, Chaoyi Chen <[email protected]> a écrit : > > Hello Midgy, > > On 6/4/2026 9:52 PM, Midgy BALON wrote: > > On the RK356x v1 IOMMU, RK_MMU_AUTO_GATING resets to 0x3. Bit 1 enables > > auto clock-gating of the page-table walker, so the walker's AXI master > > loses its clock between transactions; a TLB-miss page walk then never > > completes and the IOMMU is left stuck (PAGING_ENABLED, never IDLE). > > > > Clear bit 1 (keeping bit 0, the slave-port gate) once paging is enabled > > so the walker keeps its clock. This is required for the RK3568 NPU MMU. > > > > Signed-off-by: Midgy BALON <[email protected]> > > --- > > drivers/iommu/rockchip-iommu.c | 12 ++++++++++++ > > 1 file changed, 12 insertions(+) > > > > diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c > > index 4da80136933c4..e3d8b6e9ca12b 100644 > > --- a/drivers/iommu/rockchip-iommu.c > > +++ b/drivers/iommu/rockchip-iommu.c > > @@ -953,6 +953,18 @@ static int rk_iommu_enable(struct rk_iommu *iommu) > > > > ret = rk_iommu_enable_paging(iommu); > > > > + if (!ret) { > > + /* > > + * RK356x v1 IOMMU: RK_MMU_AUTO_GATING bit 1 enables > > page-walker > > + * auto clock-gating; the walker's AXI master then loses its > > clock > > + * between transactions and a TLB-miss page walk never > > completes, > > + * leaving the IOMMU stuck (PAGING_ENABLED, never IDLE). > > Clear > > + * bit 1 (keep bit 0, the slave-port gate) once paging is > > enabled. > > + */ > > + for (i = 0; i < iommu->num_mmu; i++) > > + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, > > 0x2); > > + } > > + > > out_disable_stall: > > rk_iommu_disable_stall(iommu); > > out_disable_clocks: > > As I said, it is v2. Could you please try using the code below > instead and see if it works? Thank you. > > diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c > index 0013cf196c57..89e3a83a0251 100644 > --- a/drivers/iommu/rockchip-iommu.c > +++ b/drivers/iommu/rockchip-iommu.c > @@ -930,6 +930,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu) > struct iommu_domain *domain = iommu->domain; > struct rk_iommu_domain *rk_domain = to_rk_domain(domain); > int ret, i; > + u32 auto_gate; > > ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks); > if (ret) > @@ -948,6 +949,10 @@ static int rk_iommu_enable(struct rk_iommu *iommu) > rk_ops->mk_dtentries(rk_domain->dt_dma)); > rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); > rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, > RK_MMU_IRQ_MASK); > + > + auto_gate = rk_iommu_read(iommu->bases[i], > RK_MMU_AUTO_GATING); > + auto_gate |= BIT(31); > + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, > auto_gate); > } > > ret = rk_iommu_enable_paging(iommu); > > -- > Best, > Chaoyi
