summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-11-22 10:48:51 +1000
committerBen Skeggs <bskeggs@redhat.com>2010-12-08 13:48:19 +1000
commit34cf01bc4b8021cef62cbd79224577c13d01b106 (patch)
tree1d4053bfe22db8e1418cc52b53462cbe6a31881c /drivers
parentb571fe21f5c24760368b3fb927af5a7384d7721b (diff)
drm/nouveau: allow gpuobj vinst to be a virtual address when necessary
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c25
2 files changed, 24 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 4c5fc9c9912..2cd87e6b54b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -158,6 +158,7 @@ enum nouveau_flags {
#define NVOBJ_FLAG_DONT_MAP (1 << 0)
#define NVOBJ_FLAG_ZERO_ALLOC (1 << 1)
#define NVOBJ_FLAG_ZERO_FREE (1 << 2)
+#define NVOBJ_FLAG_VM (1 << 3)
#define NVOBJ_CINST_GLOBAL 0xdeadbeef
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index ec102bda844..e2efd6f22ff 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -302,6 +302,7 @@ nv50_instmem_resume(struct drm_device *dev)
struct nv50_gpuobj_node {
struct nouveau_vram *vram;
+ struct nouveau_vma chan_vma;
u32 align;
};
@@ -310,6 +311,7 @@ int
nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
{
struct drm_device *dev = gpuobj->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_gpuobj_node *node = NULL;
int ret;
@@ -328,8 +330,23 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align)
}
gpuobj->vinst = node->vram->offset;
- gpuobj->size = size;
- gpuobj->node = node;
+
+ if (gpuobj->flags & NVOBJ_FLAG_VM) {
+ ret = nouveau_vm_get(dev_priv->chan_vm, size, 12,
+ NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS,
+ &node->chan_vma);
+ if (ret) {
+ nv50_vram_del(dev, &node->vram);
+ kfree(node);
+ return ret;
+ }
+
+ nouveau_vm_map(&node->chan_vma, node->vram);
+ gpuobj->vinst = node->chan_vma.offset;
+ }
+
+ gpuobj->size = size;
+ gpuobj->node = node;
return 0;
}
@@ -342,6 +359,10 @@ nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
node = gpuobj->node;
gpuobj->node = NULL;
+ if (node->chan_vma.node) {
+ nouveau_vm_unmap(&node->chan_vma);
+ nouveau_vm_put(&node->chan_vma);
+ }
nv50_vram_del(dev, &node->vram);
kfree(node);
}