summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-10-31 20:56:19 +0300
committerBen Skeggs <bskeggs@redhat.com>2017-11-02 06:32:18 +0300
commite988952eefd923a40cea1077bcb939025dafb0f1 (patch)
tree6791d80c4d08434c0dcc63acb1417141dace5245
parent48fe02478a0ddb89930f3595f8217fa2dfd98796 (diff)
downloadlinux-e988952eefd923a40cea1077bcb939025dafb0f1.tar.xz
drm/nouveau/bar: expose interface to bar2 teardown
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>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h2
6 files changed, 29 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
index eb9ad379f9e1..11427d3d6173 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
@@ -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 *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
index b55ab7183cb9..b495f7796fa3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
@@ -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;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
index 912c8194e1d9..dce74e0d2591 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c
@@ -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,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
index 7504450972fa..13d5a04f41df 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -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,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
index d6d9a1d09722..8d3f7ac42e02 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
@@ -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,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
index 8c9c897dec5d..9b1c360d62ec 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
@@ -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