summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_object.c
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-03-12 23:37:29 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-03-13 00:23:52 +1100
commit1766e1c07b03c6ccf545469663334be762c0bddf (patch)
treee60ee35ad5f843a882a1f4b65700ab66eea76c60 /shared-core/nouveau_object.c
parent88bd1e4a350d011ec44f6786e0bfdf8fb386800c (diff)
nv50: force channel vram access through vm
If we ever want to be able to use the 3D engine we have no choice. It appears that the tiling setup (required for 3D on G8x) is in the page tables. The immediate benefit of this change however is that it's now not possible for a client to use the GPU to render over the top of important engine setup tables, which also live in VRAM. G8x VRAM size is limited to 512MiB at the moment, as we use a 1-1 mapping of real vram pages to their offset within the start of a channel's VRAM DMA object and only populate a single PDE for VRAM use.
Diffstat (limited to 'shared-core/nouveau_object.c')
-rw-r--r--shared-core/nouveau_object.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c
index b6bf759d..09f9027a 100644
--- a/shared-core/nouveau_object.c
+++ b/shared-core/nouveau_object.c
@@ -983,7 +983,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
return ret;
}
- /* NV50 VM, point offset 0-512MiB at shared PCIEGART table */
+ /* NV50 VM
+ * - Allocate per-channel page-directory
+ * - Point offset 0-512MiB at shared PCIEGART table
+ * - Point offset 512-1024MiB at shared VRAM table
+ */
if (dev_priv->card_type >= NV_50) {
uint32_t vm_offset;
@@ -1004,6 +1008,14 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
INSTANCE_WR(chan->vm_pd, (0+0)/4,
chan->vm_gart_pt->instance | 0x03);
INSTANCE_WR(chan->vm_pd, (0+4)/4, 0x00000000);
+
+ if ((ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
+ dev_priv->vm_vram_pt,
+ &chan->vm_vram_pt)))
+ return ret;
+ INSTANCE_WR(chan->vm_pd, (8+0)/4,
+ chan->vm_vram_pt->instance | 0x61);
+ INSTANCE_WR(chan->vm_pd, (8+4)/4, 0x00000000);
}
/* RAMHT */
@@ -1022,6 +1034,17 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
}
/* VRAM ctxdma */
+ if (dev_priv->card_type >= NV_50) {
+ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
+ 512*1024*1024,
+ dev_priv->fb_available_size,
+ NV_DMA_ACCESS_RW,
+ NV_DMA_TARGET_AGP, &vram);
+ if (ret) {
+ DRM_ERROR("Error creating VRAM ctxdma: %d\n", ret);
+ return ret;
+ }
+ } else
if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
0, dev_priv->fb_available_size,
NV_DMA_ACCESS_RW,
@@ -1084,6 +1107,7 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
nouveau_gpuobj_del(dev, &chan->vm_pd);
nouveau_gpuobj_ref_del(dev, &chan->vm_gart_pt);
+ nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt);
if (chan->ramin_heap)
nouveau_mem_takedown(&chan->ramin_heap);