diff options
Diffstat (limited to 'shared/via_irq.c')
-rw-r--r-- | shared/via_irq.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/shared/via_irq.c b/shared/via_irq.c index da3c1414..a58717ee 100644 --- a/shared/via_irq.c +++ b/shared/via_irq.c @@ -46,16 +46,39 @@ #define VIA_IRQ_VBI_ENABLE (1 << 19) #define VIA_IRQ_VBI_PENDING (1 << 3) + + +static unsigned time_diff(struct timeval *now,struct timeval *then) +{ + return (now->tv_usec >= then->tv_usec) ? + now->tv_usec - then->tv_usec : + 1000000 - (then->tv_usec - now->tv_usec); +} + irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) { drm_device_t *dev = (drm_device_t *) arg; drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; u32 status; int handled = 0; + struct timeval cur_vblank; status = VIA_READ(VIA_REG_INTERRUPT); if (status & VIA_IRQ_VBI_PENDING) { atomic_inc(&dev->vbl_received); + if (!(atomic_read(&dev->vbl_received) & 0x0F)) { + do_gettimeofday(&cur_vblank); + if (dev_priv->last_vblank_valid) { + dev_priv->usec_per_vblank = + time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4; + } + dev_priv->last_vblank = cur_vblank; + dev_priv->last_vblank_valid = 1; + } + if (!(atomic_read(&dev->vbl_received) & 0xFF)) { + DRM_DEBUG("US per vblank is: %u\n", + dev_priv->usec_per_vblank); + } DRM_WAKEUP(&dev->vbl_queue); DRM(vbl_send_signals) (dev); handled = 1; @@ -117,6 +140,7 @@ void via_driver_irq_preinstall(drm_device_t * dev) DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); if (dev_priv) { + dev_priv->last_vblank_valid = 0; DRM_DEBUG("mmio: %p\n", dev_priv->mmio); status = VIA_READ(VIA_REG_INTERRUPT); DRM_DEBUG("intreg: %x\n", status & VIA_IRQ_VBI_ENABLE); @@ -164,3 +188,4 @@ void via_driver_irq_uninstall(drm_device_t * dev) VIA_WRITE(VIA_REG_INTERRUPT, status & ~VIA_IRQ_VBI_ENABLE); } } + |