diff options
-rw-r--r-- | shared-core/nouveau_drv.h | 5 | ||||
-rw-r--r-- | shared-core/nouveau_fifo.c | 12 | ||||
-rw-r--r-- | shared-core/nouveau_mem.c | 38 |
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"); |