From 3fd946104a39ce20a0652bfe39191d39e4a8bc56 Mon Sep 17 00:00:00 2001
From: Rob Herring <robh@kernel.org>
Date: Tue, 19 Feb 2019 12:31:23 -0600
Subject: [PATCH] drm/panfrost: fix prime import

On a prime import, we need to map the buffer into the gpu address space,
and only non-imported GEM objects should have their pages put.

These changes keep kmscube from hanging on exit.

Signed-off-by: Rob Herring <robh@kernel.org>
---
 drivers/gpu/drm/panfrost/panfrost_drv.c |  2 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c | 19 +++++++++++++++++--
 drivers/gpu/drm/panfrost/panfrost_gem.h |  5 +++++
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index c0b9cac65a40a..525bb979e657e 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -264,7 +264,7 @@ static struct drm_driver panfrost_drm_driver = {
 	.gem_create_object	= panfrost_gem_create_object,
 	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
-	.gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
+	.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
 	.gem_prime_mmap		= drm_gem_prime_mmap,
 };
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 3b208173e656a..6ca69a4966f89 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -36,10 +36,11 @@ void panfrost_gem_free_object(struct drm_gem_object *obj)
 	struct panfrost_gem_object *bo = to_panfrost_bo(obj);
 	struct panfrost_device *pfdev = obj->dev->dev_private;
 
-	drm_gem_shmem_put_pages(&bo->base);
 	panfrost_mmu_unmap(bo);
 
-	//panfrost_mmu_remove_ptes(bo);
+	if (!obj->import_attach)
+		drm_gem_shmem_put_pages(&bo->base);
+
 	spin_lock(&pfdev->mm_lock);
 	drm_mm_remove_node(&bo->node);
 	spin_unlock(&pfdev->mm_lock);
@@ -92,6 +93,20 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
 	return ERR_PTR(ret);
 }
 
+struct drm_gem_object *
+panfrost_gem_prime_import_sg_table(struct drm_device *dev,
+				   struct dma_buf_attachment *attach,
+				   struct sg_table *sgt)
+{
+	struct drm_gem_object *obj;
+
+	obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt);
+
+	panfrost_mmu_map(to_panfrost_bo(obj));
+
+	return obj;
+}
+
 int panfrost_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout)
 {
 	bool write = !!(op & ETNA_PREP_WRITE);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
index 6ea0d12fe24ae..e90a39a060b53 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -80,6 +80,11 @@ struct panfrost_gem_submit {
 
 struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size);
 
+struct drm_gem_object *
+panfrost_gem_prime_import_sg_table(struct drm_device *dev,
+				   struct dma_buf_attachment *attach,
+				   struct sg_table *sgt);
+
 void panfrost_submit_put(struct panfrost_gem_submit * submit);
 
 int panfrost_gem_wait_bo(struct panfrost_gpu *gpu, struct drm_gem_object *obj,
-- 
GitLab