How to specify IOMMU'able devices in DT (was: [RFC 0/5] ARM:dma-mapping: New dma_map_ops to control IOVA more precisely)

From: Hiroshi Doyu
Date: Mon Sep 24 2012 - 05:04:48 EST


On Fri, 21 Sep 2012 20:16:00 +0200
Krishna Reddy <vdumpa@xxxxxxxxxx> wrote:

> > > The device(H/W controller) need to access few special memory
> > > blocks(IOVA==PA) and DRAM as well.
> >
> > OK, so only /some/ of the VA space is VA==PA, and some is remapped; that's a
> > little different that what you originally implied above.
> >
> > BTW, which HW module is this; AVP/COP or something else. This sounds like an
> > odd requirement.
>
> This is not specific to ARM7. There are protected memory regions on Tegra that
> can be accessed by some controllers like display, 2D, 3D, VDE, HDA. These are
> DRAM regions configured as protected by BootRom. These memory regions
> are not exposed to and not managed by OS page allocator. The H/W controller
> accesses to these regions still to go through IOMMU.
> The IOMMU view for all the H/W controllers is not uniform on Tegra.
> Some Controllers see entire 4GB IOVA space. i.e all accesses go though IOMMU.
> Some controllers see the IOVA Space that don't overlap with MMIO space. i.e
> The MMIO address access bypass IOMMU and directly go to MMIO space.
> Tegra IOMMU can support multiple address spaces as well. To hide controller
> Specific behavior, the drivers should take care of one to one mapping and
> remove inaccessible iova spaces in their address space's based platform device info.

The above is also related to another issue,
how to specify IOMMU'able devices in DT.

As mentioned above, some IOVA mapping may be unique to some devices,
and the number of IOMMU'able device are quite many nowadays, a few
dozen in Tegra30 now. Basically they are seen as just normal platform
devices from CPU even if they belong to different busses in H/W. IOW, their
IOMMU'ability just depend on a platfrom bus from _S/W_ POV. Doing each
registration(create a map & attach device) in board files isn't so
nice. Currently we register them at "platform_device_add()" at once
with just a HACK(*1), but this could/should be done based on the info
passed from DT. For tegra, those parameter could be, "ASID" and
"address range"(start, size, alignment). For example in DT:

deviceA {
"start" "size" "align"
iommu = <0x12340000 0x00400000 0x0000000>; # exclusively specify "start" or "align"
iommu = <0x00000000 0x00400000 0x0010000>;
iommu = <0x12340000 0x00040000 0x12380000 0x00040000>; # "start", "size" could be repeated...
asid = 3; # if needed

or
dma_range = <0x12340000 0x00400000 0x0000000>; # if iommu is considered as one implementation of dma.....
};

Is there any way to specify each IOMMU'able _platform device_ and
specify its map in DT?

The above ASID may be specific to Tegra, though. If we can specify the
above info in DT and the info is passed to kernel, some platform
common code would register them as IOMMU'able device automatically. It
would be really covenient if this is done in platform_device/IOMMU
common code. If the above attribute is implemented specific to
Tegra/platform, we have to call attach_device quite many times
somewhere in device initializations.

Any comment would be really appreciated.

*1: