svn commit: r194986 - head/sys/dev/drm

Robert Noland rnoland at FreeBSD.org
Thu Jun 25 18:27:09 UTC 2009


Author: rnoland
Date: Thu Jun 25 18:27:08 2009
New Revision: 194986
URL: http://svn.freebsd.org/changeset/base/194986

Log:
  Some more cleanups for vblank code on Intel.
  
  The Intel 2d driver calls modeset before reinstalling the handler on
  a vt switch.  This means that vblank status ends up getting cleared
  after it has been setup.  Restore saved values for the pipestat registers
  rather than just wiping them out.
  
  MFC after:	3 days

Modified:
  head/sys/dev/drm/i915_drv.h
  head/sys/dev/drm/i915_irq.c

Modified: head/sys/dev/drm/i915_drv.h
==============================================================================
--- head/sys/dev/drm/i915_drv.h	Thu Jun 25 18:13:46 2009	(r194985)
+++ head/sys/dev/drm/i915_drv.h	Thu Jun 25 18:27:08 2009	(r194986)
@@ -129,7 +129,6 @@ typedef struct drm_i915_private {
 	int page_flipping;
 
 	wait_queue_head_t irq_queue;
-	atomic_t irq_received;
 	/** Protects user_irq_refcount and irq_mask_reg */
 	DRM_SPINTYPE user_irq_lock;
 	/** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */

Modified: head/sys/dev/drm/i915_irq.c
==============================================================================
--- head/sys/dev/drm/i915_irq.c	Thu Jun 25 18:13:46 2009	(r194985)
+++ head/sys/dev/drm/i915_irq.c	Thu Jun 25 18:27:08 2009	(r194986)
@@ -53,12 +53,6 @@ __FBSDID("$FreeBSD$");
 #define I915_INTERRUPT_ENABLE_MASK	(I915_INTERRUPT_ENABLE_FIX | \
 				    	 I915_INTERRUPT_ENABLE_VAR)
 
-#define I915_PIPE_VBLANK_STATUS		(PIPE_START_VBLANK_INTERRUPT_STATUS |\
-					 PIPE_VBLANK_INTERRUPT_STATUS)
- 
-#define I915_PIPE_VBLANK_ENABLE		(PIPE_START_VBLANK_INTERRUPT_ENABLE |\
-					 PIPE_VBLANK_INTERRUPT_ENABLE)
-  
 #define DRM_I915_VBLANK_PIPE_ALL	(DRM_I915_VBLANK_PIPE_A | \
 					 DRM_I915_VBLANK_PIPE_B)
 
@@ -154,7 +148,7 @@ u32 i915_get_vblank_counter(struct drm_d
 	low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -183,7 +177,7 @@ u32 g45_get_vblank_counter(struct drm_de
 	int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
 
 	if (!i915_pipe_enabled(dev, pipe)) {
-		DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+		DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe);
 		return 0;
 	}
 
@@ -200,12 +194,10 @@ irqreturn_t i915_driver_irq_handler(DRM_
 	u32 vblank_enable;
 	int irq_received;
 
-	atomic_inc(&dev_priv->irq_received);
-
 	iir = I915_READ(IIR);
 
 	if (IS_I965G(dev)) {
-		vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
+		vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS;
 		vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
 	} else {
 		vblank_status = I915_VBLANK_INTERRUPT_STATUS;
@@ -305,9 +297,12 @@ void i915_user_irq_get(struct drm_device
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
+	if (dev->irq_enabled == 0)
+		return;
+
 	DRM_DEBUG("\n");
 	DRM_SPINLOCK(&dev_priv->user_irq_lock);
-	if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
+	if (++dev_priv->user_irq_refcount == 1)
 		i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
 	DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
 }
@@ -316,12 +311,13 @@ void i915_user_irq_put(struct drm_device
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
+	if (dev->irq_enabled == 0)
+		return;
+
 	DRM_SPINLOCK(&dev_priv->user_irq_lock);
-	if (dev->irq_enabled) {
-		KASSERT(dev_priv->user_irq_refcount > 0, ("invalid refcount"));
-		if (--dev_priv->user_irq_refcount == 0)
-			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
-	}
+	KASSERT(dev_priv->user_irq_refcount > 0, ("invalid refcount"));
+	if (--dev_priv->user_irq_refcount == 0)
+		i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
 	DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
 }
 
@@ -408,11 +404,8 @@ int i915_irq_wait(struct drm_device *dev
 int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
-	u32 pipeconf;
 
-	pipeconf = I915_READ(pipeconf_reg);
-	if (!(pipeconf & PIPEACONF_ENABLE))
+	if (!i915_pipe_enabled(dev, pipe))
 		return -EINVAL;
 
 	DRM_SPINLOCK(&dev_priv->user_irq_lock);
@@ -500,8 +493,6 @@ void i915_driver_irq_preinstall(struct d
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-	atomic_set_int(&dev_priv->irq_received, 0);
-
 	I915_WRITE(HWSTAM, 0xeffe);
 	I915_WRITE(PIPEASTAT, 0);
 	I915_WRITE(PIPEBSTAT, 0);
@@ -519,9 +510,6 @@ int i915_driver_irq_postinstall(struct d
 	/* Unmask the interrupts that we always want on. */
 	dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
 
-	dev_priv->pipestat[0] = 0;
-	dev_priv->pipestat[1] = 0;
-
 	/* Disable pipe interrupt enables, clear pending pipe status */
 	I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
 	I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
@@ -531,6 +519,10 @@ int i915_driver_irq_postinstall(struct d
 
 	I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
 	I915_WRITE(IMR, dev_priv->irq_mask_reg);
+	I915_WRITE(PIPEASTAT, dev_priv->pipestat[0] |
+	    (dev_priv->pipestat[0] >> 16));
+	I915_WRITE(PIPEBSTAT, dev_priv->pipestat[1] |
+	    (dev_priv->pipestat[1] >> 16));
 	(void) I915_READ(IER);
 
 	return 0;


More information about the svn-src-all mailing list