summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/msm/msm_mmu.h4
-rw-r--r--drivers/gpu/drm/msm/msm_smmu.c70
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.c11
3 files changed, 61 insertions, 24 deletions
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index cd3a710f8f27..74dea95d90de 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -46,6 +46,10 @@ struct msm_mmu_funcs {
void (*destroy)(struct msm_mmu *mmu);
void (*enable)(struct msm_mmu *mmu);
void (*disable)(struct msm_mmu *mmu);
+ int (*early_splash_map)(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt, u32 flags);
+ void (*early_splash_unmap)(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt);
int (*set_property)(struct msm_mmu *mmu,
enum iommu_attr attr, void *data);
};
diff --git a/drivers/gpu/drm/msm/msm_smmu.c b/drivers/gpu/drm/msm/msm_smmu.c
index 4247243055b6..aefbe0988fe5 100644
--- a/drivers/gpu/drm/msm/msm_smmu.c
+++ b/drivers/gpu/drm/msm/msm_smmu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -120,30 +120,19 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova,
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
- struct iommu_domain *domain;
int ret;
if (!client || !sgt)
return -EINVAL;
- if (iova != 0) {
- if (!client->mmu_mapping || !client->mmu_mapping->domain)
- return -EINVAL;
-
- domain = client->mmu_mapping->domain;
-
- return iommu_map_sg(domain, iova, sgt->sgl,
- sgt->nents, flags);
- } else {
- 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);
+ 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);
- return (ret != sgt->nents) ? -ENOMEM : 0;
- }
+ return (ret != sgt->nents) ? -ENOMEM : 0;
}
static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
@@ -160,6 +149,47 @@ static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova,
DMA_BIDIRECTIONAL);
}
+static int msm_smmu_early_splash_map(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt, u32 flags)
+{
+ struct msm_smmu *smmu = to_msm_smmu(mmu);
+ struct msm_smmu_client *client = msm_smmu_to_client(smmu);
+ struct iommu_domain *domain;
+
+ if (!client || !sgt)
+ return -EINVAL;
+
+ if (!client->mmu_mapping || !client->mmu_mapping->domain)
+ return -EINVAL;
+
+ domain = client->mmu_mapping->domain;
+
+ return iommu_map_sg(domain, iova, sgt->sgl, sgt->nents, flags);
+}
+
+static void msm_smmu_early_splash_unmap(struct msm_mmu *mmu, uint64_t iova,
+ struct sg_table *sgt)
+{
+ 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;
+ size_t len = 0;
+ int unmapped, i = 0;
+
+ if (!client || !client->mmu_mapping || !client->mmu_mapping->domain)
+ return;
+
+ domain = client->mmu_mapping->domain;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ len += sg->length;
+
+ unmapped = iommu_unmap(domain, iova, len);
+ if (unmapped < len)
+ DRM_ERROR("could not unmap iova@%llx\n", iova);
+}
+
static void msm_smmu_destroy(struct msm_mmu *mmu)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
@@ -199,6 +229,8 @@ static const struct msm_mmu_funcs funcs = {
.map = msm_smmu_map,
.unmap = msm_smmu_unmap,
.destroy = msm_smmu_destroy,
+ .early_splash_map = msm_smmu_early_splash_map,
+ .early_splash_unmap = msm_smmu_early_splash_unmap,
.set_property = msm_smmu_set_property,
};
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c
index 19e6406600cd..2789ae053663 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.c
+++ b/drivers/gpu/drm/msm/sde/sde_splash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -301,8 +301,8 @@ static int _sde_splash_free_resource(struct msm_mmu *mmu,
return -EINVAL;
if (mmu->funcs && mmu->funcs->unmap)
- mmu->funcs->unmap(mmu, sinfo->splash_mem_paddr[conn],
- msm_obj->sgt, NULL);
+ mmu->funcs->early_splash_unmap(mmu,
+ sinfo->splash_mem_paddr[conn], msm_obj->sgt);
_sde_splash_free_bootup_memory_to_system(sinfo->splash_mem_paddr[conn],
sinfo->splash_mem_size[conn]);
@@ -489,8 +489,9 @@ int sde_splash_smmu_map(struct drm_device *dev, struct msm_mmu *mmu,
msm_obj = to_msm_bo(sinfo->obj[i]);
if (mmu->funcs && mmu->funcs->map) {
- ret = mmu->funcs->map(mmu, sinfo->splash_mem_paddr[i],
- msm_obj->sgt, IOMMU_READ | IOMMU_NOEXEC, NULL);
+ ret = mmu->funcs->early_splash_map(mmu,
+ sinfo->splash_mem_paddr[i], msm_obj->sgt,
+ IOMMU_READ | IOMMU_NOEXEC);
if (!ret) {
SDE_ERROR("Map blk %d @%pK failed.\n",