FreeBSD/sys/dev/drm/i915_dma.c
/* Really want an OS-independent resettable timer.  Would like to have
 * this loop run for (eg) 3 sec, but have the timer reset every time
 * the head pointer changes, so that EBUSY only happens if the ring
 * actually stalls for (eg) 3 seconds.
 */
Really want an OS-independent resettable timer.  Would like to have
this loop run for  3 seconds.
Really want an OS - independent resettable timer . Would like to have this loop run for 3 seconds .
int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
	u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
	u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
	u32 last_acthd = I915_READ(acthd_reg);
	u32 acthd;
	int i;
	for (i = 0; i < 100000; i++) {
		ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
		acthd = I915_READ(acthd_reg);
		ring->space = ring->head - (ring->tail + 8);
		if (ring->space < 0)
			ring->space += ring->Size;
		if (ring->space >= n)
			return 0;
		if (dev_priv->sarea_priv)
			dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
		if (ring->head != last_head)
			i = 0;
		if (acthd != last_acthd)
			i = 0;
		last_head = ring->head;
		last_acthd = acthd;
		DRM_UDELAY(10 * 1000);
	}
	return -EBUSY;
}
int i915_wait_ring ( struct drm_device * dev , int n , const char * caller ) { drm_i915_private_t * dev_priv = dev -> dev_private ; drm_i915_ring_buffer_t * ring = & ( dev_priv -> ring ) ; u32 last_head = I915_READ ( PRB0_HEAD ) & HEAD_ADDR ; u32 acthd_reg = IS_I965G ( dev ) ? ACTHD_I965 : ACTHD ; u32 last_acthd = I915_READ ( acthd_reg ) ; u32 acthd ; int i ; for ( i = 0 ; i < 100000 ; i ++ ) { ring -> head = I915_READ ( PRB0_HEAD ) & HEAD_ADDR ; acthd = I915_READ ( acthd_reg ) ; ring -> space = ring -> head - ( ring -> tail + 8 ) ; if ( ring -> space < 0 ) ring -> space += ring -> Size ; if ( ring -> space >= n ) return 0 ; if ( dev_priv -> sarea_priv ) dev_priv -> sarea_priv -> perf_boxes |= I915_BOX_WAIT ; if ( ring -> head != last_head ) i = 0 ; if ( acthd != last_acthd ) i = 0 ; last_head = ring -> head ; last_acthd = acthd ; DRM_UDELAY ( 10 * 1000 ) ; } return - EBUSY ; }
Really want an OS-independent resettable timer.
Really want an OS - independent resettable timer .