nouveau: avoid allocating vram that's used as instance memory.

main
Ben Skeggs 2007-01-08 00:37:39 +11:00
parent cd3711455e
commit faa4612299
3 changed files with 39 additions and 16 deletions

View File

@ -120,7 +120,8 @@ typedef struct drm_nouveau_private {
int fifo_alloc_count; int fifo_alloc_count;
struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER]; 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_offset;
uint32_t ramht_size; uint32_t ramht_size;
uint32_t ramht_bits; 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 int nouveau_mem_init(struct drm_device *dev);
extern void nouveau_mem_close(struct drm_device *dev); extern void nouveau_mem_close(struct drm_device *dev);
extern int nouveau_instmem_init(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, extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev,
uint32_t size, uint32_t align); uint32_t size, uint32_t align);
extern void nouveau_instmem_free(struct drm_device *dev, extern void nouveau_instmem_free(struct drm_device *dev,

View File

@ -69,11 +69,10 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev)
static int nouveau_fifo_instmem_configure(drm_device_t *dev) static int nouveau_fifo_instmem_configure(drm_device_t *dev)
{ {
drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_private_t *dev_priv = dev->dev_private;
uint32_t obj_base, obj_size;
int i; int i;
/* Clear RAMIN */ /* Clear start of RAMIN, enough to cover RAMFC/HT/RO basically */
for (i=0x00710000; i<0x00800000; i++) for (i=0x00710000; i<0x00730000; i++)
NV_WRITE(i, 0x00000000); NV_WRITE(i, 0x00000000);
/* FIFO hash table (RAMHT) /* 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_offset,
dev_priv->ramfc_size); dev_priv->ramfc_size);
obj_base = dev_priv->ramfc_offset + dev_priv->ramfc_size; if (nouveau_instmem_init(dev, dev_priv->ramfc_offset +
obj_size = (512*1024) - obj_base; /*XXX: probably wrong on some cards*/ dev_priv->ramfc_size))
if (nouveau_instmem_init(dev, obj_base, obj_size))
return 1; return 1;
DRM_DEBUG("RAMIN object space: offset=0x%08x, size=%dKiB\n",
obj_base, obj_size>>10);
return 0; return 0;
} }

View File

@ -282,6 +282,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
int nouveau_mem_init(struct drm_device *dev) int nouveau_mem_init(struct drm_device *dev)
{ {
drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_private_t *dev_priv = dev->dev_private;
uint32_t fb_size;
dev_priv->agp_phys=0; dev_priv->agp_phys=0;
dev_priv->fb_phys=0; dev_priv->fb_phys=0;
@ -340,15 +341,22 @@ no_agp:
/* Init FB */ /* Init FB */
dev_priv->fb_phys=drm_get_resource_start(dev,1); 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. /* On cards with > 256Mb, you can't map everything.
* So we create a second FB heap for that type of memory */ * 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)) if (init_heap(&dev_priv->fb_heap, drm_get_resource_start(dev,1), 256*1024*1024))
return DRM_ERR(ENOMEM); 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); return DRM_ERR(ENOMEM);
} else { } 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); return DRM_ERR(ENOMEM);
dev_priv->fb_nomap_heap=NULL; 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); free_block(block);
} }
int nouveau_instmem_init(struct drm_device *dev, uint32_t offset, int nouveau_instmem_init(struct drm_device *dev, uint32_t offset)
uint32_t size)
{ {
drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_private_t *dev_priv = dev->dev_private;
int ret; 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) { if (ret) {
dev_priv->ramin_heap = NULL; dev_priv->ramin_heap = NULL;
DRM_ERROR("Failed to init RAMIN heap\n"); DRM_ERROR("Failed to init RAMIN heap\n");