Message ID | 20190123093951.24908-4-thierry.reding@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/tegra: Fix IOVA space on Tegra186 and later | expand |
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.
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 --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)