diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-31 05:48:04 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-31 07:38:47 -0500 |
commit | 78c6e170badd22c86a5b50a7eb038a02024b8f03 (patch) | |
tree | 481dba4a9d30cf25ee25cda443a17cb6e209668c /drivers | |
parent | 021a8455bedb01750fa8047c8576e19d5af9a99f (diff) |
drm/i915: Suppress spurious vblank interrupts
Hugh Dickins found that characters in xterm were going missing and oft
delayed. Being the curious type, he managed to associate this with the
new high-precision vblank patches; disabling these he found, restored
the orderliness of his characters.
The oddness begins when one realised that Hugh was not using vblanks at
all on his system (fvwm and some xterms). Instead, all he had to go on
were warning of a pipe underrun, curiously enough at around 60Hz. He
poked and found that in addition to the underrun warning, the hardware
was flagging the start of a new frame, a vblank, which in turn was
kicking off the pending vblank processing code.
There is little we can do for the underruns on Hugh's machine, a
Crestline [965GM], which must have its FIFO watermarks set to 8.
However, we do not need to process the vblank if we know that they are
disabled...
Reported-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 8 |
2 files changed, 8 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0054e957203f..3dadfa2a8528 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -1250,7 +1250,7 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) | |||
1250 | * Drivers should call this routine in their vblank interrupt handlers to | 1250 | * Drivers should call this routine in their vblank interrupt handlers to |
1251 | * update the vblank counter and send any signals that may be pending. | 1251 | * update the vblank counter and send any signals that may be pending. |
1252 | */ | 1252 | */ |
1253 | void drm_handle_vblank(struct drm_device *dev, int crtc) | 1253 | bool drm_handle_vblank(struct drm_device *dev, int crtc) |
1254 | { | 1254 | { |
1255 | u32 vblcount; | 1255 | u32 vblcount; |
1256 | s64 diff_ns; | 1256 | s64 diff_ns; |
@@ -1258,7 +1258,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1258 | unsigned long irqflags; | 1258 | unsigned long irqflags; |
1259 | 1259 | ||
1260 | if (!dev->num_crtcs) | 1260 | if (!dev->num_crtcs) |
1261 | return; | 1261 | return false; |
1262 | 1262 | ||
1263 | /* Need timestamp lock to prevent concurrent execution with | 1263 | /* Need timestamp lock to prevent concurrent execution with |
1264 | * vblank enable/disable, as this would cause inconsistent | 1264 | * vblank enable/disable, as this would cause inconsistent |
@@ -1269,7 +1269,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1269 | /* Vblank irq handling disabled. Nothing to do. */ | 1269 | /* Vblank irq handling disabled. Nothing to do. */ |
1270 | if (!dev->vblank_enabled[crtc]) { | 1270 | if (!dev->vblank_enabled[crtc]) { |
1271 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); | 1271 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); |
1272 | return; | 1272 | return false; |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | /* Fetch corresponding timestamp for this vblank interval from | 1275 | /* Fetch corresponding timestamp for this vblank interval from |
@@ -1311,5 +1311,6 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1311 | drm_handle_vblank_events(dev, crtc); | 1311 | drm_handle_vblank_events(dev, crtc); |
1312 | 1312 | ||
1313 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); | 1313 | spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); |
1314 | return true; | ||
1314 | } | 1315 | } |
1315 | EXPORT_SYMBOL(drm_handle_vblank); | 1316 | EXPORT_SYMBOL(drm_handle_vblank); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 062f353497e6..97f946dcc1aa 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1196,18 +1196,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
1196 | intel_finish_page_flip_plane(dev, 1); | 1196 | intel_finish_page_flip_plane(dev, 1); |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | if (pipea_stats & vblank_status) { | 1199 | if (pipea_stats & vblank_status && |
1200 | drm_handle_vblank(dev, 0)) { | ||
1200 | vblank++; | 1201 | vblank++; |
1201 | drm_handle_vblank(dev, 0); | ||
1202 | if (!dev_priv->flip_pending_is_done) { | 1202 | if (!dev_priv->flip_pending_is_done) { |
1203 | i915_pageflip_stall_check(dev, 0); | 1203 | i915_pageflip_stall_check(dev, 0); |
1204 | intel_finish_page_flip(dev, 0); | 1204 | intel_finish_page_flip(dev, 0); |
1205 | } | 1205 | } |
1206 | } | 1206 | } |
1207 | 1207 | ||
1208 | if (pipeb_stats & vblank_status) { | 1208 | if (pipeb_stats & vblank_status && |
1209 | drm_handle_vblank(dev, 1)) { | ||
1209 | vblank++; | 1210 | vblank++; |
1210 | drm_handle_vblank(dev, 1); | ||
1211 | if (!dev_priv->flip_pending_is_done) { | 1211 | if (!dev_priv->flip_pending_is_done) { |
1212 | i915_pageflip_stall_check(dev, 1); | 1212 | i915_pageflip_stall_check(dev, 1); |
1213 | intel_finish_page_flip(dev, 1); | 1213 | intel_finish_page_flip(dev, 1); |