nouveau: separate region_offset into map_handle and offset.

main
Ben Skeggs 2007-07-12 10:15:16 +10:00
parent 5fbdf9da8b
commit 750371cb6e
9 changed files with 55 additions and 40 deletions

View File

@ -1048,6 +1048,9 @@ extern unsigned long drm_get_resource_start(drm_device_t *dev,
unsigned int resource); unsigned int resource);
extern unsigned long drm_get_resource_len(drm_device_t *dev, extern unsigned long drm_get_resource_len(drm_device_t *dev,
unsigned int resource); unsigned int resource);
extern drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
drm_local_map_t *map);
/* DMA support (drm_dma.h) */ /* DMA support (drm_dma.h) */
extern int drm_dma_setup(drm_device_t * dev); extern int drm_dma_setup(drm_device_t * dev);

View File

@ -48,8 +48,7 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
} }
EXPORT_SYMBOL(drm_get_resource_len); EXPORT_SYMBOL(drm_get_resource_len);
static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, drm_map_list_t *drm_find_matching_map(drm_device_t *dev, drm_local_map_t *map)
drm_local_map_t *map)
{ {
drm_map_list_t *entry; drm_map_list_t *entry;
list_for_each_entry(entry, &dev->maplist, head) { list_for_each_entry(entry, &dev->maplist, head) {
@ -62,6 +61,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
return NULL; return NULL;
} }
EXPORT_SYMBOL(drm_find_matching_map);
static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
unsigned long user_token, int hashed_handle) unsigned long user_token, int hashed_handle)

View File

@ -25,7 +25,7 @@
#ifndef __NOUVEAU_DRM_H__ #ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__ #define __NOUVEAU_DRM_H__
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 8 #define NOUVEAU_DRM_HEADER_PATCHLEVEL 9
typedef struct drm_nouveau_fifo_alloc { typedef struct drm_nouveau_fifo_alloc {
uint32_t fb_ctxdma_handle; uint32_t fb_ctxdma_handle;
@ -80,12 +80,13 @@ typedef struct drm_nouveau_mem_alloc {
int flags; int flags;
int alignment; int alignment;
uint64_t size; // in bytes uint64_t size; // in bytes
uint64_t region_offset; uint64_t offset;
drm_handle_t map_handle;
} }
drm_nouveau_mem_alloc_t; drm_nouveau_mem_alloc_t;
typedef struct drm_nouveau_mem_free { typedef struct drm_nouveau_mem_free {
uint64_t region_offset; uint64_t offset;
int flags; int flags;
} }
drm_nouveau_mem_free_t; drm_nouveau_mem_free_t;

View File

@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0 #define DRIVER_MAJOR 0
#define DRIVER_MINOR 0 #define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 8 #define DRIVER_PATCHLEVEL 9
#define NOUVEAU_FAMILY 0x0000FFFF #define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000 #define NOUVEAU_FLAGS 0xFFFF0000
@ -50,6 +50,7 @@ struct mem_block {
DRMFILE filp; /* 0: free, -1: heap, other: real files */ DRMFILE filp; /* 0: free, -1: heap, other: real files */
int flags; int flags;
drm_local_map_t *map; drm_local_map_t *map;
drm_handle_t map_handle;
}; };
enum nouveau_flags { enum nouveau_flags {

View File

@ -213,8 +213,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
DRM_DEBUG("Creating CB in AGP memory\n"); DRM_DEBUG("Creating CB in AGP memory\n");
ret = nouveau_gpuobj_dma_new(dev, channel, ret = nouveau_gpuobj_dma_new(dev, channel,
NV_CLASS_DMA_IN_MEMORY, NV_CLASS_DMA_IN_MEMORY,
cb->start - dev_priv->agp_phys, cb->start, cb->size,
cb->size,
NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, &pushbuf); NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, &pushbuf);
} else if ( cb->flags & NOUVEAU_MEM_PCI) { } else if ( cb->flags & NOUVEAU_MEM_PCI) {
DRM_DEBUG("Creating CB in PCI memory\n"); DRM_DEBUG("Creating CB in PCI memory\n");
@ -226,7 +225,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
} else if (dev_priv->card_type != NV_04) { } else if (dev_priv->card_type != NV_04) {
ret = nouveau_gpuobj_dma_new ret = nouveau_gpuobj_dma_new
(dev, channel, NV_CLASS_DMA_IN_MEMORY, (dev, channel, NV_CLASS_DMA_IN_MEMORY,
cb->start - drm_get_resource_start(dev, 1), cb->start,
cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM, cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_VIDMEM,
&pushbuf); &pushbuf);
} else { } else {
@ -236,7 +235,8 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel)
*/ */
ret = nouveau_gpuobj_dma_new ret = nouveau_gpuobj_dma_new
(dev, channel, NV_CLASS_DMA_IN_MEMORY, (dev, channel, NV_CLASS_DMA_IN_MEMORY,
cb->start, cb->size, NV_DMA_ACCESS_RO, cb->start + drm_get_resource_start(dev, 1),
cb->size, NV_DMA_ACCESS_RO,
NV_DMA_TARGET_PCI, &pushbuf); NV_DMA_TARGET_PCI, &pushbuf);
} }
@ -467,8 +467,9 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS)
{ {
DRM_DEVICE; DRM_DEVICE;
drm_nouveau_private_t *dev_priv = dev->dev_private; drm_nouveau_private_t *dev_priv = dev->dev_private;
struct nouveau_fifo *chan;
drm_nouveau_fifo_alloc_t init; drm_nouveau_fifo_alloc_t init;
drm_map_list_t *entry;
struct nouveau_fifo *chan;
int res; int res;
DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data, DRM_COPY_FROM_USER_IOCTL(init, (drm_nouveau_fifo_alloc_t __user *) data,
@ -501,12 +502,17 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS)
if (res != 0) if (res != 0)
return res; return res;
entry = drm_find_matching_map(dev, chan->regs);
if (!entry)
return DRM_ERR(EINVAL);
init.ctrl = entry->user_token;
/* pass back FIFO map info to the caller */ /* pass back FIFO map info to the caller */
init.cmdbuf = chan->pushbuf_mem->start; init.cmdbuf = chan->pushbuf_mem->map_handle;
init.cmdbuf_size = chan->pushbuf_mem->size; init.cmdbuf_size = chan->pushbuf_mem->size;
/* and the notifier block */ /* and the notifier block */
init.notifier = chan->notifier_block->start; init.notifier = chan->notifier_block->map_handle;
init.notifier_size = chan->notifier_block->size; init.notifier_size = chan->notifier_block->size;
DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data, DRM_COPY_TO_USER_IOCTL((drm_nouveau_fifo_alloc_t __user *)data,

View File

@ -339,8 +339,7 @@ int nouveau_mem_init(struct drm_device *dev)
} }
if (nouveau_mem_init_heap(&dev_priv->agp_heap, if (nouveau_mem_init_heap(&dev_priv->agp_heap,
info.aperture_base, 0, info.aperture_size))
info.aperture_size))
goto no_agp; goto no_agp;
dev_priv->agp_phys = info.aperture_base; dev_priv->agp_phys = info.aperture_base;
@ -360,7 +359,8 @@ no_agp:
goto no_pci; goto no_pci;
} }
if ( nouveau_mem_init_heap(&dev_priv->pci_heap, (uint64_t) 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!"); DRM_ERROR("Unable to initialize pci_heap!");
goto no_pci; goto no_pci;
@ -387,18 +387,13 @@ have_agp:
/* 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 (nouveau_mem_init_heap(&dev_priv->fb_heap, if (nouveau_mem_init_heap(&dev_priv->fb_heap,
drm_get_resource_start(dev,1), 0, 256*1024*1024))
256*1024*1024))
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
if (nouveau_mem_init_heap(&dev_priv->fb_nomap_heap, 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); return DRM_ERR(ENOMEM);
} else { } else {
if (nouveau_mem_init_heap(&dev_priv->fb_heap, if (nouveau_mem_init_heap(&dev_priv->fb_heap, 0, fb_size))
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;
} }
@ -473,23 +468,33 @@ alloc_ok:
if (flags&NOUVEAU_MEM_MAPPED) if (flags&NOUVEAU_MEM_MAPPED)
{ {
drm_map_list_t *entry;
int ret = 0; int ret = 0;
block->flags|=NOUVEAU_MEM_MAPPED; block->flags|=NOUVEAU_MEM_MAPPED;
if (type == NOUVEAU_MEM_AGP) if (type == NOUVEAU_MEM_AGP)
ret = drm_addmap(dev, block->start - dev->agp->base, block->size, ret = drm_addmap(dev, block->start + dev->agp->base,
_DRM_AGP, 0, &block->map); block->size, _DRM_AGP, 0, &block->map);
else if (type == NOUVEAU_MEM_FB) else if (type == NOUVEAU_MEM_FB)
ret = drm_addmap(dev, block->start, block->size, ret = drm_addmap(dev, block->start + dev_priv->fb_phys,
_DRM_FRAME_BUFFER, 0, &block->map); block->size, _DRM_FRAME_BUFFER,
0, &block->map);
else if (type == NOUVEAU_MEM_PCI) else if (type == NOUVEAU_MEM_PCI)
ret = drm_addmap(dev, block->start - (unsigned long int)dev->sg->virtual, block->size, ret = drm_addmap(dev, block->start, block->size,
_DRM_SCATTER_GATHER, 0, &block->map); _DRM_SCATTER_GATHER, 0, &block->map);
if (ret) { if (ret) {
nouveau_mem_free_block(block); nouveau_mem_free_block(block);
return NULL; return NULL;
} }
entry = drm_find_matching_map(dev, block->map);
if (!entry) {
nouveau_mem_free_block(block);
return NULL;
}
DRM_ERROR("user_token=0x%08x\n", entry->user_token);
block->map_handle = entry->user_token;
} }
DRM_INFO("allocated 0x%llx\n", block->start); DRM_INFO("allocated 0x%llx\n", block->start);
@ -526,7 +531,8 @@ int nouveau_ioctl_mem_alloc(DRM_IOCTL_ARGS)
block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp); block=nouveau_mem_alloc(dev, alloc.alignment, alloc.size, alloc.flags, filp);
if (!block) if (!block)
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
alloc.region_offset=block->start; alloc.map_handle=block->map_handle;
alloc.offset=block->start;
alloc.flags=block->flags; alloc.flags=block->flags;
DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc)); DRM_COPY_TO_USER_IOCTL((drm_nouveau_mem_alloc_t __user *) data, alloc, sizeof(alloc));
@ -546,11 +552,11 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS)
block=NULL; block=NULL;
if (memfree.flags&NOUVEAU_MEM_FB) 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) 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) else if (memfree.flags&NOUVEAU_MEM_PCI)
block = find_block(dev_priv->pci_heap, memfree.region_offset); block = find_block(dev_priv->pci_heap, memfree.offset);
if (!block) if (!block)
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
if (block->filp != filp) if (block->filp != filp)

View File

@ -95,10 +95,8 @@ nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle,
offset = chan->notifier_block->start + mem->start; offset = chan->notifier_block->start + mem->start;
if (chan->notifier_block->flags & NOUVEAU_MEM_FB) { if (chan->notifier_block->flags & NOUVEAU_MEM_FB) {
offset -= drm_get_resource_start(dev, 1);
target = NV_DMA_TARGET_VIDMEM; target = NV_DMA_TARGET_VIDMEM;
} else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { } else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) {
offset -= dev_priv->agp_phys;
target = NV_DMA_TARGET_AGP; target = NV_DMA_TARGET_AGP;
} else { } else {
DRM_ERROR("Bad DMA target, flags 0x%08x!\n", DRM_ERROR("Bad DMA target, flags 0x%08x!\n",

View File

@ -357,12 +357,12 @@ nouveau_gpuobj_instance_get(drm_device_t *dev, int channel,
DRM_ERROR("AII, no VRAM backing gpuobj\n"); DRM_ERROR("AII, no VRAM backing gpuobj\n");
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
*inst = gpuobj->im_backing->start - dev_priv->fb_phys; *inst = gpuobj->im_backing->start;
return 0; return 0;
} else { } else {
/* ...from local heap */ /* ...from local heap */
cpramin = dev_priv->fifos[gpuobj->im_channel]->ramin->gpuobj; cpramin = dev_priv->fifos[gpuobj->im_channel]->ramin->gpuobj;
*inst = (cpramin->im_backing->start - dev_priv->fb_phys) + *inst = cpramin->im_backing->start +
(gpuobj->im_pramin->start - cpramin->im_pramin->start); (gpuobj->im_pramin->start - cpramin->im_pramin->start);
return 0; return 0;
} }
@ -917,7 +917,7 @@ nouveau_gpuobj_channel_init(drm_device_t *dev, int channel,
} }
} }
else { else {
if ( dev_priv -> card_type >= NV_50 ) return 0; /*no PCIGART for NV50*/ if (dev_priv -> card_type >= NV_50 ) return 0; /*no PCIGART for NV50*/
/*PCI*/ /*PCI*/
if((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, if((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY,

View File

@ -215,7 +215,7 @@ nv50_instmem_bind(drm_device_t *dev, nouveau_gpuobj_t *gpuobj)
pte = (gpuobj->im_pramin->start >> 12) << 3; pte = (gpuobj->im_pramin->start >> 12) << 3;
pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte;
vram = gpuobj->im_backing->start - dev_priv->fb_phys; vram = gpuobj->im_backing->start;
if (pte == pte_end) { if (pte == pte_end) {
DRM_ERROR("WARNING: badness in bind() pte calc\n"); DRM_ERROR("WARNING: badness in bind() pte calc\n");