summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/radeon.h14
-rw-r--r--shared/radeon_cp.c2
-rw-r--r--shared/radeon_irq.c116
3 files changed, 46 insertions, 86 deletions
diff --git a/shared/radeon.h b/shared/radeon.h
index aa613c40..05760855 100644
--- a/shared/radeon.h
+++ b/shared/radeon.h
@@ -100,6 +100,13 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_EMIT)] = { radeon_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_IRQ_WAIT)] = { radeon_irq_wait, 1, 0 },
+
+#define USE_IRQS 1
+#if USE_IRQS
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_VBL_IRQ 1
+#define __HAVE_SHARED_IRQ 1
+
/* When a client dies:
* - Check for and clean up flipped page state
* - Free any alloced agp memory.
@@ -128,13 +135,14 @@
} \
} while (0)
+#else
+#define __HAVE_DMA_IRQ 0
+#endif
+
/* DMA customization:
*/
#define __HAVE_DMA 1
-#define __HAVE_DMA_IRQ 1
-#define __HAVE_VBL_IRQ 1
-#define __HAVE_SHARED_IRQ 1
/* Buffer customization:
*/
diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c
index c0fb63ef..60da1e41 100644
--- a/shared/radeon_cp.c
+++ b/shared/radeon_cp.c
@@ -1018,7 +1018,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
}
dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP);
- dev_priv->do_boxes = 0;
+ dev_priv->do_boxes = 1;
dev_priv->cp_mode = init->cp_mode;
/* We don't support anything other than bus-mastering ring mode,
diff --git a/shared/radeon_irq.c b/shared/radeon_irq.c
index 19872e9a..ee28872a 100644
--- a/shared/radeon_irq.c
+++ b/shared/radeon_irq.c
@@ -59,42 +59,36 @@ void DRM(dma_service)( DRM_IRQ_ARGS )
drm_device_t *dev = (drm_device_t *) arg;
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *)dev->dev_private;
- u32 stat, ack = 0;
+ u32 stat;
- /* Need to wait for fifo to drain?
- */
stat = RADEON_READ(RADEON_GEN_INT_STATUS);
+ if (!stat)
+ return;
/* SW interrupt */
if (stat & RADEON_SW_INT_TEST) {
- ack |= RADEON_SW_INT_TEST_ACK;
-#ifdef __linux__
- wake_up_interruptible(&dev_priv->swi_queue);
-#endif
-#ifdef __FreeBSD__
- wakeup(&dev->vbl_queue);
-#endif
+ DRM_WAKEUP( &dev_priv->swi_queue );
}
+#if __HAVE_VBL_IRQ
/* VBLANK interrupt */
if (stat & RADEON_CRTC_VBLANK_STAT) {
- ack |= RADEON_CRTC_VBLANK_STAT_ACK;
atomic_inc(&dev->vbl_received);
-#ifdef __linux__
- wake_up_interruptible(&dev->vbl_queue);
-#endif
-#ifdef __FreeBSD__
- wakeup(&dev->vbl_queue);
-#endif
+ DRM_WAKEUP(&dev->vbl_queue);
}
+#endif
- if (ack)
- RADEON_WRITE(RADEON_GEN_INT_STATUS, ack);
+ /* Acknowledge all the bits in GEN_INT_STATUS -- seem to get
+ * more than we asked for...
+ */
+ RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
}
static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
{
- RADEON_WRITE( RADEON_GEN_INT_STATUS, RADEON_READ( RADEON_GEN_INT_STATUS ) );
+ u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS );
+ if (tmp)
+ RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
}
int radeon_emit_irq(drm_device_t *dev)
@@ -120,52 +114,22 @@ int radeon_wait_irq(drm_device_t *dev, int swi_nr)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *)dev->dev_private;
-#ifdef __linux__
- DECLARE_WAITQUEUE(entry, current);
- unsigned long end = jiffies + HZ*3;
-#endif /* __linux__ */
int ret = 0;
if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
return 0;
+
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+ /* This is a hack to work around mysterious freezes on certain
+ * systems:
+ */
radeon_acknowledge_irqs( dev_priv );
-#ifdef __linux__
- add_wait_queue(&dev_priv->swi_queue, &entry);
-
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
- break;
- if((signed)(end - jiffies) <= 0) {
- ret = -EBUSY; /* Lockup? Missed irq? */
- break;
- }
- schedule_timeout(max(HZ/100,1));
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
- }
+ DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ,
+ RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->swi_queue, &entry);
return ret;
-#endif /* __linux__ */
-
-#ifdef __FreeBSD__
- for (;;) {
- if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
- break;
- ret = tsleep( &dev_priv->swi_queue, PZERO | PCATCH, \
- "rdnirq", 3*hz );
- if (ret)
- break;
- }
- return ret;
-#endif /* __FreeBSD__ */
}
int radeon_emit_and_wait_irq(drm_device_t *dev)
@@ -174,7 +138,8 @@ int radeon_emit_and_wait_irq(drm_device_t *dev)
}
-int radeon_vblank_wait(drm_device_t *dev, unsigned int *sequence)
+#if __HAVE_VBL_IRQ
+int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *)dev->dev_private;
@@ -186,34 +151,23 @@ int radeon_vblank_wait(drm_device_t *dev, unsigned int *sequence)
return DRM_ERR(EINVAL);
}
- /* 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_acknowledge_irqs( dev_priv );
+
+ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+ /* 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...
*/
- while ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
- + ~*sequence + 1 ) > (1<<23) ) {
- dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-
- radeon_acknowledge_irqs( dev_priv );
-
-#ifdef __linux__
- interruptible_sleep_on( &dev->vbl_queue );
-
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
-#endif /* __linux__ */
-#ifdef __FreeBSD__
- ret = tsleep( &dev->vbl_queue, 3*hz, "rdnvbl", PZERO | PCATCH);
- if (ret)
- break;
-#endif /* __FreeBSD__ */
- }
+ DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
+ ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
+ + ~*sequence + 1 ) > (1<<23) ) );
*sequence = cur_vblank;
return ret;
}
+#endif
/* Needs the lock as it touches the ring.
@@ -284,9 +238,7 @@ void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
(drm_radeon_private_t *)dev->dev_private;
atomic_set(&dev_priv->swi_emitted, 0);
-#ifdef __linux__
- init_waitqueue_head(&dev_priv->swi_queue);
-#endif
+ DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );
/* Turn on SW and VBL ints */
RADEON_WRITE( RADEON_GEN_INT_CNTL,