summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_display.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2015-01-13 09:18:49 +0100
committerBen Skeggs <bskeggs@redhat.com>2015-01-22 12:15:08 +1000
commit4dc63933ea518501fe9cfe6a8f8797d21095e76f (patch)
treeeb98c163485dba66a0dac05e41188d3e14ce3bc4 /drivers/gpu/drm/nouveau/nv50_display.c
parent4d8bb03bced49526304592728002ebea54c7f224 (diff)
downloadlinux-4dc63933ea518501fe9cfe6a8f8797d21095e76f.tar.gz
linux-4dc63933ea518501fe9cfe6a8f8797d21095e76f.tar.bz2
linux-4dc63933ea518501fe9cfe6a8f8797d21095e76f.zip
drm/nouveau: dont switch vt on suspend
Restore the nv50 cursor bo on resume, and load the lut in nv50_display_display_init so it gets set on resume too. Tested on a fermi and a curie. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@ubuntu.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index fcbbf3884781..113e8cdb0b2b 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -125,7 +125,6 @@ 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
@@ -924,29 +923,29 @@ 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, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->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, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->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, curs->image->bo.offset >> 8);
+ evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
evo_data(push, mast->base.vram.handle);
}
evo_kick(push, mast);
}
+ nv_crtc->cursor.visible = true;
}
static void
@@ -972,15 +971,15 @@ nv50_crtc_cursor_hide(struct nouveau_crtc *nv_crtc)
}
evo_kick(push, mast);
}
+ nv_crtc->cursor.visible = false;
}
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 && curs->image)
+ if (show && nv_crtc->cursor.nvbo)
nv50_crtc_cursor_show(nv_crtc);
else
nv50_crtc_cursor_hide(nv_crtc);
@@ -1280,7 +1279,6 @@ 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 = NULL;
struct nouveau_bo *nvbo = NULL;
@@ -1299,9 +1297,9 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
}
if (ret == 0) {
- if (curs->image)
- nouveau_bo_unpin(curs->image);
- nouveau_bo_ref(nvbo, &curs->image);
+ if (nv_crtc->cursor.nvbo)
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+ nouveau_bo_ref(nvbo, &nv_crtc->cursor.nvbo);
}
drm_gem_object_unreference_unlocked(gem);
@@ -1312,10 +1310,14 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
static int
nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nv50_curs *curs = nv50_curs(crtc);
struct nv50_chan *chan = nv50_chan(curs);
nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff));
nvif_wr32(&chan->user, 0x0080, 0x00000000);
+
+ nv_crtc->cursor_saved_x = x;
+ nv_crtc->cursor_saved_y = y;
return 0;
}
@@ -1337,6 +1339,14 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
}
static void
+nv50_crtc_cursor_restore(struct nouveau_crtc *nv_crtc, int x, int y)
+{
+ nv50_crtc_cursor_move(&nv_crtc->base, x, y);
+
+ nv50_crtc_cursor_show_hide(nv_crtc, true, true);
+}
+
+static void
nv50_crtc_destroy(struct drm_crtc *crtc)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
@@ -1361,9 +1371,9 @@ nv50_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_ref(NULL, &head->image);
/*XXX: ditto */
- if (head->curs.image)
- nouveau_bo_unpin(head->curs.image);
- nouveau_bo_ref(NULL, &head->curs.image);
+ if (nv_crtc->cursor.nvbo)
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
+ nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
nouveau_bo_unmap(nv_crtc->lut.nvbo);
if (nv_crtc->lut.nvbo)
@@ -1413,6 +1423,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
head->base.set_color_vibrance = nv50_crtc_set_color_vibrance;
head->base.color_vibrance = 50;
head->base.vibrant_hue = 0;
+ head->base.cursor.set_pos = nv50_crtc_cursor_restore;
for (i = 0; i < 256; i++) {
head->base.lut.r[i] = i << 8;
head->base.lut.g[i] = i << 8;
@@ -1440,8 +1451,6 @@ nv50_crtc_create(struct drm_device *dev, int index)
if (ret)
goto out;
- nv50_crtc_lut_load(crtc);
-
/* allocate cursor resources */
ret = nv50_curs_create(disp->disp, index, &head->curs);
if (ret)
@@ -2419,6 +2428,8 @@ nv50_display_init(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nv50_sync *sync = nv50_sync(crtc);
+
+ nv50_crtc_lut_load(crtc);
nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data);
}