diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h index d3071b5a4f98202d9f4ac3df560eead182f3494d..eb9ad379f9e11e20984f49872ea846b12e645ce9 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c index 0fee5e0a090e8a2dff7ba663df101f557f191e6e..b55ab7183cb92acec2247568b547d55da46330c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c @@ -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; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c index 0b63f224fa26f6c00f7426c03e74ac59d685f47f..912c8194e1d9e9f432a566ac23744b74da9799e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/g84.c @@ -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, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index fb57c0175e575656c43410aa6910e35f738cd246..7504450972faab98e761b15876fdbe961928c161 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -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, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index 9b994eaad1e5d036b6442c8c9287582280451f75..393116a7398acbd8d0f17b888e37920c4c2923d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index c9776121a076d20efcf9a18cc42e32e0a8a0b3ec..d6d9a1d0972261ff620f1bb860374d9f8c50249a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -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, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h index 52971cfd119cbe693806acfc8fca56e9d90e906f..0009ed4344f027ce403a194b532df079394f5dfc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h index d130aab01aca7280adf43b9c86712d2d85aa8284..8c9c897dec5d853c60b561d4d1c904c154fb856b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h @@ -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 *);