Commit 5a560252 authored by Ben Skeggs's avatar Ben Skeggs

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 547ad072
...@@ -569,9 +569,10 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime) ...@@ -569,9 +569,10 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->cursor.nvbo) {
nouveau_bo_unmap(nv_crtc->cursor.nvbo); nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo); nouveau_bo_unpin(nv_crtc->cursor.nvbo);
}
} }
return 0; return 0;
...@@ -599,6 +600,8 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) ...@@ -599,6 +600,8 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 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); ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
if (!ret) if (!ret)
...@@ -631,11 +634,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime) ...@@ -631,11 +634,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 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; 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.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y); nv_crtc->cursor_saved_y);
} }
......
...@@ -125,6 +125,7 @@ nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head, ...@@ -125,6 +125,7 @@ nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
struct nv50_curs { struct nv50_curs {
struct nv50_pioc base; struct nv50_pioc base;
struct nouveau_bo *image;
}; };
static int static int
...@@ -900,23 +901,24 @@ static void ...@@ -900,23 +901,24 @@ static void
nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc) nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc)
{ {
struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 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); u32 *push = evo_wait(mast, 16);
if (push) { if (push) {
if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x85000000); evo_data(push, 0x85000000);
evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); evo_data(push, curs->image->bo.offset >> 8);
} else } else
if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) {
evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
evo_data(push, 0x85000000); 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_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
evo_data(push, mast->base.vram.handle); evo_data(push, mast->base.vram.handle);
} else { } else {
evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2); evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
evo_data(push, 0x85000000); 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_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
evo_data(push, mast->base.vram.handle); evo_data(push, mast->base.vram.handle);
} }
...@@ -953,8 +955,9 @@ static void ...@@ -953,8 +955,9 @@ static void
nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update) 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_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); nv50_crtc_cursor_show(nv_crtc);
else else
nv50_crtc_cursor_hide(nv_crtc); nv50_crtc_cursor_hide(nv_crtc);
...@@ -1054,7 +1057,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) ...@@ -1054,7 +1057,7 @@ nv50_crtc_commit(struct drm_crtc *crtc)
evo_kick(push, mast); 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); 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, ...@@ -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) uint32_t handle, uint32_t width, uint32_t height)
{ {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nv50_curs *curs = nv50_curs(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_gem_object *gem; struct drm_gem_object *gem = NULL;
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo = NULL;
bool visible = (handle != 0); int ret = 0;
int i, ret = 0;
if (visible) { if (handle) {
if (width != 64 || height != 64) if (width != 64 || height != 64)
return -EINVAL; return -EINVAL;
...@@ -1264,23 +1267,17 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ...@@ -1264,23 +1267,17 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
return -ENOENT; return -ENOENT;
nvbo = nouveau_gem_object(gem); nvbo = nouveau_gem_object(gem);
ret = nouveau_bo_map(nvbo); ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true);
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);
} }
if (visible != nv_crtc->cursor.visible) { if (ret == 0) {
nv50_crtc_cursor_show_hide(nv_crtc, visible, true); if (curs->image)
nv_crtc->cursor.visible = visible; 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; return ret;
} }
...@@ -1335,10 +1332,10 @@ nv50_crtc_destroy(struct drm_crtc *crtc) ...@@ -1335,10 +1332,10 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_unpin(head->image); nouveau_bo_unpin(head->image);
nouveau_bo_ref(NULL, &head->image); nouveau_bo_ref(NULL, &head->image);
nouveau_bo_unmap(nv_crtc->cursor.nvbo); /*XXX: ditto */
if (nv_crtc->cursor.nvbo) if (head->curs.image)
nouveau_bo_unpin(nv_crtc->cursor.nvbo); nouveau_bo_unpin(head->curs.image);
nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); nouveau_bo_ref(NULL, &head->curs.image);
nouveau_bo_unmap(nv_crtc->lut.nvbo); nouveau_bo_unmap(nv_crtc->lut.nvbo);
if (nv_crtc->lut.nvbo) if (nv_crtc->lut.nvbo)
...@@ -1419,22 +1416,6 @@ nv50_crtc_create(struct drm_device *dev, int index) ...@@ -1419,22 +1416,6 @@ nv50_crtc_create(struct drm_device *dev, int index)
/* allocate cursor resources */ /* allocate cursor resources */
ret = nv50_curs_create(disp->disp, index, &head->curs); 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) if (ret)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment