diff mbox series

[3/5] drm/tegra: Setup shared IOMMU domain after initialization

Message ID 20190123093951.24908-4-thierry.reding@gmail.com
State Superseded
Headers show
Series drm/tegra: Fix IOVA space on Tegra186 and later | expand

Commit Message

Thierry Reding Jan. 23, 2019, 9:39 a.m. UTC
From: Thierry Reding <treding@nvidia.com>

Move initialization of the shared IOMMU domain after the host1x device
has been initialized. At this point all the Tegra DRM clients have been
attached to the shared IOMMU domain.

This is important because Tegra186 and later use an ARM SMMU, for which
the driver defers setting up the geometry for a domain until a device is
attached to it. This is to ensure that the domain is properly set up for
a specific ARM SMMU instance, which is unknown at allocation time.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/tegra/drm.c | 54 ++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 25 deletions(-)

Comments

Dmitry Osipenko Jan. 23, 2019, 2:55 p.m. UTC | #1
23.01.2019 12:39, Thierry Reding пишет:
> From: Thierry Reding <treding@nvidia.com>
> 
> Move initialization of the shared IOMMU domain after the host1x device
> has been initialized. At this point all the Tegra DRM clients have been
> attached to the shared IOMMU domain.
> 
> This is important because Tegra186 and later use an ARM SMMU, for which
> the driver defers setting up the geometry for a domain until a device is
> attached to it. This is to ensure that the domain is properly set up for
> a specific ARM SMMU instance, which is unknown at allocation time.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/tegra/drm.c | 54 ++++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 61dcbd218ffc..271c7a5fc954 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -92,10 +92,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  		return -ENOMEM;
>  
>  	if (iommu_present(&platform_bus_type)) {
> -		u64 carveout_start, carveout_end, gem_start, gem_end;
> -		struct iommu_domain_geometry *geometry;
> -		unsigned long order;
> -
>  		tegra->domain = iommu_domain_alloc(&platform_bus_type);
>  		if (!tegra->domain) {
>  			err = -ENOMEM;
> @@ -105,27 +101,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  		err = iova_cache_get();
>  		if (err < 0)
>  			goto domain;
> -
> -		geometry = &tegra->domain->geometry;
> -		gem_start = geometry->aperture_start;
> -		gem_end = geometry->aperture_end - CARVEOUT_SZ;
> -		carveout_start = gem_end + 1;
> -		carveout_end = geometry->aperture_end;
> -
> -		order = __ffs(tegra->domain->pgsize_bitmap);
> -		init_iova_domain(&tegra->carveout.domain, 1UL << order,
> -				 carveout_start >> order);
> -
> -		tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
> -		tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
> -
> -		drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
> -		mutex_init(&tegra->mm_lock);
> -
> -		DRM_DEBUG("IOMMU apertures:\n");
> -		DRM_DEBUG("  GEM: %#llx-%#llx\n", gem_start, gem_end);
> -		DRM_DEBUG("  Carveout: %#llx-%#llx\n", carveout_start,
> -			  carveout_end);
>  	}
>  
>  	mutex_init(&tegra->clients_lock);
> @@ -159,6 +134,35 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  	if (err < 0)
>  		goto fbdev;
>  
> +	if (tegra->domain) {
> +		u64 carveout_start, carveout_end, gem_start, gem_end;
> +		dma_addr_t start, end;
> +		unsigned long order;
> +
> +		start = tegra->domain->geometry.aperture_start;
> +		end = tegra->domain->geometry.aperture_end;
> +
> +		gem_start = start;
> +		gem_end = end - CARVEOUT_SZ;
> +		carveout_start = gem_end + 1;
> +		carveout_end = end;
> +
> +		order = __ffs(tegra->domain->pgsize_bitmap);
> +		init_iova_domain(&tegra->carveout.domain, 1UL << order,
> +				 carveout_start >> order);
> +
> +		tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
> +		tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
> +
> +		drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
> +		mutex_init(&tegra->mm_lock);
> +
> +		DRM_DEBUG("IOMMU apertures:\n");
> +		DRM_DEBUG("  GEM: %#llx-%#llx\n", gem_start, gem_end);
> +		DRM_DEBUG("  Carveout: %#llx-%#llx\n", carveout_start,
> +			  carveout_end);
> +	}
> +
>  	if (tegra->hub) {
>  		err = tegra_display_hub_prepare(tegra->hub);
>  		if (err < 0)
> 

Looks good,

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>


BTW, the "carveout" domain is only relevant for T124+, will be better to avoid its allocation on older Tegra's and then to factor out IOVA setup-code into a standalone function. Of course that could be done later on in a different series if desired.. just a minor comment.
Dmitry Osipenko Jan. 23, 2019, 4:28 p.m. UTC | #2
23.01.2019 12:39, Thierry Reding пишет:
> From: Thierry Reding <treding@nvidia.com>
> 
> Move initialization of the shared IOMMU domain after the host1x device
> has been initialized. At this point all the Tegra DRM clients have been
> attached to the shared IOMMU domain.
> 
> This is important because Tegra186 and later use an ARM SMMU, for which
> the driver defers setting up the geometry for a domain until a device is
> attached to it. This is to ensure that the domain is properly set up for
> a specific ARM SMMU instance, which is unknown at allocation time.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/gpu/drm/tegra/drm.c | 54 ++++++++++++++++++++-----------------
>  1 file changed, 29 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
> index 61dcbd218ffc..271c7a5fc954 100644
> --- a/drivers/gpu/drm/tegra/drm.c
> +++ b/drivers/gpu/drm/tegra/drm.c
> @@ -92,10 +92,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  		return -ENOMEM;
>  
>  	if (iommu_present(&platform_bus_type)) {
> -		u64 carveout_start, carveout_end, gem_start, gem_end;
> -		struct iommu_domain_geometry *geometry;
> -		unsigned long order;
> -
>  		tegra->domain = iommu_domain_alloc(&platform_bus_type);
>  		if (!tegra->domain) {
>  			err = -ENOMEM;
> @@ -105,27 +101,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  		err = iova_cache_get();
>  		if (err < 0)
>  			goto domain;
> -
> -		geometry = &tegra->domain->geometry;
> -		gem_start = geometry->aperture_start;
> -		gem_end = geometry->aperture_end - CARVEOUT_SZ;
> -		carveout_start = gem_end + 1;
> -		carveout_end = geometry->aperture_end;
> -
> -		order = __ffs(tegra->domain->pgsize_bitmap);
> -		init_iova_domain(&tegra->carveout.domain, 1UL << order,
> -				 carveout_start >> order);
> -
> -		tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
> -		tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
> -
> -		drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
> -		mutex_init(&tegra->mm_lock);
> -
> -		DRM_DEBUG("IOMMU apertures:\n");
> -		DRM_DEBUG("  GEM: %#llx-%#llx\n", gem_start, gem_end);
> -		DRM_DEBUG("  Carveout: %#llx-%#llx\n", carveout_start,
> -			  carveout_end);
>  	}
>  
>  	mutex_init(&tegra->clients_lock);
> @@ -159,6 +134,35 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
>  	if (err < 0)
>  		goto fbdev;
>  
> +	if (tegra->domain) {
> +		u64 carveout_start, carveout_end, gem_start, gem_end;
> +		dma_addr_t start, end;
> +		unsigned long order;
> +
> +		start = tegra->domain->geometry.aperture_start;
> +		end = tegra->domain->geometry.aperture_end;
> +
> +		gem_start = start;
> +		gem_end = end - CARVEOUT_SZ;
> +		carveout_start = gem_end + 1;
> +		carveout_end = end;

Given that seems falcon can't address >32bit at least right now, will make sense to reserve carveout from the bottom.

[snip]
diff mbox series

Patch

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 61dcbd218ffc..271c7a5fc954 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -92,10 +92,6 @@  static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 		return -ENOMEM;
 
 	if (iommu_present(&platform_bus_type)) {
-		u64 carveout_start, carveout_end, gem_start, gem_end;
-		struct iommu_domain_geometry *geometry;
-		unsigned long order;
-
 		tegra->domain = iommu_domain_alloc(&platform_bus_type);
 		if (!tegra->domain) {
 			err = -ENOMEM;
@@ -105,27 +101,6 @@  static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 		err = iova_cache_get();
 		if (err < 0)
 			goto domain;
-
-		geometry = &tegra->domain->geometry;
-		gem_start = geometry->aperture_start;
-		gem_end = geometry->aperture_end - CARVEOUT_SZ;
-		carveout_start = gem_end + 1;
-		carveout_end = geometry->aperture_end;
-
-		order = __ffs(tegra->domain->pgsize_bitmap);
-		init_iova_domain(&tegra->carveout.domain, 1UL << order,
-				 carveout_start >> order);
-
-		tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
-		tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
-
-		drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
-		mutex_init(&tegra->mm_lock);
-
-		DRM_DEBUG("IOMMU apertures:\n");
-		DRM_DEBUG("  GEM: %#llx-%#llx\n", gem_start, gem_end);
-		DRM_DEBUG("  Carveout: %#llx-%#llx\n", carveout_start,
-			  carveout_end);
 	}
 
 	mutex_init(&tegra->clients_lock);
@@ -159,6 +134,35 @@  static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 	if (err < 0)
 		goto fbdev;
 
+	if (tegra->domain) {
+		u64 carveout_start, carveout_end, gem_start, gem_end;
+		dma_addr_t start, end;
+		unsigned long order;
+
+		start = tegra->domain->geometry.aperture_start;
+		end = tegra->domain->geometry.aperture_end;
+
+		gem_start = start;
+		gem_end = end - CARVEOUT_SZ;
+		carveout_start = gem_end + 1;
+		carveout_end = end;
+
+		order = __ffs(tegra->domain->pgsize_bitmap);
+		init_iova_domain(&tegra->carveout.domain, 1UL << order,
+				 carveout_start >> order);
+
+		tegra->carveout.shift = iova_shift(&tegra->carveout.domain);
+		tegra->carveout.limit = carveout_end >> tegra->carveout.shift;
+
+		drm_mm_init(&tegra->mm, gem_start, gem_end - gem_start + 1);
+		mutex_init(&tegra->mm_lock);
+
+		DRM_DEBUG("IOMMU apertures:\n");
+		DRM_DEBUG("  GEM: %#llx-%#llx\n", gem_start, gem_end);
+		DRM_DEBUG("  Carveout: %#llx-%#llx\n", carveout_start,
+			  carveout_end);
+	}
+
 	if (tegra->hub) {
 		err = tegra_display_hub_prepare(tegra->hub);
 		if (err < 0)