nouveau-y += nouveau_prime.o
nouveau-y += nouveau_sgdma.o
nouveau-y += nouveau_ttm.o
+nouveau-y += nouveau_vmm.o
# DRM - modesetting
nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
};
struct nvkm_vma {
- struct list_head head;
- int refcount;
struct nvkm_vm *vm;
struct nvkm_mm_node *node;
union {
#include "nouveau_gem.h"
#include "nouveau_chan.h"
#include "nouveau_abi16.h"
+#include "nouveau_vmm.h"
static struct nouveau_abi16 *
nouveau_abi16(struct drm_file *file_priv)
}
if (chan->ntfy) {
- nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma);
+ nouveau_vma_del(&chan->ntfy_vma);
nouveau_bo_unpin(chan->ntfy);
drm_gem_object_unreference_unlocked(&chan->ntfy->gem);
}
goto done;
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nouveau_bo_vma_add(chan->ntfy, cli->vm,
- &chan->ntfy_vma);
+ ret = nouveau_vma_new(chan->ntfy, &cli->vmm, &chan->ntfy_vma);
if (ret)
goto done;
}
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM;
- args.start += chan->ntfy_vma.offset;
- args.limit += chan->ntfy_vma.offset;
+ args.start += chan->ntfy_vma->addr;
+ args.limit += chan->ntfy_vma->addr;
} else
if (drm->agp.bridge) {
args.target = NV_DMA_V0_TARGET_AGP;
struct nouveau_channel *chan;
struct list_head notifiers;
struct nouveau_bo *ntfy;
- struct nvkm_vma ntfy_vma;
+ struct nouveau_vma *ntfy_vma;
struct nvkm_mm heap;
};
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
#include "nouveau_mem.h"
+#include "nouveau_vmm.h"
/*
* NV10-NV40 tiling helpers
{
struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL;
struct nouveau_bo *nvbo = nouveau_bo(bo);
- struct nvkm_vma *vma;
+ struct nouveau_vma *vma;
/* ttm can now (stupidly) pass the driver bos it didn't create... */
if (bo->destroy != nouveau_bo_del_ttm)
if (mem && new_reg->mem_type != TTM_PL_SYSTEM &&
mem->mem.page == nvbo->page) {
list_for_each_entry(vma, &nvbo->vma_list, head) {
- nvkm_vm_map(vma, mem->_mem);
+ nouveau_vma_map(vma, mem);
}
} else {
list_for_each_entry(vma, &nvbo->vma_list, head) {
WARN_ON(ttm_bo_wait(bo, false, false));
- nvkm_vm_unmap(vma);
+ nouveau_vma_unmap(vma);
}
}
}
.io_mem_free = &nouveau_ttm_io_mem_free,
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
};
-
-struct nvkm_vma *
-nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nvkm_vm *vm)
-{
- struct nvkm_vma *vma;
- list_for_each_entry(vma, &nvbo->vma_list, head) {
- if (vma->vm == vm)
- return vma;
- }
-
- return NULL;
-}
-
-int
-nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nvkm_vm *vm,
- struct nvkm_vma *vma)
-{
- const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
- struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem);
- int ret;
-
- ret = nvkm_vm_get(vm, size, nvbo->page, NV_MEM_ACCESS_RW, vma);
- if (ret)
- return ret;
-
- if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM &&
- mem->mem.page == nvbo->page)
- nvkm_vm_map(vma, mem->_mem);
-
- list_add_tail(&vma->head, &nvbo->vma_list);
- vma->refcount = 1;
- return 0;
-}
-
-void
-nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nvkm_vma *vma)
-{
- if (vma->node) {
- if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM)
- nvkm_vm_unmap(vma);
- nvkm_vm_put(vma);
- list_del(&vma->head);
- }
-}
void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo);
void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
-struct nvkm_vma *
-nouveau_bo_vma_find(struct nouveau_bo *, struct nvkm_vm *);
-
-int nouveau_bo_vma_add(struct nouveau_bo *, struct nvkm_vm *,
- struct nvkm_vma *);
-void nouveau_bo_vma_del(struct nouveau_bo *, struct nvkm_vma *);
-
/* TODO: submit equivalent to TTM generic API upstream? */
static inline void __iomem *
nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
#include "nouveau_chan.h"
#include "nouveau_fence.h"
#include "nouveau_abi16.h"
+#include "nouveau_vmm.h"
MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM");
int nouveau_vram_pushbuf;
nvif_notify_fini(&chan->kill);
nvif_object_fini(&chan->user);
nvif_object_fini(&chan->push.ctxdma);
- nouveau_bo_vma_del(chan->push.buffer, &chan->push.vma);
+ nouveau_vma_del(&chan->push.vma);
nouveau_bo_unmap(chan->push.buffer);
if (chan->push.buffer && chan->push.buffer->pin_refcnt)
nouveau_bo_unpin(chan->push.buffer);
* pushbuf lives in, this is because the GEM code requires that
* we be able to call out to other (indirect) push buffers
*/
- chan->push.vma.offset = chan->push.buffer->bo.offset;
+ chan->push.addr = chan->push.buffer->bo.offset;
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nouveau_bo_vma_add(chan->push.buffer, cli->vm,
- &chan->push.vma);
+ ret = nouveau_vma_new(chan->push.buffer, &cli->vmm,
+ &chan->push.vma);
if (ret) {
nouveau_channel_del(pchan);
return ret;
args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0;
args.limit = cli->vm->mmu->limit - 1;
+
+ chan->push.addr = chan->push.vma->addr;
} else
if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
args.kepler.version = 0;
args.kepler.engines = engine;
args.kepler.ilength = 0x02000;
- args.kepler.ioffset = 0x10000 + chan->push.vma.offset;
+ args.kepler.ioffset = 0x10000 + chan->push.addr;
args.kepler.vm = 0;
size = sizeof(args.kepler);
} else
if (oclass[0] >= FERMI_CHANNEL_GPFIFO) {
args.fermi.version = 0;
args.fermi.ilength = 0x02000;
- args.fermi.ioffset = 0x10000 + chan->push.vma.offset;
+ args.fermi.ioffset = 0x10000 + chan->push.addr;
args.fermi.vm = 0;
size = sizeof(args.fermi);
} else {
args.nv50.version = 0;
args.nv50.ilength = 0x02000;
- args.nv50.ioffset = 0x10000 + chan->push.vma.offset;
+ args.nv50.ioffset = 0x10000 + chan->push.addr;
args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
args.nv50.vm = 0;
size = sizeof(args.nv50);
/* create channel object */
args.version = 0;
args.pushbuf = nvif_handle(&chan->push.ctxdma);
- args.offset = chan->push.vma.offset;
+ args.offset = chan->push.addr;
do {
ret = nvif_object_init(&device->object, 0, *oclass++,
struct {
struct nouveau_bo *buffer;
- struct nvkm_vma vma;
+ struct nouveau_vma *vma;
struct nvif_object ctxdma;
+ u64 addr;
} push;
/* TODO: this will be reworked in the near future */
#ifndef __NOUVEAU_DISPLAY_H__
#define __NOUVEAU_DISPLAY_H__
-
-#include <subdev/mmu.h>
-
#include "nouveau_drv.h"
struct nouveau_framebuffer {
struct drm_framebuffer base;
struct nouveau_bo *nvbo;
- struct nvkm_vma vma;
+ struct nouveau_vma *vma;
u32 r_handle;
u32 r_format;
u32 r_pitch;
#include "nouveau_drv.h"
#include "nouveau_dma.h"
+#include "nouveau_vmm.h"
void
OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
return -EBUSY;
}
- if (val < chan->push.vma.offset ||
- val > chan->push.vma.offset + (chan->dma.max << 2))
+ if (val < chan->push.addr ||
+ val > chan->push.addr + (chan->dma.max << 2))
return -EINVAL;
- return (val - chan->push.vma.offset) >> 2;
+ return (val - chan->push.addr) >> 2;
}
void
{
struct nouveau_cli *cli = (void *)chan->user.client;
struct nouveau_bo *pb = chan->push.buffer;
- struct nvkm_vma *vma;
+ struct nouveau_vma *vma;
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
u64 offset;
- vma = nouveau_bo_vma_find(bo, cli->vm);
+ vma = nouveau_vma_find(bo, &cli->vmm);
BUG_ON(!vma);
- offset = vma->offset + delta;
+ offset = vma->addr + delta;
BUG_ON(chan->dma.ib_free < 1);
* instruct the GPU to jump back to the start right
* after processing the currently pending commands.
*/
- OUT_RING(chan, chan->push.vma.offset | 0x20000000);
+ OUT_RING(chan, chan->push.addr | 0x20000000);
/* wait for GET to depart from the skips area.
* prevents writing GET==PUT and causing a race
#define WRITE_PUT(val) do { \
mb(); \
nouveau_bo_rd32(chan->push.buffer, 0); \
- nvif_wr32(&chan->user, chan->user_put, ((val) << 2) + chan->push.vma.offset); \
+ nvif_wr32(&chan->user, chan->user_put, ((val) << 2) + chan->push.addr);\
} while (0)
static inline void
static void
nouveau_cli_fini(struct nouveau_cli *cli)
{
- nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL);
usif_client_fini(cli);
+ nouveau_vmm_fini(&cli->vmm);
nvif_device_fini(&cli->device);
mutex_lock(&cli->drm->master.lock);
nvif_client_fini(&cli->base);
goto fail_device;
}
- ret = nvkm_vm_new(nvxx_device(&drm->client.device),
- 0, (1ULL << 40), 0x1000, NULL,
- &drm->client.vm);
+ ret = nouveau_vmm_init(&drm->client, 0, &drm->client.vmm);
if (ret)
goto fail_device;
+ drm->client.vm = drm->client.vmm.vm;
nvxx_client(&drm->client.base)->vm = drm->client.vm;
}
cli->base.super = false;
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nvkm_vm_new(nvxx_device(&drm->client.device), 0,
- (1ULL << 40), 0x1000, NULL, &cli->vm);
+ ret = nouveau_vmm_init(cli, 0, &cli->vmm);
if (ret)
goto done;
+ cli->vm = cli->vmm.vm;
nvxx_client(&cli->base)->vm = cli->vm;
}
#include "nouveau_fence.h"
#include "nouveau_bios.h"
+#include "nouveau_vmm.h"
struct nouveau_drm_tile {
struct nouveau_fence *fence;
struct mutex mutex;
struct nvif_device device;
+ struct nouveau_vmm vmm;
- struct nvkm_vm *vm; /*XXX*/
+ struct nvkm_vm *vm;
struct list_head head;
void *abi16;
struct list_head objects;
#include "nouveau_bo.h"
#include "nouveau_fbcon.h"
#include "nouveau_chan.h"
+#include "nouveau_vmm.h"
#include "nouveau_crtc.h"
chan = nouveau_nofbaccel ? NULL : drm->channel;
if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
- ret = nouveau_bo_vma_add(nvbo, drm->client.vm, &fb->vma);
+ ret = nouveau_vma_new(nvbo, &drm->client.vmm, &fb->vma);
if (ret) {
NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
chan = NULL;
out_unlock:
if (chan)
- nouveau_bo_vma_del(fb->nvbo, &fb->vma);
+ nouveau_vma_del(&fb->vma);
nouveau_bo_unmap(fb->nvbo);
out_unpin:
nouveau_bo_unpin(fb->nvbo);
drm_fb_helper_fini(&fbcon->helper);
if (nouveau_fb->nvbo) {
- nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
+ nouveau_vma_del(&nouveau_fb->vma);
nouveau_bo_unmap(nouveau_fb->nvbo);
nouveau_bo_unpin(nouveau_fb->nvbo);
drm_framebuffer_unreference(&nouveau_fb->base);
struct nv84_fence_chan {
struct nouveau_fence_chan base;
- struct nvkm_vma vma;
+ struct nouveau_vma *vma;
};
struct nv84_fence_priv {
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
+#include "nouveau_vmm.h"
void
nouveau_gem_object_del(struct drm_gem_object *gem)
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
- struct nvkm_vma *vma;
struct device *dev = drm->dev->dev;
+ struct nouveau_vma *vma;
int ret;
if (!cli->vm)
if (ret)
return ret;
- vma = nouveau_bo_vma_find(nvbo, cli->vm);
- if (!vma) {
- vma = kzalloc(sizeof(*vma), GFP_KERNEL);
- if (!vma) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = pm_runtime_get_sync(dev);
- if (ret < 0 && ret != -EACCES) {
- kfree(vma);
- goto out;
- }
-
- ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
- if (ret)
- kfree(vma);
-
- pm_runtime_mark_last_busy(dev);
- pm_runtime_put_autosuspend(dev);
- } else {
- vma->refcount++;
- }
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0 && ret != -EACCES)
+ goto out;
+ ret = nouveau_vma_new(nvbo, &cli->vmm, &vma);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
out:
ttm_bo_unreserve(&nvbo->bo);
return ret;
static void
nouveau_gem_object_delete(void *data)
{
- struct nvkm_vma *vma = data;
- nvkm_vm_unmap(vma);
- nvkm_vm_put(vma);
- kfree(vma);
+ struct nouveau_vma *vma = data;
+ nouveau_vma_del(&vma);
}
static void
-nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nvkm_vma *vma)
+nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
{
const bool mapped = nvbo->bo.mem.mem_type != TTM_PL_SYSTEM;
struct reservation_object *resv = nvbo->bo.resv;
fobj = reservation_object_get_list(resv);
- list_del(&vma->head);
+ list_del_init(&vma->head);
if (fobj && fobj->shared_count > 1)
ttm_bo_wait(&nvbo->bo, false, false);
else
fence = reservation_object_get_excl(nvbo->bo.resv);
- if (fence && mapped) {
+ if (fence && mapped)
nouveau_fence_work(fence, nouveau_gem_object_delete, vma);
- } else {
- if (mapped)
- nvkm_vm_unmap(vma);
- nvkm_vm_put(vma);
- kfree(vma);
- }
+ else
+ nouveau_vma_del(&vma);
}
void
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct device *dev = drm->dev->dev;
- struct nvkm_vma *vma;
+ struct nouveau_vma *vma;
int ret;
if (!cli->vm)
if (ret)
return;
- vma = nouveau_bo_vma_find(nvbo, cli->vm);
+ vma = nouveau_vma_find(nvbo, &cli->vmm);
if (vma) {
- if (--vma->refcount == 0) {
+ if (--vma->refs == 0) {
ret = pm_runtime_get_sync(dev);
if (!WARN_ON(ret < 0 && ret != -EACCES)) {
nouveau_gem_object_unmap(nvbo, vma);
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
- struct nvkm_vma *vma;
+ struct nouveau_vma *vma;
if (is_power_of_2(nvbo->valid_domains))
rep->domain = nvbo->valid_domains;
rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
rep->offset = nvbo->bo.offset;
if (cli->vm) {
- vma = nouveau_bo_vma_find(nvbo, cli->vm);
+ vma = nouveau_vma_find(nvbo, &cli->vmm);
if (!vma)
return -EINVAL;
- rep->offset = vma->offset;
+ rep->offset = vma->addr;
}
rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
bo[push[i].bo_index].user_priv;
uint32_t cmd;
- cmd = chan->push.vma.offset + ((chan->dma.cur + 2) << 2);
+ cmd = chan->push.addr + ((chan->dma.cur + 2) << 2);
cmd |= 0x20000000;
if (unlikely(cmd != req->suffix0)) {
if (!nvbo->kmap.virtual) {
req->suffix1 = 0x00000000;
} else {
req->suffix0 = 0x20000000 |
- (chan->push.vma.offset + ((chan->dma.cur + 2) << 2));
+ (chan->push.addr + ((chan->dma.cur + 2) << 2));
req->suffix1 = 0x00000000;
}
--- /dev/null
+/*
+ * Copyright 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nouveau_vmm.h"
+#include "nouveau_drv.h"
+#include "nouveau_bo.h"
+#include "nouveau_mem.h"
+
+void
+nouveau_vma_unmap(struct nouveau_vma *vma)
+{
+ if (vma->mem) {
+ nvkm_vm_unmap(&vma->_vma);
+ vma->mem = NULL;
+ }
+}
+
+int
+nouveau_vma_map(struct nouveau_vma *vma, struct nouveau_mem *mem)
+{
+ int ret = nouveau_mem_map(mem, vma->vmm->vm, &vma->_vma);
+ if (ret)
+ return ret;
+ vma->mem = mem;
+ return 0;
+}
+
+struct nouveau_vma *
+nouveau_vma_find(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm)
+{
+ struct nouveau_vma *vma;
+
+ list_for_each_entry(vma, &nvbo->vma_list, head) {
+ if (vma->vmm == vmm)
+ return vma;
+ }
+
+ return NULL;
+}
+
+void
+nouveau_vma_del(struct nouveau_vma **pvma)
+{
+ struct nouveau_vma *vma = *pvma;
+ if (vma && --vma->refs <= 0) {
+ if (likely(vma->addr != ~0ULL)) {
+ nouveau_vma_unmap(vma);
+ nvkm_vm_put(&vma->_vma);
+ }
+ list_del(&vma->head);
+ *pvma = NULL;
+ kfree(*pvma);
+ }
+}
+
+int
+nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm,
+ struct nouveau_vma **pvma)
+{
+ struct nouveau_mem *mem = nouveau_mem(&nvbo->bo.mem);
+ struct nouveau_vma *vma;
+ int ret;
+
+ if ((vma = *pvma = nouveau_vma_find(nvbo, vmm))) {
+ vma->refs++;
+ return 0;
+ }
+
+ if (!(vma = *pvma = kmalloc(sizeof(*vma), GFP_KERNEL)))
+ return -ENOMEM;
+ vma->vmm = vmm;
+ vma->refs = 1;
+ vma->addr = ~0ULL;
+ vma->mem = NULL;
+ list_add_tail(&vma->head, &nvbo->vma_list);
+
+ if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM &&
+ mem->mem.page == nvbo->page) {
+ ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page,
+ NV_MEM_ACCESS_RW, &vma->_vma);
+ if (ret)
+ goto done;
+
+ vma->addr = vma->_vma.offset;
+ ret = nouveau_vma_map(vma, mem);
+ } else {
+ ret = nvkm_vm_get(vmm->vm, mem->_mem->size << 12, mem->mem.page,
+ NV_MEM_ACCESS_RW, &vma->_vma);
+ vma->addr = vma->_vma.offset;
+ }
+
+done:
+ if (ret)
+ nouveau_vma_del(pvma);
+ return ret;
+}
+
+void
+nouveau_vmm_fini(struct nouveau_vmm *vmm)
+{
+ nvkm_vm_ref(NULL, &vmm->vm, NULL);
+}
+
+int
+nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm)
+{
+ vmm->cli = cli;
+ return nvkm_vm_new(nvxx_device(&cli->device), 0, (1ULL << 40),
+ 0x1000, NULL, &vmm->vm);
+}
--- /dev/null
+#ifndef __NOUVEAU_VMA_H__
+#define __NOUVEAU_VMA_H__
+#include <subdev/mmu.h>
+struct nouveau_bo;
+struct nouveau_mem;
+
+struct nouveau_vma {
+ struct nouveau_vmm *vmm;
+ int refs;
+ struct list_head head;
+ u64 addr;
+
+ struct nouveau_mem *mem;
+
+ struct nvkm_vma _vma;
+};
+
+struct nouveau_vma *nouveau_vma_find(struct nouveau_bo *, struct nouveau_vmm *);
+int nouveau_vma_new(struct nouveau_bo *, struct nouveau_vmm *,
+ struct nouveau_vma **);
+void nouveau_vma_del(struct nouveau_vma **);
+int nouveau_vma_map(struct nouveau_vma *, struct nouveau_mem *);
+void nouveau_vma_unmap(struct nouveau_vma *);
+
+struct nouveau_vmm {
+ struct nouveau_cli *cli;
+ struct nvkm_vm *vm;
+};
+
+int nouveau_vmm_init(struct nouveau_cli *, s32 oclass, struct nouveau_vmm *);
+void nouveau_vmm_fini(struct nouveau_vmm *);
+#endif
#include "nouveau_drv.h"
#include "nouveau_dma.h"
#include "nouveau_fbcon.h"
+#include "nouveau_vmm.h"
int
nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
OUT_RING(chan, info->fix.line_length);
OUT_RING(chan, info->var.xres_virtual);
OUT_RING(chan, info->var.yres_virtual);
- OUT_RING(chan, upper_32_bits(fb->vma.offset));
- OUT_RING(chan, lower_32_bits(fb->vma.offset));
+ OUT_RING(chan, upper_32_bits(fb->vma->addr));
+ OUT_RING(chan, lower_32_bits(fb->vma->addr));
BEGIN_NV04(chan, NvSub2D, 0x0230, 2);
OUT_RING(chan, format);
OUT_RING(chan, 1);
OUT_RING(chan, info->fix.line_length);
OUT_RING(chan, info->var.xres_virtual);
OUT_RING(chan, info->var.yres_virtual);
- OUT_RING(chan, upper_32_bits(fb->vma.offset));
- OUT_RING(chan, lower_32_bits(fb->vma.offset));
+ OUT_RING(chan, upper_32_bits(fb->vma->addr));
+ OUT_RING(chan, lower_32_bits(fb->vma->addr));
FIRE_RING(chan);
return 0;
#include "nouveau_drv.h"
#include "nouveau_dma.h"
#include "nouveau_fence.h"
+#include "nouveau_vmm.h"
#include "nv50_display.h"
{
struct nouveau_channel *chan = fence->channel;
struct nv84_fence_chan *fctx = chan->fence;
- u64 addr = fctx->vma.offset + chan->chid * 16;
+ u64 addr = fctx->vma->addr + chan->chid * 16;
return fctx->base.emit32(chan, addr, fence->base.seqno);
}
struct nouveau_channel *prev, struct nouveau_channel *chan)
{
struct nv84_fence_chan *fctx = chan->fence;
- u64 addr = fctx->vma.offset + prev->chid * 16;
+ u64 addr = fctx->vma->addr + prev->chid * 16;
return fctx->base.sync32(chan, addr, fence->base.seqno);
}
nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence);
mutex_lock(&priv->mutex);
- nouveau_bo_vma_del(priv->bo, &fctx->vma);
+ nouveau_vma_del(&fctx->vma);
mutex_unlock(&priv->mutex);
nouveau_fence_context_del(&fctx->base);
chan->fence = NULL;
fctx->base.sequence = nv84_fence_read(chan);
mutex_lock(&priv->mutex);
- ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma);
+ ret = nouveau_vma_new(priv->bo, &cli->vmm, &fctx->vma);
mutex_unlock(&priv->mutex);
if (ret)
#include "nouveau_drv.h"
#include "nouveau_dma.h"
#include "nouveau_fbcon.h"
+#include "nouveau_vmm.h"
int
nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
OUT_RING (chan, info->fix.line_length);
OUT_RING (chan, info->var.xres_virtual);
OUT_RING (chan, info->var.yres_virtual);
- OUT_RING (chan, upper_32_bits(fb->vma.offset));
- OUT_RING (chan, lower_32_bits(fb->vma.offset));
+ OUT_RING (chan, upper_32_bits(fb->vma->addr));
+ OUT_RING (chan, lower_32_bits(fb->vma->addr));
BEGIN_NVC0(chan, NvSub2D, 0x0230, 10);
OUT_RING (chan, format);
OUT_RING (chan, 1);
OUT_RING (chan, info->fix.line_length);
OUT_RING (chan, info->var.xres_virtual);
OUT_RING (chan, info->var.yres_virtual);
- OUT_RING (chan, upper_32_bits(fb->vma.offset));
- OUT_RING (chan, lower_32_bits(fb->vma.offset));
+ OUT_RING (chan, upper_32_bits(fb->vma->addr));
+ OUT_RING (chan, lower_32_bits(fb->vma->addr));
FIRE_RING (chan);
return 0;