diff options
Diffstat (limited to 'bsd-core')
| -rw-r--r-- | bsd-core/drmP.h | 27 | ||||
| -rw-r--r-- | bsd-core/drm_irq.c | 101 | 
2 files changed, 46 insertions, 82 deletions
| diff --git a/bsd-core/drmP.h b/bsd-core/drmP.h index 326b2202..473427f3 100644 --- a/bsd-core/drmP.h +++ b/bsd-core/drmP.h @@ -608,6 +608,19 @@ typedef struct drm_vbl_sig {  	int		pid;  } drm_vbl_sig_t; +struct drm_vblank_info { +	wait_queue_head_t queue;	/* vblank wait queue */ +	atomic_t count;			/* number of VBLANK interrupts */ +					/* (driver must alloc the right number of counters) */ +	struct drm_vbl_sig_list sigs;	/* signal list to send on VBLANK */ +	atomic_t refcount;		/* number of users of vblank interrupts */ +	u32 last;			/* protected by dev->vbl_lock, used */ +					/* for wraparound handling */ +	int enabled;			/* so we don't call enable more than */ +					/* once per disable */ +	int inmodeset;			/* Display driver is setting mode */ +}; +  /* location of GART table */  #define DRM_ATI_GART_MAIN 1  #define DRM_ATI_GART_FB   2 @@ -787,20 +800,12 @@ struct drm_device {  	atomic_t	  context_flag;	/* Context swapping flag	   */  	int		  last_context;	/* Last current context		   */ +  	int		  vblank_disable_allowed; -	wait_queue_head_t *vbl_queue;	/* vblank wait queue */ -	atomic_t	  *_vblank_count;	/* number of VBLANK interrupts */ -						/* (driver must alloc the right number of counters) */ -	struct drm_vbl_sig_list *vbl_sigs;	/* signal list to send on VBLANK */ -	atomic_t 	  vbl_signal_pending;	/* number of signals pending on all crtcs*/ -	atomic_t	  *vblank_refcount;	/* number of users of vblank interrupts per crtc */ -	u32		  *last_vblank;		/* protected by dev->vbl_lock, used */ -						/* for wraparound handling */ -	int		  *vblank_enabled;	/* so we don't call enable more than */ -						/* once per disable */ -	int 		  *vblank_inmodeset;	/* Display driver is setting mode */ +	atomic_t 	  vbl_signal_pending;	/* number of signals pending on all crtcs */  	struct callout	  vblank_disable_timer;  	u32		  max_vblank_count;	/* size of vblank counter register */ +	struct drm_vblank_info *vblank;		/* per crtc vblank info */  	int		  num_crtcs;  #ifdef __FreeBSD__ diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c index 6e21d41c..0f0d0fc8 100644 --- a/bsd-core/drm_irq.c +++ b/bsd-core/drm_irq.c @@ -85,13 +85,13 @@ static void vblank_disable_fn(void *arg)  		return;  	for (i = 0; i < dev->num_crtcs; i++) { -		if (atomic_read(&dev->vblank_refcount[i]) == 0 && -		    dev->vblank_enabled[i]) { +		if (atomic_read(&dev->vblank[i].refcount) == 0 && +		    dev->vblank[i].enabled) {  			DRM_DEBUG("disabling vblank on crtc %d\n", i); -			dev->last_vblank[i] = +			dev->vblank[i].last =  			    dev->driver.get_vblank_counter(dev, i);  			dev->driver.disable_vblank(dev, i); -			dev->vblank_enabled[i] = 0; +			dev->vblank[i].enabled = 0;  		}  	}  } @@ -112,20 +112,8 @@ static void drm_vblank_cleanup(struct drm_device *dev)  	vblank_disable_fn((void *)dev); -	drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, +	drm_free(dev->vblank, sizeof(struct drm_vblank_info) * dev->num_crtcs,  	    DRM_MEM_DRIVER); -	drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, -	    DRM_MEM_DRIVER); -	drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * -	    dev->num_crtcs, DRM_MEM_DRIVER); -	drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * -	    dev->num_crtcs, DRM_MEM_DRIVER); -	drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * -	    dev->num_crtcs, DRM_MEM_DRIVER); -	drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, -	    DRM_MEM_DRIVER); -	drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * -	    dev->num_crtcs, DRM_MEM_DRIVER);  	dev->num_crtcs = 0;  } @@ -138,46 +126,17 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)  	atomic_set(&dev->vbl_signal_pending, 0);  	dev->num_crtcs = num_crtcs; -	dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, -	    DRM_MEM_DRIVER); -	if (!dev->vbl_queue) -	    goto err; - -	dev->vbl_sigs = drm_alloc(sizeof(struct drm_vbl_sig) * num_crtcs, -	    DRM_MEM_DRIVER); -	if (!dev->vbl_sigs) -	    goto err; - -	dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, -	    DRM_MEM_DRIVER); -	if (!dev->_vblank_count) -	    goto err; - -	dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, -	    DRM_MEM_DRIVER); -	if (!dev->vblank_refcount) -	    goto err; - -	dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), -	    DRM_MEM_DRIVER); -	if (!dev->vblank_enabled) -	    goto err; - -	dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); -	if (!dev->last_vblank) -	    goto err; - -	dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), +	dev->vblank = drm_calloc(num_crtcs, sizeof(struct drm_vblank_info),  	    DRM_MEM_DRIVER); -	if (!dev->vblank_inmodeset) +	if (!dev->vblank)  	    goto err;  	/* Zero per-crtc vblank stuff */  	for (i = 0; i < num_crtcs; i++) { -		DRM_INIT_WAITQUEUE(&dev->vbl_queue[i]); -		TAILQ_INIT(&dev->vbl_sigs[i]); -		atomic_set(&dev->_vblank_count[i], 0); -		atomic_set(&dev->vblank_refcount[i], 0); +		DRM_INIT_WAITQUEUE(&dev->vblank[i].queue); +		TAILQ_INIT(&dev->vblank[i].sigs); +		atomic_set(&dev->vblank[i].count, 0); +		atomic_set(&dev->vblank[i].refcount, 0);  	}  	dev->vblank_disable_allowed = 0; @@ -330,7 +289,7 @@ int drm_control(struct drm_device *dev, void *data, struct drm_file *file_priv)  u32 drm_vblank_count(struct drm_device *dev, int crtc)  { -	return atomic_read(&dev->_vblank_count[crtc]); +	return atomic_read(&dev->vblank[crtc].count);  }  static void drm_update_vblank_count(struct drm_device *dev, int crtc) @@ -345,18 +304,18 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)  	 * a long time.  	 */  	cur_vblank = dev->driver.get_vblank_counter(dev, crtc); -	diff = cur_vblank - dev->last_vblank[crtc]; -	if (cur_vblank < dev->last_vblank[crtc]) { +	diff = cur_vblank - dev->vblank[crtc].last; +	if (cur_vblank < dev->vblank[crtc].last) {  		diff += dev->max_vblank_count;  		DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", -		    crtc, dev->last_vblank[crtc], cur_vblank, diff); +		    crtc, dev->vblank[crtc].last, cur_vblank, diff);  	}  	DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",  	    crtc, diff); -	atomic_add(diff, &dev->_vblank_count[crtc]); +	atomic_add(diff, &dev->vblank[crtc].count);  }  int drm_vblank_get(struct drm_device *dev, int crtc) @@ -366,14 +325,14 @@ int drm_vblank_get(struct drm_device *dev, int crtc)  	DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);  	/* Going from 0->1 means we have to enable interrupts again */ -	atomic_add_acq_int(&dev->vblank_refcount[crtc], 1); -	if (dev->vblank_refcount[crtc] == 1 && -	    !dev->vblank_enabled[crtc]) { +	atomic_add_acq_int(&dev->vblank[crtc].refcount, 1); +	if (dev->vblank[crtc].refcount == 1 && +	    !dev->vblank[crtc].enabled) {  		ret = dev->driver.enable_vblank(dev, crtc);  		if (ret) -			atomic_dec(&dev->vblank_refcount[crtc]); +			atomic_dec(&dev->vblank[crtc].refcount);  		else { -			dev->vblank_enabled[crtc] = 1; +			dev->vblank[crtc].enabled = 1;  			drm_update_vblank_count(dev, crtc);  		}  	} @@ -388,8 +347,8 @@ void drm_vblank_put(struct drm_device *dev, int crtc)  	DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);  	/* Last user schedules interrupt disable */ -	atomic_subtract_acq_int(&dev->vblank_refcount[crtc], 1); -	if (dev->vblank_refcount[crtc] == 0) +	atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1); +	if (dev->vblank[crtc].refcount == 0)  	    callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ,  		(timeout_t *)vblank_disable_fn, (void *)dev);  	DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags); @@ -421,16 +380,16 @@ int drm_modeset_ctl(struct drm_device *dev, void *data,  	 */  	switch (modeset->cmd) {  	case _DRM_PRE_MODESET: -		if (!dev->vblank_inmodeset[crtc]) { -			dev->vblank_inmodeset[crtc] = 1; +		if (!dev->vblank[crtc].inmodeset) { +			dev->vblank[crtc].inmodeset = 1;  			drm_vblank_get(dev, crtc);  		}  		break;  	case _DRM_POST_MODESET: -		if (dev->vblank_inmodeset[crtc]) { +		if (dev->vblank[crtc].inmodeset) {  			DRM_SPINLOCK_IRQSAVE(&dev->vbl_lock, irqflags);  			dev->vblank_disable_allowed = 1; -			dev->vblank_inmodeset[crtc] = 0; +			dev->vblank[crtc].inmodeset = 0;  			DRM_SPINUNLOCK_IRQRESTORE(&dev->vbl_lock, irqflags);  			drm_vblank_put(dev, crtc);  		} @@ -511,7 +470,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr  		DRM_LOCK();  		/* shared code returns -errno */ -		DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, +		DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * DRM_HZ,  		    ((drm_vblank_count(dev, crtc)  		      - vblwait->request.sequence) <= (1 << 23)));  		DRM_UNLOCK(); @@ -561,8 +520,8 @@ void drm_vbl_send_signals(struct drm_device *dev, int crtc )  void drm_handle_vblank(struct drm_device *dev, int crtc)  { -	atomic_inc(&dev->_vblank_count[crtc]); -	DRM_WAKEUP(&dev->vbl_queue[crtc]); +	atomic_inc(&dev->vblank[crtc].count); +	DRM_WAKEUP(&dev->vblank[crtc].queue);  	drm_vbl_send_signals(dev, crtc);  } | 
