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); |
