From: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org,
will.deacon-5wv7dgnIgG8@public.gmane.org,
grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org,
galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
Cc: mark.rutland-5wv7dgnIgG8@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: [PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically
Date: Tue, 19 Nov 2013 11:33:08 +0200 [thread overview]
Message-ID: <1384853593-32202-5-git-send-email-hdoyu@nvidia.com> (raw)
In-Reply-To: <1384853593-32202-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
platform_devices are registered as IOMMU'able dynamically via
add_device() and remove_device().
Tegra SMMU can have multiple address spaces(AS). IOMMU'able devices
can belong to one of them. Multiple IOVA maps are created at boot-up,
which can be attached to devices later. We reserve 2 of them for
static assignment, AS[0] for system default, AS[1] for AHB clusters as
protected domain from others, where there are many traditional
pheripheral devices like USB, SD/MMC. They should be isolated from
some smart devices like host1x for system robustness. Even if smart
devices behaves wrongly, the traditional devices(SD/MMC, USB) wouldn't
be affected, and the system could continue most likely. DMA API(ARM)
needs ARM_DMA_USE_IOMMU to be enabled.
Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
v5:
Add check NUM_OF_STATIC_MAPS < #asids.
v4:
Combined the following from v3. This makes more sense what they do.
[PATCHv3 06/19] iommu/tegra: smmu: Select ARM_DMA_USE_IOMMU in Kconfig
[PATCHv3 07/19] iommu/tegra: smmu: Create default IOVA maps
[PATCHv3 08/19] iommu/tegra: smmu: Register platform_device to IOMMU dynamically
[PATCHv3 19/19] iommu/tegra: smmu: Support Multiple ASID
---
drivers/iommu/Kconfig | 1 +
drivers/iommu/tegra-smmu.c | 70 +++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c880eba..d1bc65d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -170,6 +170,7 @@ config TEGRA_IOMMU_SMMU
bool "Tegra SMMU IOMMU Support"
depends on ARCH_TEGRA && TEGRA_AHB
select IOMMU_API
+ select ARM_DMA_USE_IOMMU
help
Enables support for remapping discontiguous physical memory
shared with the operating system into contiguous I/O virtual
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 37dd862..d836a6b 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -39,6 +39,9 @@
#include <asm/page.h>
#include <asm/cacheflush.h>
+#include <asm/dma-iommu.h>
+
+#include <dt-bindings/memory/tegra-swgroup.h>
enum smmu_hwgrp {
HWGRP_AFI,
@@ -319,6 +322,8 @@ struct smmu_device {
struct device_node *ahb;
+ struct dma_iommu_mapping **map;
+
int num_as;
struct smmu_as as[0]; /* Run-time allocated array */
};
@@ -947,6 +952,44 @@ static void smmu_iommu_domain_destroy(struct iommu_domain *domain)
dev_dbg(smmu->dev, "smmu_as@%p\n", as);
}
+/*
+ * ASID[0] for the system default
+ * ASID[1] for PPCS("AHB bus children"), which has SDMMC
+ * ASID[2][3].. open for drivers, first come, first served.
+ */
+enum {
+ SYSTEM_DEFAULT,
+ SYSTEM_PROTECTED,
+ NUM_OF_STATIC_MAPS,
+};
+
+static int smmu_iommu_add_device(struct device *dev)
+{
+ int err = -EPROBE_DEFER;
+ u32 swgroups = dev->platform_data;
+ struct dma_iommu_mapping *map = NULL;
+
+ if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
+ map = smmu_handle->map[SYSTEM_PROTECTED];
+ else
+ map = smmu_handle->map[SYSTEM_DEFAULT];
+
+ if (map)
+ err = arm_iommu_attach_device(dev, map);
+ else
+ return -EPROBE_DEFER;
+
+ pr_debug("swgroups=%08lx map=%p err=%d %s\n",
+ swgroups, map, err, dev_name(dev));
+ return err;
+}
+
+static void smmu_iommu_remove_device(struct device *dev)
+{
+ dev_dbg(dev, "Detaching from map %p\n", to_dma_iommu_mapping(dev));
+ arm_iommu_detach_device(dev);
+}
+
static struct iommu_ops smmu_iommu_ops = {
.domain_init = smmu_iommu_domain_init,
.domain_destroy = smmu_iommu_domain_destroy,
@@ -956,6 +999,8 @@ static struct iommu_ops smmu_iommu_ops = {
.unmap = smmu_iommu_unmap,
.iova_to_phys = smmu_iommu_iova_to_phys,
.domain_has_cap = smmu_iommu_domain_has_cap,
+ .add_device = smmu_iommu_add_device,
+ .remove_device = smmu_iommu_remove_device,
.pgsize_bitmap = SMMU_IOMMU_PGSIZES,
};
@@ -1144,6 +1189,23 @@ static int tegra_smmu_resume(struct device *dev)
return err;
}
+static void tegra_smmu_create_default_map(struct smmu_device *smmu)
+{
+ int i;
+
+ for (i = 0; i < smmu->num_as; i++) {
+ dma_addr_t base = smmu->iovmm_base;
+ size_t size = smmu->page_count << PAGE_SHIFT;
+
+ smmu->map[i] = arm_iommu_create_mapping(&platform_bus_type,
+ base, size, 0);
+ if (IS_ERR(smmu->map[i]))
+ dev_err(smmu->dev,
+ "Couldn't create: asid=%d map=%p %pa-%pa\n",
+ i, smmu->map[i], &base, &base + size - 1);
+ }
+}
+
static int tegra_smmu_probe(struct platform_device *pdev)
{
struct smmu_device *smmu;
@@ -1160,13 +1222,18 @@ static int tegra_smmu_probe(struct platform_device *pdev)
if (of_property_read_u32(dev->of_node, "nvidia,#asids", &asids))
return -ENODEV;
- bytes = sizeof(*smmu) + asids * sizeof(*smmu->as);
+ if (asids < NUM_OF_STATIC_MAPS)
+ return -EINVAL;
+
+ bytes = sizeof(*smmu) + asids * (sizeof(*smmu->as) +
+ sizeof(struct dma_iommu_mapping *));
smmu = devm_kzalloc(dev, bytes, GFP_KERNEL);
if (!smmu) {
dev_err(dev, "failed to allocate smmu_device\n");
return -ENOMEM;
}
+ smmu->map = (struct dma_iommu_mapping **)(smmu->as + asids);
smmu->nregs = pdev->num_resources;
smmu->regs = devm_kzalloc(dev, 2 * smmu->nregs * sizeof(*smmu->regs),
GFP_KERNEL);
@@ -1236,6 +1303,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
smmu_debugfs_create(smmu);
smmu_handle = smmu;
bus_set_iommu(&platform_bus_type, &smmu_iommu_ops);
+ tegra_smmu_create_default_map(smmu);
return 0;
}
--
1.8.1.5
next prev parent reply other threads:[~2013-11-19 9:33 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-19 9:33 [PATCHv5 0/9] Unifying Tegra IOMMU(SMMU) driver among Tegra SoCs Hiroshi Doyu
[not found] ` < 1384853593-32202-3-git-send-email-hdoyu@nvidia.com>
[not found] ` <1384853593-32202-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 9:33 ` [PATCHv5 1/9] of: introduce of_property_for_earch_phandle_with_args() Hiroshi Doyu
2013-11-19 9:33 ` [PATCHv5 2/9] driver/core: populate devices in order for IOMMUs Hiroshi Doyu
[not found] ` <1384853593-32202-3-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 10:25 ` Thierry Reding
[not found] ` <20131119102506.GG31504-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2013-11-19 12:03 ` Hiroshi Doyu
[not found] ` <20131119.140351.1342214267287135109.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:22 ` Stephen Warren
[not found] ` <528BD6A7.3030908-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-11-20 3:17 ` Hiroshi Doyu
[not found] ` <20131120.051708.396722414386125310.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-20 13:14 ` Thierry Reding
[not found] ` <20131120131447.GA8279-AwZRO8vwLAwmlAP/+Wk3EA@public.gmane.org>
2013-11-20 14:03 ` Hiroshi Doyu
[not found] ` <20131120.160359.1043627108929095327.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-20 16:30 ` Stephen Warren
[not found] ` <528CE3AB.60806-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-11-21 9:01 ` Hiroshi Doyu
2013-11-21 13:15 ` Grant Likely
[not found] ` <20131121131558.E5B82C40A2C-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2013-11-21 19:04 ` Stephen Warren
[not found] ` <528E5932.1070105-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-11-22 7:41 ` Grant Likely
[not found] ` <20131122074111.155E2C40753-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2013-11-22 17:35 ` Stephen Warren
[not found] ` <528F95FE.7080406-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-11-25 17:39 ` Will Deacon
2013-11-19 9:33 ` [PATCHv5 3/9] ARM: tegra: create a DT header defining SWGROUP ID Hiroshi Doyu
[not found] ` <1384853593-32202-4-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:36 ` Stephen Warren
2013-11-19 9:33 ` Hiroshi Doyu [this message]
[not found] ` <1384853593-32202-5-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:39 ` [PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically Stephen Warren
2013-11-19 9:33 ` [PATCHv5 5/9] iommu/tegra: smmu: calculate ASID register offset by ID Hiroshi Doyu
2013-11-19 9:33 ` [PATCHv5 6/9] iommu/tegra: smmu: get swgroups from DT "iommus=" Hiroshi Doyu
[not found] ` <1384853593-32202-7-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:52 ` Stephen Warren
2013-11-19 9:33 ` [PATCHv5 7/9] iommu/tegra: smmu: allow duplicate ASID wirte Hiroshi Doyu
2013-11-19 9:33 ` [PATCHv5 8/9] iommu/tegra: smmu: Rename hwgrp -> swgroups Hiroshi Doyu
2013-11-19 9:33 ` [PATCHv5 9/9] [FOR TEST] ARM: dt: tegra30: add "iommus" binding Hiroshi Doyu
[not found] ` < 1384853593-32202-2-git-send-email-hdoyu@nvidia.com>
[not found] ` <1384853593-32202-2-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-21 12:43 ` [PATCHv5 1/9] of: introduce of_property_for_earch_phandle_with_args() Grant Likely
[not found] ` <20131121124328.46BC1C40A2C-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2013-11-21 13:12 ` Hiroshi Doyu
[not found] ` <20131121124328. 46BC1C40A2C@trevor.secretlab.ca>
[not found] ` <20131121151218.befbb483c0cf09cdcd4cd4dd@ nvidia.com>
[not found] ` <20131121151218.befbb483c0cf09cdcd4cd4dd-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-21 15:56 ` Grant Likely
[not found] ` <20131121155649.48C96C406A3-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2013-11-21 17:20 ` Hiroshi Doyu
[not found] ` <20131121.192051.747601347584525020.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-21 18:52 ` Stephen Warren
2013-11-21 21:36 ` Rob Herring
[not found] ` < 1384853593-32202-5-git-send-email-hdoyu@nvidia.com>
[not found] ` <528BDAAA.4000203@ wwwdotorg.org>
[not found] ` <528BDAAA.4000203-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-11-21 13:23 ` [PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically Grant Likely
[not found] ` <20131121132322.EFDD1C40A2C-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2013-11-21 13:38 ` Hiroshi Doyu
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=1384853593-32202-5-git-send-email-hdoyu@nvidia.com \
--to=hdoyu-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org \
--cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
--cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
--cc=swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
--cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox