aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-11-10 00:52:02 -0500
committerBen Skeggs <bskeggs@redhat.com>2014-12-02 00:44:09 -0500
commit5a560252387e6570342f2362bed89ffb437c3645 (patch)
tree7768f7ef30cd593792a390cde8a83816a43388ff /drivers/gpu/drm/nouveau
parent547ad072838c48e18cab7bccb5c02cbfefe10da5 (diff)
drm/nv50/kms: directly use cursor image from userspace buffer
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c14
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c67
2 files changed, 32 insertions, 49 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index c8e3f702ced7..5d93902a91ab 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -569,9 +569,10 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
569 569
570 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 570 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
571 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 571 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
572 572 if (nv_crtc->cursor.nvbo) {
573 nouveau_bo_unmap(nv_crtc->cursor.nvbo); 573 nouveau_bo_unmap(nv_crtc->cursor.nvbo);
574 nouveau_bo_unpin(nv_crtc->cursor.nvbo); 574 nouveau_bo_unpin(nv_crtc->cursor.nvbo);
575 }
575 } 576 }
576 577
577 return 0; 578 return 0;
@@ -599,6 +600,8 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
599 600
600 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 601 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
601 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 602 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
603 if (!nv_crtc->cursor.nvbo)
604 continue;
602 605
603 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true); 606 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
604 if (!ret) 607 if (!ret)
@@ -631,11 +634,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
631 634
632 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 635 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
633 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 636 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
634 u32 offset = nv_crtc->cursor.nvbo->bo.offset;
635 637
636 if (!nv_crtc->cursor.set_offset) 638 if (!nv_crtc->cursor.nvbo)
637 continue; 639 continue;
638 nv_crtc->cursor.set_offset(nv_crtc, offset); 640 nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
639 nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 641 nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
640 nv_crtc->cursor_saved_y); 642 nv_crtc->cursor_saved_y);
641 } 643 }
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 89bf8ce317c4..4a0373fba03b 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -125,6 +125,7 @@ nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
125 125
126struct nv50_curs { 126struct nv50_curs {
127 struct nv50_pioc base; 127 struct nv50_pioc base;
128 struct nouveau_bo *image;
128}; 129};
129 130
130static int 131static int
@@ -900,23 +901,24 @@ static void
900nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc) 901nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc)
901{ 902{
902 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 903 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
904 struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
903 u32 *push = evo_wait(mast, 16); 905 u32 *push = evo_wait(mast, 16);
904 if (push) { 906 if (push) {
905 if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { 907 if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) {
906 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); 908 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
907 evo_data(push, 0x85000000); 909 evo_data(push, 0x85000000);
908 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 910 evo_data(push, curs->image->bo.offset >> 8);
909 } else 911 } else
910 if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 912 if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
911 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); 913 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
912 evo_data(push, 0x85000000); 914 evo_data(push, 0x85000000);
913 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 915 evo_data(push, curs->image->bo.offset >> 8);
914 evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1); 916 evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
915 evo_data(push, mast->base.vram.handle); 917 evo_data(push, mast->base.vram.handle);
916 } else { 918 } else {
917 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2); 919 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
918 evo_data(push, 0x85000000); 920 evo_data(push, 0x85000000);
919 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 921 evo_data(push, curs->image->bo.offset >> 8);
920 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1); 922 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
921 evo_data(push, mast->base.vram.handle); 923 evo_data(push, mast->base.vram.handle);
922 } 924 }
@@ -953,8 +955,9 @@ static void
953nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update) 955nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update)
954{ 956{
955 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 957 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
958 struct nv50_curs *curs = nv50_curs(&nv_crtc->base);
956 959
957 if (show) 960 if (show && curs->image)
958 nv50_crtc_cursor_show(nv_crtc); 961 nv50_crtc_cursor_show(nv_crtc);
959 else 962 else
960 nv50_crtc_cursor_hide(nv_crtc); 963 nv50_crtc_cursor_hide(nv_crtc);
@@ -1054,7 +1057,7 @@ nv50_crtc_commit(struct drm_crtc *crtc)
1054 evo_kick(push, mast); 1057 evo_kick(push, mast);
1055 } 1058 }
1056 1059
1057 nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true); 1060 nv50_crtc_cursor_show_hide(nv_crtc, true, true);
1058 nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); 1061 nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
1059} 1062}
1060 1063
@@ -1249,13 +1252,13 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
1249 uint32_t handle, uint32_t width, uint32_t height) 1252 uint32_t handle, uint32_t width, uint32_t height)
1250{ 1253{
1251 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1254 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
1255 struct nv50_curs *curs = nv50_curs(crtc);
1252 struct drm_device *dev = crtc->dev; 1256 struct drm_device *dev = crtc->dev;
1253 struct drm_gem_object *gem; 1257 struct drm_gem_object *gem = NULL;
1254 struct nouveau_bo *nvbo; 1258 struct nouveau_bo *nvbo = NULL;
1255 bool visible = (handle != 0); 1259 int ret = 0;
1256 int i, ret = 0;
1257 1260
1258 if (visible) { 1261 if (handle) {
1259 if (width != 64 || height != 64) 1262 if (width != 64 || height != 64)
1260 return -EINVAL; 1263 return -EINVAL;
1261 1264
@@ -1264,23 +1267,17 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
1264 return -ENOENT; 1267 return -ENOENT;
1265 nvbo = nouveau_gem_object(gem); 1268 nvbo = nouveau_gem_object(gem);
1266 1269
1267 ret = nouveau_bo_map(nvbo); 1270 ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true);
1268 if (ret == 0) {
1269 for (i = 0; i < 64 * 64; i++) {
1270 u32 v = nouveau_bo_rd32(nvbo, i);
1271 nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, v);
1272 }
1273 nouveau_bo_unmap(nvbo);
1274 }
1275
1276 drm_gem_object_unreference_unlocked(gem);
1277 } 1271 }
1278 1272
1279 if (visible != nv_crtc->cursor.visible) { 1273 if (ret == 0) {
1280 nv50_crtc_cursor_show_hide(nv_crtc, visible, true); 1274 if (curs->image)
1281 nv_crtc->cursor.visible = visible; 1275 nouveau_bo_unpin(curs->image);
1276 nouveau_bo_ref(nvbo, &curs->image);
1282 } 1277 }
1278 drm_gem_object_unreference_unlocked(gem);
1283 1279
1280 nv50_crtc_cursor_show_hide(nv_crtc, true, true);
1284 return ret; 1281 return ret;
1285} 1282}
1286 1283
@@ -1335,10 +1332,10 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
1335 nouveau_bo_unpin(head->image); 1332 nouveau_bo_unpin(head->image);
1336 nouveau_bo_ref(NULL, &head->image); 1333 nouveau_bo_ref(NULL, &head->image);
1337 1334
1338 nouveau_bo_unmap(nv_crtc->cursor.nvbo); 1335 /*XXX: ditto */
1339 if (nv_crtc->cursor.nvbo) 1336 if (head->curs.image)
1340 nouveau_bo_unpin(nv_crtc->cursor.nvbo); 1337 nouveau_bo_unpin(head->curs.image);
1341 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); 1338 nouveau_bo_ref(NULL, &head->curs.image);
1342 1339
1343 nouveau_bo_unmap(nv_crtc->lut.nvbo); 1340 nouveau_bo_unmap(nv_crtc->lut.nvbo);
1344 if (nv_crtc->lut.nvbo) 1341 if (nv_crtc->lut.nvbo)
@@ -1422,22 +1419,6 @@ nv50_crtc_create(struct drm_device *dev, int index)
1422 if (ret) 1419 if (ret)
1423 goto out; 1420 goto out;
1424 1421
1425 ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
1426 0, 0x0000, NULL, NULL, &head->base.cursor.nvbo);
1427 if (!ret) {
1428 ret = nouveau_bo_pin(head->base.cursor.nvbo, TTM_PL_FLAG_VRAM, true);
1429 if (!ret) {
1430 ret = nouveau_bo_map(head->base.cursor.nvbo);
1431 if (ret)
1432 nouveau_bo_unpin(head->base.lut.nvbo);
1433 }
1434 if (ret)
1435 nouveau_bo_ref(NULL, &head->base.cursor.nvbo);
1436 }
1437
1438 if (ret)
1439 goto out;
1440
1441 /* allocate page flip / sync resources */ 1422 /* allocate page flip / sync resources */
1442 ret = nv50_base_create(disp->disp, index, disp->sync->bo.offset, 1423 ret = nv50_base_create(disp->disp, index, disp->sync->bo.offset,
1443 &head->sync); 1424 &head->sync);