Commit 973b3244 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/imem: allow bar2 mapping of user allocations

Will be used to init client-allocated USERD to default values.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent e442f1e4
......@@ -37,6 +37,7 @@ struct nvkm_memory_func {
void (*release)(struct nvkm_memory *);
int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *,
struct nvkm_vma *, void *argv, u32 argc);
int (*kmap)(struct nvkm_memory *, struct nvkm_memory **);
};
struct nvkm_memory_ptrs {
......@@ -63,6 +64,7 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *,
#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v))
#define nvkm_memory_map(p,o,vm,va,av,ac) \
(p)->func->map((p),(o),(vm),(va),(av),(ac))
#define nvkm_memory_kmap(p,i) ((p)->func->kmap ? (p)->func->kmap((p), (i)) : -ENOSYS)
/* accessor macros - kmap()/done() must bracket use of the other accessor
* macros to guarantee correct behaviour across all chipsets
......
......@@ -28,7 +28,7 @@ u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
struct nvkm_memory **);
int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct nvkm_memory **);
int nv04_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
......
......@@ -25,6 +25,7 @@
#include "ram.h"
#include <core/memory.h>
#include <subdev/instmem.h>
#include <subdev/mmu.h>
struct nvkm_vram {
......@@ -34,6 +35,12 @@ struct nvkm_vram {
struct nvkm_mm_node *mn;
};
static int
nvkm_vram_kmap(struct nvkm_memory *memory, struct nvkm_memory **pmemory)
{
return nvkm_instobj_wrap(nvkm_vram(memory)->ram->fb->subdev.device, memory, pmemory);
}
static int
nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm,
struct nvkm_vma *vma, void *argv, u32 argc)
......@@ -98,6 +105,7 @@ nvkm_vram = {
.addr = nvkm_vram_addr,
.size = nvkm_vram_size,
.map = nvkm_vram_map,
.kmap = nvkm_vram_kmap,
};
int
......
......@@ -89,6 +89,18 @@ nvkm_instobj_ctor(const struct nvkm_memory_func *func,
spin_unlock(&imem->lock);
}
int
nvkm_instobj_wrap(struct nvkm_device *device,
struct nvkm_memory *memory, struct nvkm_memory **pmemory)
{
struct nvkm_instmem *imem = device->imem;
if (!imem->func->memory_wrap)
return -ENOSYS;
return imem->func->memory_wrap(imem, memory, pmemory);
}
int
nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
struct nvkm_memory **pmemory)
......
......@@ -348,13 +348,11 @@ nv50_instobj_func = {
};
static int
nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
struct nvkm_memory **pmemory)
nv50_instobj_wrap(struct nvkm_instmem *base,
struct nvkm_memory *memory, struct nvkm_memory **pmemory)
{
struct nv50_instmem *imem = nv50_instmem(base);
struct nv50_instobj *iobj;
struct nvkm_device *device = imem->base.subdev.device;
u8 page = max(order_base_2(align), 12);
if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
return -ENOMEM;
......@@ -365,7 +363,25 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
refcount_set(&iobj->maps, 0);
INIT_LIST_HEAD(&iobj->lru);
return nvkm_ram_get(device, 0, 1, page, size, true, true, &iobj->ram);
iobj->ram = nvkm_memory_ref(memory);
return 0;
}
static int
nv50_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
struct nvkm_memory **pmemory)
{
u8 page = max(order_base_2(align), 12);
struct nvkm_memory *ram;
int ret;
ret = nvkm_ram_get(imem->subdev.device, 0, 1, page, size, true, true, &ram);
if (ret)
return ret;
ret = nv50_instobj_wrap(imem, ram, pmemory);
nvkm_memory_unref(&ram);
return ret;
}
/******************************************************************************
......@@ -382,6 +398,7 @@ static const struct nvkm_instmem_func
nv50_instmem = {
.fini = nv50_instmem_fini,
.memory_new = nv50_instobj_new,
.memory_wrap = nv50_instobj_wrap,
.zero = false,
};
......
......@@ -12,6 +12,7 @@ struct nvkm_instmem_func {
void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align,
bool zero, struct nvkm_memory **);
int (*memory_wrap)(struct nvkm_instmem *, struct nvkm_memory *, struct nvkm_memory **);
bool zero;
};
......
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