aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra/dc.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-10-12 17:43:33 +0200
committerThierry Reding <treding@nvidia.com>2017-12-21 14:52:36 +0100
commitbc8828bd08bd2a645caeb64d299d67faca7a3b4f (patch)
treeab80c8b65bbe315992209e8bcb53fdff2019ead6 /drivers/gpu/drm/tegra/dc.c
parentgpu: host1x: Use IOMMU groups (diff)
downloadlinux-dev-bc8828bd08bd2a645caeb64d299d67faca7a3b4f.tar.xz
linux-dev-bc8828bd08bd2a645caeb64d299d67faca7a3b4f.zip
drm/tegra: Use IOMMU groups
In order to support IOMMUs more generically and transparently handle the ARM SMMU on Tegra186, move to using groups instead of devices for domain attachment. An IOMMU group is a set of devices that share the same IOMMU domain and is therefore a good match to represent what Tegra DRM needs. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dc.c')
-rw-r--r--drivers/gpu/drm/tegra/dc.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index d118094a96c1..dc91911094fc 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1748,6 +1748,7 @@ 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;
@@ -1759,12 +1760,17 @@ static int tegra_dc_init(struct host1x_client *client)
if (!dc->syncpt)
dev_warn(dc->dev, "failed to allocate syncpoint\n");
- if (tegra->domain) {
- err = iommu_attach_device(tegra->domain, dc->dev);
- if (err < 0) {
- dev_err(dc->dev, "failed to attach to domain: %d\n",
- err);
- return err;
+ if (group && tegra->domain) {
+ if (group != tegra->group) {
+ err = iommu_attach_group(tegra->domain, group);
+ if (err < 0) {
+ dev_err(dc->dev,
+ "failed to attach to domain: %d\n",
+ err);
+ return err;
+ }
+
+ tegra->group = group;
}
dc->domain = tegra->domain;
@@ -1825,8 +1831,8 @@ cleanup:
if (!IS_ERR(primary))
drm_plane_cleanup(primary);
- if (tegra->domain) {
- iommu_detach_device(tegra->domain, dc->dev);
+ if (group && tegra->domain) {
+ iommu_detach_group(tegra->domain, group);
dc->domain = NULL;
}
@@ -1835,6 +1841,7 @@ cleanup:
static int tegra_dc_exit(struct host1x_client *client)
{
+ struct iommu_group *group = iommu_group_get(client->dev);
struct tegra_dc *dc = host1x_client_to_dc(client);
int err;
@@ -1846,8 +1853,8 @@ static int tegra_dc_exit(struct host1x_client *client)
return err;
}
- if (dc->domain) {
- iommu_detach_device(dc->domain, dc->dev);
+ if (group && dc->domain) {
+ iommu_detach_group(dc->domain, group);
dc->domain = NULL;
}