Re: [PATCH RFC 0/4] iommu/arm-smmu-v3: Support shared Stream IDs

From: Peng Fan

Date: Wed Sep 16 2026 - 21:29:57 EST


Hi Jason,

On Wed, Sep 16, 2026 at 01:10:18PM -0300, Jason Gunthorpe wrote:
>On Wed, Sep 16, 2026 at 11:12:33PM +0800, Peng Fan (OSS) wrote:
>> Some SoCs have a limited number of IOMMU Stream IDs (SIDs) and
>> hardware that inherently shares them. For example, the NXP i.MX95
>> eDMA controller has 64 channels where each TX/RX pair is assigned
>> a single SID by the hardware - the two channel devices are distinct
>> from Linux's perspective but present the same SID to the SMMU.
>
>Is that a reflection of poor DT modelling though?
>
>Why must a TX/RX *PAIR* have two platform_devices nodes?
>
>Fix it there and you don't need any of this? Or is there more?

I think there may be a misunderstanding about the device topology here.

There is only one platform device node for the eDMA controller
(dma-controller@42000000). There are no separate platform device nodes per
channel pair.

What happens instead:
The fsl-edma driver probes the single platform device. During
dmaenginem_async_device_register(), the dmaengine core calls
__dma_async_device_channel_register() for each channel, which creates a
struct dma_chan_dev containing a struct device - registered via
device_register() with class = &dma_devclass and parent = edma_platform_dev
(see drivers/dma/dmaengine.c line 1115-1125)

For a 64-channel eDMA, this creates 64 channel devices: dma0chan[0-63]
These channel devices are not platform devices. They are class devices under
the dma device class. They have no DT node, no of_node. They are purely
software constructs created by the dmaengine framework.

The iommu-map property sits on the eDMA controller's DT node. At channel
allocation time (xlate), the driver calls of_dma_configure_id(chan_dev,
edma_np, true, &chan_id) to look up the channel index in the eDMA node's
iommu-map and attach an IOMMU domain to that specific channel device. The
dmaengine framework's dmaengine_get_dma_device() API
(which checks chan->dev->chan_dma_dev) then returns the per-channel device
instead of the parent platform device, so DMA clients map buffers through
the correct IOMMU context.

The shared-SID situation arises because in hardware, each TX/RX channel
pair presents the same Stream ID to the SMMU. So dma0chan0 and dma0chan1
both get configured with SID 0x30 via:
iommu-map = <2 &smmu 0x30 1>,
<3 &smmu 0x30 1>,
...
Both channel devices end up in the same IOMMU group, but currently the SMMU
driver rejects the second device trying to register the same SID. That is
what this series fixes.

And merging TX and RX into a single channel device is not possible -
the dmaengine framework allocates one dma_chan (and thus one dma_chan_dev) per
direction. SPI/I2C/UART clients call dma_request_chan() separately
for "tx" and "rx", each returning an independent channel with its own device.
The two channels have different source ids (e.g. 83 for TX, 84 for RX) and
are independently programmable hardware resources - they only share a SID per
hardware design.

one more point to support SID sharing is that i.MX95 only support 64 SIDs,
however there are more than 64 DMA initiators.

Hope this explains well.

Thanks,
Peng

>
>Jason
>
>