Tegra DRM and Host1x don't work properly when CONFIG_ARM_DMA_USE_IOMMU=y, i.e. in case of multiplatform ARM32 kernel. The simple workaround is to detach devices from the offending IOMMU domain. This is a resend of 9 months old patches which we lost and forgotten. The problem still persists. I rebased patches on top of recent linux-next and improved commit messages.
Dmitry Osipenko (2): gpu: host1x: Add back arm_iommu_detach_device() drm/tegra: Add back arm_iommu_detach_device()
drivers/gpu/drm/tegra/drm.c | 15 +++++++++++++++ drivers/gpu/host1x/dev.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+)
Host1x DMA buffer isn't mapped properly when CONFIG_ARM_DMA_USE_IOMMU=y. The memory management code of Host1x driver has a longstanding overhaul overdue and it's not obvious where the problem is in this case. Hence let's add back the old workaround which we already had sometime before. It explicitly detaches Host1x device from the offending implicit IOMMU domain. This fixes a completely broken Host1x DMA in case of ARM32 multiplatform kernel config.
Cc: stable@vger.kernel.org Fixes: af1cbfb9bf0f ("gpu: host1x: Support DMA mapping of buffers" Signed-off-by: Dmitry Osipenko digetx@gmail.com --- drivers/gpu/host1x/dev.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index c42ab78327e7..f5b4dcded088 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -22,6 +22,10 @@ #include <trace/events/host1x.h> #undef CREATE_TRACE_POINTS
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +#include <asm/dma-iommu.h> +#endif + #include "bus.h" #include "channel.h" #include "debug.h" @@ -263,6 +267,17 @@ static struct iommu_domain *host1x_iommu_attach(struct host1x *host) struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); int err;
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) + if (host->dev->archdata.mapping) { + struct dma_iommu_mapping *mapping = + to_dma_iommu_mapping(host->dev); + arm_iommu_detach_device(host->dev); + arm_iommu_release_mapping(mapping); + + domain = iommu_get_domain_for_dev(host->dev); + } +#endif + /* * We may not always want to enable IOMMU support (for example if the * host1x firewall is already enabled and we don't support addressing
DMA buffers of 2D/3D engines aren't mapped properly when CONFIG_ARM_DMA_USE_IOMMU=y. The memory management code of Tegra DRM driver has a longstanding overhaul overdue and it's not obvious where the problem is in this case. Hence let's add back the old workaround which we already had sometime before. It explicitly detaches DRM devices from the offending implicit IOMMU domain. This fixes a completely broken 2d/3d drivers in case of ARM32 multiplatform kernel config.
Cc: stable@vger.kernel.org Fixes: fa6661b7aa0b ("drm/tegra: Optionally attach clients to the IOMMU") Signed-off-by: Dmitry Osipenko digetx@gmail.com --- drivers/gpu/drm/tegra/drm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index dc04ce329be3..e9de91a4e7e8 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -22,6 +22,10 @@ #include <drm/drm_prime.h> #include <drm/drm_vblank.h>
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +#include <asm/dma-iommu.h> +#endif + #include "dc.h" #include "drm.h" #include "gem.h" @@ -945,6 +949,17 @@ int host1x_client_iommu_attach(struct host1x_client *client) struct iommu_group *group = NULL; int err;
+#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) + if (client->dev->archdata.mapping) { + struct dma_iommu_mapping *mapping = + to_dma_iommu_mapping(client->dev); + arm_iommu_detach_device(client->dev); + arm_iommu_release_mapping(mapping); + + domain = iommu_get_domain_for_dev(client->dev); + } +#endif + /* * If the host1x client is already attached to an IOMMU domain that is * not the shared IOMMU domain, don't try to attach it to a different
dri-devel@lists.freedesktop.org