drm/nouveau/bar: expose interface to bar2 initialisation
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)
If we want to be able to hit the instmem fast-path in a few trickier cases,
we need to be more flexible with when we can initialise BAR2 access.

There's probably a decent case to be made for merging BAR/INSTMEM into BUS,
but that's something to ponder another day.

Flushes have been added after the write to bind the instance block,
as later commits will reveal the need for them.

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/gf100.h
drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h
drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h

index d3071b5a4f98202d9f4ac3df560eead182f3494d..eb9ad379f9e11e20984f49872ea846b12e645ce9 100644 (file)
@@ -8,11 +8,13 @@ struct nvkm_bar {
        struct nvkm_subdev subdev;
 
        spinlock_t lock;
+       bool bar2;
 
        /* whether the BAR supports to be ioremapped WC or should be uncached */
        bool iomap_uncached;
 };
 
+void nvkm_bar_bar2_init(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 0fee5e0a090e8a2dff7ba663df101f557f191e6e..b55ab7183cb92acec2247568b547d55da46330c6 100644 (file)
@@ -45,11 +45,23 @@ 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_init(struct nvkm_device *device)
+{
+       struct nvkm_bar *bar = device->bar;
+       if (bar && bar->subdev.oneinit && !bar->bar2 && bar->func->bar2.init) {
+               bar->func->bar2.init(bar);
+               bar->func->bar2.wait(bar);
+               bar->bar2 = true;
+       }
+}
+
 static int
 nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
 {
        struct nvkm_bar *bar = nvkm_bar(subdev);
        bar->func->bar1.fini(bar);
+       bar->bar2 = false;
        return 0;
 }
 
@@ -57,9 +69,11 @@ static int
 nvkm_bar_init(struct nvkm_subdev *subdev)
 {
        struct nvkm_bar *bar = nvkm_bar(subdev);
+       nvkm_bar_bar2_init(subdev->device);
        bar->func->bar1.init(bar);
        bar->func->bar1.wait(bar);
-       bar->func->init(bar);
+       if (bar->func->init)
+               bar->func->init(bar);
        return 0;
 }
 
index 0b63f224fa26f6c00f7426c03e74ac59d685f47f..912c8194e1d9e9f432a566ac23744b74da9799e8 100644 (file)
@@ -47,6 +47,8 @@ g84_bar_func = {
        .bar1.init = nv50_bar_bar1_init,
        .bar1.fini = nv50_bar_bar1_fini,
        .bar1.wait = nv50_bar_bar1_wait,
+       .bar2.init = nv50_bar_bar2_init,
+       .bar2.wait = nv50_bar_bar1_wait,
        .kmap = nv50_bar_kmap,
        .umap = nv50_bar_umap,
        .flush = g84_bar_flush,
index fb57c0175e575656c43410aa6910e35f738cd246..7504450972faab98e761b15876fdbe961928c161 100644 (file)
@@ -65,18 +65,14 @@ gf100_bar_bar1_init(struct nvkm_bar *base)
 }
 
 void
-gf100_bar_init(struct nvkm_bar *base)
+gf100_bar_bar2_init(struct nvkm_bar *base)
 {
+       struct nvkm_device *device = base->subdev.device;
        struct gf100_bar *bar = gf100_bar(base);
-       struct nvkm_device *device = bar->base.subdev.device;
-       u32 addr;
-
-       if (bar->bar[0].mem) {
-               addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
-               if (bar->bar2_halve)
-                       addr |= 0x40000000;
-               nvkm_wr32(device, 0x001714, 0x80000000 | addr);
-       }
+       u32 addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
+       if (bar->bar2_halve)
+               addr |= 0x40000000;
+       nvkm_wr32(device, 0x001714, 0x80000000 | addr);
 }
 
 static int
@@ -190,10 +186,11 @@ static const struct nvkm_bar_func
 gf100_bar_func = {
        .dtor = gf100_bar_dtor,
        .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,
+       .bar2.init = gf100_bar_bar2_init,
+       .bar2.wait = gf100_bar_bar1_wait,
        .kmap = gf100_bar_kmap,
        .umap = gf100_bar_umap,
        .flush = g84_bar_flush,
index 9b994eaad1e5d036b6442c8c9287582280451f75..393116a7398acbd8d0f17b888e37920c4c2923d0 100644 (file)
@@ -19,8 +19,8 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *,
                   int, struct nvkm_bar **);
 void *gf100_bar_dtor(struct nvkm_bar *);
 int gf100_bar_oneinit(struct nvkm_bar *);
-void gf100_bar_init(struct nvkm_bar *);
 void gf100_bar_bar1_init(struct nvkm_bar *);
 void gf100_bar_bar1_wait(struct nvkm_bar *);
+void gf100_bar_bar2_init(struct nvkm_bar *);
 int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *);
 #endif
index c9776121a076d20efcf9a18cc42e32e0a8a0b3ec..d6d9a1d0972261ff620f1bb860374d9f8c50249a 100644 (file)
@@ -76,6 +76,16 @@ nv50_bar_bar1_init(struct nvkm_bar *base)
        nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4);
 }
 
+void
+nv50_bar_bar2_init(struct nvkm_bar *base)
+{
+       struct nvkm_device *device = base->subdev.device;
+       struct nv50_bar *bar = nv50_bar(base);
+       nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12);
+       nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12);
+       nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4);
+}
+
 void
 nv50_bar_init(struct nvkm_bar *base)
 {
@@ -83,9 +93,6 @@ nv50_bar_init(struct nvkm_bar *base)
        struct nvkm_device *device = bar->base.subdev.device;
        int i;
 
-       nvkm_wr32(device, 0x001704, 0x00000000 | bar->mem->addr >> 12);
-       nvkm_wr32(device, 0x001704, 0x40000000 | bar->mem->addr >> 12);
-       nvkm_wr32(device, 0x00170c, 0x80000000 | bar->bar2->node->offset >> 4);
        for (i = 0; i < 8; i++)
                nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000);
 }
@@ -216,6 +223,8 @@ nv50_bar_func = {
        .bar1.init = nv50_bar_bar1_init,
        .bar1.fini = nv50_bar_bar1_fini,
        .bar1.wait = nv50_bar_bar1_wait,
+       .bar2.init = nv50_bar_bar2_init,
+       .bar2.wait = nv50_bar_bar1_wait,
        .kmap = nv50_bar_kmap,
        .umap = nv50_bar_umap,
        .flush = nv50_bar_flush,
index 52971cfd119cbe693806acfc8fca56e9d90e906f..0009ed4344f027ce403a194b532df079394f5dfc 100644 (file)
@@ -22,6 +22,7 @@ int nv50_bar_oneinit(struct nvkm_bar *);
 void nv50_bar_init(struct nvkm_bar *);
 void nv50_bar_bar1_init(struct nvkm_bar *);
 void nv50_bar_bar1_wait(struct nvkm_bar *);
+void nv50_bar_bar2_init(struct nvkm_bar *);
 struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *);
 int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *);
 void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *);
index d130aab01aca7280adf43b9c86712d2d85aa8284..8c9c897dec5d853c60b561d4d1c904c154fb856b 100644 (file)
@@ -15,7 +15,7 @@ struct nvkm_bar_func {
                void (*init)(struct nvkm_bar *);
                void (*fini)(struct nvkm_bar *);
                void (*wait)(struct nvkm_bar *);
-       } bar1;
+       } bar1, bar2;
 
        struct nvkm_vm *(*kmap)(struct nvkm_bar *);
        int  (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *);