summaryrefslogtreecommitdiff
path: root/src/sna/sna_display.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-15 23:07:16 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-15 23:07:16 +0100
commit1a389842347bab9d91240444e161589071eb9a47 (patch)
tree92da91e3041c5eebf2d488eb9c26df3f323052df /src/sna/sna_display.c
parent615739556dd1cc4565eb1c47f93fe8abd697802f (diff)
sna: Avoid queuing a pageflip on a DPMS off pipe
If the pipe is not running, attempting to queue a pageflip will result in an error and us disabling the output in retaliation. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_display.c')
-rw-r--r--src/sna/sna_display.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 841d8417..c36dda94 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -141,6 +141,7 @@ static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
__FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
assert(bo->tiling != I915_TILING_Y);
+ assert((bo->pitch & 63) == 0);
VG_CLEAR(arg);
arg.width = width;
@@ -2943,38 +2944,42 @@ void sna_mode_redisplay(struct sna *sna)
for (i = 0; i < config->num_crtc; i++) {
struct sna_crtc *crtc = config->crtc[i]->driver_private;
- struct drm_mode_crtc_page_flip arg;
- DBG(("%s: crtc %d active? %d\n",
- __FUNCTION__, i, crtc->bo != NULL));
+ DBG(("%s: crtc %d [%d, pipe=%d] active? %d\n",
+ __FUNCTION__, i, crtc->id, crtc->pipe, crtc->bo != NULL));
if (crtc->bo != old)
continue;
- arg.crtc_id = crtc->id;
- arg.fb_id = get_fb(sna, new,
- sna->scrn->virtualX,
- sna->scrn->virtualY);
- if (arg.fb_id == 0)
- goto disable;
-
- /* Only the reference crtc will finally deliver its page flip
- * completion event. All other crtc's events will be discarded.
- */
- arg.user_data = 0;
- arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
- arg.reserved = 0;
-
- if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
- DBG(("%s: flip [fb=%d] on crtc %d [%d] failed - %d\n",
- __FUNCTION__, arg.fb_id, i, crtc->id, errno));
+ assert(config->crtc[i]->enabled);
+
+ if (crtc->dpms_mode == DPMSModeOn) {
+ struct drm_mode_crtc_page_flip arg;
+ arg.crtc_id = crtc->id;
+ arg.fb_id = get_fb(sna, new,
+ sna->scrn->virtualX,
+ sna->scrn->virtualY);
+ if (arg.fb_id == 0)
+ goto disable;
+
+ /* Only the reference crtc will finally deliver its page flip
+ * completion event. All other crtc's events will be discarded.
+ */
+ arg.user_data = 0;
+ arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
+ arg.reserved = 0;
+
+ if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
+ DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
+ __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno));
disable:
- sna_crtc_disable(config->crtc[i]);
- continue;
+ sna_crtc_disable(config->crtc[i]);
+ continue;
+ }
+ sna->mode.shadow_flip++;
}
kgem_bo_destroy(&sna->kgem, old);
crtc->bo = kgem_bo_reference(new);
- sna->mode.shadow_flip++;
}
if (sna->mode.shadow) {