Re: [RFC PATCH v3 6/9] iommu/rockchip: Clear AUTO_GATING bit 1 on the RK356x v1 IOMMU

From: Midgy Balon

Date: Sun Jun 07 2026 - 17:04:42 EST


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 <chaoyi.chen@xxxxxxxxxxxxxx> 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 <midgy971@xxxxxxxxx>
> > ---
> > 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