summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <darktama@iinet.net.au>2007-01-08 00:37:39 +1100
committerBen Skeggs <darktama@iinet.net.au>2007-01-08 00:44:02 +1100
commitfaa46122993bc5970b3d67933bd81d863a3c4762 (patch)
treea0cbd550d458c4111c6bf045082e7275ae5461f6
parentcd3711455e7e5e69448b4805bddc2adcd480c6d5 (diff)
nouveau: avoid allocating vram that's used as instance memory.
-rw-r--r--shared-core/nouveau_drv.h5
-rw-r--r--shared-core/nouveau_fifo.c12
-rw-r--r--shared-core/nouveau_mem.c38
3 files changed, 39 insertions, 16 deletions
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 7b366f14..6b09046c 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -120,7 +120,8 @@ typedef struct drm_nouveau_private {
int fifo_alloc_count;
struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER];
- /* RAMFC and RAMRO offsets */
+ /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
+ uint32_t ramin_size;
uint32_t ramht_offset;
uint32_t ramht_size;
uint32_t ramht_bits;
@@ -165,7 +166,7 @@ extern void nouveau_mem_free(struct drm_device* dev, struct mem_blo
extern int nouveau_mem_init(struct drm_device *dev);
extern void nouveau_mem_close(struct drm_device *dev);
extern int nouveau_instmem_init(struct drm_device *dev,
- uint32_t offset, uint32_t size);
+ uint32_t offset);
extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev,
uint32_t size, uint32_t align);
extern void nouveau_instmem_free(struct drm_device *dev,
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c
index 0e47da08..e5f825e6 100644
--- a/shared-core/nouveau_fifo.c
+++ b/shared-core/nouveau_fifo.c
@@ -69,11 +69,10 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev)
static int nouveau_fifo_instmem_configure(drm_device_t *dev)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
- uint32_t obj_base, obj_size;
int i;
- /* Clear RAMIN */
- for (i=0x00710000; i<0x00800000; i++)
+ /* Clear start of RAMIN, enough to cover RAMFC/HT/RO basically */
+ for (i=0x00710000; i<0x00730000; i++)
NV_WRITE(i, 0x00000000);
/* FIFO hash table (RAMHT)
@@ -139,12 +138,9 @@ static int nouveau_fifo_instmem_configure(drm_device_t *dev)
dev_priv->ramfc_offset,
dev_priv->ramfc_size);
- obj_base = dev_priv->ramfc_offset + dev_priv->ramfc_size;
- obj_size = (512*1024) - obj_base; /*XXX: probably wrong on some cards*/
- if (nouveau_instmem_init(dev, obj_base, obj_size))
+ if (nouveau_instmem_init(dev, dev_priv->ramfc_offset +
+ dev_priv->ramfc_size))
return 1;
- DRM_DEBUG("RAMIN object space: offset=0x%08x, size=%dKiB\n",
- obj_base, obj_size>>10);
return 0;
}
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index df8641ed..cd53d25d 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -282,6 +282,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
int nouveau_mem_init(struct drm_device *dev)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
+ uint32_t fb_size;
dev_priv->agp_phys=0;
dev_priv->fb_phys=0;
@@ -340,15 +341,22 @@ no_agp:
/* Init FB */
dev_priv->fb_phys=drm_get_resource_start(dev,1);
- if (nouveau_mem_fb_amount(dev)>256*1024*1024) {
+ fb_size = nouveau_mem_fb_amount(dev);
+ /* On at least NV40, RAMIN is actually at the end of vram.
+ * We don't want to allocate this... */
+ if (dev_priv->card_type >= NV_40)
+ fb_size -= dev_priv->ramin_size;
+ DRM_DEBUG("Available VRAM: %dKiB\n", fb_size>>10);
+
+ if (fb_size>256*1024*1024) {
/* On cards with > 256Mb, you can't map everything.
* So we create a second FB heap for that type of memory */
if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), 256*1024*1024))
return DRM_ERR(ENOMEM);
- if (init_heap(&dev_priv->fb_nomap_heap, drm_get_resource_start(dev,1)+256*1024*1024, nouveau_mem_fb_amount(dev)-256*1024*1024))
+ if (init_heap(&dev_priv->fb_nomap_heap, drm_get_resource_start(dev,1)+256*1024*1024, fb_size-256*1024*1024))
return DRM_ERR(ENOMEM);
} else {
- if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), nouveau_mem_fb_amount(dev)))
+ if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), fb_size))
return DRM_ERR(ENOMEM);
dev_priv->fb_nomap_heap=NULL;
}
@@ -449,13 +457,31 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
free_block(block);
}
-int nouveau_instmem_init(struct drm_device *dev, uint32_t offset,
- uint32_t size)
+int nouveau_instmem_init(struct drm_device *dev, uint32_t offset)
{
drm_nouveau_private_t *dev_priv = dev->dev_private;
int ret;
- ret = init_heap(&dev_priv->ramin_heap, offset, size);
+ if (dev_priv->card_type >= NV_40)
+ /* We'll want more instance memory than this on some NV4x cards.
+ * There's a 16MB aperture to play with that maps onto the end
+ * of vram. For now, only reserve a small piece until we know
+ * more about what each chipset requires.
+ */
+ dev_priv->ramin_size = (1*1024* 1024);
+ else {
+ /*XXX: what *are* the limits on <NV40 cards?, and does RAMIN
+ * exist in vram on those cards as well?
+ */
+ dev_priv->ramin_size = (512*1024);
+ }
+ DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10);
+
+ /* Create a heap to manage RAMIN allocations, we don't allocate
+ * the space that was reserved for RAMHT/FC/RO.
+ */
+ ret = init_heap(&dev_priv->ramin_heap, offset,
+ dev_priv->ramin_size - offset);
if (ret) {
dev_priv->ramin_heap = NULL;
DRM_ERROR("Failed to init RAMIN heap\n");