summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2016-08-16 12:09:08 +0200
committerLucas Stach <l.stach@pengutronix.de>2016-09-15 15:29:36 +0200
commitdd34bb9655176873dc6fdfc612c71f7c2f078caa (patch)
tree4c7b2a25993598b1d540417cf662e52ba763b295 /drivers/gpu/drm
parente095c8feb8feed9e2c8ef76f8ec8491f46985e24 (diff)
downloadtalos-obmc-linux-dd34bb9655176873dc6fdfc612c71f7c2f078caa.tar.gz
talos-obmc-linux-dd34bb9655176873dc6fdfc612c71f7c2f078caa.zip
drm/etnaviv: move IOMMU domain allocation into etnaviv MMU
The GPU code doesn't need to deal with the IOMMU directly, instead it can all be hidden behind the etnaviv mmu interface. Move the last remaining part into etnaviv mmu. Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c33
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu.h4
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c2
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_mmu.c28
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_mmu.h3
6 files changed, 29 insertions, 43 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 40610595a2d3..9ecb23b1089b 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -22,8 +22,6 @@
#include "etnaviv_gpu.h"
#include "etnaviv_gem.h"
#include "etnaviv_mmu.h"
-#include "etnaviv_iommu.h"
-#include "etnaviv_iommu_v2.h"
#include "common.xml.h"
#include "state.xml.h"
#include "state_hi.xml.h"
@@ -585,9 +583,6 @@ static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
{
int ret, i;
- struct iommu_domain *iommu;
- enum etnaviv_iommu_version version;
- bool mmuv2;
ret = pm_runtime_get_sync(gpu->dev);
if (ret < 0) {
@@ -635,32 +630,10 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
goto fail;
}
- /* Setup IOMMU.. eventually we will (I think) do this once per context
- * and have separate page tables per context. For now, to keep things
- * simple and to get something working, just use a single address space:
- */
- mmuv2 = gpu->identity.minor_features1 & chipMinorFeatures1_MMU_VERSION;
- dev_dbg(gpu->dev, "mmuv2: %d\n", mmuv2);
-
- if (!mmuv2) {
- iommu = etnaviv_iommu_domain_alloc(gpu);
- version = ETNAVIV_IOMMU_V1;
- } else {
- iommu = etnaviv_iommu_v2_domain_alloc(gpu);
- version = ETNAVIV_IOMMU_V2;
- }
-
- if (!iommu) {
- dev_err(gpu->dev, "Failed to allocate GPU IOMMU domain\n");
- ret = -ENOMEM;
- goto fail;
- }
-
- gpu->mmu = etnaviv_iommu_new(gpu, iommu, version);
- if (!gpu->mmu) {
+ gpu->mmu = etnaviv_iommu_new(gpu);
+ if (IS_ERR(gpu->mmu)) {
dev_err(gpu->dev, "Failed to instantiate GPU IOMMU\n");
- iommu_domain_free(iommu);
- ret = -ENOMEM;
+ ret = PTR_ERR(gpu->mmu);
goto fail;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
index 912a290a4e9c..81f1583a7946 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c
@@ -219,7 +219,7 @@ void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu)
gpu_write(gpu, VIVS_MC_MMU_RA_PAGE_TABLE, pgtable);
}
-struct iommu_domain *etnaviv_iommu_domain_alloc(struct etnaviv_gpu *gpu)
+struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu)
{
struct etnaviv_iommu_domain *etnaviv_domain;
int ret;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
index dfb4ba23ce08..4b6212999c1e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.h
@@ -20,8 +20,8 @@
#include <linux/iommu.h>
struct etnaviv_gpu;
-struct iommu_domain *etnaviv_iommu_domain_alloc(struct etnaviv_gpu *gpu);
+struct iommu_domain *etnaviv_iommuv1_domain_alloc(struct etnaviv_gpu *gpu);
void etnaviv_iommuv1_restore(struct etnaviv_gpu *gpu);
-struct iommu_domain *etnaviv_iommu_v2_domain_alloc(struct etnaviv_gpu *gpu);
+struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu);
#endif /* __ETNAVIV_IOMMU_H__ */
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
index fbb4aed3dc80..8c913c83ac5e 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c
@@ -26,7 +26,7 @@
#include "state_hi.xml.h"
-struct iommu_domain *etnaviv_iommu_v2_domain_alloc(struct etnaviv_gpu *gpu)
+struct iommu_domain *etnaviv_iommuv2_domain_alloc(struct etnaviv_gpu *gpu)
{
/* TODO */
return NULL;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
index 55d4229f6932..e744c6d81a2d 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
@@ -14,6 +14,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "common.xml.h"
#include "etnaviv_drv.h"
#include "etnaviv_gem.h"
#include "etnaviv_gpu.h"
@@ -258,26 +259,39 @@ void etnaviv_iommu_destroy(struct etnaviv_iommu *mmu)
kfree(mmu);
}
-struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu,
- struct iommu_domain *domain, enum etnaviv_iommu_version version)
+struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu)
{
+ enum etnaviv_iommu_version version;
struct etnaviv_iommu *mmu;
mmu = kzalloc(sizeof(*mmu), GFP_KERNEL);
if (!mmu)
return ERR_PTR(-ENOMEM);
- mmu->domain = domain;
+ if (!(gpu->identity.minor_features1 & chipMinorFeatures1_MMU_VERSION)) {
+ mmu->domain = etnaviv_iommuv1_domain_alloc(gpu);
+ version = ETNAVIV_IOMMU_V1;
+ } else {
+ mmu->domain = etnaviv_iommuv2_domain_alloc(gpu);
+ version = ETNAVIV_IOMMU_V2;
+ }
+
+ if (!mmu->domain) {
+ dev_err(gpu->dev, "Failed to allocate GPU IOMMU domain\n");
+ kfree(mmu);
+ return ERR_PTR(-ENOMEM);
+ }
+
mmu->gpu = gpu;
mmu->version = version;
mutex_init(&mmu->lock);
INIT_LIST_HEAD(&mmu->mappings);
- drm_mm_init(&mmu->mm, domain->geometry.aperture_start,
- domain->geometry.aperture_end -
- domain->geometry.aperture_start + 1);
+ drm_mm_init(&mmu->mm, mmu->domain->geometry.aperture_start,
+ mmu->domain->geometry.aperture_end -
+ mmu->domain->geometry.aperture_start + 1);
- iommu_set_fault_handler(domain, etnaviv_fault_handler, gpu->dev);
+ iommu_set_fault_handler(mmu->domain, etnaviv_fault_handler, gpu->dev);
return mmu;
}
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
index dea1314fc44e..70ff1e46717d 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
@@ -65,8 +65,7 @@ void etnaviv_iommu_destroy(struct etnaviv_iommu *iommu);
size_t etnaviv_iommu_dump_size(struct etnaviv_iommu *iommu);
void etnaviv_iommu_dump(struct etnaviv_iommu *iommu, void *buf);
-struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu,
- struct iommu_domain *domain, enum etnaviv_iommu_version version);
+struct etnaviv_iommu *etnaviv_iommu_new(struct etnaviv_gpu *gpu);
void etnaviv_iommu_restore(struct etnaviv_gpu *gpu);
#endif /* __ETNAVIV_MMU_H__ */
OpenPOWER on IntegriCloud