summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsd-core/drmP.h1
-rw-r--r--bsd-core/drm_irq.c42
-rw-r--r--bsd-core/i915_drv.c1
-rw-r--r--bsd-core/radeon_drv.c1
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__