diff options
author | Jesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com> | 2007-09-24 14:41:46 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com> | 2007-09-24 14:41:46 -0700 |
commit | 5cc3083179b19678456905a9122a3d0f04e6f623 (patch) | |
tree | 9b776bdd317aa5af68b7cbf8fabde12e20eccf8a /shared-core/nouveau_notifier.c | |
parent | 2a2d02bbc500140a861380df52ce66abcac39312 (diff) | |
parent | 54df1b9ff3b79097fedd8ed7bf54aca30a660cbd (diff) |
Merge branch 'master' into modesetting-101 - TTM & typedef removal
Conflicts:
linux-core/drmP.h
linux-core/drm_bo.c
linux-core/drm_drv.c
linux-core/drm_objects.h
shared-core/drm.h
shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_irq.c
Mostly removing typedefs that snuck into the modesetting code and
updating to the latest TTM APIs. As of today, the i915 driver builds,
but there are likely to be problems, so debugging and bugfixes will
come next.
Diffstat (limited to 'shared-core/nouveau_notifier.c')
-rw-r--r-- | shared-core/nouveau_notifier.c | 126 |
1 files changed, 74 insertions, 52 deletions
diff --git a/shared-core/nouveau_notifier.c b/shared-core/nouveau_notifier.c index 0cfe733e..d3b79683 100644 --- a/shared-core/nouveau_notifier.c +++ b/shared-core/nouveau_notifier.c @@ -30,21 +30,30 @@ #include "nouveau_drv.h" int -nouveau_notifier_init_channel(drm_device_t *dev, int channel, DRMFILE filp) +nouveau_notifier_init_channel(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; int flags, ret; /*TODO: PCI notifier blocks */ +#ifndef __powerpc__ if (dev_priv->agp_heap) - flags = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE; + flags = NOUVEAU_MEM_AGP; + else +#endif + if (dev_priv->pci_heap) + flags = NOUVEAU_MEM_PCI; else flags = NOUVEAU_MEM_FB; + flags |= (NOUVEAU_MEM_MAPPED | NOUVEAU_MEM_FB_ACCEPTABLE); - chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags,filp); + chan->notifier_block = nouveau_mem_alloc(dev, 0, PAGE_SIZE, flags, + (struct drm_file *)-2); if (!chan->notifier_block) - return DRM_ERR(ENOMEM); + return -ENOMEM; + DRM_DEBUG("Allocated notifier block in 0x%08x\n", + chan->notifier_block->flags); ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, chan->notifier_block->size); @@ -55,71 +64,92 @@ nouveau_notifier_init_channel(drm_device_t *dev, int channel, DRMFILE filp) } void -nouveau_notifier_takedown_channel(drm_device_t *dev, int channel) +nouveau_notifier_takedown_channel(struct nouveau_channel *chan) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; + struct drm_device *dev = chan->dev; if (chan->notifier_block) { nouveau_mem_free(dev, chan->notifier_block); chan->notifier_block = NULL; } - /*XXX: heap destroy */ + nouveau_mem_takedown(&chan->notifier_heap); +} + +static void +nouveau_notifier_gpuobj_dtor(struct drm_device *dev, + struct nouveau_gpuobj *gpuobj) +{ + DRM_DEBUG("\n"); + + if (gpuobj->priv) + nouveau_mem_free_block(gpuobj->priv); } int -nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle, +nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, int count, uint32_t *b_offset) { - drm_nouveau_private_t *dev_priv = dev->dev_private; - struct nouveau_fifo *chan = &dev_priv->fifos[channel]; - struct nouveau_object *obj; + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *nobj = NULL; struct mem_block *mem; uint32_t offset; - int target; + int target, ret; if (!chan->notifier_heap) { DRM_ERROR("Channel %d doesn't have a notifier heap!\n", - channel); - return DRM_ERR(EINVAL); + chan->id); + return -EINVAL; } - mem = nouveau_mem_alloc_block(chan->notifier_heap, 32, 0, chan->filp); + mem = nouveau_mem_alloc_block(chan->notifier_heap, count*32, 0, + (struct drm_file *)-2); if (!mem) { - DRM_ERROR("Channel %d notifier block full\n", channel); - return DRM_ERR(ENOMEM); + DRM_ERROR("Channel %d notifier block full\n", chan->id); + return -ENOMEM; } mem->flags = NOUVEAU_MEM_NOTIFIER; - offset = chan->notifier_block->start + mem->start; + offset = chan->notifier_block->start; if (chan->notifier_block->flags & NOUVEAU_MEM_FB) { - offset -= drm_get_resource_start(dev, 1); target = NV_DMA_TARGET_VIDMEM; - } else if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { - offset -= dev_priv->agp_phys; - target = NV_DMA_TARGET_AGP; + } else + if (chan->notifier_block->flags & NOUVEAU_MEM_AGP) { + if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && + dev_priv->card_type < NV_50) { + ret = nouveau_sgdma_get_page(dev, offset, &offset); + if (ret) + return ret; + target = NV_DMA_TARGET_PCI; + } else { + target = NV_DMA_TARGET_AGP; + } + } else + if (chan->notifier_block->flags & NOUVEAU_MEM_PCI) { + target = NV_DMA_TARGET_PCI_NONLINEAR; } else { DRM_ERROR("Bad DMA target, flags 0x%08x!\n", chan->notifier_block->flags); - return DRM_ERR(EINVAL); + return -EINVAL; } + offset += mem->start; - obj = nouveau_object_dma_create(dev, channel, NV_CLASS_DMA_IN_MEMORY, - offset, mem->size, NV_DMA_ACCESS_RW, - target); - if (!obj) { + if ((ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + offset, mem->size, + NV_DMA_ACCESS_RW, target, &nobj))) { nouveau_mem_free_block(mem); - DRM_ERROR("Error creating notifier ctxdma\n"); - return DRM_ERR(ENOMEM); + DRM_ERROR("Error creating notifier ctxdma: %d\n", ret); + return ret; } + nobj->dtor = nouveau_notifier_gpuobj_dtor; + nobj->priv = mem; - obj->handle = handle; - if (nouveau_ramht_insert(dev, channel, handle, obj)) { - nouveau_object_free(dev, obj); + if ((ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL))) { + nouveau_gpuobj_del(dev, &nobj); nouveau_mem_free_block(mem); - DRM_ERROR("Error inserting notifier ctxdma into RAMHT\n"); - return DRM_ERR(ENOMEM); + DRM_ERROR("Error referencing notifier ctxdma: %d\n", ret); + return ret; } *b_offset = mem->start; @@ -127,28 +157,20 @@ nouveau_notifier_alloc(drm_device_t *dev, int channel, uint32_t handle, } int -nouveau_ioctl_notifier_alloc(DRM_IOCTL_ARGS) +nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { - DRM_DEVICE; - drm_nouveau_notifier_alloc_t na; + struct drm_nouveau_notifierobj_alloc *na = data; + struct nouveau_channel *chan; int ret; - DRM_COPY_FROM_USER_IOCTL(na, (drm_nouveau_notifier_alloc_t __user*)data, - sizeof(na)); - - if (!nouveau_fifo_owner(dev, filp, na.channel)) { - DRM_ERROR("pid %d doesn't own channel %d\n", - DRM_CURRENTPID, na.channel); - return DRM_ERR(EPERM); - } + NOUVEAU_CHECK_INITIALISED_WITH_RETURN; + NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); - ret = nouveau_notifier_alloc(dev, na.channel, na.handle, - na.count, &na.offset); + ret = nouveau_notifier_alloc(chan, na->handle, na->count, &na->offset); if (ret) return ret; - DRM_COPY_TO_USER_IOCTL((drm_nouveau_notifier_alloc_t __user*)data, - na, sizeof(na)); return 0; } |