forked from Minki/linux
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: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
2100292c95
commit
c73baa831f
@ -56,6 +56,8 @@ struct nvkm_fb {
|
||||
int regions;
|
||||
} tile;
|
||||
|
||||
u8 page;
|
||||
|
||||
struct nvkm_memory *mmu_rd;
|
||||
struct nvkm_memory *mmu_wr;
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ram.h"
|
||||
|
||||
#include <core/memory.h>
|
||||
#include <core/option.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bios/M0203.h>
|
||||
#include <engine/gr.h>
|
||||
@ -134,6 +135,8 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
|
||||
|
||||
if (fb->func->init)
|
||||
fb->func->init(fb);
|
||||
if (fb->func->init_page)
|
||||
fb->func->init_page(fb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
fb->func = func;
|
||||
fb->tile.regions = fb->func->tile.regions;
|
||||
fb->page = nvkm_longopt(device->cfgopt, "NvFbBigPage", 0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -71,6 +71,22 @@ gf100_fb_oneinit(struct nvkm_fb *fb)
|
||||
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
|
||||
gf100_fb_init(struct nvkm_fb *base)
|
||||
{
|
||||
@ -79,8 +95,6 @@ gf100_fb_init(struct nvkm_fb *base)
|
||||
|
||||
if (fb->r100c10_page)
|
||||
nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8);
|
||||
|
||||
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
|
||||
}
|
||||
|
||||
void *
|
||||
@ -125,6 +139,7 @@ gf100_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.init = gf100_fb_init,
|
||||
.init_page = gf100_fb_init_page,
|
||||
.intr = gf100_fb_intr,
|
||||
.ram_new = gf100_ram_new,
|
||||
.memtype_valid = gf100_fb_memtype_valid,
|
||||
|
@ -29,6 +29,7 @@ gk104_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.init = gf100_fb_init,
|
||||
.init_page = gf100_fb_init_page,
|
||||
.intr = gf100_fb_intr,
|
||||
.ram_new = gk104_ram_new,
|
||||
.memtype_valid = gf100_fb_memtype_valid,
|
||||
|
@ -27,7 +27,6 @@ static void
|
||||
gk20a_fb_init(struct nvkm_fb *fb)
|
||||
{
|
||||
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, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8);
|
||||
}
|
||||
@ -36,6 +35,7 @@ static const struct nvkm_fb_func
|
||||
gk20a_fb = {
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.init = gk20a_fb_init,
|
||||
.init_page = gf100_fb_init_page,
|
||||
.memtype_valid = gf100_fb_memtype_valid,
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,7 @@ gm107_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.init = gf100_fb_init,
|
||||
.init_page = gf100_fb_init_page,
|
||||
.intr = gf100_fb_intr,
|
||||
.ram_new = gm107_ram_new,
|
||||
.memtype_valid = gf100_fb_memtype_valid,
|
||||
|
@ -26,6 +26,24 @@
|
||||
|
||||
#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
|
||||
gm200_fb_init(struct nvkm_fb *base)
|
||||
{
|
||||
@ -48,6 +66,7 @@ gm200_fb = {
|
||||
.dtor = gf100_fb_dtor,
|
||||
.oneinit = gf100_fb_oneinit,
|
||||
.init = gm200_fb_init,
|
||||
.init_page = gm200_fb_init_page,
|
||||
.intr = gf100_fb_intr,
|
||||
.ram_new = gm107_ram_new,
|
||||
.memtype_valid = gf100_fb_memtype_valid,
|
||||
|
@ -8,6 +8,7 @@ struct nvkm_fb_func {
|
||||
void *(*dtor)(struct nvkm_fb *);
|
||||
int (*oneinit)(struct nvkm_fb *);
|
||||
void (*init)(struct nvkm_fb *);
|
||||
void (*init_page)(struct nvkm_fb *);
|
||||
void (*intr)(struct nvkm_fb *);
|
||||
|
||||
struct {
|
||||
@ -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 *);
|
||||
|
||||
int gf100_fb_oneinit(struct nvkm_fb *);
|
||||
void gf100_fb_init_page(struct nvkm_fb *);
|
||||
bool gf100_fb_memtype_valid(struct nvkm_fb *, u32);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user