drm/msm: detach the ARM DMA mapping before attaching our own domain

On ARM32 with CONFIG_ARM_DMA_USE_IOMMU, arch_setup_dma_ops() creates a
dma_iommu_mapping for every IOMMU-backed device and attaches its domain
to the device's IOMMU group. That domain is neither the group's default
nor its blocking domain, so when msm_iommu_new() later attaches the
domain the driver manages itself, __iommu_attach_group() refuses it:

	if (group->domain && group->domain != group->default_domain &&
	    group->domain != group->blocking_domain)
		return -EBUSY;

Both the GPU and the display controller are hit by this on apq8064
(IFC6410), leaving the board with no GPU and no display:

  adreno 4300000.gpu: failed to load adreno gpu
  adreno 4300000.gpu: probe with driver adreno failed with error -16
  mdp4 5100000.display-controller: [drm:msm_drm_kms_init] *ERROR* failed to load kms
  mdp4 5100000.display-controller: adev bind failed: -16

Other ARM32 DRM drivers that manage their own domains (tegra, rockchip,
exynos) drop the arch mapping first. Do the same in msm_iommu_new(),
which both the display and the GPU paths go through.

With this the GPU and the KMS device both initialise:

  [drm] Initialized msm 1.13.0 for 4300000.gpu on minor 0
  [drm] Initialized msm-kms 1.13.0 for 5100000.display-controller on minor 1

Assisted-by: Claude:claude-opus-5
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/743333/
Link: https://lore.kernel.org/r/20260730-fix-qcom-smmu-v2-3-18e0daf2d836@oss.qualcomm.com
This commit is contained in:
Dmitry Baryshkov
2026-07-30 19:04:56 +03:00
parent 06b7ba2065
commit 140b134753

View File

@@ -7,6 +7,15 @@
#include <linux/adreno-smmu-priv.h>
#include <linux/io-pgtable.h>
#include <linux/kmemleak.h>
#if defined(CONFIG_ARM_DMA_USE_IOMMU)
#include <asm/dma-iommu.h>
#else
#define arm_iommu_detach_device(...) ({ })
#define arm_iommu_release_mapping(...) ({ })
#define to_dma_iommu_mapping(dev) NULL
#endif
#include "msm_drv.h"
#include "msm_gpu_trace.h"
#include "msm_mmu.h"
@@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks)
mutex_init(&iommu->init_lock);
/*
* ARM32 attaches a DMA mapping domain to every IOMMU-backed device,
* which would make attaching our own domain fail with -EBUSY.
*/
if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
if (mapping) {
arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
}
}
ret = iommu_attach_device(iommu->domain, dev);
if (ret) {
iommu_domain_free(domain);