diff options
author | Jesse Barnes <jesse.barnes@intel.com> | 2007-06-22 11:06:51 -0700 |
---|---|---|
committer | Jesse Barnes <jesse.barnes@intel.com> | 2007-06-22 11:06:51 -0700 |
commit | 97dcd7fd25c18d5148619254229f8d94efb55b44 (patch) | |
tree | f7e1c4e47b45241027b5ceaeb726162fd82e2b56 /linux-core | |
parent | 2d24455ed8b12df6d06d135cb70f02473d11f4b0 (diff) |
more vblank rework
- use a timer for disabling vblank events to avoid enable/disable calls too
often
- make i915 work with pre-965 chips again (would like to structure this
better, but this hack works on my test system)
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 1 | ||||
-rw-r--r-- | linux-core/drm_irq.c | 17 |
2 files changed, 16 insertions, 2 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index cf1c0fd7..0ab69feb 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -832,6 +832,7 @@ typedef struct drm_device { /* for wraparound handling */ u32 *vblank_offset; /* used to track how many vblanks */ u32 *vblank_premodeset; /* were lost during modeset */ + struct timer_list vblank_disable_timer; unsigned long max_vblank_count; /**< size of vblank counter register */ spinlock_t tasklet_lock; /**< For drm_locked_tasklet */ diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index c9d1c0d2..1e1b7f4d 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -77,10 +77,22 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, return 0; } +static void vblank_disable_fn(unsigned long arg) +{ + drm_device_t *dev = (drm_device_t *)arg; + int i; + + for (i = 0; i < dev->num_crtcs; i++) + if (atomic_read(&dev->vblank_refcount[i]) == 0) + dev->driver->disable_vblank(dev, i); +} + int drm_vblank_init(drm_device_t *dev, int num_crtcs) { int i, ret = -ENOMEM; + setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,\ + (unsigned long)dev); spin_lock_init(&dev->vbl_lock); atomic_set(&dev->vbl_signal_pending, 0); dev->num_crtcs = num_crtcs; @@ -377,9 +389,10 @@ EXPORT_SYMBOL(drm_vblank_get); */ void drm_vblank_put(drm_device_t *dev, int crtc) { - /* Last user can disable interrupts */ + /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) - dev->driver->disable_vblank(dev, crtc); + mod_timer(&dev->vblank_disable_timer, + round_jiffies_relative(DRM_HZ)); } EXPORT_SYMBOL(drm_vblank_put); |