diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-02-07 23:26:52 +0300 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-02-08 00:17:15 +0300 |
commit | 9db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7 (patch) | |
tree | 3d0d27e1115a5fae8984fbf2069d8720e5e6ee8e /drivers/gpu/drm/i915/i915_irq.c | |
parent | 8d7e3de1e019238211fa06e109437a13cae62004 (diff) | |
download | linux-9db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7.tar.xz |
drm/i915: cleanup per-pipe reg usage
We had some conversions over to the _PIPE macros, but didn't get
everything. So hide the per-pipe regs with an _ (still used in a few
places for legacy) and add a few _PIPE based macros, then make sure
everyone uses them.
[update: remove usage of non-existent no-op macro]
[update 2: keep modesetting suspend/resume code, update to new reg names]
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
[ickle: stylistic cleanups for checkpatch and taste]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 149 |
1 files changed, 66 insertions, 83 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 15d6269027e7..da3edf891c21 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -85,21 +85,11 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) } } -static inline u32 -i915_pipestat(int pipe) -{ - if (pipe == 0) - return PIPEASTAT; - if (pipe == 1) - return PIPEBSTAT; - BUG(); -} - void i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { - u32 reg = i915_pipestat(pipe); + u32 reg = PIPESTAT(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ @@ -112,7 +102,7 @@ void i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != 0) { - u32 reg = i915_pipestat(pipe); + u32 reg = PIPESTAT(pipe); dev_priv->pipestat[pipe] &= ~mask; I915_WRITE(reg, dev_priv->pipestat[pipe]); @@ -171,12 +161,12 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) if (!i915_pipe_enabled(dev, pipe)) { DRM_DEBUG_DRIVER("trying to get vblank count for disabled " - "pipe %d\n", pipe); + "pipe %c\n", pipe_name(pipe)); return 0; } - high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH; - low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; + high_frame = PIPEFRAME(pipe); + low_frame = PIPEFRAMEPIXEL(pipe); /* * High & low register fields aren't synchronized, so make sure @@ -197,11 +187,11 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; + int reg = PIPE_FRMCOUNT_GM45(pipe); if (!i915_pipe_enabled(dev, pipe)) { DRM_DEBUG_DRIVER("trying to get vblank count for disabled " - "pipe %d\n", pipe); + "pipe %c\n", pipe_name(pipe)); return 0; } @@ -219,7 +209,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, if (!i915_pipe_enabled(dev, pipe)) { DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " - "pipe %d\n", pipe); + "pipe %c\n", pipe_name(pipe)); return 0; } @@ -417,6 +407,7 @@ static void pch_irq_handler(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u32 pch_iir; + int pipe; pch_iir = I915_READ(SDEIIR); @@ -437,13 +428,11 @@ static void pch_irq_handler(struct drm_device *dev) if (pch_iir & SDE_POISON) DRM_ERROR("PCH poison interrupt\n"); - if (pch_iir & SDE_FDI_MASK) { - u32 fdia, fdib; - - fdia = I915_READ(FDI_RXA_IIR); - fdib = I915_READ(FDI_RXB_IIR); - DRM_DEBUG_DRIVER("PCH FDI RX interrupt; FDI RXA IIR: 0x%08x, FDI RXB IIR: 0x%08x\n", fdia, fdib); - } + if (pch_iir & SDE_FDI_MASK) + for_each_pipe(pipe) + DRM_DEBUG_DRIVER(" pipe %c FDI IIR: 0x%08x\n", + pipe_name(pipe), + I915_READ(FDI_RX_IIR(pipe))); if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n"); @@ -770,7 +759,7 @@ static void i915_capture_error_state(struct drm_device *dev) struct drm_i915_gem_object *obj; struct drm_i915_error_state *error; unsigned long flags; - int i; + int i, pipe; spin_lock_irqsave(&dev_priv->error_lock, flags); error = dev_priv->first_error; @@ -778,6 +767,7 @@ static void i915_capture_error_state(struct drm_device *dev) if (error) return; + /* Account for pipe specific data like PIPE*STAT */ error = kmalloc(sizeof(*error), GFP_ATOMIC); if (!error) { DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); @@ -790,8 +780,8 @@ static void i915_capture_error_state(struct drm_device *dev) error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); - error->pipeastat = I915_READ(PIPEASTAT); - error->pipebstat = I915_READ(PIPEBSTAT); + for_each_pipe(pipe) + error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); error->instpm = I915_READ(INSTPM); error->error = 0; if (INTEL_INFO(dev)->gen >= 6) { @@ -912,6 +902,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u32 eir = I915_READ(EIR); + int pipe; if (!eir) return; @@ -960,14 +951,10 @@ static void i915_report_and_clear_eir(struct drm_device *dev) } if (eir & I915_ERROR_MEMORY_REFRESH) { - u32 pipea_stats = I915_READ(PIPEASTAT); - u32 pipeb_stats = I915_READ(PIPEBSTAT); - - printk(KERN_ERR "memory refresh error\n"); - printk(KERN_ERR "PIPEASTAT: 0x%08x\n", - pipea_stats); - printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", - pipeb_stats); + printk(KERN_ERR "memory refresh error:\n"); + for_each_pipe(pipe) + printk(KERN_ERR "pipe %c stat: 0x%08x\n", + pipe_name(pipe), I915_READ(PIPESTAT(pipe))); /* pipestat has already been acked */ } if (eir & I915_ERROR_INSTRUCTION) { @@ -1081,10 +1068,10 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ obj = work->pending_flip_obj; if (INTEL_INFO(dev)->gen >= 4) { - int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; + int dspsurf = DSPSURF(intel_crtc->plane); stall_detected = I915_READ(dspsurf) == obj->gtt_offset; } else { - int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; + int dspaddr = DSPADDR(intel_crtc->plane); stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + crtc->y * crtc->fb->pitch + crtc->x * crtc->fb->bits_per_pixel/8); @@ -1104,12 +1091,13 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct drm_i915_master_private *master_priv; u32 iir, new_iir; - u32 pipea_stats, pipeb_stats; + u32 pipe_stats[I915_MAX_PIPES]; u32 vblank_status; int vblank = 0; unsigned long irqflags; int irq_received; - int ret = IRQ_NONE; + int ret = IRQ_NONE, pipe; + bool blc_event = false; atomic_inc(&dev_priv->irq_received); @@ -1132,27 +1120,23 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) * interrupts (for non-MSI). */ spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - pipea_stats = I915_READ(PIPEASTAT); - pipeb_stats = I915_READ(PIPEBSTAT); - if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) i915_handle_error(dev, false); - /* - * Clear the PIPE(A|B)STAT regs before the IIR - */ - if (pipea_stats & 0x8000ffff) { - if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) - DRM_DEBUG_DRIVER("pipe a underrun\n"); - I915_WRITE(PIPEASTAT, pipea_stats); - irq_received = 1; - } - - if (pipeb_stats & 0x8000ffff) { - if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) - DRM_DEBUG_DRIVER("pipe b underrun\n"); - I915_WRITE(PIPEBSTAT, pipeb_stats); - irq_received = 1; + for_each_pipe(pipe) { + int 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]); + irq_received = 1; + } } spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -1203,27 +1187,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) intel_finish_page_flip_plane(dev, 1); } - if (pipea_stats & vblank_status && - drm_handle_vblank(dev, 0)) { - vblank++; - if (!dev_priv->flip_pending_is_done) { - i915_pageflip_stall_check(dev, 0); - intel_finish_page_flip(dev, 0); + for_each_pipe(pipe) { + if (pipe_stats[pipe] & vblank_status && + drm_handle_vblank(dev, pipe)) { + vblank++; + if (!dev_priv->flip_pending_is_done) { + i915_pageflip_stall_check(dev, pipe); + intel_finish_page_flip(dev, pipe); + } } - } - if (pipeb_stats & vblank_status && - drm_handle_vblank(dev, 1)) { - vblank++; - if (!dev_priv->flip_pending_is_done) { - i915_pageflip_stall_check(dev, 1); - intel_finish_page_flip(dev, 1); - } + if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) + blc_event = true; } - if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || - (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) || - (iir & I915_ASLE_INTERRUPT)) + + if (blc_event || (iir & I915_ASLE_INTERRUPT)) intel_opregion_asle_intr(dev); /* With MSI, interrupts are only generated when iir @@ -1634,6 +1613,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; u32 render_irqs; u32 hotplug_mask; + int pipe; dev_priv->irq_mask = ~display_mask; @@ -1668,8 +1648,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK; - I915_WRITE(FDI_RXA_IMR, 0); - I915_WRITE(FDI_RXB_IMR, 0); + for_each_pipe(pipe) + I915_WRITE(FDI_RX_IMR(pipe), 0); } dev_priv->pch_irq_mask = ~hotplug_mask; @@ -1692,6 +1672,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) void i915_driver_irq_preinstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int pipe; atomic_set(&dev_priv->irq_received, 0); atomic_set(&dev_priv->vblank_enabled, 0); @@ -1711,8 +1692,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev) } I915_WRITE(HWSTAM, 0xeffe); - I915_WRITE(PIPEASTAT, 0); - I915_WRITE(PIPEBSTAT, 0); + for_each_pipe(pipe) + I915_WRITE(PIPESTAT(pipe), 0); I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); POSTING_READ(IER); @@ -1824,6 +1805,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev) void i915_driver_irq_uninstall(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int pipe; if (!dev_priv) return; @@ -1841,12 +1823,13 @@ void i915_driver_irq_uninstall(struct drm_device * dev) } I915_WRITE(HWSTAM, 0xffffffff); - I915_WRITE(PIPEASTAT, 0); - I915_WRITE(PIPEBSTAT, 0); + for_each_pipe(pipe) + I915_WRITE(PIPESTAT(pipe), 0); I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); - I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); - I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); + for_each_pipe(pipe) + I915_WRITE(PIPESTAT(pipe), + I915_READ(PIPESTAT(pipe)) & 0x8000ffff); I915_WRITE(IIR, I915_READ(IIR)); } |