From db689c7b95613237cec904c3f6ee27e8c2bf7ce0 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 12 Jun 2007 10:44:21 -0700 Subject: Initial checkin of vblank rework. Code attempts to reduce the number of vblank interrupt in order to save power. --- shared-core/radeon_irq.c | 75 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 25 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 5151b4d6..2534ff10 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -35,6 +35,18 @@ #include "radeon_drm.h" #include "radeon_drv.h" +static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) +{ + drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + + if (state) + dev_priv->irq_enable_reg |= mask; + else + dev_priv->irq_enable_reg &= ~mask; + + RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); +} + static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, u32 mask) { @@ -141,14 +153,17 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) } int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, - int crtc) + int crtc, int relative) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - unsigned int cur_vblank; + unsigned int cur_vblank, diff, irqflags, current_cnt; int ret = 0; int ack = 0; atomic_t *counter; + unsigned int *last_cnt; + int crtc_cnt_reg; + if (!dev_priv) { DRM_ERROR("%s called with no initialization\n", __FUNCTION__); return DRM_ERR(EINVAL); @@ -156,10 +171,14 @@ int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, if (crtc == DRM_RADEON_VBLANK_CRTC1) { counter = &dev->vbl_received; - ack |= RADEON_CRTC_VBLANK_STAT; + ack = RADEON_CRTC_VBLANK_STAT; + last_cnt = &dev_priv->crtc_last_cnt; + crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { counter = &dev->vbl_received2; - ack |= RADEON_CRTC2_VBLANK_STAT; + ack = RADEON_CRTC2_VBLANK_STAT; + last_cnt = &dev_priv->crtc2_last_cnt; + crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; } else return DRM_ERR(EINVAL); @@ -167,27 +186,46 @@ int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + if (!relative) { + /* + * Assume we haven't missed more than several hours of vblank + * events, or that it won't matter if they're not accounted + * for in the master counter. + */ + spin_lock_irqsave(&dev->vbl_lock, irqflags); + current_cnt = RADEON_READ(crtc_cnt_reg); + if (current_cnt < *last_cnt) { + current_cnt += (1 << 21) - *last_cnt; + *last_cnt = 0; + } + diff = current_cnt - *last_cnt; + *last_cnt = RADEON_READ(crtc_cnt_reg); + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + atomic_add(diff, counter); + } + /* Assume that the user has missed the current sequence number * by about a day rather than she wants to wait for years * using vertical blanks... */ + radeon_irq_set_state(dev, ack, 1); DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, (((cur_vblank = atomic_read(counter)) - *sequence) <= (1 << 23))); - + radeon_irq_set_state(dev, ack, 0); *sequence = cur_vblank; return ret; } -int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence) +int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence, int relative) { - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1); + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1, relative); } -int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence) +int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence, int relative) { - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2); + return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2, relative); } /* Needs the lock as it touches the ring. @@ -238,20 +276,7 @@ int radeon_irq_wait(DRM_IOCTL_ARGS) return radeon_wait_irq(dev, irqwait.irq_seq); } -static void radeon_enable_interrupt(drm_device_t *dev) -{ - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - - dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE; - if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1) - dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK; - - if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2) - dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK; - RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); - dev_priv->irq_enabled = 1; -} /* drm_dma.h hooks */ @@ -265,7 +290,8 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) /* Clear bits if they're already high */ radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | - RADEON_CRTC_VBLANK_STAT)); + RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT)); } void radeon_driver_irq_postinstall(drm_device_t * dev) @@ -276,7 +302,7 @@ void radeon_driver_irq_postinstall(drm_device_t * dev) atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - radeon_enable_interrupt(dev); + radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); } void radeon_driver_irq_uninstall(drm_device_t * dev) @@ -318,6 +344,5 @@ int radeon_vblank_crtc_set(drm_device_t *dev, int64_t value) return DRM_ERR(EINVAL); } dev_priv->vblank_crtc = (unsigned int)value; - radeon_enable_interrupt(dev); return 0; } -- cgit v1.2.3 From b6610363e373c13a2e7fdee8691756e1768bdd57 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 15 Jun 2007 11:21:57 -0700 Subject: First cut at radeon support for the vblank rework. --- shared-core/radeon_irq.c | 158 ++++++++++++++++++++--------------------------- 1 file changed, 68 insertions(+), 90 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 2534ff10..46ec035d 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -47,6 +47,50 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); } +int radeon_enable_vblank(drm_device_t *dev, int crtc) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (!(dev_priv->vblank_crtc & (1 << crtc))) + return -EINVAL; + + switch (crtc) { + case 0: + radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); + break; + case 1: + radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1); + break; + default: + DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", + crtc); + break; + } + + return 0; +} + +void radeon_disable_vblank(drm_device_t *dev, int crtc) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + if (!(dev_priv->vblank_crtc & (1 << crtc))) + return; + + switch (crtc) { + case 0: + radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); + break; + case 1: + radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0); + break; + default: + DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", + crtc); + break; + } +} + static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, u32 mask) { @@ -89,30 +133,14 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; /* SW interrupt */ - if (stat & RADEON_SW_INT_TEST) { + if (stat & RADEON_SW_INT_TEST) DRM_WAKEUP(&dev_priv->swi_queue); - } /* VBLANK interrupt */ - if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) { - int vblank_crtc = dev_priv->vblank_crtc; - - if ((vblank_crtc & - (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) == - (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) { - if (stat & RADEON_CRTC_VBLANK_STAT) - atomic_inc(&dev->vbl_received); - if (stat & RADEON_CRTC2_VBLANK_STAT) - atomic_inc(&dev->vbl_received2); - } else if (((stat & RADEON_CRTC_VBLANK_STAT) && - (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) || - ((stat & RADEON_CRTC2_VBLANK_STAT) && - (vblank_crtc & DRM_RADEON_VBLANK_CRTC2))) - atomic_inc(&dev->vbl_received); - - DRM_WAKEUP(&dev->vbl_queue); - drm_vbl_send_signals(dev); - } + if (stat & RADEON_CRTC_VBLANK_STAT) + drm_handle_vblank(dev, 0); + if (stat & RADEON_CRTC2_VBLANK_STAT) + drm_handle_vblank(dev, 1); return IRQ_HANDLED; } @@ -152,80 +180,21 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) return ret; } -int radeon_driver_vblank_do_wait(drm_device_t * dev, unsigned int *sequence, - int crtc, int relative) +u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) { - drm_radeon_private_t *dev_priv = - (drm_radeon_private_t *) dev->dev_private; - unsigned int cur_vblank, diff, irqflags, current_cnt; - int ret = 0; - int ack = 0; - atomic_t *counter; - unsigned int *last_cnt; - int crtc_cnt_reg; - - if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); - return DRM_ERR(EINVAL); - } + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 crtc_cnt_reg, current_cnt; - if (crtc == DRM_RADEON_VBLANK_CRTC1) { - counter = &dev->vbl_received; - ack = RADEON_CRTC_VBLANK_STAT; - last_cnt = &dev_priv->crtc_last_cnt; + if (crtc == DRM_RADEON_VBLANK_CRTC1) crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; - } else if (crtc == DRM_RADEON_VBLANK_CRTC2) { - counter = &dev->vbl_received2; - ack = RADEON_CRTC2_VBLANK_STAT; - last_cnt = &dev_priv->crtc2_last_cnt; + else if (crtc == DRM_RADEON_VBLANK_CRTC2) crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; - } else - return DRM_ERR(EINVAL); - - radeon_acknowledge_irqs(dev_priv, ack); - - dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - - if (!relative) { - /* - * Assume we haven't missed more than several hours of vblank - * events, or that it won't matter if they're not accounted - * for in the master counter. - */ - spin_lock_irqsave(&dev->vbl_lock, irqflags); - current_cnt = RADEON_READ(crtc_cnt_reg); - if (current_cnt < *last_cnt) { - current_cnt += (1 << 21) - *last_cnt; - *last_cnt = 0; - } - diff = current_cnt - *last_cnt; - *last_cnt = RADEON_READ(crtc_cnt_reg); - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - atomic_add(diff, counter); - } - - /* Assume that the user has missed the current sequence number - * by about a day rather than she wants to wait for years - * using vertical blanks... - */ - radeon_irq_set_state(dev, ack, 1); - DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, - (((cur_vblank = atomic_read(counter)) - - *sequence) <= (1 << 23))); - radeon_irq_set_state(dev, ack, 0); - *sequence = cur_vblank; - - return ret; -} + else + return 0; -int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence, int relative) -{ - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1, relative); -} + current_cnt = RADEON_READ(crtc_cnt_reg); -int radeon_driver_vblank_wait2(drm_device_t *dev, unsigned int *sequence, int relative) -{ - return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2, relative); + return current_cnt; } /* Needs the lock as it touches the ring. @@ -294,15 +263,24 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) RADEON_CRTC2_VBLANK_STAT)); } -void radeon_driver_irq_postinstall(drm_device_t * dev) +int radeon_driver_irq_postinstall(drm_device_t * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + int num_pipes = 2, ret; atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); + ret = drm_vblank_init(dev, num_pipes); + if (ret) + return ret; + + dev->max_vblank_count = 0xffffffff; + radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); + + return 0; } void radeon_driver_irq_uninstall(drm_device_t * dev) -- cgit v1.2.3 From 741d1c80314de6f30bcc7eca7a7720b0aac3c56c Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 15 Jun 2007 17:06:46 -0700 Subject: Remove broken crtc enable checks, radeon does it slightly differently (this makes get_vblank_counter return an actual value). --- shared-core/radeon_irq.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 46ec035d..d1f0e313 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -51,9 +51,6 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - if (!(dev_priv->vblank_crtc & (1 << crtc))) - return -EINVAL; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); @@ -64,7 +61,7 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - break; + return -EINVAL; } return 0; @@ -74,9 +71,6 @@ void radeon_disable_vblank(drm_device_t *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - if (!(dev_priv->vblank_crtc & (1 << crtc))) - return; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); @@ -185,9 +179,9 @@ u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) drm_radeon_private_t *dev_priv = dev->dev_private; u32 crtc_cnt_reg, current_cnt; - if (crtc == DRM_RADEON_VBLANK_CRTC1) + if (crtc == 0) crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; - else if (crtc == DRM_RADEON_VBLANK_CRTC2) + else if (crtc == 1) crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; else return 0; -- cgit v1.2.3 From d8ed021d29951b17cfbda0ade968c73a52ac7ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 18 Jun 2007 13:08:21 +0200 Subject: radeon: VBlank rework fixups. Fix range of frame counter registers. Use DRM_ERR() instead of Linux specific error codes in shared code. Remove duplicate register definitions and superfluous local variables. --- shared-core/radeon_irq.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index d1f0e313..cf72fc5b 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -49,8 +49,6 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) int radeon_enable_vblank(drm_device_t *dev, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); @@ -61,7 +59,7 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) default: DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc); - return -EINVAL; + return DRM_ERR(EINVAL); } return 0; @@ -69,8 +67,6 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) void radeon_disable_vblank(drm_device_t *dev, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); @@ -177,7 +173,7 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - u32 crtc_cnt_reg, current_cnt; + u32 crtc_cnt_reg; if (crtc == 0) crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; @@ -186,9 +182,7 @@ u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) else return 0; - current_cnt = RADEON_READ(crtc_cnt_reg); - - return current_cnt; + return RADEON_READ(crtc_cnt_reg); } /* Needs the lock as it touches the ring. @@ -261,16 +255,16 @@ int radeon_driver_irq_postinstall(drm_device_t * dev) { drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; - int num_pipes = 2, ret; + int ret; atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - ret = drm_vblank_init(dev, num_pipes); + ret = drm_vblank_init(dev, 2); if (ret) return ret; - dev->max_vblank_count = 0xffffffff; + dev->max_vblank_count = 0x001fffff; radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); -- cgit v1.2.3 From afe842297f7117cf80718de78ce706f6fd83584b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 21 Jun 2007 15:23:20 -0700 Subject: RADEON: fix race in vblank interrupt handling It's possible that we disable vblank interrupts and clear the corresponding flag in irq_enable_reg, but receive an interrupt at just the wrong time, causing us to not ack it properly, nor report to the core kernel that it was handled. Fix that case by always handling vblank interrupts, even if the irq_enable_reg field is clear. --- shared-core/radeon_irq.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index d1f0e313..4409026c 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -37,7 +37,7 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) { - drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private; + drm_radeon_private_t *dev_priv = dev->dev_private; if (state) dev_priv->irq_enable_reg |= mask; @@ -49,8 +49,6 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state) int radeon_enable_vblank(drm_device_t *dev, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1); @@ -69,8 +67,6 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc) void radeon_disable_vblank(drm_device_t *dev, int crtc) { - drm_radeon_private_t *dev_priv = dev->dev_private; - switch (crtc) { case 0: radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0); @@ -88,7 +84,8 @@ void radeon_disable_vblank(drm_device_t *dev, int crtc) static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, u32 mask) { - u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask; + u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & + (mask | RADEON_CRTC_VBLANK_MASK | RADEON_CRTC2_VBLANK_MASK); if (irqs) RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); return irqs; -- cgit v1.2.3 From b8dd31487551ff83b63205a5cefbd06de7d4fbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 22 Jun 2007 11:42:54 +0200 Subject: Remove mask parameter from radeon_acknowledge_irqs(). Simply always acknowledge all interrupts we're interested in, to avoid hard hangs when an unexpected interrupt is flagged. --- shared-core/radeon_irq.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index a1b79718..d7f10f93 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -81,13 +81,15 @@ void radeon_disable_vblank(drm_device_t *dev, int crtc) } } -static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv, - u32 mask) +static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv) { u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & - (mask | RADEON_CRTC_VBLANK_MASK | RADEON_CRTC2_VBLANK_MASK); + (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | + RADEON_CRTC2_VBLANK_STAT); + if (irqs) RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs); + return irqs; } @@ -119,10 +121,12 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS) /* Only consider the bits we're interested in - others could be used * outside the DRM */ - stat = radeon_acknowledge_irqs(dev_priv, dev_priv->irq_enable_reg); + stat = radeon_acknowledge_irqs(dev_priv); if (!stat) return IRQ_NONE; + stat &= dev_priv->irq_enable_reg; + /* SW interrupt */ if (stat & RADEON_SW_INT_TEST) DRM_WAKEUP(&dev_priv->swi_queue); @@ -247,9 +251,7 @@ void radeon_driver_irq_preinstall(drm_device_t * dev) RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); /* Clear bits if they're already high */ - radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | - RADEON_CRTC_VBLANK_STAT | - RADEON_CRTC2_VBLANK_STAT)); + radeon_acknowledge_irqs(dev_priv); } int radeon_driver_irq_postinstall(drm_device_t * dev) -- cgit v1.2.3 From 5b726b63906419ccb3de2e065f9bf7ae875ccdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 6 Jul 2007 09:50:50 +0200 Subject: radeon: Improve vblank counter. The frame counter seems to increase only at the end of vertical blank, so we need to add 1 while in vertical blank. --- shared-core/radeon_irq.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index d7f10f93..4ff8a5c3 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -178,16 +178,18 @@ static int radeon_wait_irq(drm_device_t * dev, int swi_nr) u32 radeon_get_vblank_counter(drm_device_t *dev, int crtc) { drm_radeon_private_t *dev_priv = dev->dev_private; - u32 crtc_cnt_reg; + u32 crtc_cnt_reg, crtc_status_reg; - if (crtc == 0) + if (crtc == 0) { crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME; - else if (crtc == 1) + crtc_status_reg = RADEON_CRTC_STATUS; + } else if (crtc == 1) { crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME; - else + crtc_status_reg = RADEON_CRTC2_STATUS; + } else return 0; - return RADEON_READ(crtc_cnt_reg); + return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1); } /* Needs the lock as it touches the ring. -- cgit v1.2.3 From 9ab620d661253f9b08f683a2a6f9ddee002015bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Thu, 3 Jan 2008 16:56:04 +1000 Subject: drm: cleanup DRM_DEBUG() parameters As DRM_DEBUG macro already prints out the __FUNCTION__ string (see drivers/char/drm/drmP.h), it is not worth doing this again. At some other places the ending "\n" was added. airlied:- I cleaned up a few that this patch missed also --- shared-core/radeon_irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-core/radeon_irq.c') diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c index 2b2407ee..7e202d23 100644 --- a/shared-core/radeon_irq.c +++ b/shared-core/radeon_irq.c @@ -154,7 +154,7 @@ static int radeon_driver_vblank_do_wait(struct drm_device * dev, int ack = 0; atomic_t *counter; if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + DRM_ERROR("called with no initialization\n"); return -EINVAL; } @@ -205,7 +205,7 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr LOCK_TEST_WITH_RETURN(dev, file_priv); if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + DRM_ERROR("called with no initialization\n"); return -EINVAL; } @@ -227,7 +227,7 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr drm_radeon_irq_wait_t *irqwait = data; if (!dev_priv) { - DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + DRM_ERROR("called with no initialization\n"); return -EINVAL; } -- cgit v1.2.3