diff options
-rw-r--r-- | bsd-core/drmP.h | 1 | ||||
-rw-r--r-- | bsd-core/drm_irq.c | 42 | ||||
-rw-r--r-- | bsd-core/i915_drv.c | 1 | ||||
-rw-r--r-- | bsd-core/radeon_drv.c | 1 |
4 files changed, 37 insertions, 8 deletions
diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 243a984c..56605d1f 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -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; }; diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index a58307c5..6a852873 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -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(); diff --git a/bsd-core/i915_drv.c b/bsd-core/i915_drv.c index 5150cf9f..e8897fbe 100644 --- a/bsd-core/i915_drv.c +++ b/bsd-core/i915_drv.c @@ -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__ diff --git a/bsd-core/radeon_drv.c b/bsd-core/radeon_drv.c index 114b98dd..93f875c5 100644 --- a/bsd-core/radeon_drv.c +++ b/bsd-core/radeon_drv.c @@ -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__ |