Commit 48fe0247 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/bar: expose interface to bar2 initialisation

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent bbb163e1
...@@ -8,11 +8,13 @@ struct nvkm_bar { ...@@ -8,11 +8,13 @@ struct nvkm_bar {
struct nvkm_subdev subdev; struct nvkm_subdev subdev;
spinlock_t lock; spinlock_t lock;
bool bar2;
/* whether the BAR supports to be ioremapped WC or should be uncached */ /* whether the BAR supports to be ioremapped WC or should be uncached */
bool iomap_uncached; bool iomap_uncached;
}; };
void nvkm_bar_bar2_init(struct nvkm_device *);
void nvkm_bar_flush(struct nvkm_bar *); void nvkm_bar_flush(struct nvkm_bar *);
struct nvkm_vm *nvkm_bar_kmap(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 *); int nvkm_bar_umap(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *);
......
...@@ -45,11 +45,23 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma) ...@@ -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); 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 static int
nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend) nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
{ {
struct nvkm_bar *bar = nvkm_bar(subdev); struct nvkm_bar *bar = nvkm_bar(subdev);
bar->func->bar1.fini(bar); bar->func->bar1.fini(bar);
bar->bar2 = false;
return 0; return 0;
} }
...@@ -57,9 +69,11 @@ static int ...@@ -57,9 +69,11 @@ static int
nvkm_bar_init(struct nvkm_subdev *subdev) nvkm_bar_init(struct nvkm_subdev *subdev)
{ {
struct nvkm_bar *bar = nvkm_bar(subdev); struct nvkm_bar *bar = nvkm_bar(subdev);
nvkm_bar_bar2_init(subdev->device);
bar->func->bar1.init(bar); bar->func->bar1.init(bar);
bar->func->bar1.wait(bar); bar->func->bar1.wait(bar);
bar->func->init(bar); if (bar->func->init)
bar->func->init(bar);
return 0; return 0;
} }
......
...@@ -47,6 +47,8 @@ g84_bar_func = { ...@@ -47,6 +47,8 @@ g84_bar_func = {
.bar1.init = nv50_bar_bar1_init, .bar1.init = nv50_bar_bar1_init,
.bar1.fini = nv50_bar_bar1_fini, .bar1.fini = nv50_bar_bar1_fini,
.bar1.wait = nv50_bar_bar1_wait, .bar1.wait = nv50_bar_bar1_wait,
.bar2.init = nv50_bar_bar2_init,
.bar2.wait = nv50_bar_bar1_wait,
.kmap = nv50_bar_kmap, .kmap = nv50_bar_kmap,
.umap = nv50_bar_umap, .umap = nv50_bar_umap,
.flush = g84_bar_flush, .flush = g84_bar_flush,
......
...@@ -65,18 +65,14 @@ gf100_bar_bar1_init(struct nvkm_bar *base) ...@@ -65,18 +65,14 @@ gf100_bar_bar1_init(struct nvkm_bar *base)
} }
void 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 gf100_bar *bar = gf100_bar(base);
struct nvkm_device *device = bar->base.subdev.device; u32 addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
u32 addr; if (bar->bar2_halve)
addr |= 0x40000000;
if (bar->bar[0].mem) { nvkm_wr32(device, 0x001714, 0x80000000 | addr);
addr = nvkm_memory_addr(bar->bar[0].mem) >> 12;
if (bar->bar2_halve)
addr |= 0x40000000;
nvkm_wr32(device, 0x001714, 0x80000000 | addr);
}
} }
static int static int
...@@ -190,10 +186,11 @@ static const struct nvkm_bar_func ...@@ -190,10 +186,11 @@ static const struct nvkm_bar_func
gf100_bar_func = { gf100_bar_func = {
.dtor = gf100_bar_dtor, .dtor = gf100_bar_dtor,
.oneinit = gf100_bar_oneinit, .oneinit = gf100_bar_oneinit,
.init = gf100_bar_init,
.bar1.init = gf100_bar_bar1_init, .bar1.init = gf100_bar_bar1_init,
.bar1.fini = gf100_bar_bar1_fini, .bar1.fini = gf100_bar_bar1_fini,
.bar1.wait = gf100_bar_bar1_wait, .bar1.wait = gf100_bar_bar1_wait,
.bar2.init = gf100_bar_bar2_init,
.bar2.wait = gf100_bar_bar1_wait,
.kmap = gf100_bar_kmap, .kmap = gf100_bar_kmap,
.umap = gf100_bar_umap, .umap = gf100_bar_umap,
.flush = g84_bar_flush, .flush = g84_bar_flush,
......
...@@ -19,8 +19,8 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *, ...@@ -19,8 +19,8 @@ int gf100_bar_new_(const struct nvkm_bar_func *, struct nvkm_device *,
int, struct nvkm_bar **); int, struct nvkm_bar **);
void *gf100_bar_dtor(struct nvkm_bar *); void *gf100_bar_dtor(struct nvkm_bar *);
int gf100_bar_oneinit(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_init(struct nvkm_bar *);
void gf100_bar_bar1_wait(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 *); int gf100_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *);
#endif #endif
...@@ -76,6 +76,16 @@ nv50_bar_bar1_init(struct nvkm_bar *base) ...@@ -76,6 +76,16 @@ nv50_bar_bar1_init(struct nvkm_bar *base)
nvkm_wr32(device, 0x001708, 0x80000000 | bar->bar1->node->offset >> 4); 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 void
nv50_bar_init(struct nvkm_bar *base) nv50_bar_init(struct nvkm_bar *base)
{ {
...@@ -83,9 +93,6 @@ 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; struct nvkm_device *device = bar->base.subdev.device;
int i; 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++) for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000); nvkm_wr32(device, 0x001900 + (i * 4), 0x00000000);
} }
...@@ -216,6 +223,8 @@ nv50_bar_func = { ...@@ -216,6 +223,8 @@ nv50_bar_func = {
.bar1.init = nv50_bar_bar1_init, .bar1.init = nv50_bar_bar1_init,
.bar1.fini = nv50_bar_bar1_fini, .bar1.fini = nv50_bar_bar1_fini,
.bar1.wait = nv50_bar_bar1_wait, .bar1.wait = nv50_bar_bar1_wait,
.bar2.init = nv50_bar_bar2_init,
.bar2.wait = nv50_bar_bar1_wait,
.kmap = nv50_bar_kmap, .kmap = nv50_bar_kmap,
.umap = nv50_bar_umap, .umap = nv50_bar_umap,
.flush = nv50_bar_flush, .flush = nv50_bar_flush,
......
...@@ -22,6 +22,7 @@ int nv50_bar_oneinit(struct nvkm_bar *); ...@@ -22,6 +22,7 @@ int nv50_bar_oneinit(struct nvkm_bar *);
void nv50_bar_init(struct nvkm_bar *); void nv50_bar_init(struct nvkm_bar *);
void nv50_bar_bar1_init(struct nvkm_bar *); void nv50_bar_bar1_init(struct nvkm_bar *);
void nv50_bar_bar1_wait(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 *); struct nvkm_vm *nv50_bar_kmap(struct nvkm_bar *);
int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *); int nv50_bar_umap(struct nvkm_bar *, u64, int, struct nvkm_vma *);
void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *); void nv50_bar_unmap(struct nvkm_bar *, struct nvkm_vma *);
......
...@@ -15,7 +15,7 @@ struct nvkm_bar_func { ...@@ -15,7 +15,7 @@ struct nvkm_bar_func {
void (*init)(struct nvkm_bar *); void (*init)(struct nvkm_bar *);
void (*fini)(struct nvkm_bar *); void (*fini)(struct nvkm_bar *);
void (*wait)(struct nvkm_bar *); void (*wait)(struct nvkm_bar *);
} bar1; } bar1, bar2;
struct nvkm_vm *(*kmap)(struct nvkm_bar *); struct nvkm_vm *(*kmap)(struct nvkm_bar *);
int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *); int (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment