diff options
Diffstat (limited to 'shared-core/nouveau_mem.c')
-rw-r--r-- | shared-core/nouveau_mem.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 79f94fd4..f09bcea7 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -208,7 +208,7 @@ void nouveau_mem_takedown(struct mem_block **heap) void nouveau_mem_close(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; nouveau_mem_takedown(&dev_priv->agp_heap); nouveau_mem_takedown(&dev_priv->fb_heap); if ( dev_priv->pci_heap ) @@ -220,7 +220,7 @@ void nouveau_mem_close(struct drm_device *dev) /* returns the amount of FB ram in bytes */ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) { - drm_nouveau_private_t *dev_priv=dev->dev_private; + struct drm_nouveau_private *dev_priv=dev->dev_private; switch(dev_priv->card_type) { case NV_03: @@ -253,6 +253,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) } break; case NV_10: + case NV_11: case NV_17: case NV_20: case NV_30: @@ -285,7 +286,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; + struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t fb_size; drm_scatter_gather_t sgreq; dev_priv->agp_phys=0; @@ -339,16 +340,18 @@ int nouveau_mem_init(struct drm_device *dev) } if (nouveau_mem_init_heap(&dev_priv->agp_heap, - info.aperture_base, - info.aperture_size)) + 0, info.aperture_size)) goto no_agp; dev_priv->agp_phys = info.aperture_base; dev_priv->agp_available_size = info.aperture_size; + goto have_agp; } -goto have_agp; no_agp: + + if ( dev_priv->card_type >= NV_50 ) goto no_pci; + dev_priv->pci_heap = NULL; DRM_DEBUG("Allocating sg memory for PCI DMA\n"); if ( drm_sg_alloc(dev, &sgreq) ) @@ -357,8 +360,8 @@ no_agp: goto no_pci; } - DRM_DEBUG("Got %d KiB\n", (dev->sg->pages * PAGE_SIZE) >> 10); - if ( nouveau_mem_init_heap(&dev_priv->pci_heap, dev->sg->virtual, dev->sg->pages * PAGE_SIZE)) + if ( nouveau_mem_init_heap(&dev_priv->pci_heap, 0, + dev->sg->pages * PAGE_SIZE)) { DRM_ERROR("Unable to initialize pci_heap!"); goto no_pci; @@ -385,18 +388,13 @@ have_agp: /* On cards with > 256Mb, you can't map everything. * So we create a second FB heap for that type of memory */ if (nouveau_mem_init_heap(&dev_priv->fb_heap, - drm_get_resource_start(dev,1), - 256*1024*1024)) + 0, 256*1024*1024)) return DRM_ERR(ENOMEM); if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, - drm_get_resource_start(dev,1) + - 256*1024*1024, - fb_size-256*1024*1024)) + 256*1024*1024, fb_size-256*1024*1024)) return DRM_ERR(ENOMEM); } else { - if (nouveau_mem_init_heap(&dev_priv->fb_heap, - drm_get_resource_start(dev,1), - fb_size)) + if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size)) return DRM_ERR(ENOMEM); dev_priv->fb_nomap_heap=NULL; } @@ -408,7 +406,7 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6 { struct mem_block *block; int type; - drm_nouveau_private_t *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = dev->dev_private; /* * Make things easier on ourselves: all allocations are page-aligned. @@ -471,23 +469,32 @@ alloc_ok: if (flags&NOUVEAU_MEM_MAPPED) { + drm_map_list_t *entry; int ret = 0; block->flags|=NOUVEAU_MEM_MAPPED; if (type == NOUVEAU_MEM_AGP) - ret = drm_addmap(dev, block->start - dev->agp->base, block->size, - _DRM_AGP, 0, &block->map); - else if (type == NOUVEAU_MEM_FB) ret = drm_addmap(dev, block->start, block->size, - _DRM_FRAME_BUFFER, 0, &block->map); + _DRM_AGP, 0, &block->map); + else if (type == NOUVEAU_MEM_FB) + ret = drm_addmap(dev, block->start + dev_priv->fb_phys, + block->size, _DRM_FRAME_BUFFER, + 0, &block->map); else if (type == NOUVEAU_MEM_PCI) - ret = drm_addmap(dev, block->start - (unsigned long int)dev->sg->virtual, block->size, - _DRM_SCATTER_GATHER, 0, &block->map); + ret = drm_addmap(dev, block->start, block->size, + _DRM_SCATTER_GATHER, 0, &block->map); if (ret) { nouveau_mem_free_block(block); return NULL; } + + entry = drm_find_matching_map(dev, block->map); + if (!entry) { + nouveau_mem_free_block(block); + return NULL; + } + block->map_handle = entry->user_token; } DRM_INFO("allocated 0x%llx\n", block->start); @@ -509,8 +516,8 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_alloc_t alloc; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_alloc alloc; struct mem_block *block; if (!dev_priv) { @@ -518,16 +525,19 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) return DRM_ERR(EINVAL); } - DRM_COPY_FROM_USER_IOCTL(alloc, (drm_nouveau_mem_alloc_t __user *) data, + DRM_COPY_FROM_USER_IOCTL(alloc, + (struct drm_nouveau_mem_alloc_t __user *) data, sizeof(alloc)); block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); if (!block) return DRM_ERR(ENOMEM); - alloc.region_offset=block->start; + alloc.map_handle=block->map_handle; + alloc.offset=block->start; alloc.flags=block->flags; - DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); + DRM_COPY_TO_USER_IOCTL((struct drm_nouveau_mem_alloc __user *)data, + alloc, sizeof(alloc)); return 0; } @@ -535,18 +545,21 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS) int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) { DRM_DEVICE; - drm_nouveau_private_t *dev_priv = dev->dev_private; - drm_nouveau_mem_free_t memfree; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_mem_free memfree; struct mem_block *block; - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data, + DRM_COPY_FROM_USER_IOCTL(memfree, + (struct drm_nouveau_mem_free_t __user *)data, sizeof(memfree)); block=NULL; if (memfree.flags&NOUVEAU_MEM_FB) - block = find_block(dev_priv->fb_heap, memfree.region_offset); + block = find_block(dev_priv->fb_heap, memfree.offset); else if (memfree.flags&NOUVEAU_MEM_AGP) - block = find_block(dev_priv->agp_heap, memfree.region_offset); + block = find_block(dev_priv->agp_heap, memfree.offset); + else if (memfree.flags&NOUVEAU_MEM_PCI) + block = find_block(dev_priv->pci_heap, memfree.offset); if (!block) return DRM_ERR(EFAULT); if (block->filp != filp) |