Commit c73baa83 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ struct nvkm_fb {
		int regions;
	} tile;

	u8 page;

	struct nvkm_memory *mmu_rd;
	struct nvkm_memory *mmu_wr;
};
+4 −0
Original line number Diff line number Diff line
@@ -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
+17 −2
Original line number Diff line number Diff line
@@ -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,
+1 −0
Original line number Diff line number Diff line
@@ -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,
+1 −1
Original line number Diff line number Diff line
@@ -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,
};

Loading