Commit b9f8b09c authored by Thierry Reding's avatar Thierry Reding

drm/tegra: Setup shared IOMMU domain after initialization

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.
Reviewed-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 77a0b09d
...@@ -92,10 +92,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) ...@@ -92,10 +92,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
return -ENOMEM; return -ENOMEM;
if (iommu_present(&platform_bus_type)) { 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); tegra->domain = iommu_domain_alloc(&platform_bus_type);
if (!tegra->domain) { if (!tegra->domain) {
err = -ENOMEM; err = -ENOMEM;
...@@ -105,27 +101,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) ...@@ -105,27 +101,6 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
err = iova_cache_get(); err = iova_cache_get();
if (err < 0) if (err < 0)
goto domain; 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); mutex_init(&tegra->clients_lock);
...@@ -159,6 +134,35 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) ...@@ -159,6 +134,35 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
if (err < 0) if (err < 0)
goto fbdev; 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) { if (tegra->hub) {
err = tegra_display_hub_prepare(tegra->hub); err = tegra_display_hub_prepare(tegra->hub);
if (err < 0) if (err < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment