public inbox for linux-tegra@vger.kernel.org
 help / color / mirror / Atom feed
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 6/9] iommu/tegra: smmu: get swgroups from DT "iommus="
Date: Tue, 19 Nov 2013 11:33:10 +0200	[thread overview]
Message-ID: <1384853593-32202-7-git-send-email-hdoyu@nvidia.com> (raw)
In-Reply-To: <1384853593-32202-1-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

This provides the info about which swgroups a device belongs to. This
info is passed from DT. This is necessary for the unified SMMU driver
among Tegra SoCs since each has different H/W accelerators.

Signed-off-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
v5:
"iommu=" in a device DT is used instead of "mmu-masters" in an iommu
DT. This is "iommu=" version of:

  [PATCHv4 5/7] iommu/tegra: smmu: Support "mmu-masters" binding
---
 .../bindings/iommu/nvidia,tegra30-smmu.txt         |  17 ++-
 drivers/iommu/tegra-smmu.c                         | 125 ++++++++++++++++++---
 2 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
index 89fb543..44a4dc3 100644
--- a/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/nvidia,tegra30-smmu.txt
@@ -8,9 +8,12 @@ Required properties:
 - nvidia,#asids : # of ASIDs
 - dma-window : IOVA start address and length.
 - nvidia,ahb : phandle to the ahb bus connected to SMMU.
+- iommus: phandle to an iommu device which a device is
+  attached to and indicates which swgroups a device belongs to(SWGROUP ID).
+  SWGROUP ID is from 0 to 63, and a device can belong to multiple SWGROUPS.
 
 Example:
-	smmu {
+	smmu: iommu {
 		compatible = "nvidia,tegra30-smmu";
 		reg = <0x7000f010 0x02c
 		       0x7000f1f0 0x010
@@ -18,4 +21,16 @@ Example:
 		nvidia,#asids = <4>;		/* # of ASIDs */
 		dma-window = <0 0x40000000>;	/* IOVA start & length */
 		nvidia,ahb = <&ahb>;
+		#iommu-cells = <2>;
 	};
+
+	host1x {
+		compatible = "nvidia,tegra30-host1x", "simple-bus";
+		iommus = <&smmu TEGRA_SWGROUP_CELLS(HC)>;
+		....
+		gr3d {
+			compatible = "nvidia,tegra30-gr3d";
+			nvidia,memory-clients = <&smmu TEGRA_SWGROUP_CELLS(NV)
+						       TEGRA_SWGROUP_CELLS(NV2)>;
+			....
+		};
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index e999ad0..e915201a 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -190,6 +190,8 @@ enum {
  * Per client for address space
  */
 struct smmu_client {
+	struct device_node	*of_node;
+	struct rb_node		node;
 	struct device		*dev;
 	struct list_head	list;
 	struct smmu_as		*as;
@@ -233,6 +235,7 @@ struct smmu_device {
 	spinlock_t	lock;
 	char		*name;
 	struct device	*dev;
+	struct rb_root	clients;
 	struct page *avp_vector_page;	/* dummy page shared by all AS's */
 
 	/*
@@ -310,6 +313,96 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
  */
 #define FLUSH_SMMU_REGS(smmu)	smmu_read(smmu, SMMU_CONFIG)
 
+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,
+					    struct device_node *dev_node)
+{
+	struct rb_node *node = smmu->clients.rb_node;
+
+	while (node) {
+		struct smmu_client *client;
+
+		client = container_of(node, struct smmu_client, node);
+		if (dev_node < client->of_node)
+			node = node->rb_left;
+		else if (dev_node > client->of_node)
+			node = node->rb_right;
+		else
+			return client;
+	}
+
+	return NULL;
+}
+
+static int insert_smmu_client(struct smmu_device *smmu,
+			      struct smmu_client *client)
+{
+	struct rb_node **new, *parent;
+
+	new = &smmu->clients.rb_node;
+	parent = NULL;
+	while (*new) {
+		struct smmu_client *this;
+		this = container_of(*new, struct smmu_client, node);
+
+		parent = *new;
+		if (client->of_node < this->of_node)
+			new = &((*new)->rb_left);
+		else if (client->of_node > this->of_node)
+			new = &((*new)->rb_right);
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&client->node, parent, new);
+	rb_insert_color(&client->node, &smmu->clients);
+	return 0;
+}
+
+static int register_smmu_client(struct smmu_device *smmu,
+				struct device *dev, unsigned long *swgroups)
+{
+	struct smmu_client *client;
+
+	client = find_smmu_client(smmu, dev->of_node);
+	if (client) {
+		dev_err(dev,
+			"rejecting multiple registrations for client device %s\n",
+			dev->of_node->full_name);
+		return -EBUSY;
+	}
+
+	client = devm_kzalloc(smmu->dev, sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+
+	client->dev = dev;
+	client->of_node = dev->of_node;
+	memcpy(client->hwgrp, swgroups, sizeof(u64));
+	return insert_smmu_client(smmu, client);
+}
+
+static int smmu_of_get_swgroups(struct device *dev, unsigned long *swgroups)
+{
+	int i;
+	struct of_phandle_args args;
+
+	of_property_for_each_phandle_with_args(dev->of_node, "iommus",
+					       "#iommu-cells", i, &args) {
+		if (args.np != smmu_handle->dev->of_node)
+			continue;
+
+		BUG_ON(args.args_count != 2);
+
+		memcpy(swgroups, args.args, sizeof(u64));
+		pr_debug("swgroups=%08lx %08lx ops=%p %s\n",
+			 swgroups[0], swgroups[1],
+			 dev->bus->iommu_ops, dev_name(dev));
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
 static int __smmu_client_set_hwgrp(struct smmu_client *c,
 				   unsigned long *map, int on)
 {
@@ -719,21 +812,16 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,
 	struct smmu_as *as = domain->priv;
 	struct smmu_device *smmu = as->smmu;
 	struct smmu_client *client, *c;
-	unsigned long *map;
 	int err;
 
-	client = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL);
+	client = find_smmu_client(smmu, dev->of_node);
 	if (!client)
 		return -ENOMEM;
-	client->dev = dev;
-	client->as = as;
-	map = (unsigned long *)dev->platform_data;
-	if (!map)
-		return -EINVAL;
 
-	err = smmu_client_enable_hwgrp(client, map);
+	client->as = as;
+	err = smmu_client_enable_hwgrp(client, client->hwgrp);
 	if (err)
-		goto err_hwgrp;
+		return -EINVAL;
 
 	spin_lock(&as->client_lock);
 	list_for_each_entry(c, &as->client, list) {
@@ -751,7 +839,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,
 	 * Reserve "page zero" for AVP vectors using a common dummy
 	 * page.
 	 */
-	if (test_bit(TEGRA_SWGROUP_AVPC, map)) {
+	if (test_bit(TEGRA_SWGROUP_AVPC, client->hwgrp)) {
 		struct page *page;
 
 		page = as->smmu->avp_vector_page;
@@ -766,8 +854,6 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,
 err_client:
 	smmu_client_disable_hwgrp(client);
 	spin_unlock(&as->client_lock);
-err_hwgrp:
-	devm_kfree(smmu->dev, client);
 	return err;
 }
 
@@ -784,7 +870,6 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain,
 		if (c->dev == dev) {
 			smmu_client_disable_hwgrp(c);
 			list_del(&c->list);
-			devm_kfree(smmu->dev, c);
 			c->as = NULL;
 			dev_dbg(smmu->dev,
 				"%s is detached\n", dev_name(c->dev));
@@ -896,6 +981,15 @@ static int smmu_iommu_add_device(struct device *dev)
 	if (err)
 		return -ENODEV;
 
+	if (!find_smmu_client(smmu_handle, dev->of_node)) {
+		err = register_smmu_client(smmu_handle, dev, swgroups);
+		if (err) {
+			dev_err(dev, "failed to add client %s\n",
+				dev_name(dev));
+			return -EINVAL;
+		}
+	}
+
 	if (test_bit(TEGRA_SWGROUP_PPCS, swgroups))
 		map = smmu_handle->map[SYSTEM_PROTECTED];
 	else
@@ -906,8 +1000,8 @@ static int smmu_iommu_add_device(struct device *dev)
 	else
 		return -EPROBE_DEFER;
 
-	pr_debug("swgroups=%08lx map=%p err=%d %s\n",
-		 swgroups, map, err, dev_name(dev));
+	pr_debug("swgroups=%08lx %08lx map=%p err=%d %s\n",
+		 swgroups[0], swgroups[1], map, err, dev_name(dev));
 	return err;
 }
 
@@ -1160,6 +1254,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	smmu->clients = RB_ROOT;
 	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),
-- 
1.8.1.5

  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   ` [PATCHv5 4/9] iommu/tegra: smmu: register device to iommu dynamically Hiroshi Doyu
     [not found]     ` <1384853593-32202-5-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:39       ` 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   ` Hiroshi Doyu [this message]
     [not found]     ` <1384853593-32202-7-git-send-email-hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-11-19 21:52       ` [PATCHv5 6/9] iommu/tegra: smmu: get swgroups from DT "iommus=" 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-7-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