summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-05-02 09:07:18 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-05-02 09:07:17 -0700
commit02e860bddbfdad3bbd92d011903a50eac958b4e9 (patch)
treeeb115f5da465d0d2f7709085119ff303891f4bce /drivers/gpu
parent82fffc58bfceb6e2d5c183eced7d9bc8c6eac3bc (diff)
parentd84fd15df03db850f81d7057f8082478a994e5e1 (diff)
Merge "msm/drm: Move msm_drm_config configuration into the GPUs"
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/adreno/a3xx_gpu.c9
-rw-r--r--drivers/gpu/drm/msm/adreno/a4xx_gpu.c9
-rw-r--r--drivers/gpu/drm/msm/adreno/a5xx_gpu.c16
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c37
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.h2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c23
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c7
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h2
-rw-r--r--drivers/gpu/drm/msm/msm_gem.h13
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c15
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c206
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.c8
-rw-r--r--drivers/gpu/drm/msm/msm_gpu.h3
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c271
-rw-r--r--drivers/gpu/drm/msm/msm_mmu.h41
-rw-r--r--drivers/gpu/drm/msm/msm_smmu.c135
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c7
17 files changed, 325 insertions, 479 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index c4f886fd6037..a417e42944fc 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -466,6 +466,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
struct msm_gpu *gpu;
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
+ struct msm_gpu_config a3xx_config = { 0 };
int ret;
if (!pdev) {
@@ -491,7 +492,13 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a3xx_registers;
adreno_gpu->reg_offsets = a3xx_register_offsets;
- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+ a3xx_config.ioname = MSM_GPU_DEFAULT_IONAME;
+ a3xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME;
+ a3xx_config.nr_rings = 1;
+ a3xx_config.va_start = 0x300000;
+ a3xx_config.va_end = 0xffffffff;
+
+ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a3xx_config);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 534a7c3fbdca..069823f054f7 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -543,6 +543,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
struct msm_gpu *gpu;
struct msm_drm_private *priv = dev->dev_private;
struct platform_device *pdev = priv->gpu_pdev;
+ struct msm_gpu_config a4xx_config = { 0 };
int ret;
if (!pdev) {
@@ -568,7 +569,13 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a4xx_registers;
adreno_gpu->reg_offsets = a4xx_register_offsets;
- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+ a4xx_config.ioname = MSM_GPU_DEFAULT_IONAME;
+ a4xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME;
+ a4xx_config.nr_rings = 1;
+ a4xx_config.va_start = 0x300000;
+ a4xx_config.va_end = 0xffffffff;
+
+ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a4xx_config);
if (ret)
goto fail;
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 9ceef8f437b5..98679e9bbea4 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1368,6 +1368,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
struct a5xx_gpu *a5xx_gpu = NULL;
struct adreno_gpu *adreno_gpu;
struct msm_gpu *gpu;
+ struct msm_gpu_config a5xx_config = { 0 };
int ret;
if (!pdev) {
@@ -1391,7 +1392,20 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
/* Check the efuses for some configuration */
a5xx_efuses_read(pdev, adreno_gpu);
- ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4);
+ a5xx_config.ioname = MSM_GPU_DEFAULT_IONAME;
+ a5xx_config.irqname = MSM_GPU_DEFAULT_IRQNAME;
+
+ /* Set the number of rings to 4 - yay preemption */
+ a5xx_config.nr_rings = 4;
+
+ /*
+ * Set the user domain range to fall into the TTBR1 region for global
+ * objects
+ */
+ a5xx_config.va_start = 0x800000000;
+ a5xx_config.va_end = 0x8ffffffff;
+
+ ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, &a5xx_config);
if (ret) {
a5xx_destroy(&(a5xx_gpu->base.base));
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 19267b2a3b49..9952fa8dcda5 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -405,10 +405,6 @@ void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords)
ring->gpu->name, ring->id);
}
-static const char *iommu_ports[] = {
- "gfx3d_user",
-};
-
/* Read the set of powerlevels */
static int _adreno_get_pwrlevels(struct msm_gpu *gpu, struct device_node *node)
{
@@ -524,10 +520,10 @@ static int adreno_of_parse(struct platform_device *pdev, struct msm_gpu *gpu)
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_gpu *adreno_gpu,
- const struct adreno_gpu_funcs *funcs, int nr_rings)
+ const struct adreno_gpu_funcs *funcs,
+ struct msm_gpu_config *gpu_config)
{
struct adreno_platform_config *config = pdev->dev.platform_data;
- struct msm_gpu_config adreno_gpu_config = { 0 };
struct msm_gpu *gpu = &adreno_gpu->base;
struct msm_mmu *mmu;
int ret;
@@ -541,26 +537,8 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
/* Get the rest of the target configuration from the device tree */
adreno_of_parse(pdev, gpu);
- adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
- adreno_gpu_config.irqname = "kgsl_3d0_irq";
- adreno_gpu_config.nr_rings = nr_rings;
-
- adreno_gpu_config.va_start = SZ_16M;
- adreno_gpu_config.va_end = 0xffffffff;
-
- if (adreno_gpu->revn >= 500) {
- /* 5XX targets use a 64 bit region */
- adreno_gpu_config.va_start = 0x800000000;
- adreno_gpu_config.va_end = 0x8ffffffff;
- } else {
- adreno_gpu_config.va_start = 0x300000;
- adreno_gpu_config.va_end = 0xffffffff;
- }
-
- adreno_gpu_config.nr_rings = nr_rings;
-
ret = msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
- adreno_gpu->info->name, &adreno_gpu_config);
+ adreno_gpu->info->name, gpu_config);
if (ret)
return ret;
@@ -580,8 +558,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
mmu = gpu->aspace->mmu;
if (mmu) {
- ret = mmu->funcs->attach(mmu, iommu_ports,
- ARRAY_SIZE(iommu_ports));
+ ret = mmu->funcs->attach(mmu, NULL, 0);
if (ret)
return ret;
}
@@ -722,7 +699,7 @@ static struct adreno_counter_group *get_counter_group(struct msm_gpu *gpu,
return ERR_PTR(-ENODEV);
if (groupid >= adreno_gpu->nr_counter_groups)
- return ERR_PTR(-EINVAL);
+ return ERR_PTR(-ENODEV);
return (struct adreno_counter_group *)
adreno_gpu->counter_groups[groupid];
@@ -745,7 +722,7 @@ u64 adreno_read_counter(struct msm_gpu *gpu, u32 groupid, int counterid)
struct adreno_counter_group *group =
get_counter_group(gpu, groupid);
- if (!IS_ERR(group) && group->funcs.read)
+ if (!IS_ERR_OR_NULL(group) && group->funcs.read)
return group->funcs.read(gpu, group, counterid);
return 0;
@@ -756,6 +733,6 @@ void adreno_put_counter(struct msm_gpu *gpu, u32 groupid, int counterid)
struct adreno_counter_group *group =
get_counter_group(gpu, groupid);
- if (!IS_ERR(group) && group->funcs.put)
+ if (!IS_ERR_OR_NULL(group) && group->funcs.put)
group->funcs.put(gpu, group, counterid);
}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index 8e8f3e5182d6..3f9bc655c383 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -257,7 +257,7 @@ struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu);
int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
- int nr_rings);
+ struct msm_gpu_config *config);
void adreno_gpu_cleanup(struct adreno_gpu *gpu);
void adreno_snapshot(struct msm_gpu *gpu, struct msm_snapshot *snapshot);
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index b6cddee0cf34..119221eacb43 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -184,8 +184,7 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file);
if (aspace) {
- aspace->mmu->funcs->detach(aspace->mmu,
- iommu_ports, ARRAY_SIZE(iommu_ports));
+ aspace->mmu->funcs->detach(aspace->mmu);
msm_gem_address_space_destroy(aspace);
}
}
@@ -202,8 +201,7 @@ static void mdp4_destroy(struct msm_kms *kms)
drm_gem_object_unreference_unlocked(mdp4_kms->blank_cursor_bo);
if (aspace) {
- aspace->mmu->funcs->detach(aspace->mmu,
- iommu_ports, ARRAY_SIZE(iommu_ports));
+ aspace->mmu->funcs->detach(aspace->mmu);
msm_gem_address_space_put(aspace);
}
@@ -416,10 +414,6 @@ fail:
return ret;
}
-static const char *iommu_ports[] = {
- "mdp_port0_cb0", "mdp_port1_cb0",
-};
-
struct msm_kms *mdp4_kms_init(struct drm_device *dev)
{
struct platform_device *pdev = dev->platformdev;
@@ -515,15 +509,11 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
mdelay(16);
if (config->iommu) {
- struct msm_mmu *mmu = msm_iommu_new(&pdev->dev, config->iommu);
-
- if (IS_ERR(mmu)) {
- ret = PTR_ERR(mmu);
- goto fail;
- }
+ config->iommu->geometry.aperture_start = 0x1000;
+ config->iommu->geometry.aperture_end = 0xffffffff;
aspace = msm_gem_address_space_create(&pdev->dev,
- mmu, "mdp4", 0x1000, 0xffffffff);
+ config->iommu, MSM_IOMMU_DOMAIN_DEFAULT, "mdp4");
if (IS_ERR(aspace)) {
ret = PTR_ERR(aspace);
goto fail;
@@ -531,8 +521,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
mdp4_kms->aspace = aspace;
- ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
- ARRAY_SIZE(iommu_ports));
+ ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
if (ret)
goto fail;
} else {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index e4e69ebd116e..4dbf456504b7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -22,10 +22,6 @@
#include "msm_mmu.h"
#include "mdp5_kms.h"
-static const char *iommu_ports[] = {
- "mdp_0",
-};
-
static int mdp5_hw_init(struct msm_kms *kms)
{
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -613,8 +609,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
mdp5_kms->aspace = aspace;
- ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports,
- ARRAY_SIZE(iommu_ports));
+ ret = aspace->mmu->funcs->attach(aspace->mmu, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "failed to attach iommu: %d\n",
ret);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 0ee584e32e39..bd75a1ba1f8b 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -413,7 +413,7 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
/* For GPU and legacy display */
struct msm_gem_address_space *
msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
- const char *name);
+ int type, const char *name);
struct msm_gem_address_space *
msm_gem_address_space_create_instance(struct msm_mmu *parent, const char *name,
uint64_t start, uint64_t end);
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 2045dc34c20a..0b19d11bc666 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -25,21 +25,12 @@
/* Additional internal-use only BO flags: */
#define MSM_BO_STOLEN 0x10000000 /* try to use stolen/splash memory */
-struct msm_gem_aspace_ops {
- int (*map)(struct msm_gem_address_space *, struct msm_gem_vma *,
- struct sg_table *sgt, void *priv, unsigned int flags);
-
- void (*unmap)(struct msm_gem_address_space *, struct msm_gem_vma *,
- struct sg_table *sgt, void *priv);
-
- void (*destroy)(struct msm_gem_address_space *);
-};
-
struct msm_gem_address_space {
const char *name;
struct msm_mmu *mmu;
- const struct msm_gem_aspace_ops *ops;
struct kref kref;
+ struct drm_mm mm;
+ u64 va_len;
};
struct msm_gem_vma {
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 52fc81420690..8e0f15c416fd 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -82,13 +82,16 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
void __user *userptr =
to_user_ptr(args->bos + (i * sizeof(submit_bo)));
- ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo));
- if (unlikely(ret)) {
+ if (copy_from_user_inatomic(&submit_bo, userptr,
+ sizeof(submit_bo))) {
pagefault_enable();
spin_unlock(&file->table_lock);
- ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
- if (ret)
+ if (copy_from_user(&submit_bo, userptr,
+ sizeof(submit_bo))) {
+ ret = -EFAULT;
goto out;
+ }
+
spin_lock(&file->table_lock);
pagefault_disable();
}
@@ -283,8 +286,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
uint32_t off;
bool valid;
- ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc));
- if (ret)
+ if (copy_from_user(&submit_reloc, userptr,
+ sizeof(submit_reloc)))
return -EFAULT;
if (submit_reloc.submit_offset % 4) {
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index a227f1ba0573..47f7436854fb 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -25,8 +25,10 @@ msm_gem_address_space_destroy(struct kref *kref)
struct msm_gem_address_space *aspace = container_of(kref,
struct msm_gem_address_space, kref);
- if (aspace->ops->destroy)
- aspace->ops->destroy(aspace);
+ if (aspace->va_len)
+ drm_mm_takedown(&aspace->mm);
+
+ aspace->mmu->funcs->destroy(aspace->mmu);
kfree(aspace);
}
@@ -37,57 +39,9 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace)
kref_put(&aspace->kref, msm_gem_address_space_destroy);
}
-/* SDE address space operations */
-static void smmu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt,
- void *priv)
-{
- struct dma_buf *buf = priv;
-
- if (buf)
- aspace->mmu->funcs->unmap_dma_buf(aspace->mmu,
- sgt, buf, DMA_BIDIRECTIONAL);
- else
- aspace->mmu->funcs->unmap_sg(aspace->mmu, sgt,
- DMA_BIDIRECTIONAL);
-
- vma->iova = 0;
-
- msm_gem_address_space_put(aspace);
-}
-
-
-static int smmu_aspace_map_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt,
- void *priv, unsigned int flags)
-{
- struct dma_buf *buf = priv;
- int ret;
-
- if (buf)
- ret = aspace->mmu->funcs->map_dma_buf(aspace->mmu, sgt, buf,
- DMA_BIDIRECTIONAL);
- else
- ret = aspace->mmu->funcs->map_sg(aspace->mmu, sgt,
- DMA_BIDIRECTIONAL);
-
- if (!ret)
- vma->iova = sg_dma_address(sgt->sgl);
-
- /* Get a reference to the aspace to keep it around */
- kref_get(&aspace->kref);
-
- return ret;
-}
-
-static const struct msm_gem_aspace_ops smmu_aspace_ops = {
- .map = smmu_aspace_map_vma,
- .unmap = smmu_aspace_unmap_vma,
-};
-
-struct msm_gem_address_space *
-msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu,
- const char *name)
+static struct msm_gem_address_space *
+msm_gem_address_space_new(struct msm_mmu *mmu, const char *name,
+ uint64_t start, uint64_t end)
{
struct msm_gem_address_space *aspace;
@@ -100,57 +54,28 @@ msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu,
aspace->name = name;
aspace->mmu = mmu;
- aspace->ops = &smmu_aspace_ops;
-
- kref_init(&aspace->kref);
-
- return aspace;
-}
-/* GPU address space operations */
-struct msm_iommu_aspace {
- struct msm_gem_address_space base;
- struct drm_mm mm;
-};
+ aspace->va_len = end - start;
-#define to_iommu_aspace(aspace) \
- ((struct msm_iommu_aspace *) \
- container_of(aspace, struct msm_iommu_aspace, base))
+ if (aspace->va_len)
+ drm_mm_init(&aspace->mm, (start >> PAGE_SHIFT),
+ (end >> PAGE_SHIFT) - 1);
-static void iommu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt, void *priv)
-{
- if (!vma->iova)
- return;
-
- if (aspace->mmu)
- aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt);
-
- drm_mm_remove_node(&vma->node);
-
- vma->iova = 0;
+ kref_init(&aspace->kref);
- msm_gem_address_space_put(aspace);
+ return aspace;
}
-static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt, void *priv,
- unsigned int flags)
+static int allocate_iova(struct msm_gem_address_space *aspace,
+ struct msm_gem_vma *vma, struct sg_table *sgt,
+ u64 *iova)
{
- struct msm_iommu_aspace *local = to_iommu_aspace(aspace);
- size_t size = 0;
struct scatterlist *sg;
+ size_t size = 0;
int ret, i;
- int iommu_flags = IOMMU_READ;
-
- if (!(flags & MSM_BO_GPU_READONLY))
- iommu_flags |= IOMMU_WRITE;
- if (flags & MSM_BO_PRIVILEGED)
- iommu_flags |= IOMMU_PRIV;
-
- if ((flags & MSM_BO_CACHED) && msm_iommu_coherent(aspace->mmu))
- iommu_flags |= IOMMU_CACHE;
+ if (!aspace->va_len)
+ return 0;
if (WARN_ON(drm_mm_node_allocated(&vma->node)))
return 0;
@@ -158,84 +83,73 @@ static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace,
for_each_sg(sgt->sgl, sg, sgt->nents, i)
size += sg->length + sg->offset;
- ret = drm_mm_insert_node(&local->mm, &vma->node, size >> PAGE_SHIFT,
+ ret = drm_mm_insert_node(&aspace->mm, &vma->node, size >> PAGE_SHIFT,
0, DRM_MM_SEARCH_DEFAULT);
- if (ret)
- return ret;
-
- vma->iova = vma->node.start << PAGE_SHIFT;
-
- if (aspace->mmu)
- ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
- iommu_flags);
- /* Get a reference to the aspace to keep it around */
- kref_get(&aspace->kref);
+ if (!ret && iova)
+ *iova = vma->node.start << PAGE_SHIFT;
return ret;
}
-static void iommu_aspace_destroy(struct msm_gem_address_space *aspace)
+int msm_gem_map_vma(struct msm_gem_address_space *aspace,
+ struct msm_gem_vma *vma, struct sg_table *sgt,
+ void *priv, unsigned int flags)
{
- struct msm_iommu_aspace *local = to_iommu_aspace(aspace);
-
- drm_mm_takedown(&local->mm);
- aspace->mmu->funcs->destroy(aspace->mmu);
-}
-
-static const struct msm_gem_aspace_ops msm_iommu_aspace_ops = {
- .map = iommu_aspace_map_vma,
- .unmap = iommu_aspace_unmap_vma,
- .destroy = iommu_aspace_destroy,
-};
+ u64 iova = 0;
+ int ret;
-static struct msm_gem_address_space *
-msm_gem_address_space_new(struct msm_mmu *mmu, const char *name,
- uint64_t start, uint64_t end)
-{
- struct msm_iommu_aspace *local;
+ if (!aspace)
+ return -EINVAL;
- if (!mmu)
- return ERR_PTR(-EINVAL);
+ ret = allocate_iova(aspace, vma, sgt, &iova);
+ if (ret)
+ return ret;
- local = kzalloc(sizeof(*local), GFP_KERNEL);
- if (!local)
- return ERR_PTR(-ENOMEM);
+ ret = aspace->mmu->funcs->map(aspace->mmu, iova, sgt,
+ flags, priv);
- drm_mm_init(&local->mm, (start >> PAGE_SHIFT),
- (end >> PAGE_SHIFT) - 1);
+ if (ret) {
+ if (drm_mm_node_allocated(&vma->node))
+ drm_mm_remove_node(&vma->node);
- local->base.name = name;
- local->base.mmu = mmu;
- local->base.ops = &msm_iommu_aspace_ops;
+ return ret;
+ }
- kref_init(&local->base.kref);
+ vma->iova = sg_dma_address(sgt->sgl);
+ kref_get(&aspace->kref);
- return &local->base;
+ return 0;
}
-int msm_gem_map_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt,
- void *priv, unsigned int flags)
+void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
+ struct msm_gem_vma *vma, struct sg_table *sgt, void *priv)
{
- if (aspace && aspace->ops->map)
- return aspace->ops->map(aspace, vma, sgt, priv, flags);
+ if (!aspace || !vma->iova)
+ return;
- return -EINVAL;
+ aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, priv);
+
+ if (drm_mm_node_allocated(&vma->node))
+ drm_mm_remove_node(&vma->node);
+
+ vma->iova = 0;
+
+ msm_gem_address_space_put(aspace);
}
-void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
- struct msm_gem_vma *vma, struct sg_table *sgt, void *priv)
+struct msm_gem_address_space *
+msm_gem_smmu_address_space_create(struct device *dev, struct msm_mmu *mmu,
+ const char *name)
{
- if (aspace && aspace->ops->unmap)
- aspace->ops->unmap(aspace, vma, sgt, priv);
+ return msm_gem_address_space_new(mmu, name, 0, 0);
}
struct msm_gem_address_space *
msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
- const char *name)
+ int type, const char *name)
{
- struct msm_mmu *mmu = msm_iommu_new(dev, domain);
+ struct msm_mmu *mmu = msm_iommu_new(dev, type, domain);
if (IS_ERR(mmu))
return (struct msm_gem_address_space *) mmu;
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 5a505a8bf328..2f01db8b08c3 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -183,6 +183,9 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu)
if (ret)
return ret;
+ if (gpu->aspace && gpu->aspace->mmu)
+ msm_mmu_enable(gpu->aspace->mmu);
+
return 0;
}
@@ -203,6 +206,9 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu)
if (WARN_ON(gpu->active_cnt < 0))
return -EINVAL;
+ if (gpu->aspace && gpu->aspace->mmu)
+ msm_mmu_disable(gpu->aspace->mmu);
+
ret = disable_axi(gpu);
if (ret)
return ret;
@@ -837,7 +843,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
dev_info(drm->dev, "%s: using IOMMU\n", name);
gpu->aspace = msm_gem_address_space_create(&pdev->dev,
- iommu, "gpu");
+ iommu, MSM_IOMMU_DOMAIN_USER, "gpu");
if (IS_ERR(gpu->aspace)) {
ret = PTR_ERR(gpu->aspace);
dev_err(drm->dev, "failed to init iommu: %d\n", ret);
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 3fac423929c5..29e2e59b580b 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -29,6 +29,9 @@
struct msm_gem_submit;
struct msm_gpu_perfcntr;
+#define MSM_GPU_DEFAULT_IONAME "kgsl_3d0_reg_memory"
+#define MSM_GPU_DEFAULT_IRQNAME "kgsl_3d0_irq"
+
struct msm_gpu_config {
const char *ioname;
const char *irqname;
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3af24646f4f1..b52c4752c5fe 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -17,6 +17,7 @@
#include <linux/of_platform.h>
#include <linux/of_address.h>
+#include <soc/qcom/secure_buffer.h>
#include "msm_drv.h"
#include "msm_iommu.h"
@@ -27,31 +28,17 @@ static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev,
return 0;
}
-/*
- * Get and enable the IOMMU clocks so that we can make
- * sure they stay on the entire duration so that we can
- * safely change the pagetable from the GPU
- */
-static void _get_iommu_clocks(struct msm_mmu *mmu, struct platform_device *pdev)
+static void iommu_get_clocks(struct msm_iommu *iommu, struct device *dev)
{
- struct msm_iommu *iommu = to_msm_iommu(mmu);
- struct device *dev;
struct property *prop;
const char *name;
int i = 0;
- if (WARN_ON(!pdev))
- return;
-
- dev = &pdev->dev;
-
iommu->nr_clocks =
of_property_count_strings(dev->of_node, "clock-names");
- if (iommu->nr_clocks < 0) {
- iommu->nr_clocks = 0;
+ if (iommu->nr_clocks < 0)
return;
- }
if (WARN_ON(iommu->nr_clocks > ARRAY_SIZE(iommu->clocks)))
iommu->nr_clocks = ARRAY_SIZE(iommu->clocks);
@@ -60,78 +47,58 @@ static void _get_iommu_clocks(struct msm_mmu *mmu, struct platform_device *pdev)
if (i == iommu->nr_clocks)
break;
- iommu->clocks[i] = clk_get(dev, name);
- if (iommu->clocks[i])
- clk_prepare_enable(iommu->clocks[i]);
-
- i++;
+ iommu->clocks[i++] = clk_get(dev, name);
}
}
-static int _attach_iommu_device(struct msm_mmu *mmu,
- struct iommu_domain *domain, const char **names, int cnt)
+
+static void msm_iommu_clocks_enable(struct msm_mmu *mmu)
{
+ struct msm_iommu *iommu = to_msm_iommu(mmu);
int i;
- /* See if there is a iommus member in the current device. If not, look
- * for the names and see if there is one in there.
- */
+ if (!iommu->nr_clocks)
+ iommu_get_clocks(iommu, mmu->dev->parent);
- if (of_find_property(mmu->dev->of_node, "iommus", NULL))
- return iommu_attach_device(domain, mmu->dev);
-
- /* Look through the list of names for a target */
- for (i = 0; i < cnt; i++) {
- struct device_node *node =
- of_find_node_by_name(mmu->dev->of_node, names[i]);
-
- if (!node)
- continue;
-
- if (of_find_property(node, "iommus", NULL)) {
- struct platform_device *pdev;
-
- /* Get the platform device for the node */
- of_platform_populate(node->parent, NULL, NULL,
- mmu->dev);
-
- pdev = of_find_device_by_node(node);
-
- if (!pdev)
- continue;
-
- _get_iommu_clocks(mmu,
- of_find_device_by_node(node->parent));
+ for (i = 0; i < iommu->nr_clocks; i++) {
+ if (iommu->clocks[i])
+ clk_prepare_enable(iommu->clocks[i]);
+ }
+}
- mmu->dev = &pdev->dev;
+static void msm_iommu_clocks_disable(struct msm_mmu *mmu)
+{
+ struct msm_iommu *iommu = to_msm_iommu(mmu);
+ int i;
- return iommu_attach_device(domain, mmu->dev);
- }
+ for (i = 0; i < iommu->nr_clocks; i++) {
+ if (iommu->clocks[i])
+ clk_disable_unprepare(iommu->clocks[i]);
}
+}
- dev_err(mmu->dev, "Couldn't find a IOMMU device\n");
- return -ENODEV;
+static int msm_iommu_attach(struct msm_mmu *mmu, const char **names,
+ int cnt)
+{
+ struct msm_iommu *iommu = to_msm_iommu(mmu);
+
+ return iommu_attach_device(iommu->domain, mmu->dev);
}
-static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt)
+static int msm_iommu_attach_user(struct msm_mmu *mmu, const char **names,
+ int cnt)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
- int val = 1, ret;
+ int ret, val = 1;
/* Hope springs eternal */
- iommu->allow_dynamic = true;
-
- /* per-instance pagetables need TTBR1 support in the IOMMU driver */
- ret = iommu_domain_set_attr(iommu->domain,
- DOMAIN_ATTR_ENABLE_TTBR1, &val);
- if (ret)
- iommu->allow_dynamic = false;
+ iommu->allow_dynamic = !iommu_domain_set_attr(iommu->domain,
+ DOMAIN_ATTR_ENABLE_TTBR1, &val) ? true : false;
/* Mark the GPU as I/O coherent if it is supported */
iommu->is_coherent = of_dma_is_coherent(mmu->dev->of_node);
- /* Attach the device to the domain */
- ret = _attach_iommu_device(mmu, iommu->domain, names, cnt);
+ ret = iommu_attach_device(iommu->domain, mmu->dev);
if (ret)
return ret;
@@ -176,17 +143,25 @@ static int msm_iommu_attach_dynamic(struct msm_mmu *mmu, const char **names,
return 0;
}
+static int msm_iommu_attach_secure(struct msm_mmu *mmu, const char **names,
+ int cnt)
+{
+ struct msm_iommu *iommu = to_msm_iommu(mmu);
+ int ret, vmid = VMID_CP_PIXEL;
+
+ ret = iommu_domain_set_attr(iommu->domain, DOMAIN_ATTR_SECURE_VMID,
+ &vmid);
+ if (ret)
+ return ret;
+
+ return iommu_attach_device(iommu->domain, mmu->dev);
+}
+
static void msm_iommu_detach(struct msm_mmu *mmu)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
- int i;
iommu_detach_device(iommu->domain, mmu->dev);
-
- for (i = 0; i < iommu->nr_clocks; i++) {
- if (iommu->clocks[i])
- clk_disable(iommu->clocks[i]);
- }
}
static void msm_iommu_detach_dynamic(struct msm_mmu *mmu)
@@ -196,69 +171,50 @@ static void msm_iommu_detach_dynamic(struct msm_mmu *mmu)
}
static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt, int prot)
+ struct sg_table *sgt, u32 flags, void *priv)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
struct iommu_domain *domain = iommu->domain;
- struct scatterlist *sg;
- uint64_t da = iova;
- unsigned int i, j;
int ret;
+ u32 prot = IOMMU_READ;
if (!domain || !sgt)
return -EINVAL;
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- phys_addr_t pa = sg_phys(sg) - sg->offset;
- size_t bytes = sg->length + sg->offset;
+ if (!(flags & MSM_BO_GPU_READONLY))
+ prot |= IOMMU_WRITE;
- VERB("map[%d]: %016llx %pa(%zx)", i, iova, &pa, bytes);
+ if (flags & MSM_BO_PRIVILEGED)
+ prot |= IOMMU_PRIV;
- ret = iommu_map(domain, da, pa, bytes, prot);
- if (ret)
- goto fail;
+ if ((flags & MSM_BO_CACHED) && msm_iommu_coherent(mmu))
+ prot |= IOMMU_CACHE;
- da += bytes;
- }
-
- return 0;
-
-fail:
- da = iova;
+ /* iommu_map_sg returns the number of bytes mapped */
+ ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->nents, prot);
+ if (ret)
+ sgt->sgl->dma_address = iova;
- for_each_sg(sgt->sgl, sg, i, j) {
- size_t bytes = sg->length + sg->offset;
- iommu_unmap(domain, da, bytes);
- da += bytes;
- }
- return ret;
+ return ret ? 0 : -ENOMEM;
}
-static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt)
+static void msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt, void *priv)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
struct iommu_domain *domain = iommu->domain;
struct scatterlist *sg;
- uint64_t da = iova;
- int i;
+ size_t len = 0;
+ int ret, i;
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes = sg->length + sg->offset;
- size_t unmapped;
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ len += sg->length;
- unmapped = iommu_unmap(domain, da, bytes);
- if (unmapped < bytes)
- return unmapped;
+ ret = iommu_unmap(domain, iova, len);
+ if (ret != len)
+ dev_warn(mmu->dev, "could not unmap iova %llx\n", iova);
- VERB("unmap[%d]: %016llx(%zx)", i, iova, bytes);
-
- BUG_ON(!PAGE_ALIGNED(bytes));
-
- da += bytes;
- }
-
- return 0;
+ sgt->sgl->dma_address = 0;
}
static void msm_iommu_destroy(struct msm_mmu *mmu)
@@ -268,7 +224,30 @@ static void msm_iommu_destroy(struct msm_mmu *mmu)
kfree(iommu);
}
-static const struct msm_mmu_funcs funcs = {
+static struct device *find_context_bank(const char *name)
+{
+ struct device_node *node = of_find_node_by_name(NULL, name);
+ struct platform_device *pdev, *parent;
+
+ if (!node)
+ return ERR_PTR(-ENODEV);
+
+ if (!of_find_property(node, "iommus", NULL))
+ return ERR_PTR(-ENODEV);
+
+ /* Get the parent device */
+ parent = of_find_device_by_node(node->parent);
+
+ /* Populate the sub nodes */
+ of_platform_populate(parent->dev.of_node, NULL, NULL, &parent->dev);
+
+ /* Get the context bank device */
+ pdev = of_find_device_by_node(node);
+
+ return pdev ? &pdev->dev : ERR_PTR(-ENODEV);
+}
+
+static const struct msm_mmu_funcs default_funcs = {
.attach = msm_iommu_attach,
.detach = msm_iommu_detach,
.map = msm_iommu_map,
@@ -276,6 +255,24 @@ static const struct msm_mmu_funcs funcs = {
.destroy = msm_iommu_destroy,
};
+static const struct msm_mmu_funcs user_funcs = {
+ .attach = msm_iommu_attach_user,
+ .detach = msm_iommu_detach,
+ .map = msm_iommu_map,
+ .unmap = msm_iommu_unmap,
+ .destroy = msm_iommu_destroy,
+ .enable = msm_iommu_clocks_enable,
+ .disable = msm_iommu_clocks_disable,
+};
+
+static const struct msm_mmu_funcs secure_funcs = {
+ .attach = msm_iommu_attach_secure,
+ .detach = msm_iommu_detach,
+ .map = msm_iommu_map,
+ .unmap = msm_iommu_unmap,
+ .destroy = msm_iommu_destroy,
+};
+
static const struct msm_mmu_funcs dynamic_funcs = {
.attach = msm_iommu_attach_dynamic,
.detach = msm_iommu_detach_dynamic,
@@ -284,8 +281,26 @@ static const struct msm_mmu_funcs dynamic_funcs = {
.destroy = msm_iommu_destroy,
};
-struct msm_mmu *_msm_iommu_new(struct device *dev, struct iommu_domain *domain,
- const struct msm_mmu_funcs *funcs)
+static const struct {
+ const char *cbname;
+ const struct msm_mmu_funcs *funcs;
+} msm_iommu_domains[] = {
+ [MSM_IOMMU_DOMAIN_DEFAULT] = {
+ .cbname = NULL,
+ .funcs = &default_funcs,
+ },
+ [MSM_IOMMU_DOMAIN_USER] = {
+ .cbname = "gfx3d_user",
+ .funcs = &user_funcs,
+ },
+ [MSM_IOMMU_DOMAIN_SECURE] = {
+ .cbname = "gfx3d_secure",
+ .funcs = &secure_funcs
+ },
+};
+
+static struct msm_mmu *iommu_create(struct device *dev,
+ struct iommu_domain *domain, const struct msm_mmu_funcs *funcs)
{
struct msm_iommu *iommu;
@@ -299,9 +314,23 @@ struct msm_mmu *_msm_iommu_new(struct device *dev, struct iommu_domain *domain,
return &iommu->base;
}
-struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain)
+
+struct msm_mmu *msm_iommu_new(struct device *parent,
+ enum msm_iommu_domain_type type, struct iommu_domain *domain)
{
- return _msm_iommu_new(dev, domain, &funcs);
+ struct device *dev = parent;
+
+ if (type >= ARRAY_SIZE(msm_iommu_domains) ||
+ !msm_iommu_domains[type].funcs)
+ return ERR_PTR(-ENODEV);
+
+ if (msm_iommu_domains[type].cbname) {
+ dev = find_context_bank(msm_iommu_domains[type].cbname);
+ if (IS_ERR(dev))
+ return ERR_CAST(dev);
+ }
+
+ return iommu_create(dev, domain, msm_iommu_domains[type].funcs);
}
/*
@@ -326,7 +355,7 @@ struct msm_mmu *msm_iommu_new_dynamic(struct msm_mmu *base)
if (!domain)
return ERR_PTR(-ENODEV);
- mmu = _msm_iommu_new(base->dev, domain, &dynamic_funcs);
+ mmu = iommu_create(base->dev, domain, &dynamic_funcs);
if (IS_ERR(mmu)) {
if (domain)
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 501f12bef00d..033370ccbe24 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -30,21 +30,22 @@ enum msm_mmu_domain_type {
MSM_SMMU_DOMAIN_MAX,
};
+enum msm_iommu_domain_type {
+ MSM_IOMMU_DOMAIN_DEFAULT,
+ MSM_IOMMU_DOMAIN_USER,
+ MSM_IOMMU_DOMAIN_SECURE,
+};
+
struct msm_mmu_funcs {
int (*attach)(struct msm_mmu *mmu, const char **names, int cnt);
void (*detach)(struct msm_mmu *mmu);
int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
- int prot);
- int (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt);
- int (*map_sg)(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir);
- void (*unmap_sg)(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir);
- int (*map_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir);
- void (*unmap_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir);
+ u32 flags, void *priv);
+ void (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
+ void *priv);
void (*destroy)(struct msm_mmu *mmu);
+ void (*enable)(struct msm_mmu *mmu);
+ void (*disable)(struct msm_mmu *mmu);
};
struct msm_mmu {
@@ -59,9 +60,27 @@ static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
mmu->funcs = funcs;
}
-struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain);
+/* Create a new SDE mmu device */
struct msm_mmu *msm_smmu_new(struct device *dev,
enum msm_mmu_domain_type domain);
+
+/* Create a new legacy MDP4 or GPU mmu device */
+struct msm_mmu *msm_iommu_new(struct device *parent,
+ enum msm_iommu_domain_type type, struct iommu_domain *domain);
+
+/* Create a new dynamic domain for GPU */
struct msm_mmu *msm_iommu_new_dynamic(struct msm_mmu *orig);
+static inline void msm_mmu_enable(struct msm_mmu *mmu)
+{
+ if (mmu->funcs->enable)
+ mmu->funcs->enable(mmu);
+}
+
+static inline void msm_mmu_disable(struct msm_mmu *mmu)
+{
+ if (mmu->funcs->disable)
+ mmu->funcs->disable(mmu);
+}
+
#endif /* __MSM_MMU_H__ */
diff --git a/drivers/gpu/drm/msm/msm_smmu.c b/drivers/gpu/drm/msm/msm_smmu.c
index c99f51e09700..f5c6e0cd8048 100644
--- a/drivers/gpu/drm/msm/msm_smmu.c
+++ b/drivers/gpu/drm/msm/msm_smmu.c
@@ -105,106 +105,34 @@ static void msm_smmu_detach(struct msm_mmu *mmu)
}
static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt, int prot)
+ struct sg_table *sgt, u32 flags, void *priv)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- struct iommu_domain *domain;
- struct scatterlist *sg;
- uint64_t da = iova;
- unsigned int i, j;
int ret;
- if (!client)
- return -ENODEV;
-
- domain = client->mmu_mapping->domain;
- if (!domain || !sgt)
- return -EINVAL;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- u32 pa = sg_phys(sg) - sg->offset;
- size_t bytes = sg->length + sg->offset;
-
- VERB("map[%d]: %16llx %08x(%zx)", i, iova, pa, bytes);
-
- ret = iommu_map(domain, da, pa, bytes, prot);
- if (ret)
- goto fail;
-
- da += bytes;
- }
-
- return 0;
-
-fail:
- da = iova;
-
- for_each_sg(sgt->sgl, sg, i, j) {
- size_t bytes = sg->length + sg->offset;
-
- iommu_unmap(domain, da, bytes);
- da += bytes;
- }
- return ret;
-}
-
-static int msm_smmu_map_sg(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- int ret;
-
- ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, dir);
- if (ret != sgt->nents)
- return -ENOMEM;
-
- return 0;
-}
-
-static void msm_smmu_unmap_sg(struct msm_mmu *mmu, struct sg_table *sgt,
- enum dma_data_direction dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
+ if (priv)
+ ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents,
+ DMA_BIDIRECTIONAL, priv);
+ else
+ ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents,
+ DMA_BIDIRECTIONAL);
- dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir);
+ return (ret != sgt->nents) ? -ENOMEM : 0;
}
-static int msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
- struct sg_table *sgt)
+static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt, void *priv)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- struct iommu_domain *domain;
- struct scatterlist *sg;
- uint64_t da = iova;
- int i;
-
- if (!client)
- return -ENODEV;
-
- domain = client->mmu_mapping->domain;
- if (!domain || !sgt)
- return -EINVAL;
-
- for_each_sg(sgt->sgl, sg, sgt->nents, i) {
- size_t bytes = sg->length + sg->offset;
- size_t unmapped;
-
- unmapped = iommu_unmap(domain, da, bytes);
- if (unmapped < bytes)
- return unmapped;
-
- VERB("unmap[%d]: %16llx(%zx)", i, iova, bytes);
- WARN_ON(!PAGE_ALIGNED(bytes));
-
- da += bytes;
- }
-
- return 0;
+ if (priv)
+ msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents,
+ DMA_BIDIRECTIONAL, priv);
+ else
+ dma_unmap_sg(client->dev, sgt->sgl, sgt->nents,
+ DMA_BIDIRECTIONAL);
}
static void msm_smmu_destroy(struct msm_mmu *mmu)
@@ -217,42 +145,11 @@ static void msm_smmu_destroy(struct msm_mmu *mmu)
kfree(smmu);
}
-static int msm_smmu_map_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- int ret;
-
- ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, dir,
- dma_buf);
- if (ret != sgt->nents) {
- DRM_ERROR("dma map sg failed\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-
-static void msm_smmu_unmap_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
- struct dma_buf *dma_buf, int dir)
-{
- struct msm_smmu *smmu = to_msm_smmu(mmu);
- struct msm_smmu_client *client = msm_smmu_to_client(smmu);
-
- msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir, dma_buf);
-}
-
static const struct msm_mmu_funcs funcs = {
.attach = msm_smmu_attach,
.detach = msm_smmu_detach,
.map = msm_smmu_map,
- .map_sg = msm_smmu_map_sg,
- .unmap_sg = msm_smmu_unmap_sg,
.unmap = msm_smmu_unmap,
- .map_dma_buf = msm_smmu_map_dma_buf,
- .unmap_dma_buf = msm_smmu_unmap_dma_buf,
.destroy = msm_smmu_destroy,
};
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 826c1e905c04..f8c236f21e22 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -41,10 +41,6 @@
#define CREATE_TRACE_POINTS
#include "sde_trace.h"
-static const char * const iommu_ports[] = {
- "mdp_0",
-};
-
/**
* Controls size of event log buffer. Specified as a power of 2.
*/
@@ -1077,8 +1073,7 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
sde_kms->aspace[i] = aspace;
- ret = mmu->funcs->attach(mmu, (const char **)iommu_ports,
- ARRAY_SIZE(iommu_ports));
+ ret = mmu->funcs->attach(mmu, NULL, 0);
if (ret) {
SDE_ERROR("failed to attach iommu %d: %d\n", i, ret);
msm_gem_address_space_put(aspace);