mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 10:31:33 -04:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user