Blob Blame History Raw
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 1 Nov 2017 03:56:19 +1000
Subject: drm/nouveau/bar: implement bar1 teardown
Git-commit: bbb163e18960a90b0c5974fe448ad78a5df8e5d7
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Will prevent spurious MMU fault interrupts if something decides to touch
BAR1 after we've unloaded the driver.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c  |    9 +++++++++
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c   |    1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c |    7 +++++++
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c |    1 +
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c  |    7 +++++++
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h  |    5 +++++
 6 files changed, 30 insertions(+)

--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
@@ -46,6 +46,14 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64
 }
 
 static int
+nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
+{
+	struct nvkm_bar *bar = nvkm_bar(subdev);
+	bar->func->bar1.fini(bar);
+	return 0;
+}
+
+static int
 nvkm_bar_init(struct nvkm_subdev *subdev)
 {
 	struct nvkm_bar *bar = nvkm_bar(subdev);
@@ -74,6 +82,7 @@ nvkm_bar = {
 	.dtor = nvkm_bar_dtor,
 	.oneinit = nvkm_bar_oneinit,
 	.init = nvkm_bar_init,
+	.fini = nvkm_bar_fini,
 };
 
 void
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
@@ -45,6 +45,7 @@ g84_bar_func = {
 	.oneinit = nv50_bar_oneinit,
 	.init = nv50_bar_init,
 	.bar1.init = nv50_bar_bar1_init,
+	.bar1.fini = nv50_bar_bar1_fini,
 	.bar1.wait = nv50_bar_bar1_wait,
 	.kmap = nv50_bar_kmap,
 	.umap = nv50_bar_umap,
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -50,6 +50,12 @@ gf100_bar_bar1_wait(struct nvkm_bar *bas
 }
 
 void
+gf100_bar_bar1_fini(struct nvkm_bar *bar)
+{
+	nvkm_mask(bar->subdev.device, 0x001704, 0x80000000, 0x00000000);
+}
+
+void
 gf100_bar_bar1_init(struct nvkm_bar *base)
 {
 	struct nvkm_device *device = base->subdev.device;
@@ -186,6 +192,7 @@ gf100_bar_func = {
 	.oneinit = gf100_bar_oneinit,
 	.init = gf100_bar_init,
 	.bar1.init = gf100_bar_bar1_init,
+	.bar1.fini = gf100_bar_bar1_fini,
 	.bar1.wait = gf100_bar_bar1_wait,
 	.kmap = gf100_bar_kmap,
 	.umap = gf100_bar_umap,
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c
@@ -26,6 +26,7 @@ gk20a_bar_func = {
 	.dtor = gf100_bar_dtor,
 	.oneinit = gf100_bar_oneinit,
 	.bar1.init = gf100_bar_bar1_init,
+	.bar1.fini = gf100_bar_bar1_fini,
 	.bar1.wait = gf100_bar_bar1_wait,
 	.umap = gf100_bar_umap,
 	.flush = g84_bar_flush,
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
@@ -63,6 +63,12 @@ nv50_bar_bar1_wait(struct nvkm_bar *base
 }
 
 void
+nv50_bar_bar1_fini(struct nvkm_bar *bar)
+{
+	nvkm_wr32(bar->subdev.device, 0x001708, 0x00000000);
+}
+
+void
 nv50_bar_bar1_init(struct nvkm_bar *base)
 {
 	struct nvkm_device *device = base->subdev.device;
@@ -208,6 +214,7 @@ nv50_bar_func = {
 	.oneinit = nv50_bar_oneinit,
 	.init = nv50_bar_init,
 	.bar1.init = nv50_bar_bar1_init,
+	.bar1.fini = nv50_bar_bar1_fini,
 	.bar1.wait = nv50_bar_bar1_wait,
 	.kmap = nv50_bar_kmap,
 	.umap = nv50_bar_umap,
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
@@ -13,6 +13,7 @@ struct nvkm_bar_func {
 
 	struct {
 		void (*init)(struct nvkm_bar *);
+		void (*fini)(struct nvkm_bar *);
 		void (*wait)(struct nvkm_bar *);
 	} bar1;
 
@@ -21,5 +22,9 @@ struct nvkm_bar_func {
 	void (*flush)(struct nvkm_bar *);
 };
 
+void nv50_bar_bar1_fini(struct nvkm_bar *);
+
 void g84_bar_flush(struct nvkm_bar *);
+
+void gf100_bar_bar1_fini(struct nvkm_bar *);
 #endif