summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_vm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-11-10 14:10:04 +1000
committerBen Skeggs <bskeggs@redhat.com>2010-12-21 17:17:09 +1000
commit4c74eb7ff276813ee73943a3756b295675fb2865 (patch)
tree29f0c29e5209d572906ed33031e8a42fab84899e /drivers/gpu/drm/nouveau/nouveau_vm.c
parent3ee0128140eed7d32b785a335099a2ec38258283 (diff)
drm/nvc0: import initial vm backend
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_vm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_vm.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c
index b023a64c27d..97d82aedf86 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c
@@ -295,7 +295,34 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset,
vm->flush = nv50_vm_flush;
vm->spg_shift = 12;
vm->lpg_shift = 16;
+
pgt_bits = 29;
+ block = (1 << pgt_bits);
+ if (length < block)
+ block = length;
+
+ } else
+ if (dev_priv->card_type == NV_C0) {
+ vm->map_pgt = nvc0_vm_map_pgt;
+ vm->map = nvc0_vm_map;
+ vm->map_sg = nvc0_vm_map_sg;
+ vm->unmap = nvc0_vm_unmap;
+ vm->flush = nvc0_vm_flush;
+ vm->spg_shift = 12;
+ vm->lpg_shift = 17;
+ pgt_bits = 27;
+
+ /* Should be 4096 everywhere, this is a hack that's
+ * currently necessary to avoid an elusive bug that
+ * causes corruption when mixing small/large pages
+ */
+ if (length < (1ULL << 40))
+ block = 4096;
+ else {
+ block = (1 << pgt_bits);
+ if (length < block)
+ block = length;
+ }
} else {
kfree(vm);
return -ENOSYS;
@@ -314,10 +341,6 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset,
vm->refcount = 1;
vm->pgt_bits = pgt_bits - 12;
- block = (1 << pgt_bits);
- if (length < block)
- block = length;
-
ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
block >> 12);
if (ret) {