summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@jbarnes-t61.(none)>2008-06-24 10:41:46 -0700
committerEric Anholt <eric@anholt.net>2008-06-26 09:30:41 -0700
commit21a63e9e193b91345cdab077a8ec80b3d8a80690 (patch)
tree2260cf5b948010409fb3fce77fcac7650ffee722
parent313e9383121d74f448d4d26910085c0915163d8a (diff)
Add support for keeping vblank counters sane across mode setting
The DRM supports disabling of vblank interrupts when not in use, but in order to function properly it must also be aware of mode setting, which will reset the frame counter to 0. Add code to call into the DRM before and after mode setting, so that it can account for any lost vblank events. (cherry picked from commit 65eee25d7d2ca979205f3776d620dbb36bf68a13)
-rw-r--r--src/i830_display.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/i830_display.c b/src/i830_display.c
index 7857ee36..43a761ce 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -35,6 +35,7 @@
#include <assert.h>
#include <stdlib.h>
#include <math.h>
+#include <sys/ioctl.h>
#include "xf86.h"
#include "i830.h"
@@ -730,6 +731,39 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
return TRUE;
}
+#if defined(DRM_IOCTL_MODESET_CTL) && defined(XF86DRI)
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ struct drm_modeset_ctl modeset;
+
+ modeset.crtc = intel_crtc->plane;
+
+ /*
+ * DPMS will be called many times (especially off), but we only
+ * want to catch the transition from on->off and off->on.
+ */
+ if (pre && intel_crtc->dpms_mode != DPMSModeOff) {
+ /* On -> off is a pre modeset */
+ modeset.cmd = _DRM_PRE_MODESET;
+ ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+ ErrorF("modeset: on -> off on plane %d\n", modeset.crtc);
+ } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) {
+ /* Off -> on means post modeset */
+ modeset.cmd = _DRM_POST_MODESET;
+ ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset);
+ ErrorF("modeset: off -> on on plane %d\n", modeset.crtc);
+ }
+}
+#else
+static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state)
+{
+ return;
+}
+#endif /* DRM_IOCTL_MODESET_CTL && XF86DRI */
+
/**
* Sets the power management mode of the pipe and plane.
*
@@ -797,8 +831,10 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Reenable compression if needed */
if (i830_use_fb_compression(crtc))
i830_enable_fb_compression(crtc);
+ i830_modeset_ctl(crtc, 0);
break;
case DPMSModeOff:
+ i830_modeset_ctl(crtc, 1);
/* Shut off compression if in use */
if (i830_use_fb_compression(crtc))
i830_disable_fb_compression(crtc);