diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-10-13 08:05:55 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-10-13 08:05:55 +1000 |
commit | b6d298076b630ba62b96fecd70c6cb6d9152e9d0 (patch) | |
tree | ea413fabe20744aeecd31ac882f45c9f418790b3 | |
parent | 8d226c718530392448366f7b8cd6a44cff125213 (diff) |
WIPdrm/nouveau/fb: create heaps from common code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c | 54 |
10 files changed, 96 insertions, 130 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c index bd8b4f13528e..bd8dcd790b6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gt215.c @@ -28,6 +28,7 @@ static const struct nv50_fb_func gt215_fb = { .vidmem.type = nv50_fb_vidmem_type, .vidmem.size = nv50_fb_vidmem_size, + .vidmem.rblock = nv50_fb_vidmem_rblock, .ram_new = gt215_ram_new, .tags = nv20_fb_tags, .trap = 0x000d0fff, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c index daa6ecdd9df5..edb3ba7412e6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c @@ -211,6 +211,48 @@ nv50_fb_tags(struct nvkm_fb *base) return 0; } +u32 +nv50_fb_vidmem_rblock(struct nvkm_fb *fb) +{ + struct nvkm_subdev *subdev = &fb->subdev; + struct nvkm_device *device = subdev->device; + int colbits, rowbitsa, rowbitsb, banks; + u64 rowsize, predicted; + u32 r0, r4, rt, rblock_size; + + fb->ram->part_mask = (nvkm_rd32(device, 0x001540) & 0x00ff0000) >> 16; + fb->ram->parts = hweight8(fb->ram->part_mask); + fb->ram->ranks = (nvkm_rd32(device, 0x100200) & 0x4) ? 2 : 1; + + r0 = nvkm_rd32(device, 0x100200); + r4 = nvkm_rd32(device, 0x100204); + rt = nvkm_rd32(device, 0x100250); + nvkm_debug(subdev, "memcfg %08x %08x %08x %08x\n", + r0, r4, rt, nvkm_rd32(device, 0x001540)); + + colbits = (r4 & 0x0000f000) >> 12; + rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; + rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; + banks = 1 << (((r4 & 0x03000000) >> 24) + 2); + + rowsize = fb->ram->parts * banks * (1 << colbits) * 8; + predicted = rowsize << rowbitsa; + if (r0 & 0x00000004) + predicted += rowsize << rowbitsb; + + if (predicted != fb->ram->size) { + nvkm_warn(subdev, "memory controller reports %d MiB VRAM\n", + (u32)(fb->ram->size >> 20)); + } + + rblock_size = rowsize; + if (rt & 1) + rblock_size *= 3; + + nvkm_debug(subdev, "rblock %d bytes\n", rblock_size); + return rblock_size; +} + u64 nv50_fb_vidmem_size(struct nvkm_fb *fb, u64 *plower, u64 *pubase, u64 *pusize) { @@ -268,6 +310,7 @@ nv50_fb_ = { .sysmem.flush_page_init = nv50_fb_sysmem_flush_page_init, .vidmem.type = nv50_fb_vidmem_type, .vidmem.size = nv50_fb_vidmem_size, + .vidmem.rblock = nv50_fb_vidmem_rblock, .ram_new = nv50_fb_ram_new, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h index 3e24de0b1de9..dfc45775a888 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h @@ -23,6 +23,7 @@ struct nvkm_fb_func { struct nvkm_fb_func_vidmem { enum nvkm_ram_type (*type)(struct nvkm_fb *); u64 (*size)(struct nvkm_fb *, u64 *lower, u64 *ubase, u64 *usize); + u32 (*rblock)(struct nvkm_fb *); u64 upper; u32 (*probe_fbp)(struct nvkm_fb *, int fbp, int *pltcs); u32 (*probe_fbp_amount)(struct nvkm_fb *, u32 fbpao, int fbp, int *pltcs); @@ -89,6 +90,7 @@ void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size, enum nvkm_ram_type nv50_fb_vidmem_type(struct nvkm_fb *); u64 nv50_fb_vidmem_size(struct nvkm_fb *, u64 *, u64 *, u64 *); +u32 nv50_fb_vidmem_rblock(struct nvkm_fb *); int gf100_fb_oneinit(struct nvkm_fb *); int gf100_fb_init_page(struct nvkm_fb *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index 269fc4726137..66e980b1e086 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -198,22 +198,43 @@ nvkm_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, u32 rsvd_hea [NVKM_RAM_TYPE_HBM2 ] = "HBM2", }; struct nvkm_subdev *subdev = &fb->subdev; + u64 lower = 0, ubase, usize; int ret; ram->func = func; ram->fb = fb; ram->type = fb->func->vidmem.type(fb); - ram->size = fb->func->vidmem.size(fb, NULL, NULL, NULL); + ram->size = fb->func->vidmem.size(fb, &lower, &ubase, &usize); + ram->stolen = (ram->type == NVKM_RAM_TYPE_STOLEN) ? lower : 0; mutex_init(&ram->mutex); nvkm_info(subdev, "%d MiB %s\n", (int)(ram->size >> 20), name[ram->type]); - if (!nvkm_mm_initialised(&ram->vram)) { - ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, rsvd_head >> NVKM_RAM_MM_SHIFT, - (ram->size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, - 1); + /* Some GPUs are in what's known as a "mixed memory" configuration. + * + * This is either where some FBPs have more memory than the others, + * or where LTCs have been disabled on a FBP. + */ + if (lower && lower != ram->size && !ram->stolen) { + /* The common memory amount is addressed normally. */ + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, + rsvd_head >> NVKM_RAM_MM_SHIFT, lower >> NVKM_RAM_MM_SHIFT, 1); if (ret) return ret; + + /* And the rest is much higher in the physical address + * space, and may not be usable for certain operations. + */ + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_MIXED, ubase >> NVKM_RAM_MM_SHIFT, + (usize - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1); + if (ret) + return ret; + } else { + /* GPUs without mixed-memory are a lot nicer... */ + ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, rsvd_head >> NVKM_RAM_MM_SHIFT, + (ram->size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, + fb->func->vidmem.rblock ? + fb->func->vidmem.rblock(fb) >> NVKM_RAM_MM_SHIFT : 1); } return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h index 713ed7444b2a..58c1cc237820 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h @@ -15,8 +15,6 @@ int nv50_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *, int gf100_ram_new_(const struct nvkm_ram_func *, struct nvkm_fb *, struct nvkm_ram **); -int gf100_ram_ctor(const struct nvkm_ram_func *, struct nvkm_fb *, - struct nvkm_ram *); int gf100_ram_init(struct nvkm_ram *); int gf100_ram_calc(struct nvkm_ram *, u32); int gf100_ram_prog(struct nvkm_ram *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index 133c8c5852f6..3d4a6b2c12dd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -463,57 +463,6 @@ gf100_ram_init(struct nvkm_ram *base) } int -gf100_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, - struct nvkm_ram *ram) -{ - const u32 rsvd_head = ( 256 * 1024); /* vga memory */ - const u32 rsvd_tail = (1024 * 1024); /* vbios etc */ - u64 total, lower, ubase, usize; - int ret; - - total = fb->func->vidmem.size(fb, &lower, &ubase, &usize); - - ret = nvkm_ram_ctor(func, fb, rsvd_head, rsvd_tail, ram); - if (ret) - return ret; - - nvkm_mm_fini(&ram->vram); - - /* Some GPUs are in what's known as a "mixed memory" configuration. - * - * This is either where some FBPs have more memory than the others, - * or where LTCs have been disabled on a FBP. - */ - if (lower != total) { - /* The common memory amount is addressed normally. */ - ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, - rsvd_head >> NVKM_RAM_MM_SHIFT, - (lower - rsvd_head) >> NVKM_RAM_MM_SHIFT, 1); - if (ret) - return ret; - - /* And the rest is much higher in the physical address - * space, and may not be usable for certain operations. - */ - ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_MIXED, - ubase >> NVKM_RAM_MM_SHIFT, - (usize - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1); - if (ret) - return ret; - } else { - /* GPUs without mixed-memory are a lot nicer... */ - ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, - rsvd_head >> NVKM_RAM_MM_SHIFT, - (total - rsvd_head - rsvd_tail) >> - NVKM_RAM_MM_SHIFT, 1); - if (ret) - return ret; - } - - return 0; -} - -int gf100_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb, struct nvkm_ram **pram) { @@ -526,7 +475,7 @@ gf100_ram_new_(const struct nvkm_ram_func *func, return -ENOMEM; *pram = &ram->base; - ret = gf100_ram_ctor(func, fb, &ram->base); + ret = nv50_ram_ctor(func, fb, &ram->base); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c index ee809af7787a..40cbc3f9ba12 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c @@ -1534,7 +1534,7 @@ gk104_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb, return -ENOMEM; *pram = &ram->base; - ret = gf100_ram_ctor(func, fb, &ram->base); + ret = nv50_ram_ctor(func, fb, &ram->base); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c index d93376d35568..1dbe2a4c8325 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c @@ -84,6 +84,6 @@ gp100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) if (!(ram = *pram = kzalloc(sizeof(*ram), GFP_KERNEL))) return -ENOMEM; - return gf100_ram_ctor(&gp100_ram, fb, ram); + return nv50_ram_ctor(&gp100_ram, fb, ram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c index fef7fd0d3964..965e330636b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c @@ -24,9 +24,11 @@ #define mcp77_ram(p) container_of((p), struct mcp77_ram, base) #include "ram.h" +#include <core/memory.h> + struct mcp77_ram { struct nvkm_ram base; - u64 poller_base; + struct nvkm_memory *poller; }; static int @@ -34,9 +36,10 @@ mcp77_ram_init(struct nvkm_ram *base) { struct mcp77_ram *ram = mcp77_ram(base); struct nvkm_device *device = ram->base.fb->subdev.device; - u32 dniso = ((ram->base.size - (ram->poller_base + 0x00)) >> 5) - 1; - u32 hostnb = ((ram->base.size - (ram->poller_base + 0x20)) >> 5) - 1; - u32 flush = ((ram->base.size - (ram->poller_base + 0x40)) >> 5) - 1; + u32 poller_base = nvkm_memory_addr(ram->poller); + u32 dniso = ((ram->base.size - (poller_base + 0x00)) >> 5) - 1; + u32 hostnb = ((ram->base.size - (poller_base + 0x20)) >> 5) - 1; + u32 flush = ((ram->base.size - (poller_base + 0x40)) >> 5) - 1; /* Enable NISO poller for various clients and set their associated * read address, only for MCP77/78 and MCP79/7A. (fd#27501) @@ -50,17 +53,24 @@ mcp77_ram_init(struct nvkm_ram *base) return 0; } +static void * +mcp77_ram_dtor(struct nvkm_ram *base) +{ + struct mcp77_ram *ram = mcp77_ram(base); + + nvkm_memory_unref(&ram->poller); + return ram; +} + static const struct nvkm_ram_func mcp77_ram_func = { + .dtor = mcp77_ram_dtor, .init = mcp77_ram_init, }; int mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) { - u32 rsvd_head = ( 256 * 1024); /* vga memory */ - u32 rsvd_tail = (1024 * 1024) + 0x1000; /* vbios etc + poller mem */ - u64 base, size = fb->func->vidmem.size(fb, &base, NULL, NULL); struct mcp77_ram *ram; int ret; @@ -68,16 +78,10 @@ mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) return -ENOMEM; *pram = &ram->base; - ret = nvkm_ram_ctor(&mcp77_ram_func, fb, rsvd_head, rsvd_tail, &ram->base); + ret = nv50_ram_ctor(&mcp77_ram_func, fb, &ram->base); if (ret) return ret; - ram->poller_base = size - rsvd_tail; - ram->base.stolen = base; - nvkm_mm_fini(&ram->base.vram); - - return nvkm_mm_init(&ram->base.vram, NVKM_RAM_MM_NORMAL, - rsvd_head >> NVKM_RAM_MM_SHIFT, - (size - rsvd_head - rsvd_tail) >> - NVKM_RAM_MM_SHIFT, 1); + return nvkm_ram_get(fb->subdev.device, NVKM_RAM_MM_NORMAL, 0x01, 0, 0x1000, true, true, + &ram->poller); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index b1069de1f5c4..7adc380df1b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -499,66 +499,14 @@ nv50_ram_func = { .tidy = nv50_ram_tidy, }; -static u32 -nv50_fb_vram_rblock(struct nvkm_ram *ram) -{ - struct nvkm_subdev *subdev = &ram->fb->subdev; - struct nvkm_device *device = subdev->device; - int colbits, rowbitsa, rowbitsb, banks; - u64 rowsize, predicted; - u32 r0, r4, rt, rblock_size; - - r0 = nvkm_rd32(device, 0x100200); - r4 = nvkm_rd32(device, 0x100204); - rt = nvkm_rd32(device, 0x100250); - nvkm_debug(subdev, "memcfg %08x %08x %08x %08x\n", - r0, r4, rt, nvkm_rd32(device, 0x001540)); - - colbits = (r4 & 0x0000f000) >> 12; - rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; - rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; - banks = 1 << (((r4 & 0x03000000) >> 24) + 2); - - rowsize = ram->parts * banks * (1 << colbits) * 8; - predicted = rowsize << rowbitsa; - if (r0 & 0x00000004) - predicted += rowsize << rowbitsb; - - if (predicted != ram->size) { - nvkm_warn(subdev, "memory controller reports %d MiB VRAM\n", - (u32)(ram->size >> 20)); - } - - rblock_size = rowsize; - if (rt & 1) - rblock_size *= 3; - - nvkm_debug(subdev, "rblock %d bytes\n", rblock_size); - return rblock_size; -} - int nv50_ram_ctor(const struct nvkm_ram_func *func, struct nvkm_fb *fb, struct nvkm_ram *ram) { - struct nvkm_device *device = fb->subdev.device; const u32 rsvd_head = ( 256 * 1024); /* vga memory */ const u32 rsvd_tail = (1024 * 1024); /* vbios etc */ - int ret; - - ret = nvkm_ram_ctor(func, fb, rsvd_head, rsvd_tail, ram); - if (ret) - return ret; - - ram->part_mask = (nvkm_rd32(device, 0x001540) & 0x00ff0000) >> 16; - ram->parts = hweight8(ram->part_mask); - ram->ranks = (nvkm_rd32(device, 0x100200) & 0x4) ? 2 : 1; - nvkm_mm_fini(&ram->vram); - return nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, - rsvd_head >> NVKM_RAM_MM_SHIFT, - (ram->size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT, - nv50_fb_vram_rblock(ram) >> NVKM_RAM_MM_SHIFT); + return nvkm_ram_ctor(func, fb, rsvd_head, rsvd_tail, ram); } int |