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 { ...@@ -37,6 +37,7 @@ struct nvkm_memory_func {
void (*release)(struct nvkm_memory *); void (*release)(struct nvkm_memory *);
int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *, int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *,
struct nvkm_vma *, void *argv, u32 argc); struct nvkm_vma *, void *argv, u32 argc);
int (*kmap)(struct nvkm_memory *, struct nvkm_memory **);
}; };
struct nvkm_memory_ptrs { struct nvkm_memory_ptrs {
...@@ -63,6 +64,7 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *, ...@@ -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_boot(p,v) (p)->func->boot((p),(v))
#define nvkm_memory_map(p,o,vm,va,av,ac) \ #define nvkm_memory_map(p,o,vm,va,av,ac) \
(p)->func->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 /* accessor macros - kmap()/done() must bracket use of the other accessor
* macros to guarantee correct behaviour across all chipsets * macros to guarantee correct behaviour across all chipsets
......
...@@ -28,7 +28,7 @@ u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr); ...@@ -28,7 +28,7 @@ u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data); void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero, int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
struct nvkm_memory **); 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 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 **); int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "ram.h" #include "ram.h"
#include <core/memory.h> #include <core/memory.h>
#include <subdev/instmem.h>
#include <subdev/mmu.h> #include <subdev/mmu.h>
struct nvkm_vram { struct nvkm_vram {
...@@ -34,6 +35,12 @@ struct nvkm_vram { ...@@ -34,6 +35,12 @@ struct nvkm_vram {
struct nvkm_mm_node *mn; 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 static int
nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm, nvkm_vram_map(struct nvkm_memory *memory, u64 offset, struct nvkm_vmm *vmm,
struct nvkm_vma *vma, void *argv, u32 argc) struct nvkm_vma *vma, void *argv, u32 argc)
...@@ -98,6 +105,7 @@ nvkm_vram = { ...@@ -98,6 +105,7 @@ nvkm_vram = {
.addr = nvkm_vram_addr, .addr = nvkm_vram_addr,
.size = nvkm_vram_size, .size = nvkm_vram_size,
.map = nvkm_vram_map, .map = nvkm_vram_map,
.kmap = nvkm_vram_kmap,
}; };
int int
......
...@@ -89,6 +89,18 @@ nvkm_instobj_ctor(const struct nvkm_memory_func *func, ...@@ -89,6 +89,18 @@ nvkm_instobj_ctor(const struct nvkm_memory_func *func,
spin_unlock(&imem->lock); 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 int
nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
struct nvkm_memory **pmemory) struct nvkm_memory **pmemory)
......
...@@ -348,13 +348,11 @@ nv50_instobj_func = { ...@@ -348,13 +348,11 @@ nv50_instobj_func = {
}; };
static int static int
nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, nv50_instobj_wrap(struct nvkm_instmem *base,
struct nvkm_memory **pmemory) struct nvkm_memory *memory, struct nvkm_memory **pmemory)
{ {
struct nv50_instmem *imem = nv50_instmem(base); struct nv50_instmem *imem = nv50_instmem(base);
struct nv50_instobj *iobj; 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))) if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
...@@ -365,7 +363,25 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, ...@@ -365,7 +363,25 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
refcount_set(&iobj->maps, 0); refcount_set(&iobj->maps, 0);
INIT_LIST_HEAD(&iobj->lru); 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 ...@@ -382,6 +398,7 @@ static const struct nvkm_instmem_func
nv50_instmem = { nv50_instmem = {
.fini = nv50_instmem_fini, .fini = nv50_instmem_fini,
.memory_new = nv50_instobj_new, .memory_new = nv50_instobj_new,
.memory_wrap = nv50_instobj_wrap,
.zero = false, .zero = false,
}; };
......
...@@ -12,6 +12,7 @@ struct nvkm_instmem_func { ...@@ -12,6 +12,7 @@ struct nvkm_instmem_func {
void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data); void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align, int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align,
bool zero, struct nvkm_memory **); bool zero, struct nvkm_memory **);
int (*memory_wrap)(struct nvkm_instmem *, struct nvkm_memory *, struct nvkm_memory **);
bool zero; 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