[Intel-gfx] [PATCH 51/71] drm/i915/chv: Use valleyview_pipestat_irq_handler() for CHV

Daniel Vetter daniel at ffwll.ch
Tue May 20 15:28:51 CEST 2014


On Wed, Apr 09, 2014 at 01:28:49PM +0300, ville.syrjala at linux.intel.com wrote:
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c | 91 ++++++++---------------------------------
>  1 file changed, 17 insertions(+), 74 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 9c18a47..9702fde 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -1660,6 +1660,9 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
>  		case PIPE_B:
>  			iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
>  			break;
> +		case PIPE_C:
> +			iir_bit = I915_DISPLAY_PIPE_C_EVENT_INTERRUPT;
> +			break;
>  		}
>  		if (iir & iir_bit)
>  			mask |= dev_priv->pipestat_irq_mask[pipe];
> @@ -1771,87 +1774,32 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
>  	drm_i915_private_t *dev_priv = dev->dev_private;
>  	u32 master_ctl, iir;
>  	irqreturn_t ret = IRQ_NONE;
> -	unsigned int pipes = 0;
> -
> -	master_ctl = I915_READ(GEN8_MASTER_IRQ);
> -
> -	I915_WRITE(GEN8_MASTER_IRQ, 0);
> -
> -	ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl);
>  
> +	master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~DE_MASTER_IRQ_CONTROL;
>  	iir = I915_READ(VLV_IIR);
>  
> -	if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT))
> -		pipes |= 1 << 0;
> -	if (iir & (I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT))
> -		pipes |= 1 << 1;
> -	if (iir & (I915_DISPLAY_PIPE_C_VBLANK_INTERRUPT | I915_DISPLAY_PIPE_C_EVENT_INTERRUPT))
> -		pipes |= 1 << 2;
> -
> -	if (pipes) {
> -		u32 pipe_stats[I915_MAX_PIPES] = {};
> -		unsigned long irqflags;
> -		int pipe;
> -
> -		spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
> -		for_each_pipe(pipe) {
> -			unsigned int reg;
> -
> -			if (!(pipes & (1 << pipe)))
> -				continue;
> -
> -			reg = PIPESTAT(pipe);
> -			pipe_stats[pipe] = I915_READ(reg);
> -
> -			/*
> -			 * Clear the PIPE*STAT regs before the IIR
> -			 */
> -			if (pipe_stats[pipe] & 0x8000ffff) {
> -				if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
> -					DRM_DEBUG_DRIVER("pipe %c underrun\n",
> -							 pipe_name(pipe));
> -				I915_WRITE(reg, pipe_stats[pipe]);
> -			}
> -		}
> -		spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
> -
> -		for_each_pipe(pipe) {
> -			if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
> -				drm_handle_vblank(dev, pipe);
> +	if (master_ctl == 0 && iir == 0)
> +		return IRQ_NONE;
>  
> -			if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) {
> -				intel_prepare_page_flip(dev, pipe);
> -				intel_finish_page_flip(dev, pipe);
> -			}
> -		}
> +	I915_WRITE(GEN8_MASTER_IRQ, 0);
>  
> -		if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
> -			gmbus_irq_handler(dev);
> +	gen8_gt_irq_handler(dev, dev_priv, master_ctl);
>  
> -		ret = IRQ_HANDLED;
> -	}
> +	valleyview_pipestat_irq_handler(dev, iir);
>  
>  	/* Consume port.  Then clear IIR or we'll miss events */
>  	if (iir & I915_DISPLAY_PORT_INTERRUPT) {
> -		u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
> -
> -		I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
> -
> -		DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
> -				 hotplug_status);
> -		if (hotplug_status & HOTPLUG_INT_STATUS_I915)
> -			queue_work(dev_priv->wq,
> -				   &dev_priv->hotplug_work);
> -
> +		i9xx_hpd_irq_handler(dev, iir);

Fun conflict here - my version of i9xx_hpd_irq_handler doesn't want an iir
argument. Please sanity-check, thanks.
-Daniel

>  		ret = IRQ_HANDLED;
>  	}
>  
> -
>  	I915_WRITE(VLV_IIR, iir);
>  
>  	I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
>  	POSTING_READ(GEN8_MASTER_IRQ);
>  
> +	ret = IRQ_HANDLED;
> +
>  	return ret;
>  }
>  
> @@ -3526,12 +3474,10 @@ static int cherryview_irq_postinstall(struct drm_device *dev)
>  	drm_i915_private_t *dev_priv = dev->dev_private;
>  	u32 enable_mask = I915_DISPLAY_PORT_INTERRUPT |
>  		I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
> -		I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
>  		I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
> -		I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT |
> -		I915_DISPLAY_PIPE_C_EVENT_INTERRUPT |
> -		I915_DISPLAY_PIPE_C_VBLANK_INTERRUPT;
> -	u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV;
> +		I915_DISPLAY_PIPE_C_EVENT_INTERRUPT;
> +	u32 pipestat_enable = PLANE_FLIP_DONE_INT_STATUS_VLV |
> +		PIPE_CRC_DONE_INTERRUPT_STATUS;
>  	unsigned long irqflags;
>  	int pipe;
>  
> @@ -3539,16 +3485,13 @@ static int cherryview_irq_postinstall(struct drm_device *dev)
>  	 * Leave vblank interrupts masked initially.  enable/disable will
>  	 * toggle them based on usage.
>  	 */
> -	dev_priv->irq_mask = ~enable_mask |
> -		I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
> -		I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT |
> -		I915_DISPLAY_PIPE_C_VBLANK_INTERRUPT;
> +	dev_priv->irq_mask = ~enable_mask;
>  
>  	for_each_pipe(pipe)
>  		I915_WRITE(PIPESTAT(pipe), 0xffff);
>  
>  	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
> -	i915_enable_pipestat(dev_priv, 0, PIPE_GMBUS_EVENT_ENABLE);
> +	i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
>  	for_each_pipe(pipe)
>  		i915_enable_pipestat(dev_priv, pipe, pipestat_enable);
>  	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
> -- 
> 1.8.3.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch



More information about the Intel-gfx mailing list