diff options
-rw-r--r-- | drivers/gpu/drm/drm_irq.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 1 | ||||
-rw-r--r-- | include/drm/drmP.h | 1 |
3 files changed, 28 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6b3ce6d38848..7998ee66b317 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -429,15 +429,21 @@ int drm_vblank_get(struct drm_device *dev, int crtc) | |||
429 | 429 | ||
430 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 430 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
431 | /* Going from 0->1 means we have to enable interrupts again */ | 431 | /* Going from 0->1 means we have to enable interrupts again */ |
432 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 && | 432 | if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { |
433 | !dev->vblank_enabled[crtc]) { | 433 | if (!dev->vblank_enabled[crtc]) { |
434 | ret = dev->driver->enable_vblank(dev, crtc); | 434 | ret = dev->driver->enable_vblank(dev, crtc); |
435 | DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); | 435 | DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); |
436 | if (ret) | 436 | if (ret) |
437 | atomic_dec(&dev->vblank_refcount[crtc]); | ||
438 | else { | ||
439 | dev->vblank_enabled[crtc] = 1; | ||
440 | drm_update_vblank_count(dev, crtc); | ||
441 | } | ||
442 | } | ||
443 | } else { | ||
444 | if (!dev->vblank_enabled[crtc]) { | ||
437 | atomic_dec(&dev->vblank_refcount[crtc]); | 445 | atomic_dec(&dev->vblank_refcount[crtc]); |
438 | else { | 446 | ret = -EINVAL; |
439 | dev->vblank_enabled[crtc] = 1; | ||
440 | drm_update_vblank_count(dev, crtc); | ||
441 | } | 447 | } |
442 | } | 448 | } |
443 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 449 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
@@ -464,6 +470,18 @@ void drm_vblank_put(struct drm_device *dev, int crtc) | |||
464 | } | 470 | } |
465 | EXPORT_SYMBOL(drm_vblank_put); | 471 | EXPORT_SYMBOL(drm_vblank_put); |
466 | 472 | ||
473 | void drm_vblank_off(struct drm_device *dev, int crtc) | ||
474 | { | ||
475 | unsigned long irqflags; | ||
476 | |||
477 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | ||
478 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | ||
479 | dev->vblank_enabled[crtc] = 0; | ||
480 | dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); | ||
481 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | ||
482 | } | ||
483 | EXPORT_SYMBOL(drm_vblank_off); | ||
484 | |||
467 | /** | 485 | /** |
468 | * drm_vblank_pre_modeset - account for vblanks across mode sets | 486 | * drm_vblank_pre_modeset - account for vblanks across mode sets |
469 | * @dev: DRM device | 487 | * @dev: DRM device |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 267adc6fbfc1..65b76fffd9e3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1924,6 +1924,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1924 | 1924 | ||
1925 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1925 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1926 | intel_crtc_dpms_overlay(intel_crtc, false); | 1926 | intel_crtc_dpms_overlay(intel_crtc, false); |
1927 | drm_vblank_off(dev, pipe); | ||
1927 | 1928 | ||
1928 | if (dev_priv->cfb_plane == plane && | 1929 | if (dev_priv->cfb_plane == plane && |
1929 | dev_priv->display.disable_fbc) | 1930 | dev_priv->display.disable_fbc) |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index febf6c530c66..fd919959d146 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -1288,6 +1288,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc); | |||
1288 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); | 1288 | extern void drm_handle_vblank(struct drm_device *dev, int crtc); |
1289 | extern int drm_vblank_get(struct drm_device *dev, int crtc); | 1289 | extern int drm_vblank_get(struct drm_device *dev, int crtc); |
1290 | extern void drm_vblank_put(struct drm_device *dev, int crtc); | 1290 | extern void drm_vblank_put(struct drm_device *dev, int crtc); |
1291 | extern void drm_vblank_off(struct drm_device *dev, int crtc); | ||
1291 | extern void drm_vblank_cleanup(struct drm_device *dev); | 1292 | extern void drm_vblank_cleanup(struct drm_device *dev); |
1292 | /* Modesetting support */ | 1293 | /* Modesetting support */ |
1293 | extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); | 1294 | extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); |