aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-24 13:30:58 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2017-03-29 06:51:26 -0400
commit75cff0837c14eaf632efabb8d7ab9eec6394d20d (patch)
tree14c5aec4996d9bf770f4e666de780f60d2216a1f /drivers/gpu/drm/drm_irq.c
parent38b6441e4e75c0b319cfe4d9364c1059fc1e3c2b (diff)
drm: Make the decision to keep vblank irq enabled earlier
We want to provide the vblank irq shadow for pageflip events as well as vblank queries. Such events are completed within the vblank interrupt handler, and so the current check for disabling the irq will disable it from with the same interrupt as the last pageflip event. If we move the decision on whether to disable the irq (based on there no being no remaining vblank events, i.e. vblank->refcount == 0) to before we signal the events, we will only disable the irq on the interrupt after the last event was signaled. In the normal course of events, this will keep the vblank irq enabled for the entire flip sequence whereas before it would flip-flop around every interrupt. v2: Move the disable_fn() call outside of the vblank_event_lock. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Michel Dänzer <michel@daenzer.net> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Dave Airlie <airlied@redhat.com>, Cc: Mario Kleiner <mario.kleiner.de@gmail.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> #v1 Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com> #v1 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170324173058.23051-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 4b0c7475ed13..290e65b93a65 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1699,6 +1699,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1699{ 1699{
1700 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 1700 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1701 unsigned long irqflags; 1701 unsigned long irqflags;
1702 bool disable_irq;
1702 1703
1703 if (WARN_ON_ONCE(!dev->num_crtcs)) 1704 if (WARN_ON_ONCE(!dev->num_crtcs))
1704 return false; 1705 return false;
@@ -1726,20 +1727,23 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1726 spin_unlock(&dev->vblank_time_lock); 1727 spin_unlock(&dev->vblank_time_lock);
1727 1728
1728 wake_up(&vblank->queue); 1729 wake_up(&vblank->queue);
1729 drm_handle_vblank_events(dev, pipe);
1730 1730
1731 /* With instant-off, we defer disabling the interrupt until after 1731 /* With instant-off, we defer disabling the interrupt until after
1732 * we finish processing the following vblank. The disable has to 1732 * we finish processing the following vblank after all events have
1733 * be last (after drm_handle_vblank_events) so that the timestamp 1733 * been signaled. The disable has to be last (after
1734 * is always accurate. 1734 * drm_handle_vblank_events) so that the timestamp is always accurate.
1735 */ 1735 */
1736 if (dev->vblank_disable_immediate && 1736 disable_irq = (dev->vblank_disable_immediate &&
1737 drm_vblank_offdelay > 0 && 1737 drm_vblank_offdelay > 0 &&
1738 !atomic_read(&vblank->refcount)) 1738 !atomic_read(&vblank->refcount));
1739 vblank_disable_fn((unsigned long)vblank); 1739
1740 drm_handle_vblank_events(dev, pipe);
1740 1741
1741 spin_unlock_irqrestore(&dev->event_lock, irqflags); 1742 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1742 1743
1744 if (disable_irq)
1745 vblank_disable_fn((unsigned long)vblank);
1746
1743 return true; 1747 return true;
1744} 1748}
1745EXPORT_SYMBOL(drm_handle_vblank); 1749EXPORT_SYMBOL(drm_handle_vblank);