drm/nv50/kms: directly use cursor image from userspace buffer
authorBen Skeggs <bskeggs@redhat.com>
Mon, 10 Nov 2014 05:52:02 +0000 (15:52 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 2 Dec 2014 05:44:09 +0000 (15:44 +1000)
Preparation for transition to planes, which use framebuffers for the
cursor image.  We've always done copies from the userspace buffer up
until now for legacy reasons, there's no good reason to do so on the
chipsets this code covers.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nv50_display.c

index c8e3f702ced72a30645f34a8ca7c867de6063066..5d93902a91ab038cfe040197f767c0de05d7931f 100644 (file)
@@ -569,9 +569,10 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-
-               nouveau_bo_unmap(nv_crtc->cursor.nvbo);
-               nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+               if (nv_crtc->cursor.nvbo) {
+                       nouveau_bo_unmap(nv_crtc->cursor.nvbo);
+                       nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+               }
        }
 
        return 0;
@@ -599,6 +600,8 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+               if (!nv_crtc->cursor.nvbo)
+                       continue;
 
                ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
                if (!ret)
@@ -631,11 +634,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
 
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-               u32 offset = nv_crtc->cursor.nvbo->bo.offset;
 
-               if (!nv_crtc->cursor.set_offset)
+               if (!nv_crtc->cursor.nvbo)
                        continue;
-               nv_crtc->cursor.set_offset(nv_crtc, offset);
+               nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
                nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
                                                 nv_crtc->cursor_saved_y);
        }
index 89bf8ce317c49f04a8ff60f1009201f46940a165..4a0373fba03b4caedde23a68cb2bff32269bd686 100644 (file)
@@ -125,6 +125,7 @@ nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
 
 struct nv50_curs {
        struct nv50_pioc base;
+       struct nouveau_bo *image;
 };
 
 static int
@@ -900,23 +901,24 @@ static void
 nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc)
 {
        struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
+       struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
        u32 *push = evo_wait(mast, 16);
        if (push) {
                if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) {
                        evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
                        evo_data(push, 0x85000000);
-                       evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
+                       evo_data(push, curs->image->bo.offset >> 8);
                } else
                if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
                        evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
                        evo_data(push, 0x85000000);
-                       evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
+                       evo_data(push, curs->image->bo.offset >> 8);
                        evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
                        evo_data(push, mast->base.vram.handle);
                } else {
                        evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
                        evo_data(push, 0x85000000);
-                       evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
+                       evo_data(push, curs->image->bo.offset >> 8);
                        evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
                        evo_data(push, mast->base.vram.handle);
                }
@@ -953,8 +955,9 @@ static void
 nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update)
 {
        struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
+       struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
 
-       if (show)
+       if (show && curs->image)
                nv50_crtc_cursor_show(nv_crtc);
        else
                nv50_crtc_cursor_hide(nv_crtc);
@@ -1054,7 +1057,7 @@ nv50_crtc_commit(struct drm_crtc *crtc)
                evo_kick(push, mast);
        }
 
-       nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true);
+       nv50_crtc_cursor_show_hide(nv_crtc, true, true);
        nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
 }
 
@@ -1249,13 +1252,13 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
                     uint32_t handle, uint32_t width, uint32_t height)
 {
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
+       struct nv50_curs *curs = nv50_curs(crtc);
        struct drm_device *dev = crtc->dev;
-       struct drm_gem_object *gem;
-       struct nouveau_bo *nvbo;
-       bool visible = (handle != 0);
-       int i, ret = 0;
+       struct drm_gem_object *gem = NULL;
+       struct nouveau_bo *nvbo = NULL;
+       int ret = 0;
 
-       if (visible) {
+       if (handle) {
                if (width != 64 || height != 64)
                        return -EINVAL;
 
@@ -1264,23 +1267,17 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
                        return -ENOENT;
                nvbo = nouveau_gem_object(gem);
 
-               ret = nouveau_bo_map(nvbo);
-               if (ret == 0) {
-                       for (i = 0; i < 64 * 64; i++) {
-                               u32 v = nouveau_bo_rd32(nvbo, i);
-                               nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, v);
-                       }
-                       nouveau_bo_unmap(nvbo);
-               }
-
-               drm_gem_object_unreference_unlocked(gem);
+               ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true);
        }
 
-       if (visible != nv_crtc->cursor.visible) {
-               nv50_crtc_cursor_show_hide(nv_crtc, visible, true);
-               nv_crtc->cursor.visible = visible;
+       if (ret == 0) {
+               if (curs->image)
+                       nouveau_bo_unpin(curs->image);
+               nouveau_bo_ref(nvbo, &curs->image);
        }
+       drm_gem_object_unreference_unlocked(gem);
 
+       nv50_crtc_cursor_show_hide(nv_crtc, true, true);
        return ret;
 }
 
@@ -1335,10 +1332,10 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
                nouveau_bo_unpin(head->image);
        nouveau_bo_ref(NULL, &head->image);
 
-       nouveau_bo_unmap(nv_crtc->cursor.nvbo);
-       if (nv_crtc->cursor.nvbo)
-               nouveau_bo_unpin(nv_crtc->cursor.nvbo);
-       nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
+       /*XXX: ditto */
+       if (head->curs.image)
+               nouveau_bo_unpin(head->curs.image);
+       nouveau_bo_ref(NULL, &head->curs.image);
 
        nouveau_bo_unmap(nv_crtc->lut.nvbo);
        if (nv_crtc->lut.nvbo)
@@ -1419,22 +1416,6 @@ nv50_crtc_create(struct drm_device *dev, int index)
 
        /* allocate cursor resources */
        ret = nv50_curs_create(disp->disp, index, &head->curs);
-       if (ret)
-               goto out;
-
-       ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
-                            0, 0x0000, NULL, NULL, &head->base.cursor.nvbo);
-       if (!ret) {
-               ret = nouveau_bo_pin(head->base.cursor.nvbo, TTM_PL_FLAG_VRAM, true);
-               if (!ret) {
-                       ret = nouveau_bo_map(head->base.cursor.nvbo);
-                       if (ret)
-                               nouveau_bo_unpin(head->base.lut.nvbo);
-               }
-               if (ret)
-                       nouveau_bo_ref(NULL, &head->base.cursor.nvbo);
-       }
-
        if (ret)
                goto out;