summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2022-10-13 08:05:55 +1000
committerBen Skeggs <bskeggs@redhat.com>2022-10-13 08:05:55 +1000
commitb6d298076b630ba62b96fecd70c6cb6d9152e9d0 (patch)
treeea413fabe20744aeecd31ac882f45c9f418790b3
parent8d226c718530392448366f7b8cd6a44cff125213 (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.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c43
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c31
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c53
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c54
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