Skip to contentSkip to conversation

Support IOMMU for 2d/3d on Tegra30/114

PATCH Applied Dmitry Osipenko 2 participants 17 messages May 3, 2018 – May 4, 2018

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover Support IOMMU for 2d/3d on Tegra30/114

Hi,

This series enables IOMMU support for 2d/3d HW on Tegra30/114, as a result userspace that uses 2d/3d could work with the active IOMMU.

Dmitry Osipenko (5):
drm/tegra: dc: Balance IOMMU group refcounting drm/tegra: gr2d: Add IOMMU support
drm/tegra: gr3d: Add IOMMU support
ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients
ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients

 arch/arm/boot/dts/tegra114.dtsi |  5 +++++
 arch/arm/boot/dts/tegra30.dtsi  | 14 +++++++++++++
 drivers/gpu/drm/tegra/dc.c      | 35 ++++++++++++++++-----------------
 drivers/gpu/drm/tegra/dc.h      |  2 +-
 drivers/gpu/drm/tegra/drm.h     |  2 +-
 drivers/gpu/drm/tegra/gr2d.c    | 31 +++++++++++++++++++++++++++--
 drivers/gpu/drm/tegra/gr3d.c    | 27 +++++++++++++++++++++++++
 7 files changed, 94 insertions(+), 22 deletions(-)
Signature · 1 line
2.17.0
#1 lore raw

PATCH 1/5 drm/tegra: dc: Balance IOMMU group refcounting

Remove unneeded iommu_group_get() and add missing iommu_group_put(), correcting IOMMU group refcount. This is a minor correction / cleanup that doesn't really fix anything because Tegra's IOMMU driver are built-in and hence groups refcounting can't hold IOMMU driver from unloading.

---
 drivers/gpu/drm/tegra/dc.c  | 35 +++++++++++++++++------------------
 drivers/gpu/drm/tegra/dc.h  |  2 +-
 drivers/gpu/drm/tegra/drm.h |  2 +-
 3 files changed, 19 insertions(+), 20 deletions(-)
drivers/gpu/drm/tegra/dc.c +17 -18
index d7a0f62c6e2e..9fc34c6a7218 100644
@@ -1927,7 +1927,6 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 static int tegra_dc_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
@@ -1939,20 +1938,21 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!dc->syncpt)
 		dev_warn(dc->dev, "failed to allocate syncpoint\n");
 
-	if (group && tegra->domain) {
-		if (group != tegra->group) {
-			err = iommu_attach_group(tegra->domain, group);
+	if (tegra->domain) {
+		dc->group = iommu_group_get(client->dev);
+
+		if (dc->group && dc->group != tegra->dc_group) {
+			err = iommu_attach_group(tegra->domain, dc->group);
 			if (err < 0) {
 				dev_err(dc->dev,
 					"failed to attach to domain: %d\n",
 					err);
+				iommu_group_put(dc->group);
 				return err;
 			}
 
-			tegra->group = group;
+			tegra->dc_group = dc->group;
 		}
-
-		dc->domain = tegra->domain;
 	}
 
 	if (dc->soc->wgrps)
@@ -2017,13 +2017,13 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!IS_ERR(primary))
 		drm_plane_cleanup(primary);
 
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	return err;
@@ -2032,7 +2032,6 @@ static int tegra_dc_init(struct host1x_client *client)
 static int tegra_dc_exit(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
 	int err;
@@ -2045,13 +2044,13 @@ static int tegra_dc_exit(struct host1x_client *client)
 		return err;
 	}
 
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	host1x_syncpt_free(dc->syncpt);
drivers/gpu/drm/tegra/dc.h +1 -1
index ca5cac6bf8ea..5ca4e07333bb 100644
@@ -94,7 +94,7 @@ struct tegra_dc {
 
 	const struct tegra_dc_soc_info *soc;
 
-	struct iommu_domain *domain;
+	struct iommu_group *group;
 };
 
 static inline struct tegra_dc *
drivers/gpu/drm/tegra/drm.h +1 -1
index 4f41aaec8530..7777640a6911 100644
@@ -46,7 +46,7 @@ struct tegra_drm {
 	struct drm_device *drm;
 
 	struct iommu_domain *domain;
-	struct iommu_group *group;
+	struct iommu_group *dc_group;
 	struct mutex mm_lock;
 	struct drm_mm mm;
 
Signature · 1 line
2.17.0
#2 lore raw

Re: [PATCH v1 1/5] drm/tegra: dc: Balance IOMMU group refcounting

Quoted 53 lines · Dmitry Osipenko

Remove unneeded iommu_group_get() and add missing iommu_group_put(), correcting IOMMU group refcount. This is a minor correction / cleanup that doesn't really fix anything because Tegra's IOMMU driver are built-in and hence groups refcounting can't hold IOMMU driver from unloading.

---
 drivers/gpu/drm/tegra/dc.c  | 35 +++++++++++++++++------------------
 drivers/gpu/drm/tegra/dc.h  |  2 +-
 drivers/gpu/drm/tegra/drm.h |  2 +-
 3 files changed, 19 insertions(+), 20 deletions(-)
drivers/gpu/drm/tegra/dc.c +7 -7
index d7a0f62c6e2e..9fc34c6a7218 100644
@@ -1927,7 +1927,6 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 static int tegra_dc_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
@@ -1939,20 +1938,21 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!dc->syncpt)
 		dev_warn(dc->dev, "failed to allocate syncpoint\n");
 
-	if (group && tegra->domain) {
-		if (group != tegra->group) {
-			err = iommu_attach_group(tegra->domain, group);
+	if (tegra->domain) {
+		dc->group = iommu_group_get(client->dev);
+
+		if (dc->group && dc->group != tegra->dc_group) {
+			err = iommu_attach_group(tegra->domain, dc->group);
 			if (err < 0) {
 				dev_err(dc->dev,
 					"failed to attach to domain: %d\n",
 					err);
+				iommu_group_put(dc->group);
 				return err;
 			}
 
-			tegra->group = group;
+			tegra->dc_group = dc->group;
 		}
-
-		dc->domain = tegra->domain;
 	}
 
 	if (dc->soc->wgrps)

drivers/gpu/drm/tegra/dc.c static int tegra_dc_init(struct host1x_client *client) · line 2021

Quoted 9 lines
drivers/gpu/drm/tegra/dc.c +2 -4
@@ -2017,13 +2017,13 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!IS_ERR(primary))
 		drm_plane_cleanup(primary);
 
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {

You can drop the dc->group check from the second conditional.

Quoted 54 lines
drivers/gpu/drm/tegra/dc.c +8 -7
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	return err;
@@ -2032,7 +2032,6 @@ static int tegra_dc_init(struct host1x_client *client)
 static int tegra_dc_exit(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
 	int err;
@@ -2045,13 +2044,13 @@ static int tegra_dc_exit(struct host1x_client *client)
 		return err;
 	}
 
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	host1x_syncpt_free(dc->syncpt);
drivers/gpu/drm/tegra/dc.h +1 -1
index ca5cac6bf8ea..5ca4e07333bb 100644
@@ -94,7 +94,7 @@ struct tegra_dc {
 
 	const struct tegra_dc_soc_info *soc;
 
-	struct iommu_domain *domain;
+	struct iommu_group *group;
 };
 
 static inline struct tegra_dc *
drivers/gpu/drm/tegra/drm.h +0 -0
index 4f41aaec8530..7777640a6911 100644

drivers/gpu/drm/tegra/drm.h struct tegra_drm { · line 49

Quoted 5 lines
drivers/gpu/drm/tegra/drm.h +1 -1
@@ -46,7 +46,7 @@ struct tegra_drm {
 	struct drm_device *drm;
 
 	struct iommu_domain *domain;
-	struct iommu_group *group;
+	struct iommu_group *dc_group;

It's not obvious to me why this needs to be renamed.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#3 lore raw

Re: [PATCH v1 1/5] drm/tegra: dc: Balance IOMMU group refcounting

Quoted 57 lines · Thierry Reding
Quoted 56 lines · Dmitry Osipenko

Remove unneeded iommu_group_get() and add missing iommu_group_put(), correcting IOMMU group refcount. This is a minor correction / cleanup that doesn't really fix anything because Tegra's IOMMU driver are built-in and hence groups refcounting can't hold IOMMU driver from unloading.

---
 drivers/gpu/drm/tegra/dc.c  | 35 +++++++++++++++++------------------
 drivers/gpu/drm/tegra/dc.h  |  2 +-
 drivers/gpu/drm/tegra/drm.h |  2 +-
 3 files changed, 19 insertions(+), 20 deletions(-)
drivers/gpu/drm/tegra/dc.c +7 -7
index d7a0f62c6e2e..9fc34c6a7218 100644
@@ -1927,7 +1927,6 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 static int tegra_dc_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
@@ -1939,20 +1938,21 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!dc->syncpt)
 		dev_warn(dc->dev, "failed to allocate syncpoint\n");
 
-	if (group && tegra->domain) {
-		if (group != tegra->group) {
-			err = iommu_attach_group(tegra->domain, group);
+	if (tegra->domain) {
+		dc->group = iommu_group_get(client->dev);
+
+		if (dc->group && dc->group != tegra->dc_group) {
+			err = iommu_attach_group(tegra->domain, dc->group);
 			if (err < 0) {
 				dev_err(dc->dev,
 					"failed to attach to domain: %d\n",
 					err);
+				iommu_group_put(dc->group);
 				return err;
 			}
 
-			tegra->group = group;
+			tegra->dc_group = dc->group;
 		}
-
-		dc->domain = tegra->domain;
 	}
 
 	if (dc->soc->wgrps)
@@ -2017,13 +2017,13 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (!IS_ERR(primary))
 		drm_plane_cleanup(primary);
 
Quoted 8 lines

drivers/gpu/drm/tegra/dc.c static int tegra_dc_init(struct host1x_client *client) · line 2021

Quoted 6 lines
drivers/gpu/drm/tegra/dc.c +2 -4
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {

You can drop the dc->group check from the second conditional.

Indeed.

Quoted 56 lines
Quoted 56 lines
drivers/gpu/drm/tegra/dc.c +8 -7
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	return err;
@@ -2032,7 +2032,6 @@ static int tegra_dc_init(struct host1x_client *client)
 static int tegra_dc_exit(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
-	struct iommu_group *group = iommu_group_get(client->dev);
 	struct tegra_dc *dc = host1x_client_to_dc(client);
 	struct tegra_drm *tegra = drm->dev_private;
 	int err;
@@ -2045,13 +2044,13 @@ static int tegra_dc_exit(struct host1x_client *client)
 		return err;
 	}
 
-	if (group && dc->domain) {
-		if (group == tegra->group) {
-			iommu_detach_group(dc->domain, group);
-			tegra->group = NULL;
+	if (dc->group) {
+		if (dc->group && dc->group == tegra->dc_group) {
+			iommu_detach_group(tegra->domain, dc->group);
+			tegra->dc_group = NULL;
 		}
 
-		dc->domain = NULL;
+		iommu_group_put(dc->group);
 	}
 
 	host1x_syncpt_free(dc->syncpt);
drivers/gpu/drm/tegra/dc.h +1 -1
index ca5cac6bf8ea..5ca4e07333bb 100644
@@ -94,7 +94,7 @@ struct tegra_dc {
 
 	const struct tegra_dc_soc_info *soc;
 
-	struct iommu_domain *domain;
+	struct iommu_group *group;
 };
 
 static inline struct tegra_dc *
drivers/gpu/drm/tegra/drm.h +0 -0
index 4f41aaec8530..7777640a6911 100644
@@ -46,7 +46,7 @@ struct tegra_drm {
 	struct drm_device *drm;
 
Quoted 5 lines

drivers/gpu/drm/tegra/drm.h struct tegra_drm { · line 49

Quoted 3 lines
drivers/gpu/drm/tegra/drm.h +1 -1
 	struct iommu_domain *domain;
-	struct iommu_group *group;
+	struct iommu_group *dc_group;

It's not obvious to me why this needs to be renamed.

tegra->group is only used by the dc.c and seems its sole purpose is to avoid re-attaching DC group if DC0 and DC1 share the same group, like DC's on newer Tegra's do. I think it's better to rename 'group' to 'dc_group' for the clarity.

#4 lore raw

Re: [PATCH v1 1/5] drm/tegra: dc: Balance IOMMU group refcounting

In reply to Dmitry Osipenko
Quoted 11 lines · Dmitry Osipenko

Remove unneeded iommu_group_get() and add missing iommu_group_put(), correcting IOMMU group refcount. This is a minor correction / cleanup that doesn't really fix anything because Tegra's IOMMU driver are built-in and hence groups refcounting can't hold IOMMU driver from unloading.

---
 drivers/gpu/drm/tegra/dc.c  | 35 +++++++++++++++++------------------
 drivers/gpu/drm/tegra/dc.h  |  2 +-
 drivers/gpu/drm/tegra/drm.h |  2 +-
 3 files changed, 19 insertions(+), 20 deletions(-)

Applied, thanks.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#5 lore raw

PATCH 2/5 drm/tegra: gr2d: Add IOMMU support

In reply to Dmitry Osipenko

Attach GR2D to the display IOMMU group in order to provide GR2D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr2d.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/gpu/drm/tegra/gr2d.c +29 -2
index 9a8ea93016a9..8eb530a85dd0 100644
@@ -7,12 +7,14 @@
  */
 
 #include <linux/clk.h>
+#include <linux/iommu.h>
 
 #include "drm.h"
 #include "gem.h"
 #include "gr2d.h"
 
 struct gr2d {
+	struct iommu_group *group;
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
 	struct clk *clk;
@@ -30,7 +32,9 @@ static int gr2d_init(struct host1x_client *client)
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
 	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr2d *gr2d = to_gr2d(drm);
+	int err;
 
 	gr2d->channel = host1x_channel_request(client->dev);
 	if (!gr2d->channel)
@@ -42,23 +46,46 @@ static int gr2d_init(struct host1x_client *client)
 		return -ENOMEM;
 	}
 
-	return tegra_drm_register_client(dev->dev_private, drm);
+	if (tegra->domain) {
+		gr2d->group = iommu_group_get(client->dev);
+
+		if (gr2d->group) {
+			err = iommu_attach_group(tegra->domain, gr2d->group);
+			if (err < 0) {
+				dev_err(client->dev,
+					"failed to attach to domain: %d\n",
+					err);
+				host1x_syncpt_free(client->syncpts[0]);
+				host1x_channel_put(gr2d->channel);
+				iommu_group_put(gr2d->group);
+				return err;
+			}
+		}
+	}
+
+	return tegra_drm_register_client(tegra, drm);
 }
 
 static int gr2d_exit(struct host1x_client *client)
 {
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr2d *gr2d = to_gr2d(drm);
 	int err;
 
-	err = tegra_drm_unregister_client(dev->dev_private, drm);
+	err = tegra_drm_unregister_client(tegra, drm);
 	if (err < 0)
 		return err;
 
 	host1x_syncpt_free(client->syncpts[0]);
 	host1x_channel_put(gr2d->channel);
 
+	if (gr2d->group) {
+		iommu_detach_group(tegra->domain, gr2d->group);
+		iommu_group_put(gr2d->group);
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.17.0
#6 lore raw

Re: [PATCH v1 2/5] drm/tegra: gr2d: Add IOMMU support

Quoted 48 lines · Dmitry Osipenko

Attach GR2D to the display IOMMU group in order to provide GR2D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr2d.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/gpu/drm/tegra/gr2d.c +10 -1
index 9a8ea93016a9..8eb530a85dd0 100644
@@ -7,12 +7,14 @@
  */
 
 #include <linux/clk.h>
+#include <linux/iommu.h>
 
 #include "drm.h"
 #include "gem.h"
 #include "gr2d.h"
 
 struct gr2d {
+	struct iommu_group *group;
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
 	struct clk *clk;
@@ -30,7 +32,9 @@ static int gr2d_init(struct host1x_client *client)
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
 	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr2d *gr2d = to_gr2d(drm);
+	int err;
 
 	gr2d->channel = host1x_channel_request(client->dev);
 	if (!gr2d->channel)
@@ -42,23 +46,46 @@ static int gr2d_init(struct host1x_client *client)
 		return -ENOMEM;
 	}
 
-	return tegra_drm_register_client(dev->dev_private, drm);
+	if (tegra->domain) {
+		gr2d->group = iommu_group_get(client->dev);
+
+		if (gr2d->group) {
+			err = iommu_attach_group(tegra->domain, gr2d->group);
+			if (err < 0) {

drivers/gpu/drm/tegra/gr2d.c static int gr2d_init(struct host1x_client *client) · line 64

Quoted 10 lines
drivers/gpu/drm/tegra/gr2d.c +10 -0
+				dev_err(client->dev,
+					"failed to attach to domain: %d\n",
+					err);
+				host1x_syncpt_free(client->syncpts[0]);
+				host1x_channel_put(gr2d->channel);
+				iommu_group_put(gr2d->group);
+				return err;
+			}
+		}
+	}

This is almost identical to the code in DC, perhaps we should factor this out into a separate helper? Nothing that needs to be done right now, I'll take a look at it and see if I can come up with something good in a follow-up patch.

Quoted 18 lines
drivers/gpu/drm/tegra/gr2d.c +4 -1
+
+	return tegra_drm_register_client(tegra, drm);
 }
 
 static int gr2d_exit(struct host1x_client *client)
 {
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr2d *gr2d = to_gr2d(drm);
 	int err;
 
-	err = tegra_drm_unregister_client(dev->dev_private, drm);
+	err = tegra_drm_unregister_client(tegra, drm);
 	if (err < 0)
 		return err;
 
 	host1x_syncpt_free(client->syncpts[0]);

drivers/gpu/drm/tegra/gr2d.c static int gr2d_init(struct host1x_client *client) · line 91

Quoted 10 lines
drivers/gpu/drm/tegra/gr2d.c +5 -0
 	host1x_channel_put(gr2d->channel);
 
+	if (gr2d->group) {
+		iommu_detach_group(tegra->domain, gr2d->group);
+		iommu_group_put(gr2d->group);
+	}
+
 	return 0;
 }
 

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#7 lore raw

Re: [PATCH v1 2/5] drm/tegra: gr2d: Add IOMMU support

Quoted 56 lines · Thierry Reding
Quoted 55 lines · Dmitry Osipenko

Attach GR2D to the display IOMMU group in order to provide GR2D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr2d.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/gpu/drm/tegra/gr2d.c +17 -1
index 9a8ea93016a9..8eb530a85dd0 100644
@@ -7,12 +7,14 @@
  */
 
 #include <linux/clk.h>
+#include <linux/iommu.h>
 
 #include "drm.h"
 #include "gem.h"
 #include "gr2d.h"
 
 struct gr2d {
+	struct iommu_group *group;
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
 	struct clk *clk;
@@ -30,7 +32,9 @@ static int gr2d_init(struct host1x_client *client)
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
 	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr2d *gr2d = to_gr2d(drm);
+	int err;
 
 	gr2d->channel = host1x_channel_request(client->dev);
 	if (!gr2d->channel)
@@ -42,23 +46,46 @@ static int gr2d_init(struct host1x_client *client)
 		return -ENOMEM;
 	}
 
-	return tegra_drm_register_client(dev->dev_private, drm);
+	if (tegra->domain) {
+		gr2d->group = iommu_group_get(client->dev);
+
+		if (gr2d->group) {
+			err = iommu_attach_group(tegra->domain, gr2d->group);
+			if (err < 0) {
+				dev_err(client->dev,
+					"failed to attach to domain: %d\n",
+					err);
+				host1x_syncpt_free(client->syncpts[0]);
+				host1x_channel_put(gr2d->channel);
+				iommu_group_put(gr2d->group);
+				return err;
Quoted 8 lines

drivers/gpu/drm/tegra/gr2d.c static int gr2d_init(struct host1x_client *client) · line 64

Quoted 3 lines
drivers/gpu/drm/tegra/gr2d.c +3 -0
+			}
+		}
+	}

This is almost identical to the code in DC, perhaps we should factor this out into a separate helper? Nothing that needs to be done right now, I'll take a look at it and see if I can come up with something good in a follow-up patch.

Sounds good.

#8 lore raw

Re: [PATCH v1 2/5] drm/tegra: gr2d: Add IOMMU support

In reply to Dmitry Osipenko
Quoted 7 lines · Dmitry Osipenko

Attach GR2D to the display IOMMU group in order to provide GR2D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr2d.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

Applied, thanks.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#9 lore raw

PATCH 3/5 drm/tegra: gr3d: Add IOMMU support

In reply to Dmitry Osipenko

Attach GR3D to the displays IOMMU group in order to provide GR3D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr3d.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
drivers/gpu/drm/tegra/gr3d.c +27 -0
index 28c4ef63065b..ce5120683091 100644
@@ -9,6 +9,7 @@
 
 #include <linux/clk.h>
 #include <linux/host1x.h>
+#include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
@@ -20,6 +21,7 @@
 #include "gr3d.h"
 
 struct gr3d {
+	struct iommu_group *group;
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
 	struct clk *clk_secondary;
@@ -40,7 +42,9 @@ static int gr3d_init(struct host1x_client *client)
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
 	unsigned long flags = HOST1X_SYNCPT_HAS_BASE;
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr3d *gr3d = to_gr3d(drm);
+	int err;
 
 	gr3d->channel = host1x_channel_request(client->dev);
 	if (!gr3d->channel)
@@ -52,6 +56,23 @@ static int gr3d_init(struct host1x_client *client)
 		return -ENOMEM;
 	}
 
+	if (tegra->domain) {
+		gr3d->group = iommu_group_get(client->dev);
+
+		if (gr3d->group) {
+			err = iommu_attach_group(tegra->domain, gr3d->group);
+			if (err < 0) {
+				dev_err(client->dev,
+					"failed to attach to domain: %d\n",
+					err);
+				host1x_syncpt_free(client->syncpts[0]);
+				host1x_channel_put(gr3d->channel);
+				iommu_group_put(gr3d->group);
+				return err;
+			}
+		}
+	}
+
 	return tegra_drm_register_client(dev->dev_private, drm);
 }
 
@@ -59,6 +80,7 @@ static int gr3d_exit(struct host1x_client *client)
 {
 	struct tegra_drm_client *drm = host1x_to_drm_client(client);
 	struct drm_device *dev = dev_get_drvdata(client->parent);
+	struct tegra_drm *tegra = dev->dev_private;
 	struct gr3d *gr3d = to_gr3d(drm);
 	int err;
 
@@ -69,6 +91,11 @@ static int gr3d_exit(struct host1x_client *client)
 	host1x_syncpt_free(client->syncpts[0]);
 	host1x_channel_put(gr3d->channel);
 
+	if (gr3d->group) {
+		iommu_detach_group(tegra->domain, gr3d->group);
+		iommu_group_put(gr3d->group);
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.17.0
#10 lore raw

Re: [PATCH v1 3/5] drm/tegra: gr3d: Add IOMMU support

Quoted 7 lines · Dmitry Osipenko

Attach GR3D to the displays IOMMU group in order to provide GR3D access to BO's IOVA.

---
 drivers/gpu/drm/tegra/gr3d.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

Applied, thanks.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#11 lore raw

PATCH 4/5 ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients

In reply to Dmitry Osipenko

Enable IOMMU support for Host1x and its clients.

---
 arch/arm/boot/dts/tegra30.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
arch/arm/boot/dts/tegra30.dtsi +14 -0
index a110cf84d85f..09087b9c5e26 100644
@@ -112,6 +112,7 @@
 		clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
 		resets = <&tegra_car 28>;
 		reset-names = "host1x";
+		iommus = <&mc TEGRA_SWGROUP_HC>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -125,6 +126,8 @@
 			clocks = <&tegra_car TEGRA30_CLK_MPE>;
 			resets = <&tegra_car 60>;
 			reset-names = "mpe";
+
+			iommus = <&mc TEGRA_SWGROUP_MPE>;
 		};
 
 		vi@54080000 {
@@ -134,6 +137,8 @@
 			clocks = <&tegra_car TEGRA30_CLK_VI>;
 			resets = <&tegra_car 20>;
 			reset-names = "vi";
+
+			iommus = <&mc TEGRA_SWGROUP_VI>;
 		};
 
 		epp@540c0000 {
@@ -143,6 +148,8 @@
 			clocks = <&tegra_car TEGRA30_CLK_EPP>;
 			resets = <&tegra_car 19>;
 			reset-names = "epp";
+
+			iommus = <&mc TEGRA_SWGROUP_EPP>;
 		};
 
 		isp@54100000 {
@@ -152,6 +159,8 @@
 			clocks = <&tegra_car TEGRA30_CLK_ISP>;
 			resets = <&tegra_car 23>;
 			reset-names = "isp";
+
+			iommus = <&mc TEGRA_SWGROUP_ISP>;
 		};
 
 		gr2d@54140000 {
@@ -161,6 +170,8 @@
 			clocks = <&tegra_car TEGRA30_CLK_GR2D>;
 			resets = <&tegra_car 21>;
 			reset-names = "2d";
+
+			iommus = <&mc TEGRA_SWGROUP_G2>;
 		};
 
 		gr3d@54180000 {
@@ -172,6 +183,9 @@
 			resets = <&tegra_car 24>,
 				 <&tegra_car 98>;
 			reset-names = "3d", "3d2";
+
+			iommus = <&mc TEGRA_SWGROUP_NV>,
+				 <&mc TEGRA_SWGROUP_NV2>;
 		};
 
 		dc@54200000 {
Signature · 1 line
2.17.0
#12 lore raw

Re: [PATCH v1 4/5] ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients

Quoted 6 lines · Dmitry Osipenko

Enable IOMMU support for Host1x and its clients.

---
 arch/arm/boot/dts/tegra30.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Applied, thanks.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#13 lore raw

PATCH 5/5 ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients

In reply to Dmitry Osipenko

Enable IOMMU support for Host1x and its clients.

---
 arch/arm/boot/dts/tegra114.dtsi | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/boot/dts/tegra114.dtsi +5 -0
index 0e4a13295d8a..84c4358dacac 100644
@@ -19,6 +19,7 @@
 		clocks = <&tegra_car TEGRA114_CLK_HOST1X>;
 		resets = <&tegra_car 28>;
 		reset-names = "host1x";
+		iommus = <&mc TEGRA_SWGROUP_HC>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -32,6 +33,8 @@
 			clocks = <&tegra_car TEGRA114_CLK_GR2D>;
 			resets = <&tegra_car 21>;
 			reset-names = "2d";
+
+			iommus = <&mc TEGRA_SWGROUP_G2>;
 		};
 
 		gr3d@54180000 {
@@ -40,6 +43,8 @@
 			clocks = <&tegra_car TEGRA114_CLK_GR3D>;
 			resets = <&tegra_car 24>;
 			reset-names = "3d";
+
+			iommus = <&mc TEGRA_SWGROUP_NV>;
 		};
 
 		dc@54200000 {
Signature · 1 line
2.17.0
#14 lore raw

Re: [PATCH v1 5/5] ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients

Quoted 6 lines · Dmitry Osipenko

Enable IOMMU support for Host1x and its clients.

---
 arch/arm/boot/dts/tegra114.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

Applied, thanks.

Thierry

#15 lore raw
In reply to Dmitry Osipenko
Quoted 12 lines · Dmitry Osipenko

Hi,

This series enables IOMMU support for 2d/3d HW on Tegra30/114, as a result userspace that uses 2d/3d could work with the active IOMMU.

Dmitry Osipenko (5):
drm/tegra: dc: Balance IOMMU group refcounting drm/tegra: gr2d: Add IOMMU support
drm/tegra: gr3d: Add IOMMU support
ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients
ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients

Quoted 8 lines
 arch/arm/boot/dts/tegra114.dtsi |  5 +++++
 arch/arm/boot/dts/tegra30.dtsi  | 14 +++++++++++++
 drivers/gpu/drm/tegra/dc.c      | 35 ++++++++++++++++-----------------
 drivers/gpu/drm/tegra/dc.h      |  2 +-
 drivers/gpu/drm/tegra/drm.h     |  2 +-
 drivers/gpu/drm/tegra/gr2d.c    | 31 +++++++++++++++++++++++++++--
 drivers/gpu/drm/tegra/gr3d.c    | 27 +++++++++++++++++++++++++
 7 files changed, 94 insertions(+), 22 deletions(-)

Overall I think this is great. No need to resend for the two comments on patch 1, I can fix those up when I apply if you have no objections.

Thierry

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

#16 lore raw
Quoted 22 lines · Thierry Reding
Quoted 12 lines · Dmitry Osipenko

Hi,

This series enables IOMMU support for 2d/3d HW on Tegra30/114, as a result userspace that uses 2d/3d could work with the active IOMMU.

Dmitry Osipenko (5):
drm/tegra: dc: Balance IOMMU group refcounting drm/tegra: gr2d: Add IOMMU support
drm/tegra: gr3d: Add IOMMU support
ARM: dts: tegra30: Add IOMMU nodes to Host1x and its clients
ARM: dts: tegra114: Add IOMMU nodes to Host1x and its clients

Quoted 8 lines
 arch/arm/boot/dts/tegra114.dtsi |  5 +++++
 arch/arm/boot/dts/tegra30.dtsi  | 14 +++++++++++++
 drivers/gpu/drm/tegra/dc.c      | 35 ++++++++++++++++-----------------
 drivers/gpu/drm/tegra/dc.h      |  2 +-
 drivers/gpu/drm/tegra/drm.h     |  2 +-
 drivers/gpu/drm/tegra/gr2d.c    | 31 +++++++++++++++++++++++++++--
 drivers/gpu/drm/tegra/gr3d.c    | 27 +++++++++++++++++++++++++
 7 files changed, 94 insertions(+), 22 deletions(-)
Quoted 2 lines

Overall I think this is great. No need to resend for the two comments on patch 1, I can fix those up when I apply if you have no objections.

No objections from me, thanks.