From 4872ac9c6204c3f212fd622ed292f6fc245020bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Jun 2008 04:39:32 +1000 Subject: nouveau: interface changes for nv5x 3d --- shared-core/nouveau_mem.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 861d699f..db207e76 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -606,8 +606,11 @@ nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, /* Align allocation sizes to 64KiB blocks on G8x. We use a 64KiB * page size in the GPU VM. */ - if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) - size = (size + (64 * 1024)) & ~((64 * 1024) - 1); + if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) { + size = (size + 65535) & ~65535; + if (alignment < 16) + alignment = 16; + } /* * Warn about 0 sized allocations, but let it go through. It'll return 1 page @@ -669,6 +672,7 @@ alloc_ok: struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; unsigned offset = block->start; unsigned count = block->size / 65536; + unsigned tile = 0; if (!pt) { DRM_ERROR("vm alloc without vm pt\n"); @@ -676,11 +680,22 @@ alloc_ok: return NULL; } + /* The tiling stuff is *not* what NVIDIA does - but both the + * 2D and 3D engines seem happy with this simpler method. + * Should look into why NVIDIA do what they do at some point. + */ + if (flags & NOUVEAU_MEM_TILE) { + if (flags & NOUVEAU_MEM_TILE_ZETA) + tile = 0x00002800; + else + tile = 0x00007000; + } + while (count--) { unsigned pte = offset / 65536; INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); - INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000); + INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile); offset += 65536; } } else { @@ -833,3 +848,53 @@ int nouveau_ioctl_mem_free(struct drm_device *dev, void *data, struct drm_file * nouveau_mem_free(dev, block); return 0; } + +int +nouveau_ioctl_mem_tile(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_tile *memtile = data; + struct mem_block *block = NULL; + + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + + if (dev_priv->card_type < NV_50) + return -EINVAL; + + if (memtile->flags & NOUVEAU_MEM_FB) { + memtile->offset -= 512*1024*1024; + block = find_block(dev_priv->fb_heap, memtile->offset); + } + + if (!block) + return -EINVAL; + + if (block->file_priv != file_priv) + return -EPERM; + + { + struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt; + unsigned offset = block->start + memtile->delta; + unsigned count = memtile->size / 65536; + unsigned tile = 0; + + if (memtile->flags & NOUVEAU_MEM_TILE) { + if (memtile->flags & NOUVEAU_MEM_TILE_ZETA) + tile = 0x00002800; + else + tile = 0x00007000; + } + + while (count--) { + unsigned pte = offset / 65536; + + INSTANCE_WR(pt, (pte * 2) + 0, offset | 1); + INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile); + offset += 65536; + } + } + + return 0; +} + -- cgit v1.2.3