Commit c8cc2655 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Joerg Roedel
Browse files

iommu/tegra-smmu: Implement an IDENTITY domain



What tegra-smmu does during tegra_smmu_set_platform_dma() is actually
putting the iommu into identity mode.

Move to the new core support for ARM_DMA_USE_IOMMU by defining
ops->identity_domain.

Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/11-v8-81230027b2fa+9d-iommu_all_defdom_jgg@nvidia.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent b3d14960
Loading
Loading
Loading
Loading
+32 −5
Original line number Diff line number Diff line
@@ -511,23 +511,39 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
	return err;
}

static void tegra_smmu_set_platform_dma(struct device *dev)
static int tegra_smmu_identity_attach(struct iommu_domain *identity_domain,
				      struct device *dev)
{
	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
	struct tegra_smmu_as *as = to_smmu_as(domain);
	struct tegra_smmu *smmu = as->smmu;
	struct tegra_smmu_as *as;
	struct tegra_smmu *smmu;
	unsigned int index;

	if (!fwspec)
		return;
		return -ENODEV;

	if (domain == identity_domain || !domain)
		return 0;

	as = to_smmu_as(domain);
	smmu = as->smmu;
	for (index = 0; index < fwspec->num_ids; index++) {
		tegra_smmu_disable(smmu, fwspec->ids[index], as->id);
		tegra_smmu_as_unprepare(smmu, as);
	}
	return 0;
}

static struct iommu_domain_ops tegra_smmu_identity_ops = {
	.attach_dev = tegra_smmu_identity_attach,
};

static struct iommu_domain tegra_smmu_identity_domain = {
	.type = IOMMU_DOMAIN_IDENTITY,
	.ops = &tegra_smmu_identity_ops,
};

static void tegra_smmu_set_pde(struct tegra_smmu_as *as, unsigned long iova,
			       u32 value)
{
@@ -962,11 +978,22 @@ static int tegra_smmu_of_xlate(struct device *dev,
	return iommu_fwspec_add_ids(dev, &id, 1);
}

static int tegra_smmu_def_domain_type(struct device *dev)
{
	/*
	 * 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.
	 */
	return IOMMU_DOMAIN_IDENTITY;
}

static const struct iommu_ops tegra_smmu_ops = {
	.identity_domain = &tegra_smmu_identity_domain,
	.def_domain_type = &tegra_smmu_def_domain_type,
	.domain_alloc = tegra_smmu_domain_alloc,
	.probe_device = tegra_smmu_probe_device,
	.device_group = tegra_smmu_device_group,
	.set_platform_dma_ops = tegra_smmu_set_platform_dma,
	.of_xlate = tegra_smmu_of_xlate,
	.pgsize_bitmap = SZ_4K,
	.default_domain_ops = &(const struct iommu_domain_ops) {