drm/nouveau/bar: expose interface to bar2 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.

Exposed external to BAR so that INSTMEM can use it to better control the
suspend/resume fast-path access.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
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/nv50.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h

index eb9ad37..11427d3 100644 (file)
@@ -15,6 +15,7 @@ struct nvkm_bar {
 };
 
 void nvkm_bar_bar2_init(struct nvkm_device *);
+void nvkm_bar_bar2_fini(struct nvkm_device *);
 void nvkm_bar_flush(struct nvkm_bar *);
 struct nvkm_vm *nvkm_bar_kmap(struct nvkm_bar *);
 int nvkm_bar_umap(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *);
index b55ab71..b495f77 100644 (file)
@@ -46,6 +46,16 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma)
 }
 
 void
+nvkm_bar_bar2_fini(struct nvkm_device *device)
+{
+       struct nvkm_bar *bar = device->bar;
+       if (bar && bar->bar2) {
+               bar->func->bar2.fini(bar);
+               bar->bar2 = false;
+       }
+}
+
+void
 nvkm_bar_bar2_init(struct nvkm_device *device)
 {
        struct nvkm_bar *bar = device->bar;
@@ -61,7 +71,7 @@ nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
 {
        struct nvkm_bar *bar = nvkm_bar(subdev);
        bar->func->bar1.fini(bar);
-       bar->bar2 = false;
+       nvkm_bar_bar2_fini(subdev->device);
        return 0;
 }
 
index 912c819..dce74e0 100644 (file)
@@ -48,6 +48,7 @@ g84_bar_func = {
        .bar1.fini = nv50_bar_bar1_fini,
        .bar1.wait = nv50_bar_bar1_wait,
        .bar2.init = nv50_bar_bar2_init,
+       .bar2.fini = nv50_bar_bar2_fini,
        .bar2.wait = nv50_bar_bar1_wait,
        .kmap = nv50_bar_kmap,
        .umap = nv50_bar_umap,
index 7504450..13d5a04 100644 (file)
@@ -65,6 +65,12 @@ gf100_bar_bar1_init(struct nvkm_bar *base)
 }
 
 void
+gf100_bar_bar2_fini(struct nvkm_bar *bar)
+{
+       nvkm_mask(bar->subdev.device, 0x001714, 0x80000000, 0x00000000);
+}
+
+void
 gf100_bar_bar2_init(struct nvkm_bar *base)
 {
        struct nvkm_device *device = base->subdev.device;
@@ -190,6 +196,7 @@ gf100_bar_func = {
        .bar1.fini = gf100_bar_bar1_fini,
        .bar1.wait = gf100_bar_bar1_wait,
        .bar2.init = gf100_bar_bar2_init,
+       .bar2.fini = gf100_bar_bar2_fini,
        .bar2.wait = gf100_bar_bar1_wait,
        .kmap = gf100_bar_kmap,
        .umap = gf100_bar_umap,
index d6d9a1d..8d3f7ac 100644 (file)
@@ -77,6 +77,12 @@ nv50_bar_bar1_init(struct nvkm_bar *base)
 }
 
 void
+nv50_bar_bar2_fini(struct nvkm_bar *bar)
+{
+       nvkm_wr32(bar->subdev.device, 0x00170c, 0x00000000);
+}
+
+void
 nv50_bar_bar2_init(struct nvkm_bar *base)
 {
        struct nvkm_device *device = base->subdev.device;
@@ -224,6 +230,7 @@ nv50_bar_func = {
        .bar1.fini = nv50_bar_bar1_fini,
        .bar1.wait = nv50_bar_bar1_wait,
        .bar2.init = nv50_bar_bar2_init,
+       .bar2.fini = nv50_bar_bar2_fini,
        .bar2.wait = nv50_bar_bar1_wait,
        .kmap = nv50_bar_kmap,
        .umap = nv50_bar_umap,
index 8c9c897..9b1c360 100644 (file)
@@ -23,8 +23,10 @@ struct nvkm_bar_func {
 };
 
 void nv50_bar_bar1_fini(struct nvkm_bar *);
+void nv50_bar_bar2_fini(struct nvkm_bar *);
 
 void g84_bar_flush(struct nvkm_bar *);
 
 void gf100_bar_bar1_fini(struct nvkm_bar *);
+void gf100_bar_bar2_fini(struct nvkm_bar *);
 #endif