diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_drv.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index df0df55d26f9..1182c9f81bfd 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -26,6 +26,7 @@ #include "msm_gem.h" #include "msm_gpu.h" #include "msm_kms.h" +#include "msm_mmu.h" #include "adreno/adreno_gpu.h" /* @@ -267,6 +268,44 @@ static int msm_drm_uninit(struct device *dev) #include <linux/of_address.h> +struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev) +{ + struct iommu_domain *domain; + struct msm_gem_address_space *aspace; + struct msm_mmu *mmu; + struct device *mdp_dev = dev->dev; + struct device *mdss_dev = mdp_dev->parent; + struct device *iommu_dev; + + domain = iommu_domain_alloc(&platform_bus_type); + if (!domain) { + drm_info(dev, "no IOMMU, fallback to phys contig buffers for scanout\n"); + return NULL; + } + + /* + * IOMMUs can be a part of MDSS device tree binding, or the + * MDP/DPU device. + */ + if (dev_iommu_fwspec_get(mdp_dev)) + iommu_dev = mdp_dev; + else + iommu_dev = mdss_dev; + + mmu = msm_iommu_new(iommu_dev, domain); + if (IS_ERR(mmu)) { + iommu_domain_free(domain); + return ERR_CAST(mmu); + } + + aspace = msm_gem_address_space_create(mmu, "mdp_kms", + 0x1000, 0x100000000 - 0x1000); + if (IS_ERR(aspace)) + mmu->funcs->destroy(mmu); + + return aspace; +} + bool msm_use_mmu(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; |