/* * Reserve one free slot in the blit queue. Will wait for one second for one * to become available. Otherwise -EBUSY is returned. */ static int via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) { struct drm_device *dev = blitq->dev; int ret=0; DRM_DEBUG("Num free is %d\n", blitq->num_free); mtx_lock(&blitq->blit_lock); while(blitq->num_free == 0) { mtx_unlock(&blitq->blit_lock); DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); if (ret) { return (-EINTR == ret) ? -EAGAIN : ret; } mtx_lock(&blitq->blit_lock); } blitq->num_free--; mtx_unlock(&blitq->blit_lock); return 0; }
int via_decoder_futex(DRM_IOCTL_ARGS) { DRM_DEVICE; drm_via_futex_t fx; volatile int *lock; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; drm_via_sarea_t *sAPriv = dev_priv->sarea_priv; int ret = 0; DRM_DEBUG("%s\n", __FUNCTION__); DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t __user *) data, sizeof(fx)); if (fx.lock > VIA_NR_XVMC_LOCKS) return -EFAULT; lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock); switch (fx.func) { case VIA_FUTEX_WAIT: DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock], (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val); return ret; case VIA_FUTEX_WAKE: DRM_WAKEUP(&(dev_priv->decoder_queue[fx.lock])); return 0; } return 0; }
int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_via_futex_t *fx = data; volatile int *lock; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; drm_via_sarea_t *sAPriv = dev_priv->sarea_priv; int ret = 0; DRM_DEBUG("\n"); if (fx->lock >= VIA_NR_XVMC_LOCKS) return -EFAULT; lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock); switch (fx->func) { case VIA_FUTEX_WAIT: DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock], (fx->ms / 10) * (DRM_HZ / 100), *lock != fx->val); return ret; case VIA_FUTEX_WAKE: DRM_WAKEUP(&(dev_priv->decoder_queue[fx->lock])); return 0; } return 0; }
static int i915_wait_irq(drm_device_t * dev, int irq_nr) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = 0; DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr, READ_BREADCRUMB(dev_priv)); if (READ_BREADCRUMB(dev_priv) >= irq_nr) return 0; dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); if (ret == DRM_ERR(EBUSY)) { DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n", __FUNCTION__, READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); } dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); return ret; }
int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *)dev->dev_private; unsigned int cur_vblank; int ret = 0; if ( !dev_priv ) { DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); return DRM_ERR(EINVAL); } radeon_acknowledge_irqs( dev_priv ); dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using vertical blanks... */ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) ) - *sequence ) <= (1<<23) ) ); *sequence = cur_vblank; return ret; }
int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct timeval now; union drm_wait_vblank *vblwait = data; int ret, flags, crtc, seq; if (!dev->irq_enabled || dev->vblank == NULL || vblwait->request.type & _DRM_VBLANK_SIGNAL) return (EINVAL); flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; if (crtc >= dev->vblank->vb_num) return (EINVAL); if ((ret = drm_vblank_get(dev, crtc)) != 0) return (ret); seq = drm_vblank_count(dev, crtc); if (vblwait->request.type & _DRM_VBLANK_RELATIVE) { vblwait->request.sequence += seq; vblwait->request.type &= ~_DRM_VBLANK_RELATIVE; } flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; if ((flags & _DRM_VBLANK_NEXTONMISS) && (seq - vblwait->request.sequence) <= (1<<23)) { vblwait->request.sequence = seq + 1; } if (flags & _DRM_VBLANK_EVENT) return (drm_queue_vblank_event(dev, crtc, vblwait, file_priv)); DPRINTF("%s: %d waiting on %d, current %d\n", __func__, crtc, vblwait->request.sequence, drm_vblank_count(dev, crtc)); DRM_WAIT_ON(ret, &dev->vblank->vb_crtcs[crtc], &dev->vblank->vb_lock, 3 * hz, "drmvblq", ((drm_vblank_count(dev, crtc) - vblwait->request.sequence) <= (1 << 23)) || dev->irq_enabled == 0); microtime(&now); vblwait->reply.tval_sec = now.tv_sec; vblwait->reply.tval_usec = now.tv_usec; vblwait->reply.sequence = drm_vblank_count(dev, crtc); DPRINTF("%s: %d done waiting, seq = %d\n", __func__, crtc, vblwait->reply.sequence); drm_vblank_put(dev, crtc); return (ret); }
int mga_driver_fence_wait(struct drm_device *dev, unsigned int *sequence) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; unsigned int cur_fence; int ret = 0; DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ, (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) - *sequence) <= (1 << 23))); *sequence = cur_fence; return ret; }
static int psb_vblank_do_wait(struct drm_device *dev, unsigned int *sequence, atomic_t * counter) { unsigned int cur_vblank; int ret = 0; DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; }
static int radeon_wait_irq(struct drm_device * dev, int swi_nr) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; int ret = 0; if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr) return 0; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr); return ret; }
int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) { unsigned int cur_vblank; int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using vertical blanks... */ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; }
static int via_dmablit_sync(drm_device_t *dev, uint32_t handle, int engine) { drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private; drm_via_blitq_t *blitq = dev_priv->blit_queues + engine; wait_queue_head_t *queue; int ret = 0; if (via_dmablit_active(blitq, engine, handle, &queue)) { DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ, !via_dmablit_active(blitq, engine, handle, NULL)); } DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n", handle, engine, ret); return ret; }
int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; unsigned int cur_fence; int ret = 0; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using fences. */ DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ, (((cur_fence = atomic_read(&dev_priv->last_fence_retired)) - *sequence) <= (1 << 23))); *sequence = cur_fence; return ret; }
int i915_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned int cur_vblank; int ret = 0; if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); } DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(&dev->vbl_received)) - *sequence) <= (1<<23))); *sequence = cur_vblank; return ret; }
int radeon_wait_irq(drm_device_t *dev, int swi_nr) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *)dev->dev_private; int ret = 0; if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr) return 0; dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; /* This is a hack to work around mysterious freezes on certain * systems: */ radeon_acknowledge_irqs( dev_priv ); DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); return ret; }
static int radeon_driver_vblank_do_wait(struct drm_device * dev, unsigned int *sequence, int crtc) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; unsigned int cur_vblank; int ret = 0; int ack = 0; atomic_t *counter; if (!dev_priv) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } if (crtc == DRM_RADEON_VBLANK_CRTC1) { counter = &dev->vbl_received; ack |= RADEON_CRTC_VBLANK_STAT; } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { counter = &dev->vbl_received2; ack |= RADEON_CRTC2_VBLANK_STAT; } else return -EINVAL; radeon_acknowledge_irqs(dev_priv, ack); dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using vertical blanks... */ DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23))); *sequence = cur_vblank; return ret; }
static int via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine) { int ret=0; unsigned long irqsave; DRM_DEBUG("Num free is %d\n", blitq->num_free); spin_lock_irqsave(&blitq->blit_lock, irqsave); while(blitq->num_free == 0) { spin_unlock_irqrestore(&blitq->blit_lock, irqsave); DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0); if (ret) { return (DRM_ERR(EINTR) == ret) ? DRM_ERR(EAGAIN) : ret; } spin_lock_irqsave(&blitq->blit_lock, irqsave); } blitq->num_free--; spin_unlock_irqrestore(&blitq->blit_lock, irqsave); return 0; }