summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-10-02 07:53:31 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-10-02 07:53:31 -0700
commitd175a2f8880b6372b85878df1607192a53a5ce3f (patch)
tree89ba302e422353df3c4e8c34a63b92023fdd4066
parent48452f9f022373afd76724f8a273a061835c7fd4 (diff)
Update to DRI CVS tree
-rw-r--r--drivers/char/drm/ati_pcigart.h10
-rw-r--r--drivers/char/drm/drm.h15
-rw-r--r--drivers/char/drm/drmP.h12
-rw-r--r--drivers/char/drm/drm_dma.h44
-rw-r--r--drivers/char/drm/drm_drv.h4
-rw-r--r--drivers/char/drm/drm_os_linux.h55
-rw-r--r--drivers/char/drm/radeon.h57
-rw-r--r--drivers/char/drm/radeon_drm.h2
-rw-r--r--drivers/char/drm/radeon_drv.h14
-rw-r--r--drivers/char/drm/radeon_irq.c177
-rw-r--r--drivers/char/drm/radeon_mem.c2
-rw-r--r--drivers/char/drm/radeon_state.c5
12 files changed, 258 insertions, 139 deletions
diff --git a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h
index 5851b72f6529..a259edb5633f 100644
--- a/drivers/char/drm/ati_pcigart.h
+++ b/drivers/char/drm/ati_pcigart.h
@@ -30,14 +30,20 @@
#define __NO_VERSION__
#include "drmP.h"
-#if PAGE_SIZE == 8192
+#if PAGE_SIZE == 65536
+# define ATI_PCIGART_TABLE_ORDER 0
+# define ATI_PCIGART_TABLE_PAGES (1 << 0)
+#elif PAGE_SIZE == 16384
+# define ATI_PCIGART_TABLE_ORDER 1
+# define ATI_PCIGART_TABLE_PAGES (1 << 1)
+#elif PAGE_SIZE == 8192
# define ATI_PCIGART_TABLE_ORDER 2
# define ATI_PCIGART_TABLE_PAGES (1 << 2)
#elif PAGE_SIZE == 4096
# define ATI_PCIGART_TABLE_ORDER 3
# define ATI_PCIGART_TABLE_PAGES (1 << 3)
#else
-# error - PAGE_SIZE not 8K or 4K
+# error - PAGE_SIZE not 64K, 16K, 8K or 4K
#endif
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 376568e0d47b..f26d4442820f 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -345,6 +345,19 @@ typedef struct drm_irq_busid {
int funcnum;
} drm_irq_busid_t;
+typedef enum {
+ _DRM_VBLANK_ABSOLUTE = 0x0, /* Wait for specific vblank sequence number */
+ _DRM_VBLANK_RELATIVE = 0x1 /* Wait for given number of vblanks */
+} drm_vblank_seq_type_t;
+
+typedef struct drm_radeon_vbl_wait {
+ drm_vblank_seq_type_t type;
+ unsigned int sequence;
+ long tval_sec;
+ long tval_usec;
+} drm_wait_vblank_t;
+
+
typedef struct drm_agp_mode {
unsigned long mode;
} drm_agp_mode_t;
@@ -439,6 +452,8 @@ typedef struct drm_scatter_gather {
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
+#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
+
/* Device specfic ioctls should only be in their respective headers
* The device specific ioctl range is 0x40 to 0x79. */
#define DRM_COMMAND_BASE 0x40
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 48825cbfc483..3588e4b886bc 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -576,6 +576,10 @@ typedef struct drm_device {
int last_context; /* Last current context */
unsigned long last_switch; /* jiffies at last context switch */
struct work_struct work;
+#if __HAVE_VBL_IRQ
+ wait_queue_head_t vbl_queue;
+ atomic_t vbl_received;
+#endif
cycles_t ctx_start;
cycles_t lck_start;
#if __HAVE_DMA_HISTOGRAM
@@ -808,6 +812,14 @@ extern int DRM(irq_install)( drm_device_t *dev, int irq );
extern int DRM(irq_uninstall)( drm_device_t *dev );
extern void DRM(dma_service)( int irq, void *device,
struct pt_regs *regs );
+extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
+extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
+extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
+#if __HAVE_VBL_IRQ
+extern int DRM(wait_vblank)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
+#endif
#if __HAVE_DMA_IRQ_BH
extern void DRM(dma_immediate_bh)( void *dev );
#endif
diff --git a/drivers/char/drm/drm_dma.h b/drivers/char/drm/drm_dma.h
index b3482b06c76a..1bbed275744e 100644
--- a/drivers/char/drm/drm_dma.h
+++ b/drivers/char/drm/drm_dma.h
@@ -535,8 +535,12 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
INIT_WORK(&dev->work, DRM(dma_immediate_bh), dev);
#endif
+#if __HAVE_VBL_IRQ
+ init_waitqueue_head(&dev->vbl_queue);
+#endif
+
/* Before installing handler */
- DRIVER_PREINSTALL();
+ DRM(driver_irq_preinstall)(dev);
/* Install handler */
ret = request_irq( dev->irq, DRM(dma_service),
@@ -549,7 +553,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
}
/* After installing handler */
- DRIVER_POSTINSTALL();
+ DRM(driver_irq_postinstall)(dev);
return 0;
}
@@ -568,7 +572,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
- DRIVER_UNINSTALL();
+ DRM(driver_irq_uninstall)( dev );
free_irq( irq, dev );
@@ -595,6 +599,40 @@ int DRM(control)( struct inode *inode, struct file *filp,
}
}
+#if __HAVE_VBL_IRQ
+
+int DRM(wait_vblank)( DRM_IOCTL_ARGS )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_wait_vblank_t vblwait;
+ struct timeval now;
+ int ret;
+
+ if (!dev->irq)
+ return -EINVAL;
+
+ DRM_COPY_FROM_USER_IOCTL( vblwait, (drm_wait_vblank_t *)data,
+ sizeof(vblwait) );
+
+ if ( vblwait.type == _DRM_VBLANK_RELATIVE ) {
+ vblwait.sequence += atomic_read( &dev->vbl_received );
+ }
+
+ ret = DRM(vblank_wait)( dev, &vblwait.sequence );
+
+ do_gettimeofday( &now );
+ vblwait.tval_sec = now.tv_sec;
+ vblwait.tval_usec = now.tv_usec;
+
+ DRM_COPY_TO_USER_IOCTL( (drm_wait_vblank_t *)data, vblwait,
+ sizeof(vblwait) );
+
+ return ret;
+}
+
+#endif /* __HAVE_VBL_IRQ */
+
#else
int DRM(control)( struct inode *inode, struct file *filp,
diff --git a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
index 7e2cfd8c561a..3ebe78115313 100644
--- a/drivers/char/drm/drm_drv.h
+++ b/drivers/char/drm/drm_drv.h
@@ -222,6 +222,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
#endif
+#if __HAVE_VBL_IRQ
+ [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { DRM(wait_vblank), 0, 0 },
+#endif
+
DRIVER_IOCTLS
};
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index cb3043983572..cf0031378b45 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -44,16 +44,47 @@
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
#define DRM_FREE(x) kfree(x)
-#define DRM_GETSAREA() \
-do { \
- struct list_head *list; \
- list_for_each( list, &dev->maplist->head ) { \
- drm_map_list_t *entry = (drm_map_list_t *)list; \
- if ( entry->map && \
- entry->map->type == _DRM_SHM && \
- (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \
- dev_priv->sarea = entry->map; \
- break; \
- } \
- } \
+#define DRM_GETSAREA() \
+do { \
+ struct list_head *list; \
+ list_for_each( list, &dev->maplist->head ) { \
+ drm_map_list_t *entry = (drm_map_list_t *)list; \
+ if ( entry->map && \
+ entry->map->type == _DRM_SHM && \
+ (entry->map->flags & _DRM_CONTAINS_LOCK) ) { \
+ dev_priv->sarea = entry->map; \
+ break; \
+ } \
+ } \
} while (0)
+
+#define DRM_HZ HZ
+
+#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
+do { \
+ DECLARE_WAITQUEUE(entry, current); \
+ unsigned long end = jiffies + (timeout); \
+ add_wait_queue(&(queue), &entry); \
+ \
+ for (;;) { \
+ current->state = TASK_INTERRUPTIBLE; \
+ if (condition) \
+ break; \
+ if((signed)(end - jiffies) <= 0) { \
+ ret = -EBUSY; \
+ break; \
+ } \
+ schedule_timeout(max(HZ/100,1)); \
+ if (signal_pending(current)) { \
+ ret = -EINTR; \
+ break; \
+ } \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&(queue), &entry); \
+} while (0)
+
+
+#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
+#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
+
diff --git a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h
index 69e16b37d092..59b9ebe7fcfc 100644
--- a/drivers/char/drm/radeon.h
+++ b/drivers/char/drm/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,57 +135,15 @@
} \
} while (0)
+#else
+#define __HAVE_DMA_IRQ 0
+#endif
+
/* DMA customization:
*/
#define __HAVE_DMA 1
-#define __HAVE_DMA_IRQ 1
-#define __HAVE_DMA_IRQ_BH 1
-#define __HAVE_SHARED_IRQ 1
-
-#define DRIVER_PREINSTALL() do { \
- drm_radeon_private_t *dev_priv = \
- (drm_radeon_private_t *)dev->dev_private; \
- u32 tmp; \
- \
- /* Clear bit if it's already high: */ \
- tmp = RADEON_READ( RADEON_GEN_INT_STATUS ); \
- tmp = tmp & RADEON_SW_INT_TEST_ACK; \
- RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp ); \
- \
- /* Disable *all* interrupts */ \
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \
-} while (0)
-
-#ifdef __linux__
-#define IWH(x) init_waitqueue_head(x)
-#else
-#define IWH(x)
-#endif
-
-#define DRIVER_POSTINSTALL() do { \
- drm_radeon_private_t *dev_priv = \
- (drm_radeon_private_t *)dev->dev_private; \
- \
- atomic_set(&dev_priv->irq_received, 0); \
- atomic_set(&dev_priv->irq_emitted, 0); \
- IWH(&dev_priv->irq_queue); \
- \
- /* Turn on SW_INT only */ \
- RADEON_WRITE( RADEON_GEN_INT_CNTL, \
- RADEON_SW_INT_ENABLE ); \
-} while (0)
-
-#define DRIVER_UNINSTALL() do { \
- drm_radeon_private_t *dev_priv = \
- (drm_radeon_private_t *)dev->dev_private; \
- if ( dev_priv ) { \
- /* Disable *all* interrupts */ \
- RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); \
- } \
-} while (0)
-
/* Buffer customization:
*/
#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 9a747e049b51..7c45898af8dd 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -517,7 +517,7 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_LAST_FRAME 2
#define RADEON_PARAM_LAST_DISPATCH 3
#define RADEON_PARAM_LAST_CLEAR 4
-#define RADEON_PARAM_IRQ_ACTIVE 5
+#define RADEON_PARAM_IRQ_NR 5
#define RADEON_PARAM_AGP_BASE 6 /* card offset of agp base */
typedef struct drm_radeon_getparam {
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index efe3020cf619..40c4d9fe5157 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -139,9 +139,9 @@ typedef struct drm_radeon_private {
struct mem_block *agp_heap;
struct mem_block *fb_heap;
- wait_queue_head_t irq_queue;
- atomic_t irq_received;
- atomic_t irq_emitted;
+ /* SW interrupt */
+ wait_queue_head_t swi_queue;
+ atomic_t swi_emitted;
} drm_radeon_private_t;
@@ -187,11 +187,12 @@ extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
extern void radeon_mem_takedown( struct mem_block **heap );
extern void radeon_mem_release( struct mem_block *heap );
+ /* radeon_irq.c */
extern int radeon_irq_emit( DRM_IOCTL_ARGS );
extern int radeon_irq_wait( DRM_IOCTL_ARGS );
extern int radeon_emit_and_wait_irq(drm_device_t *dev);
-extern int radeon_wait_irq(drm_device_t *dev, int irq_nr);
+extern int radeon_wait_irq(drm_device_t *dev, int swi_nr);
extern int radeon_emit_irq(drm_device_t *dev);
@@ -271,11 +272,15 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_GEN_INT_CNTL 0x0040
+# define RADEON_CRTC_VBLANK_MASK (1 << 0)
# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
# define RADEON_SW_INT_ENABLE (1 << 25)
#define RADEON_GEN_INT_STATUS 0x0044
+# define RADEON_CRTC_VBLANK_STAT (1 << 0)
+# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0)
# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19)
+# define RADEON_SW_INT_TEST (1 << 25)
# define RADEON_SW_INT_TEST_ACK (1 << 25)
# define RADEON_SW_INT_FIRE (1 << 26)
@@ -632,6 +637,7 @@ extern int radeon_emit_irq(drm_device_t *dev);
#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0
#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1
#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2
+#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3
#define RADEON_LAST_DISPATCH 1
#define RADEON_MAX_VB_AGE 0x7fffffff
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 36f667e0df98..54702bee63ac 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -1,4 +1,4 @@
-/* radeon_mem.c -- Simple agp/fb memory manager for radeon -*- linux-c -*-
+/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
@@ -27,6 +27,7 @@
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@daenzer.net>
*/
#include "radeon.h"
@@ -58,110 +59,117 @@ 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 temp;
+ u32 stat;
- /* Need to wait for fifo to drain?
- */
- temp = RADEON_READ(RADEON_GEN_INT_STATUS);
- temp = temp & RADEON_SW_INT_TEST_ACK;
- if (temp == 0) return;
- RADEON_WRITE(RADEON_GEN_INT_STATUS, temp);
-
- atomic_inc(&dev_priv->irq_received);
-#ifdef __linux__
- schedule_work(&dev->work);
-#endif /* __linux__ */
-#ifdef __FreeBSD__
- taskqueue_enqueue(taskqueue_swi, &dev->task);
-#endif /* __FreeBSD__ */
-}
+ stat = RADEON_READ(RADEON_GEN_INT_STATUS);
+ if (!stat)
+ return;
-void DRM(dma_immediate_bh)( DRM_TASKQUEUE_ARGS )
-{
- drm_device_t *dev = (drm_device_t *) arg;
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *)dev->dev_private;
+ /* SW interrupt */
+ if (stat & RADEON_SW_INT_TEST) {
+ DRM_WAKEUP( &dev_priv->swi_queue );
+ }
-#ifdef __linux__
- wake_up_interruptible(&dev_priv->irq_queue);
-#endif /* __linux__ */
-#ifdef __FreeBSD__
- wakeup( &dev_priv->irq_queue );
+#if __HAVE_VBL_IRQ
+ /* VBLANK interrupt */
+ if (stat & RADEON_CRTC_VBLANK_STAT) {
+ atomic_inc(&dev->vbl_received);
+ DRM_WAKEUP(&dev->vbl_queue);
+ }
#endif
+
+ /* 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)
+{
+ 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)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ unsigned int ret;
RING_LOCALS;
- atomic_inc(&dev_priv->irq_emitted);
+ atomic_inc(&dev_priv->swi_emitted);
+ ret = atomic_read(&dev_priv->swi_emitted);
- BEGIN_RING(2);
- OUT_RING( CP_PACKET0( RADEON_GEN_INT_STATUS, 0 ) );
- OUT_RING( RADEON_SW_INT_FIRE );
+ BEGIN_RING( 4 );
+ OUT_RING_REG( RADEON_LAST_SWI_REG, ret );
+ OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE );
ADVANCE_RING();
COMMIT_RING();
- return atomic_read(&dev_priv->irq_emitted);
+ return ret;
}
-int radeon_wait_irq(drm_device_t *dev, int irq_nr)
+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 (atomic_read(&dev_priv->irq_received) >= irq_nr)
+ if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
return 0;
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-#ifdef __linux__
- add_wait_queue(&dev_priv->irq_queue, &entry);
-
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if (atomic_read(&dev_priv->irq_received) >= irq_nr)
- break;
- if((signed)(end - jiffies) <= 0) {
- ret = -EBUSY; /* Lockup? Missed irq? */
- break;
- }
- schedule_timeout(HZ*3);
- if (signal_pending(current)) {
- ret = -EINTR;
- break;
- }
- }
+ /* This is a hack to work around mysterious freezes on certain
+ * systems:
+ */
+ radeon_acknowledge_irqs( dev_priv );
+
+ 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->irq_queue, &entry);
- return ret;
-#endif /* __linux__ */
-
-#ifdef __FreeBSD__
- ret = tsleep( &dev_priv->irq_queue, PZERO | PCATCH, \
- "rdnirq", 3*hz );
- if ( (ret == EWOULDBLOCK) || (ret == EINTR) )
- return DRM_ERR(EBUSY);
return ret;
-#endif /* __FreeBSD__ */
}
-
int radeon_emit_and_wait_irq(drm_device_t *dev)
{
return radeon_wait_irq( dev, radeon_emit_irq(dev) );
}
+#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;
+ unsigned int cur_vblank;
+ int ret = 0;
+
+ if ( !dev_priv ) {
+ DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ return DRM_ERR(EINVAL);
+ }
+
+ 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...
+ */
+ 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.
*/
int radeon_irq_emit( DRM_IOCTL_ARGS )
@@ -211,3 +219,38 @@ int radeon_irq_wait( DRM_IOCTL_ARGS )
return radeon_wait_irq( dev, irqwait.irq_seq );
}
+
+/* drm_dma.h hooks
+*/
+void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *)dev->dev_private;
+
+ /* Disable *all* interrupts */
+ RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+
+ /* Clear bits if they're already high */
+ radeon_acknowledge_irqs( dev_priv );
+}
+
+void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *)dev->dev_private;
+
+ atomic_set(&dev_priv->swi_emitted, 0);
+ DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );
+
+ /* Turn on SW and VBL ints */
+ RADEON_WRITE( RADEON_GEN_INT_CNTL,
+ RADEON_CRTC_VBLANK_MASK |
+ RADEON_SW_INT_ENABLE );
+}
+
+void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
+ drm_radeon_private_t *dev_priv =
+ (drm_radeon_private_t *)dev->dev_private;
+ if ( dev_priv ) {
+ /* Disable *all* interrupts */
+ RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
+ }
+}
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
index d77c60b914f9..5c07c1afe1d1 100644
--- a/drivers/char/drm/radeon_mem.c
+++ b/drivers/char/drm/radeon_mem.c
@@ -118,7 +118,7 @@ static void free_block( struct mem_block *p )
p->size += q->size;
p->next = q->next;
p->next->prev = p;
- DRM_FREE(p);
+ DRM_FREE(q);
}
if (p->prev->pid == 0) {
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 0172128bef5d..179a22027741 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -1283,7 +1283,6 @@ int radeon_cp_clear( DRM_IOCTL_ARGS )
}
-
/* Not sure why this isn't set all the time:
*/
static int radeon_do_init_pageflip( drm_device_t *dev )
@@ -2172,8 +2171,8 @@ int radeon_cp_getparam( DRM_IOCTL_ARGS )
dev_priv->stats.last_clear_reads++;
value = GET_SCRATCH( 2 );
break;
- case RADEON_PARAM_IRQ_ACTIVE:
- value = dev->irq ? 1 : 0;
+ case RADEON_PARAM_IRQ_NR:
+ value = dev->irq;
break;
case RADEON_PARAM_AGP_BASE:
value = dev_priv->agp_vm_start;