From 237172b7670611b36d92be3b92983674846f6564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 3 Jun 2008 11:28:10 +0200 Subject: vblank: Clean up compensation for spurious wraparounds of driver counter. Only compensate when the driver counter actually appears to have moved backwards. The compensation deltas need to be incremental instead of absolute; drop the vblank_offset field and just use atomic_sub(). --- linux-core/drm_irq.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'linux-core/drm_irq.c') diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index ccb3ca89..3627a890 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -112,8 +112,6 @@ static void drm_vblank_cleanup(struct drm_device *dev) DRM_MEM_DRIVER); drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * dev->num_crtcs, DRM_MEM_DRIVER); - drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs, - DRM_MEM_DRIVER); dev->num_crtcs = 0; } @@ -162,10 +160,6 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) if (!dev->vblank_premodeset) goto err; - dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); - if (!dev->vblank_offset) - goto err; - /* Zero per-crtc vblank stuff */ for (i = 0; i < num_crtcs; i++) { init_waitqueue_head(&dev->vbl_queue[i]); @@ -330,8 +324,7 @@ int drm_control(struct drm_device *dev, void *data, */ u32 drm_vblank_count(struct drm_device *dev, int crtc) { - return atomic_read(&dev->_vblank_count[crtc]) + - dev->vblank_offset[crtc]; + return atomic_read(&dev->_vblank_count[crtc]); } EXPORT_SYMBOL(drm_vblank_count); @@ -457,7 +450,18 @@ int drm_modeset_ctl(struct drm_device *dev, void *data, break; case _DRM_POST_MODESET: new = dev->driver->get_vblank_counter(dev, crtc); - dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new; + + /* Compensate for spurious wraparound */ + if (new < dev->vblank_premodeset[crtc]) { + atomic_sub(dev->max_vblank_count + new - + dev->vblank_premodeset[crtc], + &dev->_vblank_count[crtc]); + DRM_DEBUG("vblank_premodeset[%d]=0x%x, new=0x%x " + "=> _vblank_count[%d]-=0x%x\n", crtc, + dev->vblank_premodeset[crtc], new, + crtc, dev->max_vblank_count + new - + dev->vblank_premodeset[crtc]); + } break; default: ret = -EINVAL; -- cgit v1.2.3