drm/tegra: Add IOMMU support
When an IOMMU device is available on the platform bus, allocate an IOMMU domain and attach the display controllers to it. The display controllers can then scan out non-contiguous buffers by mapping them through the IOMMU. Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/host1x.h>
|
||||
#include <linux/iommu.h>
|
||||
|
||||
#include "drm.h"
|
||||
#include "gem.h"
|
||||
@@ -33,6 +34,17 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
|
||||
if (!tegra)
|
||||
return -ENOMEM;
|
||||
|
||||
if (iommu_present(&platform_bus_type)) {
|
||||
tegra->domain = iommu_domain_alloc(&platform_bus_type);
|
||||
if (IS_ERR(tegra->domain)) {
|
||||
err = PTR_ERR(tegra->domain);
|
||||
goto free;
|
||||
}
|
||||
|
||||
DRM_DEBUG("IOMMU context initialized\n");
|
||||
drm_mm_init(&tegra->mm, 0, SZ_2G);
|
||||
}
|
||||
|
||||
mutex_init(&tegra->clients_lock);
|
||||
INIT_LIST_HEAD(&tegra->clients);
|
||||
drm->dev_private = tegra;
|
||||
@@ -76,6 +88,12 @@ fbdev:
|
||||
tegra_drm_fb_free(drm);
|
||||
config:
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
||||
if (tegra->domain) {
|
||||
iommu_domain_free(tegra->domain);
|
||||
drm_mm_takedown(&tegra->mm);
|
||||
}
|
||||
free:
|
||||
kfree(tegra);
|
||||
return err;
|
||||
}
|
||||
@@ -83,6 +101,7 @@ config:
|
||||
static int tegra_drm_unload(struct drm_device *drm)
|
||||
{
|
||||
struct host1x_device *device = to_host1x_device(drm->dev);
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
int err;
|
||||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
@@ -94,6 +113,11 @@ static int tegra_drm_unload(struct drm_device *drm)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tegra->domain) {
|
||||
iommu_domain_free(tegra->domain);
|
||||
drm_mm_takedown(&tegra->mm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user