]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/gpu/drm/nouveau/nouveau_bo.c
Merge tag 'spi-v3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
[linux-imx.git] / drivers / gpu / drm / nouveau / nouveau_bo.c
index 4b1afb131380312bc971117635c9ac072fbdba1a..af20fba3a1a47ae441f8c587d79670d445ed6374 100644 (file)
@@ -148,6 +148,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
 
        if (unlikely(nvbo->gem))
                DRM_ERROR("bo %p still attached to GEM object\n", bo);
+       WARN_ON(nvbo->pin_refcnt > 0);
        nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
        kfree(nvbo);
 }
@@ -197,6 +198,17 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
        size_t acc_size;
        int ret;
        int type = ttm_bo_type_device;
+       int lpg_shift = 12;
+       int max_size;
+
+       if (drm->client.base.vm)
+               lpg_shift = drm->client.base.vm->vmm->lpg_shift;
+       max_size = INT_MAX & ~((1 << lpg_shift) - 1);
+
+       if (size <= 0 || size > max_size) {
+               nv_warn(drm, "skipped size %x\n", (u32)size);
+               return -EINVAL;
+       }
 
        if (sg)
                type = ttm_bo_type_sg;
@@ -340,13 +352,15 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
 {
        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret;
+       int ret, ref;
 
        ret = ttm_bo_reserve(bo, false, false, false, 0);
        if (ret)
                return ret;
 
-       if (--nvbo->pin_refcnt)
+       ref = --nvbo->pin_refcnt;
+       WARN_ON_ONCE(ref < 0);
+       if (ref)
                goto out;
 
        nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
@@ -578,7 +592,7 @@ nve0_bo_move_init(struct nouveau_channel *chan, u32 handle)
        int ret = RING_SPACE(chan, 2);
        if (ret == 0) {
                BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
-               OUT_RING  (chan, handle);
+               OUT_RING  (chan, handle & 0x0000ffff);
                FIRE_RING (chan);
        }
        return ret;
@@ -973,7 +987,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
        struct ttm_mem_reg *old_mem = &bo->mem;
        int ret;
 
-       mutex_lock(&chan->cli->mutex);
+       mutex_lock_nested(&chan->cli->mutex, SINGLE_DEPTH_NESTING);
 
        /* create temporary vmas for the transfer and attach them to the
         * old nouveau_mem node, these will get cleaned up after ttm has
@@ -1014,7 +1028,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
                            struct ttm_mem_reg *, struct ttm_mem_reg *);
                int (*init)(struct nouveau_channel *, u32 handle);
        } _methods[] = {
-               {  "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
+               {  "COPY", 4, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
                {  "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
                { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
                { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
@@ -1034,7 +1048,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
                struct nouveau_channel *chan;
                u32 handle = (mthd->engine << 16) | mthd->oclass;
 
-               if (mthd->init == nve0_bo_move_init)
+               if (mthd->engine)
                        chan = drm->cechan;
                else
                        chan = drm->channel;