Refactor the confusing logic to make it both clearer and more robust. If the host1x parent device does have an IOMMU domain then iommu_present() is redundantly true, while otherwise for the 32-bit DMA mask case it still doesn't say whether the IOMMU driver actually knows about the DRM device or not. Signed-off-by: Robin Murphy <robin.murphy@xxxxxxx> --- v2: Fix logic for older SoCs and clarify. drivers/gpu/drm/tegra/drm.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 9464f522e257..4f2bdab31064 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1092,6 +1092,19 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev) struct host1x *host1x = dev_get_drvdata(dev->dev.parent); struct iommu_domain *domain; + /* For starters, this is moot if no IOMMU is available */ + if (!device_iommu_mapped(&dev->dev)) + return false; + + /* + * 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 (host1x_get_dma_mask(host1x) <= DMA_BIT_MASK(32)) + return true; + /* * If the Tegra DRM clients are backed by an IOMMU, push buffers are * likely to be allocated beyond the 32-bit boundary if sufficient @@ -1122,14 +1135,13 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev) 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. + * At the moment, the exact type of domain doesn't actually matter. + * Only for 64-bit kernels might this be a managed DMA API domain, and + * then only on newer SoCs using arm-smmu, since tegra-smmu doesn't + * support default domains at all, and since those SoCs are the same + * ones with extended GATHER support, even if it's a passthrough domain + * it can still work out OK. */ - if (!domain && host1x_get_dma_mask(host1x) <= DMA_BIT_MASK(32)) - return true; - return domain != NULL; } @@ -1149,7 +1161,7 @@ static int host1x_drm_probe(struct host1x_device *dev) goto put; } - if (host1x_drm_wants_iommu(dev) && iommu_present(&platform_bus_type)) { + if (host1x_drm_wants_iommu(dev)) { tegra->domain = iommu_domain_alloc(&platform_bus_type); if (!tegra->domain) { err = -ENOMEM; -- 2.28.0.dirty