Commit 2d9384ff authored by Thierry Reding's avatar Thierry Reding

drm/tegra: Relax IOMMU usage criteria on old Tegra

Older Tegra devices only allow addressing 32 bits of memory, so whether
or not the host1x is attached to an IOMMU doesn't matter. host1x IOMMU
attachment is only needed on devices that can address memory beyond the
32-bit boundary and where the host1x doesn't support the wide GATHER
opcode that allows it to access buffers at higher addresses.

Cc: <stable@vger.kernel.org> # v5.5
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
Tested-by: default avatarDmitry Osipenko <digetx@gmail.com>
Reviewed-by: default avatarDmitry Osipenko <digetx@gmail.com>
parent c472a0b0
......@@ -1037,23 +1037,9 @@ void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt,
free_pages((unsigned long)virt, get_order(size));
}
static int host1x_drm_probe(struct host1x_device *dev)
static bool host1x_drm_wants_iommu(struct host1x_device *dev)
{
struct drm_driver *driver = &tegra_drm_driver;
struct iommu_domain *domain;
struct tegra_drm *tegra;
struct drm_device *drm;
int err;
drm = drm_dev_alloc(driver, &dev->dev);
if (IS_ERR(drm))
return PTR_ERR(drm);
tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
if (!tegra) {
err = -ENOMEM;
goto put;
}
/*
* If the Tegra DRM clients are backed by an IOMMU, push buffers are
......@@ -1082,9 +1068,38 @@ static int host1x_drm_probe(struct host1x_device *dev)
* up the device tree appropriately. This is considered an problem
* of integration, so care must be taken for the DT to be consistent.
*/
domain = iommu_get_domain_for_dev(drm->dev->parent);
domain = iommu_get_domain_for_dev(dev->dev.parent);
/*
* Tegra20 and Tegra30 don't support addressing memory beyond the
* 32-bit boundary, so the regular GATHER opcodes will always be
* sufficient and whether or not the host1x is attached to an IOMMU
* doesn't matter.
*/
if (!domain && dma_get_mask(dev->dev.parent) <= DMA_BIT_MASK(32))
return true;
return domain != NULL;
}
static int host1x_drm_probe(struct host1x_device *dev)
{
struct drm_driver *driver = &tegra_drm_driver;
struct tegra_drm *tegra;
struct drm_device *drm;
int err;
drm = drm_dev_alloc(driver, &dev->dev);
if (IS_ERR(drm))
return PTR_ERR(drm);
tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
if (!tegra) {
err = -ENOMEM;
goto put;
}
if (domain && iommu_present(&platform_bus_type)) {
if (host1x_drm_wants_iommu(dev) && iommu_present(&platform_bus_type)) {
tegra->domain = iommu_domain_alloc(&platform_bus_type);
if (!tegra->domain) {
err = -ENOMEM;
......
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