All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mikko Perttunen <mperttunen@nvidia.com>
To: Marek Szyprowski <m.szyprowski@samsung.com>,
	"Joerg Roedel (AMD)" <joro@8bytes.org>,
	Will Deacon <will@kernel.org>,
	Russell King <linux@armlinux.org.uk>,
	Heiko Stuebner <heiko@sntech.de>,
	Thierry Reding <thierry.reding@kernel.org>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Krishna Reddy <vdumpa@nvidia.com>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	Jason Gunthorpe <jgg@ziepe.ca>,
	linux-tegra@vger.kernel.org
Cc: Peter Griffin <peter.griffin@linaro.org>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Chen-Yu Tsai <wens@kernel.org>,
	Jernej Skrabec <jernej.skrabec@gmail.com>,
	Samuel Holland <samuel@sholland.org>,
	Yong Wu <yong.wu@mediatek.com>,
	Matthias Brugger <matthias.bgg@gmail.com>,
	AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	Rob Clark <robin.clark@oss.qualcomm.com>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org,
	Robin Murphy <robin.murphy@arm.com>
Subject: Re: [PATCH v2 11/11] iommu/tegra-smmu: Use a DMA API default domain per swgroup
Date: Fri, 23 Oct 2026 14:14:23 +0900	[thread overview]
Message-ID: <9NN3esQaTdOIroYwCH7uag@nvidia.com> (raw)
In-Reply-To: <605a143f-d452-408f-9fcf-259af8ad004b@arm.com>

On Wednesday, October 21, 2026 12:30 AM Robin Murphy wrote:
> On 16/10/2026 7:46 am, Mikko Perttunen wrote:
> > Everything is now in place for the Tegra SMMU to give devices a real
> > IOMMU_DOMAIN_DMA default domain.
> > 
> > Some device drivers still rely on explicit domains (and being able to
> > detach a legacy ARM DMA domain if any), so DMA default domains are
> > enabled on a per-swgroup basis via a use_dma_api flag. As drivers are
> > converted to DMA API usage we can eventually get rid of this. Initially
> > the flag is enabled for TegraDRM and Host1x devices.
> > 
> > On multi_v7_defconfig (where CONFIG_ARM_DMA_USE_IOMMU was always
> > enabled), this will fix TegraDRM probing with certain probe orderings
> > where the legacy implementation's lack of support for multiple devices
> > in one IOMMU group would cause breakage.
> > 
> > On tegra_defconfig, as this now enables CONFIG_ARM_DMA_USE_IOMMU, all
> > devices move to either the legacy ARM DMA path or the new one. This
> > should in principle not cause issues as the drivers would already have
> > been verified on multi_v7_defconfig.
> > 
> > Also set .release_domain to the identity domain to ensure the AS is
> > released appropriately now that the domain can be non-static.
> > 
> > Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
> > ---
> >   drivers/iommu/Kconfig           |  1 +
> >   drivers/iommu/tegra-smmu.c      | 59 ++++++++++++++++++++++++++++++++++++++---
> >   drivers/memory/tegra/tegra114.c | 13 +++++----
> >   drivers/memory/tegra/tegra124.c | 10 ++++---
> >   drivers/memory/tegra/tegra30.c  | 16 ++++++-----
> >   include/soc/tegra/mc.h          |  7 +++++
> >   6 files changed, 87 insertions(+), 19 deletions(-)
> > 
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index 6e07bd69467a..817e84e0e6ab 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -252,6 +252,7 @@ config TEGRA_IOMMU_SMMU
> >   	depends on TEGRA_AHB
> >   	depends on TEGRA_MC
> >   	select IOMMU_API
> > +	select ARM_DMA_USE_IOMMU if ARM
> >   	help
> >   	  This driver supports the IOMMU hardware (SMMU) found on NVIDIA Tegra
> >   	  SoCs (Tegra30 up to Tegra210).
> > diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> > index 6779528a9e7c..1c1910f25553 100644
> > --- a/drivers/iommu/tegra-smmu.c
> > +++ b/drivers/iommu/tegra-smmu.c
> > @@ -994,16 +994,31 @@ static int tegra_smmu_of_xlate(struct device *dev,
> >   
> >   static int tegra_smmu_def_domain_type(struct device *dev)
> >   {
> > +	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> > +	struct tegra_smmu *smmu = dev_iommu_priv_get(dev);
> > +	unsigned int i;
> > +
> > +	if (!fwspec || !smmu)
> > +		return IOMMU_DOMAIN_IDENTITY;
> 
> Dead code - by this point tegra_smmu_probe_device() has already run (and 
> we've literally reached this call via dev_iommu_ops(dev)) so the device 
> is definitely valid.
> 
> > +
> >   	/*
> > -	 * FIXME: For now we want to run all translation in IDENTITY mode, due
> > -	 * to some device quirks. Better would be to just quirk the troubled
> > -	 * devices.
> > +	 * Only clients known to work with the DMA API get a DMA default domain.
> > +	 * The rest keep running in identity mode.
> >   	 */
> > -	return IOMMU_DOMAIN_IDENTITY;
> > +	for (i = 0; i < fwspec->num_ids; i++) {
> > +		const struct tegra_smmu_swgroup *group;
> > +
> > +		group = tegra_smmu_find_swgroup(smmu, fwspec->ids[i]);
> > +		if (!group || !group->use_dma_api)
> 
> Similarly, dev->iommu_group is already assigned with whatever valid 
> group tegra_smmu_device_group() returned, so you could perhaps just do a 
> single iteration over smmu->groups for the lookup.

Yeah, this was way overcomplicated. I've rewritten the function to 
directly pass the fwspec ID to tegra_smmu_find_swgroup - much simpler.

Thanks!
Mikko

> 
> Thanks,
> Robin.
> 
> > +			return IOMMU_DOMAIN_IDENTITY;
> > +	}
> > +
> > +	return IOMMU_DOMAIN_DMA;
> >   }
> >   
> >   static const struct iommu_ops tegra_smmu_ops = {
> >   	.identity_domain = &tegra_smmu_identity_domain,
> > +	.release_domain = &tegra_smmu_identity_domain,
> >   	.def_domain_type = &tegra_smmu_def_domain_type,
> >   	.domain_alloc_paging = tegra_smmu_domain_alloc_paging,
> >   	.probe_device = tegra_smmu_probe_device,
> > @@ -1108,6 +1123,40 @@ static void tegra_smmu_debugfs_exit(struct tegra_smmu *smmu)
> >   	debugfs_remove_recursive(smmu->debugfs);
> >   }
> >   
> > +/*
> > + * The default domain type is a property of the IOMMU group, so all swgroups in
> > + * one group must agree on use_dma_api. Otherwise the core sees conflicting
> > + * def_domain_type and falls back to identity for the whole group.
> > + */
> > +static void tegra_smmu_check_groups(struct tegra_smmu *smmu)
> > +{
> > +	const struct tegra_smmu_soc *soc = smmu->soc;
> > +	unsigned int i, j;
> > +
> > +	for (i = 0; i < soc->num_groups; i++) {
> > +		const struct tegra_smmu_group_soc *group = &soc->groups[i];
> > +		int dma_api = -1;
> > +
> > +		for (j = 0; j < group->num_swgroups; j++) {
> > +			const struct tegra_smmu_swgroup *swgrp;
> > +
> > +			swgrp = tegra_smmu_find_swgroup(smmu,
> > +							group->swgroups[j]);
> > +			if (!swgrp)
> > +				continue;
> > +
> > +			if (dma_api < 0)
> > +				dma_api = swgrp->use_dma_api;
> > +			else if (swgrp->use_dma_api != !!dma_api)
> > +				break;
> > +		}
> > +
> > +		WARN(j < group->num_swgroups,
> > +		     "SMMU group %s mixes DMA API and identity swgroups\n",
> > +		     group->name);
> > +	}
> > +}
> > +
> >   struct tegra_smmu *tegra_smmu_probe(struct device *dev,
> >   				    const struct tegra_smmu_soc *soc,
> >   				    struct tegra_mc *mc)
> > @@ -1142,6 +1191,8 @@ struct tegra_smmu *tegra_smmu_probe(struct device *dev,
> >   	smmu->dev = dev;
> >   	smmu->mc = mc;
> >   
> > +	tegra_smmu_check_groups(smmu);
> > +
> >   	smmu->pfn_mask =
> >   		BIT_MASK(mc->soc->num_address_bits - SMMU_PTE_SHIFT) - 1;
> >   	dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n",
> > diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
> > index 2883c4f91144..024c63bdd480 100644
> > --- a/drivers/memory/tegra/tegra114.c
> > +++ b/drivers/memory/tegra/tegra114.c
> > @@ -1029,15 +1029,18 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
> >   
> >   static const struct tegra_smmu_swgroup tegra114_swgroups[] = {
> >   	{ .name = "dc",        .swgroup = TEGRA_SWGROUP_DC,        .reg = 0x240,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "dcb",       .swgroup = TEGRA_SWGROUP_DCB,       .reg = 0x244,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "epp",       .swgroup = TEGRA_SWGROUP_EPP,       .reg = 0x248 },
> > -	{ .name = "g2",        .swgroup = TEGRA_SWGROUP_G2,        .reg = 0x24c },
> > +	{ .name = "g2",        .swgroup = TEGRA_SWGROUP_G2,        .reg = 0x24c,
> > +	  .use_dma_api = true },
> >   	{ .name = "avpc",      .swgroup = TEGRA_SWGROUP_AVPC,      .reg = 0x23c },
> > -	{ .name = "nv",        .swgroup = TEGRA_SWGROUP_NV,        .reg = 0x268 },
> > +	{ .name = "nv",        .swgroup = TEGRA_SWGROUP_NV,        .reg = 0x268,
> > +	  .use_dma_api = true },
> >   	{ .name = "hda",       .swgroup = TEGRA_SWGROUP_HDA,       .reg = 0x254 },
> > -	{ .name = "hc",        .swgroup = TEGRA_SWGROUP_HC,        .reg = 0x250 },
> > +	{ .name = "hc",        .swgroup = TEGRA_SWGROUP_HC,        .reg = 0x250,
> > +	  .use_dma_api = true },
> >   	{ .name = "msenc",     .swgroup = TEGRA_SWGROUP_MSENC,     .reg = 0x264 },
> >   	{ .name = "ppcs",      .swgroup = TEGRA_SWGROUP_PPCS,      .reg = 0x270 },
> >   	{ .name = "vde",       .swgroup = TEGRA_SWGROUP_VDE,       .reg = 0x27c },
> > diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
> > index a38fbf2baf6c..17068aaf163f 100644
> > --- a/drivers/memory/tegra/tegra124.c
> > +++ b/drivers/memory/tegra/tegra124.c
> > @@ -1071,13 +1071,14 @@ static const struct tegra_mc_client tegra124_mc_clients[] = {
> >   
> >   static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
> >   	{ .name = "dc",        .swgroup = TEGRA_SWGROUP_DC,        .reg = 0x240,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "dcb",       .swgroup = TEGRA_SWGROUP_DCB,       .reg = 0x244,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "afi",       .swgroup = TEGRA_SWGROUP_AFI,       .reg = 0x238 },
> >   	{ .name = "avpc",      .swgroup = TEGRA_SWGROUP_AVPC,      .reg = 0x23c },
> >   	{ .name = "hda",       .swgroup = TEGRA_SWGROUP_HDA,       .reg = 0x254 },
> > -	{ .name = "hc",        .swgroup = TEGRA_SWGROUP_HC,        .reg = 0x250 },
> > +	{ .name = "hc",        .swgroup = TEGRA_SWGROUP_HC,        .reg = 0x250,
> > +	  .use_dma_api = true },
> >   	{ .name = "msenc",     .swgroup = TEGRA_SWGROUP_MSENC,     .reg = 0x264 },
> >   	{ .name = "ppcs",      .swgroup = TEGRA_SWGROUP_PPCS,      .reg = 0x270 },
> >   	{ .name = "sata",      .swgroup = TEGRA_SWGROUP_SATA,      .reg = 0x274 },
> > @@ -1093,7 +1094,8 @@ static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
> >   	{ .name = "sdmmc2a",   .swgroup = TEGRA_SWGROUP_SDMMC2A,   .reg = 0xa98 },
> >   	{ .name = "sdmmc3a",   .swgroup = TEGRA_SWGROUP_SDMMC3A,   .reg = 0xa9c },
> >   	{ .name = "sdmmc4a",   .swgroup = TEGRA_SWGROUP_SDMMC4A,   .reg = 0xaa0 },
> > -	{ .name = "vic",       .swgroup = TEGRA_SWGROUP_VIC,       .reg = 0x284 },
> > +	{ .name = "vic",       .swgroup = TEGRA_SWGROUP_VIC,       .reg = 0x284,
> > +	  .use_dma_api = true },
> >   	{ .name = "vi",        .swgroup = TEGRA_SWGROUP_VI,        .reg = 0x280 },
> >   };
> >   
> > diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
> > index 0ee4715413ba..df6b5a499ccc 100644
> > --- a/drivers/memory/tegra/tegra30.c
> > +++ b/drivers/memory/tegra/tegra30.c
> > @@ -1140,19 +1140,23 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
> >   
> >   static const struct tegra_smmu_swgroup tegra30_swgroups[] = {
> >   	{ .name = "dc",   .swgroup = TEGRA_SWGROUP_DC,   .reg = 0x240,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "dcb",  .swgroup = TEGRA_SWGROUP_DCB,  .reg = 0x244,
> > -	  .defer_enable = true },
> > +	  .defer_enable = true, .use_dma_api = true },
> >   	{ .name = "epp",  .swgroup = TEGRA_SWGROUP_EPP,  .reg = 0x248 },
> > -	{ .name = "g2",   .swgroup = TEGRA_SWGROUP_G2,   .reg = 0x24c },
> > +	{ .name = "g2",   .swgroup = TEGRA_SWGROUP_G2,   .reg = 0x24c,
> > +	  .use_dma_api = true },
> >   	{ .name = "mpe",  .swgroup = TEGRA_SWGROUP_MPE,  .reg = 0x264 },
> >   	{ .name = "vi",   .swgroup = TEGRA_SWGROUP_VI,   .reg = 0x280 },
> >   	{ .name = "afi",  .swgroup = TEGRA_SWGROUP_AFI,  .reg = 0x238 },
> >   	{ .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
> > -	{ .name = "nv",   .swgroup = TEGRA_SWGROUP_NV,   .reg = 0x268 },
> > -	{ .name = "nv2",  .swgroup = TEGRA_SWGROUP_NV2,  .reg = 0x26c },
> > +	{ .name = "nv",   .swgroup = TEGRA_SWGROUP_NV,   .reg = 0x268,
> > +	  .use_dma_api = true },
> > +	{ .name = "nv2",  .swgroup = TEGRA_SWGROUP_NV2,  .reg = 0x26c,
> > +	  .use_dma_api = true },
> >   	{ .name = "hda",  .swgroup = TEGRA_SWGROUP_HDA,  .reg = 0x254 },
> > -	{ .name = "hc",   .swgroup = TEGRA_SWGROUP_HC,   .reg = 0x250 },
> > +	{ .name = "hc",   .swgroup = TEGRA_SWGROUP_HC,   .reg = 0x250,
> > +	  .use_dma_api = true },
> >   	{ .name = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
> >   	{ .name = "sata", .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x278 },
> >   	{ .name = "vde",  .swgroup = TEGRA_SWGROUP_VDE,  .reg = 0x27c },
> > diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
> > index ea67972fd585..1cbd990fc0f4 100644
> > --- a/include/soc/tegra/mc.h
> > +++ b/include/soc/tegra/mc.h
> > @@ -78,6 +78,13 @@ struct tegra_smmu_swgroup {
> >   	 * tegra_smmu_enable_translation().
> >   	 */
> >   	bool defer_enable;
> > +
> > +	/*
> > +	 * Set once the clients behind this swgroup are known to work with an
> > +	 * IOMMU_DOMAIN_DMA default domain. All swgroups of a
> > +	 * tegra_smmu_group_soc must agree.
> > +	 */
> > +	bool use_dma_api;
> >   };
> >   
> >   struct tegra_smmu_group_soc {
> > 
> 
> 






      reply	other threads:[~2026-10-23  5:16 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16  6:46 [PATCH v2 00/11] Make the 32-bit ARM DMA API work with normal IOMMU DMA default domains (+ Tegra PoC) Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 01/11] iommu: Add iommu_teardown_dma_ops Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 02/11] iommu: Add cookie type for ARM_DMA_USE_IOMMU Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 03/11] ARM: dma-mapping: Split mapping allocation from domain allocation Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 04/11] ARM: dma-mapping: Implement and expose DMA setup functions Mikko Perttunen
2026-10-16  7:06   ` sashiko-bot
2026-10-22 13:16   ` Robin Murphy
2026-10-23  5:12     ` Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 05/11] ARM: dma-mapping: Bypass the legacy path for core-owned DMA API domains Mikko Perttunen
2026-10-16  7:01   ` sashiko-bot
2026-10-19 16:55   ` Robin Murphy
2026-10-20  4:01     ` Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 06/11] ARM: dma-mapping: Handle foreign buffers in arm_iommu_get_sgtable Mikko Perttunen
2026-10-16  7:04   ` sashiko-bot
2026-10-19 15:47   ` Robin Murphy
2026-10-20  3:55     ` Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 07/11] iommu: Let 32-bit ARM drivers opt into a DMA API default domain Mikko Perttunen
2026-10-20 11:28   ` Robin Murphy
2026-10-21  3:12     ` Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 08/11] iommu/tegra-smmu: Defer display client translation to driver handover Mikko Perttunen
2026-10-16  7:01   ` sashiko-bot
2026-10-16  6:46 ` [PATCH v2 09/11] gpu: host1x: Drop release of legacy 32-bit ARM DMA domain Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 10/11] drm/tegra: " Mikko Perttunen
2026-10-16  6:46 ` [PATCH v2 11/11] iommu/tegra-smmu: Use a DMA API default domain per swgroup Mikko Perttunen
2026-10-20 15:30   ` Robin Murphy
2026-10-23  5:14     ` Mikko Perttunen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9NN3esQaTdOIroYwCH7uag@nvidia.com \
    --to=mperttunen@nvidia.com \
    --cc=airlied@gmail.com \
    --cc=alim.akhtar@samsung.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=geert+renesas@glider.be \
    --cc=heiko@sntech.de \
    --cc=iommu@lists.linux.dev \
    --cc=jernej.skrabec@gmail.com \
    --cc=jgg@ziepe.ca \
    --cc=jonathanh@nvidia.com \
    --cc=joro@8bytes.org \
    --cc=krzk@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=m.szyprowski@samsung.com \
    --cc=matthias.bgg@gmail.com \
    --cc=peter.griffin@linaro.org \
    --cc=robin.clark@oss.qualcomm.com \
    --cc=robin.murphy@arm.com \
    --cc=samuel@sholland.org \
    --cc=simona@ffwll.ch \
    --cc=thierry.reding@kernel.org \
    --cc=vdumpa@nvidia.com \
    --cc=wens@kernel.org \
    --cc=will@kernel.org \
    --cc=yong.wu@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.