diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-02 07:53:31 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-02 07:53:31 -0700 |
| commit | d175a2f8880b6372b85878df1607192a53a5ce3f (patch) | |
| tree | 89ba302e422353df3c4e8c34a63b92023fdd4066 | |
| parent | 48452f9f022373afd76724f8a273a061835c7fd4 (diff) | |
Update to DRI CVS tree
| -rw-r--r-- | drivers/char/drm/ati_pcigart.h | 10 | ||||
| -rw-r--r-- | drivers/char/drm/drm.h | 15 | ||||
| -rw-r--r-- | drivers/char/drm/drmP.h | 12 | ||||
| -rw-r--r-- | drivers/char/drm/drm_dma.h | 44 | ||||
| -rw-r--r-- | drivers/char/drm/drm_drv.h | 4 | ||||
| -rw-r--r-- | drivers/char/drm/drm_os_linux.h | 55 | ||||
| -rw-r--r-- | drivers/char/drm/radeon.h | 57 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drm.h | 2 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_drv.h | 14 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_irq.c | 177 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_mem.c | 2 | ||||
| -rw-r--r-- | drivers/char/drm/radeon_state.c | 5 |
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; |
