]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/nouveau/nouveau_notifier.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / gpu / drm / nouveau / nouveau_notifier.c
index 2cc59f8c658bd63b840fbf35c7871d090a587d95..5ea167623a82cc74c2ae979899f2cd89ca1220ce 100644 (file)
@@ -96,48 +96,33 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
 
 int
 nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
-                      int size, uint32_t *b_offset)
+                      int size, uint32_t start, uint32_t end,
+                      uint32_t *b_offset)
 {
        struct drm_device *dev = chan->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_gpuobj *nobj = NULL;
        struct drm_mm_node *mem;
        uint32_t offset;
        int target, ret;
 
-       mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0);
+       mem = drm_mm_search_free_in_range(&chan->notifier_heap, size, 0,
+                                         start, end, 0);
        if (mem)
-               mem = drm_mm_get_block(mem, size, 0);
+               mem = drm_mm_get_block_range(mem, size, 0, start, end);
        if (!mem) {
                NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
                return -ENOMEM;
        }
 
-       offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT;
-       if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) {
-               target = NV_DMA_TARGET_VIDMEM;
-       } else
-       if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) {
-               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;
-                       if (dev_priv->card_type >= NV_50)
-                               offset += dev_priv->vm_gart_base;
-               }
-       } else {
-               NV_ERROR(dev, "Bad DMA target, mem_type %d!\n",
-                        chan->notifier_bo->bo.mem.mem_type);
-               return -EINVAL;
-       }
+       if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM)
+               target = NV_MEM_TARGET_VRAM;
+       else
+               target = NV_MEM_TARGET_GART;
+       offset  = chan->notifier_bo->bo.mem.start << PAGE_SHIFT;
        offset += mem->start;
 
        ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset,
-                                    mem->size, NV_DMA_ACCESS_RW, target,
+                                    mem->size, NV_MEM_ACCESS_RW, target,
                                     &nobj);
        if (ret) {
                drm_mm_put_block(mem);
@@ -181,15 +166,21 @@ int
 nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
                             struct drm_file *file_priv)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct drm_nouveau_notifierobj_alloc *na = data;
        struct nouveau_channel *chan;
        int ret;
 
-       NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
+       /* completely unnecessary for these chipsets... */
+       if (unlikely(dev_priv->card_type >= NV_C0))
+               return -EINVAL;
 
-       ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
-       if (ret)
-               return ret;
+       chan = nouveau_channel_get(dev, file_priv, na->channel);
+       if (IS_ERR(chan))
+               return PTR_ERR(chan);
 
-       return 0;
+       ret = nouveau_notifier_alloc(chan, na->handle, na->size, 0, 0x1000,
+                                    &na->offset);
+       nouveau_channel_put(&chan);
+       return ret;
 }