drm/nouveau/bar: implement bar1 teardown
authorBen Skeggs <bskeggs@redhat.com>
Tue, 31 Oct 2017 17:56:19 +0000 (03:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 2 Nov 2017 03:32:18 +0000 (13:32 +1000)
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>
drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/gk20a.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h

index adaf91e..0fee5e0 100644 (file)
@@ -45,6 +45,14 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma)
        return bar->func->umap(bar, size, type, vma);
 }
 
+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)
 {
@@ -74,6 +82,7 @@ nvkm_bar = {
        .dtor = nvkm_bar_dtor,
        .oneinit = nvkm_bar_oneinit,
        .init = nvkm_bar_init,
+       .fini = nvkm_bar_fini,
 };
 
 void
index dee1cd9..0b63f22 100644 (file)
@@ -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,
index fc3d771..fb57c01 100644 (file)
@@ -49,6 +49,12 @@ gf100_bar_bar1_wait(struct nvkm_bar *base)
        nvkm_bar_flush(base);
 }
 
+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)
 {
@@ -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,
index 86aca93..ab4664b 100644 (file)
@@ -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,
index 8cb8e72..c977612 100644 (file)
@@ -62,6 +62,12 @@ nv50_bar_bar1_wait(struct nvkm_bar *base)
        nvkm_bar_flush(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)
 {
@@ -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,
index 8b50837..d130aab 100644 (file)
@@ -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