Blob Blame History Raw
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 1 Nov 2017 03:56:19 +1000
Subject: drm/nouveau/imem: separate pre-BAR2-bootstrap objects from the rest
Git-commit: b00b8430468d2922c5ea9a0557c7a36136df98c2
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

These will require slow-path access during suspend/resume.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h |    1 
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c    |   27 ++++++++++++++++++
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c    |    1 
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h    |    1 
 4 files changed, 30 insertions(+)

--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -9,6 +9,7 @@ struct nvkm_instmem {
 
 	spinlock_t lock;
 	struct list_head list;
+	struct list_head boot;
 	u32 reserved;
 
 	struct nvkm_memory *vbios;
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -129,6 +129,21 @@ nvkm_instmem_wr32(struct nvkm_instmem *i
 	return imem->func->wr32(imem, addr, data);
 }
 
+void
+nvkm_instmem_boot(struct nvkm_instmem *imem)
+{
+	/* Separate bootstrapped objects from normal list, as we need
+	 * to make sure they're accessed with the slowpath on suspend
+	 * and resume.
+	 */
+	struct nvkm_instobj *iobj, *itmp;
+	spin_lock(&imem->lock);
+	list_for_each_entry_safe(iobj, itmp, &imem->list, head) {
+		list_move_tail(&iobj->head, &imem->boot);
+	}
+	spin_unlock(&imem->lock);
+}
+
 static int
 nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
 {
@@ -141,6 +156,12 @@ nvkm_instmem_fini(struct nvkm_subdev *su
 			if (ret)
 				return ret;
 		}
+
+		list_for_each_entry(iobj, &imem->boot, head) {
+			int ret = nvkm_instobj_save(iobj);
+			if (ret)
+				return ret;
+		}
 	}
 
 	if (imem->func->fini)
@@ -155,6 +176,11 @@ nvkm_instmem_init(struct nvkm_subdev *su
 	struct nvkm_instmem *imem = nvkm_instmem(subdev);
 	struct nvkm_instobj *iobj;
 
+	list_for_each_entry(iobj, &imem->boot, head) {
+		if (iobj->suspend)
+			nvkm_instobj_load(iobj);
+	}
+
 	list_for_each_entry(iobj, &imem->list, head) {
 		if (iobj->suspend)
 			nvkm_instobj_load(iobj);
@@ -198,4 +224,5 @@ nvkm_instmem_ctor(const struct nvkm_inst
 	imem->func = func;
 	spin_lock_init(&imem->lock);
 	INIT_LIST_HEAD(&imem->list);
+	INIT_LIST_HEAD(&imem->boot);
 }
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -271,6 +271,7 @@ nv50_instobj_boot(struct nvkm_memory *me
 	}
 
 	nv50_instobj_kmap(iobj, vmm);
+	nvkm_instmem_boot(imem);
 	mutex_unlock(&imem->subdev.mutex);
 }
 
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
@@ -16,6 +16,7 @@ struct nvkm_instmem_func {
 
 void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *,
 		       int index, struct nvkm_instmem *);
+void nvkm_instmem_boot(struct nvkm_instmem *);
 
 #include <core/memory.h>