Skip to content

Commit

Permalink
drm/i915: support page flipping on ValleyView
Browse files Browse the repository at this point in the history
And restructure the IRQ handling a little.  We can use pipestat for most
things, and make sure we don't affect pipe events when enabling and
disabling vblank interupts.

We can leave vblank interrupts masked but enabled so we're not dependent
on the first client to toggle the disable timer.  We can also mask all
render based interrupts, since the ring code will handle unmasking them
for us.

v2: roll in vblank masking, remove unneeded variable (Daniel)

Signed-off-by: Jesse Barnes <[email protected]>
Signed-off-by: Daniel Vetter <[email protected]>
  • Loading branch information
jbarnes993 authored and danvet committed Jun 20, 2012
1 parent 9355360 commit 31acc7f
Showing 1 changed file with 46 additions and 51 deletions.
97 changes: 46 additions & 51 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,15 +513,10 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
unsigned long irqflags;
int pipe;
u32 pipe_stats[I915_MAX_PIPES];
u32 vblank_status;
int vblank = 0;
bool blc_event;

atomic_inc(&dev_priv->irq_received);

vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS |
PIPE_VBLANK_INTERRUPT_STATUS;

while (true) {
iir = I915_READ(VLV_IIR);
gt_iir = I915_READ(GTIIR);
Expand Down Expand Up @@ -551,6 +546,16 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
}
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 (pipe_stats[pipe] & PLANE_FLIPDONE_INT_STATUS_VLV) {
intel_prepare_page_flip(dev, pipe);
intel_finish_page_flip(dev, pipe);
}
}

/* Consume port. Then clear IIR or we'll miss events */
if (iir & I915_DISPLAY_PORT_INTERRUPT) {
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
Expand All @@ -565,19 +570,6 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
I915_READ(PORT_HOTPLUG_STAT);
}


if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) {
drm_handle_vblank(dev, 0);
vblank++;
intel_finish_page_flip(dev, 0);
}

if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) {
drm_handle_vblank(dev, 1);
vblank++;
intel_finish_page_flip(dev, 0);
}

if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
blc_event = true;

Expand Down Expand Up @@ -1479,23 +1471,20 @@ 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 dpfl, imr;
u32 imr;

if (!i915_pipe_enabled(dev, pipe))
return -EINVAL;

spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
dpfl = I915_READ(VLV_DPFLIPSTAT);
imr = I915_READ(VLV_IMR);
if (pipe == 0) {
dpfl |= PIPEA_VBLANK_INT_EN;
if (pipe == 0)
imr &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
} else {
dpfl |= PIPEA_VBLANK_INT_EN;
else
imr &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
}
I915_WRITE(VLV_DPFLIPSTAT, dpfl);
I915_WRITE(VLV_IMR, imr);
i915_enable_pipestat(dev_priv, pipe,
PIPE_START_VBLANK_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);

return 0;
Expand Down Expand Up @@ -1545,20 +1534,17 @@ 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 dpfl, imr;
u32 imr;

spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
dpfl = I915_READ(VLV_DPFLIPSTAT);
i915_disable_pipestat(dev_priv, pipe,
PIPE_START_VBLANK_INTERRUPT_ENABLE);
imr = I915_READ(VLV_IMR);
if (pipe == 0) {
dpfl &= ~PIPEA_VBLANK_INT_EN;
if (pipe == 0)
imr |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
} else {
dpfl &= ~PIPEB_VBLANK_INT_EN;
else
imr |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
}
I915_WRITE(VLV_IMR, imr);
I915_WRITE(VLV_DPFLIPSTAT, dpfl);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}

Expand Down Expand Up @@ -1892,16 +1878,24 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
static int valleyview_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 render_irqs;
u32 enable_mask;
u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV;
u16 msid;

enable_mask = I915_DISPLAY_PORT_INTERRUPT;
enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
enable_mask |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |
I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT |
I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;

dev_priv->irq_mask = ~enable_mask;
/*
*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;

dev_priv->pipestat[0] = 0;
dev_priv->pipestat[1] = 0;
Expand All @@ -1920,26 +1914,27 @@ static int valleyview_irq_postinstall(struct drm_device *dev)
I915_WRITE(PIPESTAT(1), 0xffff);
POSTING_READ(VLV_IER);

i915_enable_pipestat(dev_priv, 0, pipestat_enable);
i915_enable_pipestat(dev_priv, 1, pipestat_enable);

I915_WRITE(VLV_IIR, 0xffffffff);
I915_WRITE(VLV_IIR, 0xffffffff);

render_irqs = GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
GT_GEN6_BLT_CS_ERROR_INTERRUPT |
GT_GEN6_BLT_USER_INTERRUPT |
GT_GEN6_BSD_USER_INTERRUPT |
GT_GEN6_BSD_CS_ERROR_INTERRUPT |
GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
GT_PIPE_NOTIFY |
GT_RENDER_CS_ERROR_INTERRUPT |
GT_SYNC_STATUS |
GT_USER_INTERRUPT;

dev_priv->gt_irq_mask = ~render_irqs;
dev_priv->gt_irq_mask = ~0;

I915_WRITE(GTIIR, I915_READ(GTIIR));
I915_WRITE(GTIIR, I915_READ(GTIIR));
I915_WRITE(GTIMR, 0);
I915_WRITE(GTIER, render_irqs);
I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
I915_WRITE(GTIER, GT_GEN6_BLT_FLUSHDW_NOTIFY_INTERRUPT |
GT_GEN6_BLT_CS_ERROR_INTERRUPT |
GT_GEN6_BLT_USER_INTERRUPT |
GT_GEN6_BSD_USER_INTERRUPT |
GT_GEN6_BSD_CS_ERROR_INTERRUPT |
GT_GEN7_L3_PARITY_ERROR_INTERRUPT |
GT_PIPE_NOTIFY |
GT_RENDER_CS_ERROR_INTERRUPT |
GT_SYNC_STATUS |
GT_USER_INTERRUPT);
POSTING_READ(GTIER);

/* ack & enable invalid PTE error interrupts */
Expand Down

0 comments on commit 31acc7f

Please sign in to comment.