diff mbox

[1/7] drm/i915: vlv: don't unmask IIR[DISPLAY_PIPE_A/B_VBLANK] interrupt

Message ID 1391542551-20239-2-git-send-email-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Imre Deak Feb. 4, 2014, 7:35 p.m. UTC
Bspec and the code suggests that the interrupt signaled by IIR[7,5]
(DISPLAY_PIPE_A/B_VBLANK) is a first level IRQ flag for the second
level PIPEA/BSTAT[2] (Start of Vertical Blank) interrupt. Measuring
the relative timings of when IIR[7] and PIPEASTAT[1,2] get set and
checking the effect of unmasking different pipestat and IIR events
shows that this isn't so:

First, ISR/IIR[7] gets set independently of PIPEASTAT[18] (Start of
Vertical Blank Enable) or any other pipestat enable bit, so it isn't
a first level IRQ bit showing the state of PIPEASTAT[2], but is
connected directly to the timing generator.

Second, setting only PIPEASTAT[18] and leaving all other pipestat events
disabled, IIR[6] (DISPLAY_PIPE_A_EVENT) gets set close to the moment when
PIPEASTAT[2] gets set, so the former is a first level interrupt flag for
the latter. The bspec is rather unclear about this, but I also assume
that IIR[6] signals all pipestat A events, except PIPEASTAT[31] (FIFO
Under-run Status).

Third, IIR[7] is set close to the moment when PIPEASTAT[1] (Framestart
Interrupt) gets set, in the mode I used about 12usec after PIPEASTAT[2]
and IIR[6] gets set. This means the IIR[7] isn't marking the start of
vblank, but rather signals the framestart event.

Based on the above, we don't need to unmask IIR[7] when waiting for
start of vblank events, but we can rely on IIR[6] being always unmasked,
which will signal when PIPEASTAT[2] gets set. Doing this will also get
rid of the overhead of getting an interrupt and servicing IIR[7], which
is atm raised always some time after IIR[6]/PIPEASTAT[2] is raised.

Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 14 --------------
 1 file changed, 14 deletions(-)

Comments

Jesse Barnes Feb. 5, 2014, 3:22 p.m. UTC | #1
On Tue,  4 Feb 2014 21:35:45 +0200
Imre Deak <imre.deak@intel.com> wrote:

> Bspec and the code suggests that the interrupt signaled by IIR[7,5]
> (DISPLAY_PIPE_A/B_VBLANK) is a first level IRQ flag for the second
> level PIPEA/BSTAT[2] (Start of Vertical Blank) interrupt. Measuring
> the relative timings of when IIR[7] and PIPEASTAT[1,2] get set and
> checking the effect of unmasking different pipestat and IIR events
> shows that this isn't so:
> 
> First, ISR/IIR[7] gets set independently of PIPEASTAT[18] (Start of
> Vertical Blank Enable) or any other pipestat enable bit, so it isn't
> a first level IRQ bit showing the state of PIPEASTAT[2], but is
> connected directly to the timing generator.
> 
> Second, setting only PIPEASTAT[18] and leaving all other pipestat events
> disabled, IIR[6] (DISPLAY_PIPE_A_EVENT) gets set close to the moment when
> PIPEASTAT[2] gets set, so the former is a first level interrupt flag for
> the latter. The bspec is rather unclear about this, but I also assume
> that IIR[6] signals all pipestat A events, except PIPEASTAT[31] (FIFO
> Under-run Status).
> 
> Third, IIR[7] is set close to the moment when PIPEASTAT[1] (Framestart
> Interrupt) gets set, in the mode I used about 12usec after PIPEASTAT[2]
> and IIR[6] gets set. This means the IIR[7] isn't marking the start of
> vblank, but rather signals the framestart event.
> 
> Based on the above, we don't need to unmask IIR[7] when waiting for
> start of vblank events, but we can rely on IIR[6] being always unmasked,
> which will signal when PIPEASTAT[2] gets set. Doing this will also get
> rid of the overhead of getting an interrupt and servicing IIR[7], which
> is atm raised always some time after IIR[6]/PIPEASTAT[2] is raised.
> 
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_irq.c | 14 --------------
>  1 file changed, 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index b226ae6..137ac65 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -2297,18 +2297,11 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
>  {
>  	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>  	unsigned long irqflags;
> -	u32 imr;
>  
>  	if (!i915_pipe_enabled(dev, pipe))
>  		return -EINVAL;
>  
>  	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
> -	imr = I915_READ(VLV_IMR);
> -	if (pipe == PIPE_A)
> -		imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
> -	else
> -		imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> -	I915_WRITE(VLV_IMR, imr);
>  	i915_enable_pipestat(dev_priv, pipe,
>  			     PIPE_START_VBLANK_INTERRUPT_ENABLE);
>  	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
> @@ -2366,17 +2359,10 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
>  {
>  	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
>  	unsigned long irqflags;
> -	u32 imr;
>  
>  	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
>  	i915_disable_pipestat(dev_priv, pipe,
>  			      PIPE_START_VBLANK_INTERRUPT_ENABLE);
> -	imr = I915_READ(VLV_IMR);
> -	if (pipe == PIPE_A)
> -		imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
> -	else
> -		imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
> -	I915_WRITE(VLV_IMR, imr);
>  	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
>  }
>  

Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b226ae6..137ac65 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2297,18 +2297,11 @@  static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
-	u32 imr;
 
 	if (!i915_pipe_enabled(dev, pipe))
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
-	imr = I915_READ(VLV_IMR);
-	if (pipe == PIPE_A)
-		imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
-	else
-		imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
-	I915_WRITE(VLV_IMR, imr);
 	i915_enable_pipestat(dev_priv, pipe,
 			     PIPE_START_VBLANK_INTERRUPT_ENABLE);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
@@ -2366,17 +2359,10 @@  static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
-	u32 imr;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	i915_disable_pipestat(dev_priv, pipe,
 			      PIPE_START_VBLANK_INTERRUPT_ENABLE);
-	imr = I915_READ(VLV_IMR);
-	if (pipe == PIPE_A)
-		imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
-	else
-		imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
-	I915_WRITE(VLV_IMR, imr);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }