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 eb9ad379f9e11e20984f49872ea846b12e645ce9..11427d3d617386bd91cef54ac4ff41e6116cba34 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 b55ab7183cb92acec2247568b547d55da46330c6..b495f7796fa3d93be7674b61c81cb9c6612c0f3f 100644 (file)
@@ -45,6 +45,16 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma)
        return bar->func->umap(bar, size, type, 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)
 {
@@ -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 912c8194e1d9e9f432a566ac23744b74da9799e8..dce74e0d2591f61639fb55b2e044f59e35115fa6 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 7504450972faab98e761b15876fdbe961928c161..13d5a04f41dfccbca3564f19761d420c911dbe55 100644 (file)
@@ -64,6 +64,12 @@ gf100_bar_bar1_init(struct nvkm_bar *base)
        nvkm_wr32(device, 0x001704, 0x80000000 | addr);
 }
 
+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)
 {
@@ -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 d6d9a1d0972261ff620f1bb860374d9f8c50249a..8d3f7ac42e02396a1a4dd89a1993a4019c8be806 100644 (file)
@@ -76,6 +76,12 @@ nv50_bar_bar1_init(struct nvkm_bar *base)
        nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4);
 }
 
+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)
 {
@@ -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 8c9c897dec5d853c60b561d4d1c904c154fb856b..9b1c360d62ec981f707c3aa7adae7f298ab15434 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