summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core/nouveau_mem.c')
-rw-r--r--shared-core/nouveau_mem.c79
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)