Commit c73baa83 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fb/gf100-: allow selection of an alternate big page size

GFxxx/GM1xx support the selection of 64/128KiB big pages globally.

GM2xx supports the same, as well as another mode where the page size
can be selected per-instance.

We default to 128KiB pages (With per-instance for GM200, but the current
code selects 128KiB there already) as the MMU code isn't currently able
to handle otherwise.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2100292c
...@@ -56,6 +56,8 @@ struct nvkm_fb { ...@@ -56,6 +56,8 @@ struct nvkm_fb {
int regions; int regions;
} tile; } tile;
u8 page;
struct nvkm_memory *mmu_rd; struct nvkm_memory *mmu_rd;
struct nvkm_memory *mmu_wr; struct nvkm_memory *mmu_wr;
}; };
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "ram.h" #include "ram.h"
#include <core/memory.h> #include <core/memory.h>
#include <core/option.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/M0203.h> #include <subdev/bios/M0203.h>
#include <engine/gr.h> #include <engine/gr.h>
...@@ -134,6 +135,8 @@ nvkm_fb_init(struct nvkm_subdev *subdev) ...@@ -134,6 +135,8 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
if (fb->func->init) if (fb->func->init)
fb->func->init(fb); fb->func->init(fb);
if (fb->func->init_page)
fb->func->init_page(fb);
return 0; return 0;
} }
...@@ -171,6 +174,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, ...@@ -171,6 +174,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device,
nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev); nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev);
fb->func = func; fb->func = func;
fb->tile.regions = fb->func->tile.regions; fb->tile.regions = fb->func->tile.regions;
fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage", 0);
} }
int int
......
...@@ -71,6 +71,22 @@ gf100_fb_oneinit(struct nvkm_fb *fb) ...@@ -71,6 +71,22 @@ gf100_fb_oneinit(struct nvkm_fb *fb)
return 0; return 0;
} }
void
gf100_fb_init_page(struct nvkm_fb *fb)
{
struct nvkm_device *device = fb->subdev.device;
switch (fb->page) {
case 16:
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000001);
break;
case 17:
default:
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000);
fb->page = 17;
break;
}
}
void void
gf100_fb_init(struct nvkm_fb *base) gf100_fb_init(struct nvkm_fb *base)
{ {
...@@ -79,8 +95,6 @@ gf100_fb_init(struct nvkm_fb *base) ...@@ -79,8 +95,6 @@ gf100_fb_init(struct nvkm_fb *base)
if (fb->r100c10_page) if (fb->r100c10_page)
nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8); nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8);
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
} }
void * void *
...@@ -125,6 +139,7 @@ gf100_fb = { ...@@ -125,6 +139,7 @@ gf100_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init, .init = gf100_fb_init,
.init_page = gf100_fb_init_page,
.intr = gf100_fb_intr, .intr = gf100_fb_intr,
.ram_new = gf100_ram_new, .ram_new = gf100_ram_new,
.memtype_valid = gf100_fb_memtype_valid, .memtype_valid = gf100_fb_memtype_valid,
......
...@@ -29,6 +29,7 @@ gk104_fb = { ...@@ -29,6 +29,7 @@ gk104_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init, .init = gf100_fb_init,
.init_page = gf100_fb_init_page,
.intr = gf100_fb_intr, .intr = gf100_fb_intr,
.ram_new = gk104_ram_new, .ram_new = gk104_ram_new,
.memtype_valid = gf100_fb_memtype_valid, .memtype_valid = gf100_fb_memtype_valid,
......
...@@ -27,7 +27,6 @@ static void ...@@ -27,7 +27,6 @@ static void
gk20a_fb_init(struct nvkm_fb *fb) gk20a_fb_init(struct nvkm_fb *fb)
{ {
struct nvkm_device *device = fb->subdev.device; struct nvkm_device *device = fb->subdev.device;
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8); nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8);
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8); nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8);
} }
...@@ -36,6 +35,7 @@ static const struct nvkm_fb_func ...@@ -36,6 +35,7 @@ static const struct nvkm_fb_func
gk20a_fb = { gk20a_fb = {
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gk20a_fb_init, .init = gk20a_fb_init,
.init_page = gf100_fb_init_page,
.memtype_valid = gf100_fb_memtype_valid, .memtype_valid = gf100_fb_memtype_valid,
}; };
......
...@@ -29,6 +29,7 @@ gm107_fb = { ...@@ -29,6 +29,7 @@ gm107_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init, .init = gf100_fb_init,
.init_page = gf100_fb_init_page,
.intr = gf100_fb_intr, .intr = gf100_fb_intr,
.ram_new = gm107_ram_new, .ram_new = gm107_ram_new,
.memtype_valid = gf100_fb_memtype_valid, .memtype_valid = gf100_fb_memtype_valid,
......
...@@ -26,6 +26,24 @@ ...@@ -26,6 +26,24 @@
#include <core/memory.h> #include <core/memory.h>
static void
gm200_fb_init_page(struct nvkm_fb *fb)
{
struct nvkm_device *device = fb->subdev.device;
switch (fb->page) {
case 16:
nvkm_mask(device, 0x100c80, 0x00000801, 0x00000001);
break;
case 17:
nvkm_mask(device, 0x100c80, 0x00000801, 0x00000000);
break;
default:
nvkm_mask(device, 0x100c80, 0x00000800, 0x00000800);
fb->page = 0;
break;
}
}
static void static void
gm200_fb_init(struct nvkm_fb *base) gm200_fb_init(struct nvkm_fb *base)
{ {
...@@ -48,6 +66,7 @@ gm200_fb = { ...@@ -48,6 +66,7 @@ gm200_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gm200_fb_init, .init = gm200_fb_init,
.init_page = gm200_fb_init_page,
.intr = gf100_fb_intr, .intr = gf100_fb_intr,
.ram_new = gm107_ram_new, .ram_new = gm107_ram_new,
.memtype_valid = gf100_fb_memtype_valid, .memtype_valid = gf100_fb_memtype_valid,
......
...@@ -8,6 +8,7 @@ struct nvkm_fb_func { ...@@ -8,6 +8,7 @@ struct nvkm_fb_func {
void *(*dtor)(struct nvkm_fb *); void *(*dtor)(struct nvkm_fb *);
int (*oneinit)(struct nvkm_fb *); int (*oneinit)(struct nvkm_fb *);
void (*init)(struct nvkm_fb *); void (*init)(struct nvkm_fb *);
void (*init_page)(struct nvkm_fb *);
void (*intr)(struct nvkm_fb *); void (*intr)(struct nvkm_fb *);
struct { struct {
...@@ -60,5 +61,6 @@ void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, ...@@ -60,5 +61,6 @@ void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nvkm_fb_tile *); u32 pitch, u32 flags, struct nvkm_fb_tile *);
int gf100_fb_oneinit(struct nvkm_fb *); int gf100_fb_oneinit(struct nvkm_fb *);
void gf100_fb_init_page(struct nvkm_fb *);
bool gf100_fb_memtype_valid(struct nvkm_fb *, u32); bool gf100_fb_memtype_valid(struct nvkm_fb *, u32);
#endif #endif
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