Re: [PATCH 0/3] Apple M1 DART IOMMU driver

From: Sven Peter
Date: Thu Mar 25 2021 - 04:00:05 EST


Hi Robin,


On Wed, Mar 24, 2021, at 16:29, Robin Murphy wrote:
> On 2021-03-20 15:19, Sven Peter wrote:
> >
> > I have just noticed today though that at least the USB DWC3 controller in host
> > mode uses *two* darts at the same time. I'm not sure yet which parts seem to
> > require which DART instance.
> >
> > This means that we might need to support devices attached to two iommus
> > simultaneously and just create the same iova mappings. Currently this only
> > seems to be required for USB according to Apple's Device Tree.
> >
> > I see two options for this and would like to get feedback before
> > I implement either one:
> >
> > 1) Change #iommu-cells = <1>; to #iommu-cells = <2>; and use the first cell
> > to identify the DART and the second one to identify the master.
> > The DART DT node would then also take two register ranges that would
> > correspond to the two DARTs. Both instances use the same IRQ and the
> > same clocks according to Apple's device tree and my experiments.
> > This would keep a single device node and the DART driver would then
> > simply map iovas in both DARTs if required.
>
> This is broadly similar to the approach used by rockchip-iommu and the
> special arm-smmu-nvidia implementation, where there are multiple
> instances which require programming identically, that are abstracted
> behind a single "device". Your case is a little different since you're
> not programming both *entirely* identically, although maybe that's a
> possibility if each respective ID isn't used by anything else on the
> "other" DART?

That would be possible. The only difference is that I need to
program ID 0 of the first DART and ID 1 of the second one. Both
of these IDs are only connected to the same USB controller.


>
> Overall I tend to view this approach as a bit of a hack because it's not
> really describing the hardware truthfully - just because two distinct
> functional blocks have their IRQ lines wired together doesn't suddenly
> make them a single monolithic block with multiple interfaces - and tends
> to be done for the sake of making the driver implementation easier in
> terms of the Linux IOMMU API (which, note, hasn't evolved all that far
> from its PCI-centric origins and isn't exactly great for arbitrary SoC
> topologies).

Yes, the easier driver implementation was my reason to favour this option.

>
> > 2) Keep #iommu-cells as-is but support
> > iommus = <&usb_dart1a 1>, <&usb_dart1b 0>;
> > instead.
> > This would then require two devices nodes for the two DART instances and
> > some housekeeping in the DART driver to support mapping iovas in both
> > DARTs.
> > I believe omap-iommu.c supports this setup but I will have to read
> > more code to understand the details there and figure out how to implement
> > this in a sane way.
>
> This approach is arguably the most honest, and more robust in terms of
> making fewer assumptions, and is used by at least exynos-iommu and
> omap-iommu. In Linux it currently takes a little bit more housekeeping
> to keep track of linked instances within the driver since the IOMMU API
> holds the notion that any given client device is associated with "an
> IOMMU", but that's always free to change at any time, unlike the design
> of a DT binding.

Sounds good. I'll read those drivers and give it a try for v2.


Thanks,


Sven