bsd: Now make secondary vblank work
authorRobert Noland <rnoland@2hip.net>
Sun, 2 Dec 2007 06:23:11 +0000 (01:23 -0500)
committerRobert Noland <rnoland@2hip.net>
Sun, 2 Dec 2007 06:23:11 +0000 (01:23 -0500)
We needed to specifically check for driver support and test the correct
vbl_received value.  Also pulled over support for _DRM_VBLANK_NEXTONMISS
from the linux code.

bsd-core/drmP.h
bsd-core/drm_irq.c
bsd-core/i915_drv.c
bsd-core/radeon_drv.c

index 243a984..56605d1 100644 (file)
@@ -687,6 +687,7 @@ struct drm_driver_info {
        unsigned use_dma_queue :1;
        unsigned use_irq :1;
        unsigned use_vbl_irq :1;
+       unsigned use_vbl_irq2 :1;
        unsigned use_mtrr :1;
 };
 
index a58307c..6a85287 100644 (file)
@@ -211,17 +211,43 @@ int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
 {
        drm_wait_vblank_t *vblwait = data;
        struct timeval now;
-       int ret, flags;
+       int ret = 0;
+       int flags, seq;
 
        if (!dev->irq_enabled)
                return EINVAL;
 
-       if (vblwait->request.type & _DRM_VBLANK_RELATIVE) {
-               vblwait->request.sequence += atomic_read(&dev->vbl_received);
-               vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
+       if (vblwait->request.type &
+           ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
+               DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
+                   vblwait->request.type,
+                   (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
+               return EINVAL;
        }
 
        flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
+
+       if ((flags & _DRM_VBLANK_SECONDARY) && !dev->driver.use_vbl_irq2)
+               return EINVAL;
+       
+       seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ?
+           &dev->vbl_received2 : &dev->vbl_received);
+
+       switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
+       case _DRM_VBLANK_RELATIVE:
+               vblwait->request.sequence += seq;
+               vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
+       case _DRM_VBLANK_ABSOLUTE:
+               break;
+       default:
+               return EINVAL;
+       }
+
+       if ((flags & _DRM_VBLANK_NEXTONMISS) &&
+           (seq - vblwait->request.sequence) <= (1<<23)) {
+               vblwait->request.sequence = seq + 1;
+       }
+
        if (flags & _DRM_VBLANK_SIGNAL) {
 #if 0 /* disabled */
                drm_vbl_sig_t *vbl_sig = malloc(sizeof(drm_vbl_sig_t), M_DRM,
@@ -247,10 +273,10 @@ int drm_wait_vblank(drm_device_t *dev, void *data, struct drm_file *file_priv)
                if (flags & _DRM_VBLANK_SECONDARY) {
                        if (dev->driver.vblank_wait2)
                                ret = -dev->driver.vblank_wait2(dev,
-                                       &vblwait->request.sequence);
-                       } else if (dev->driver.vblank_wait)
-                               ret = -dev->driver.vblank_wait(dev,
-                                       &vblwait->request.sequence);
+                                   &vblwait->request.sequence);
+               } else if (dev->driver.vblank_wait)
+                       ret = -dev->driver.vblank_wait(dev,
+                           &vblwait->request.sequence);
 
                DRM_UNLOCK();
 
index 5150cf9..e8897fb 100644 (file)
@@ -69,6 +69,7 @@ static void i915_configure(drm_device_t *dev)
        dev->driver.use_mtrr            = 1;
        dev->driver.use_irq             = 1;
        dev->driver.use_vbl_irq         = 1;
+       dev->driver.use_vbl_irq2        = 1;
 }
 
 #ifdef __FreeBSD__
index 114b98d..93f875c 100644 (file)
@@ -77,6 +77,7 @@ static void radeon_configure(drm_device_t *dev)
        dev->driver.use_dma             = 1;
        dev->driver.use_irq             = 1;
        dev->driver.use_vbl_irq         = 1;
+       dev->driver.use_vbl_irq2        = 1;
 }
 
 #ifdef __FreeBSD__