diff options
author | Gareth Hughes <gareth@users.sourceforge.net> | 2001-02-16 05:24:06 +0000 |
---|---|---|
committer | Gareth Hughes <gareth@users.sourceforge.net> | 2001-02-16 05:24:06 +0000 |
commit | 01a14789edce0ce1cae0f3fd4328833399fae56d (patch) | |
tree | 455e6c689273e86516654df7b62e97a3131256d5 /linux | |
parent | 1d30ac11404c588e4a158d72f987c1fb3e478bea (diff) |
- Clean up the way customization of the templates is done.ati-5-0-1-20010220-head
- Fix old-style DMA for gamma driver (please test).
- Pull out IRQ handling into drm_dma.h (please test on i810, gamma).
- Lots of general cleanups, remove compiler warnings etc.
Diffstat (limited to 'linux')
37 files changed, 976 insertions, 1183 deletions
diff --git a/linux/Makefile.linux b/linux/Makefile.linux index b5aca0a8..7c1269c6 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -47,37 +47,34 @@ # **** End of SMP/MODVERSIONS detection -MODS= gamma.o tdfx.o -LIBS= +MODS = gamma.o tdfx.o +LIBS = -#DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ -# lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o -DRMOBS= -DRMTEMPLATES= drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \ - drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \ - drm_fops.h drm_vm.h drm_dma.h drm_stub.h -DRMHEADERS= drm.h drmP.h compat-pre24.h +DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ + drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \ + drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h +DRMHEADERS = drm.h drmP.h compat-pre24.h -GAMMAOBJS= gamma_drv.o gamma_drm.o gamma_dma.o gamma_context.o -GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +GAMMAOBJS = gamma_drv.o gamma_dma.o +GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) -TDFXOBJS= tdfx_drv.o -TDFXHEADERS= tdfx.h $(DRMHEADERS) +TDFXOBJS = tdfx_drv.o +TDFXHEADERS = tdfx.h $(DRMHEADERS) -INC= /usr/include +INC = /usr/include -CFLAGS= -O2 $(WARNINGS) -WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ +CFLAGS = -O2 $(WARNINGS) +WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \ -Wstrict-prototypes -Wnested-externs \ -Wpointer-arith # -Wshadow -Winline -- make output too noisy -MODCFLAGS= $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer -PRGCFLAGS= $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ +MODCFLAGS = $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer +PRGCFLAGS = $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \ -I../../../../../../include -I../../../../../../../../include \ -I../../../../../../../../programs/Xserver/hw/xfree86/common \ -I. -I../../.. -I../../../../../../../../lib/X11 -PRGLIBS= +PRGLIBS = # **** Start of SMP/MODVERSIONS detection @@ -133,7 +130,8 @@ endif ifeq ($(AGP),1) MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE -#DRMOBJS += agpsupport.o +DRMTEMPLATES += drm_agpsupport.h +DRMHEADERS += agpsupport-pre24.h MODS += mga.o r128.o radeon.o ifeq ($(MACHINE),i386) MODS += i810.o @@ -143,17 +141,17 @@ MODS += i810.o endif -MGAOBJS= mga_drv.o mga_dma.o mga_state.o mga_warp.o -MGAHEADERS= mga.h mga_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o +MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -I810OBJS= i810_drv.o i810_dma.o -I810HEADERS= i810.h i810_drv.h $(DRMHEADERS) $(DRMTEMPLATES) +I810OBJS = i810_drv.o i810_dma.o +I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -R128OBJS= r128_drv.o r128_cce.o r128_state.o -R128HEADERS= r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) +R128OBJS = r128_drv.o r128_cce.o r128_state.o +R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) -RADEONOBJS= radeon_drv.o radeon_cp.o radeon_state.o -RADEONHEADERS= radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ +RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o +RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ $(DRMTEMPLATES) endif @@ -204,10 +202,6 @@ endif # **** End of configuration -libdrm.a: $(DRMOBJS) - -$(RM) -f $@ - $(AR) rcs $@ $(DRMOBJS) - dristat: dristat.c $(CC) $(PRGCFLAGS) $< -o $@ @@ -259,7 +253,6 @@ ChangeLog: %.o: %.c $(CC) $(MODCFLAGS) -I$(TREE) -c $< -o $@ -$(DRMOBJS): $(DRMHEADERS) $(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) ifeq ($(AGP),1) diff --git a/linux/drmP.h b/linux/drmP.h index 58d98f50..4032689a 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -83,15 +83,24 @@ #ifndef __HAVE_MTRR #define __HAVE_MTRR 0 #endif +#ifndef __HAVE_CTX_BITMAP +#define __HAVE_CTX_BITMAP 0 +#endif #ifndef __HAVE_DMA #define __HAVE_DMA 0 #endif +#ifndef __HAVE_DMA_IRQ +#define __HAVE_DMA_IRQ 0 +#endif #ifndef __HAVE_DMA_WAITLIST #define __HAVE_DMA_WAITLIST 0 #endif #ifndef __HAVE_DMA_FREELIST #define __HAVE_DMA_FREELIST 0 #endif +#ifndef __HAVE_DMA_HISTOGRAM +#define __HAVE_DMA_HISTOGRAM 0 +#endif #define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \ defined(CONFIG_AGP_MODULE))) @@ -103,7 +112,6 @@ #define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then also include looping detection. */ -#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */ #define DRM_HASH_SIZE 16 /* Size of key hash table */ #define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */ @@ -627,7 +635,7 @@ typedef struct drm_device { struct tq_struct tq; cycles_t ctx_start; cycles_t lck_start; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM drm_histogram_t histo; #endif @@ -651,9 +659,11 @@ typedef struct drm_device { } drm_device_t; - /* Internal function definitions */ +/* ================================================================ + * Internal function definitions + */ - /* Misc. support (init.c) */ + /* Misc. support (drm_init.h) */ extern int DRM(flags); extern void DRM(parse_options)( char *s ); extern int DRM(cpu_valid)( void ); @@ -670,7 +680,7 @@ extern int DRM(lock)(struct inode *inode, struct file *filp, extern int DRM(unlock)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Device support (fops.c) */ + /* Device support (drm_fops.h) */ extern int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev); extern int DRM(flush)(struct file *filp); @@ -682,7 +692,7 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s); extern unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait); - /* Mapping support (vm.c) */ + /* Mapping support (drm_vm.h) */ #if LINUX_VERSION_CODE < 0x020317 extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma, unsigned long address, @@ -717,17 +727,7 @@ extern int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma); extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma); - - /* Proc support (proc.c) */ -extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev, - int minor, - struct proc_dir_entry *root, - struct proc_dir_entry **dev_root); -extern int drm_proc_cleanup(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); - - /* Memory management support (memory.c) */ + /* Memory management support (drm_memory.h) */ extern void DRM(mem_init)(void); extern int DRM(mem_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); @@ -750,7 +750,7 @@ extern int DRM(bind_agp)(agp_memory *handle, unsigned int start); extern int DRM(unbind_agp)(agp_memory *handle); #endif - /* Misc. IOCTL support (ioctl.c) */ + /* Misc. IOCTL support (drm_ioctl.h) */ extern int DRM(irq_busid)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(getunique)(struct inode *inode, struct file *filp, @@ -764,7 +764,7 @@ extern int DRM(getclient)(struct inode *inode, struct file *filp, extern int DRM(getstats)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Context IOCTL support (context.c) */ + /* Context IOCTL support (drm_context.h) */ extern int DRM(resctx)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int DRM(addctx)( struct inode *inode, struct file *filp, @@ -783,14 +783,19 @@ extern int DRM(rmctx)( struct inode *inode, struct file *filp, extern int DRM(context_switch)(drm_device_t *dev, int old, int new); extern int DRM(context_switch_complete)(drm_device_t *dev, int new); - /* Drawable IOCTL support (drawable.c) */ +#if __HAVE_CTX_BITMAP +extern int DRM(ctxbitmap_init)( drm_device_t *dev ); +extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev ); +#endif + + /* Drawable IOCTL support (drm_drawable.h) */ extern int DRM(adddraw)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(rmdraw)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Authentication IOCTL support (auth.c) */ + /* Authentication IOCTL support (drm_auth.h) */ extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic); extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic); @@ -800,7 +805,7 @@ extern int DRM(authmagic)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* Locking IOCTL support (lock.c) */ + /* Locking IOCTL support (drm_lock.h) */ extern int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int DRM(unblock)(struct inode *inode, struct file *filp, @@ -821,17 +826,11 @@ extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context, drm_lock_flags_t flags); extern int DRM(notifier)(void *priv); - /* Context Bitmap support (ctxbitmap.c) */ -extern int DRM(ctxbitmap_init)( drm_device_t *dev ); -extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev ); - - - - - /* Buffer management support (bufs.c) */ + /* Buffer management support (drm_bufs.h) */ extern int DRM(order)( unsigned long size ); extern int DRM(addmap)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +#if __HAVE_DMA extern int DRM(addbufs)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int DRM(infobufs)( struct inode *inode, struct file *filp, @@ -843,27 +842,37 @@ extern int DRM(freebufs)( struct inode *inode, struct file *filp, extern int DRM(mapbufs)( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); - -#if __HAVE_DMA - /* DMA support (dma.c) */ + /* DMA support (drm_dma.h) */ extern int DRM(dma_setup)(drm_device_t *dev); extern void DRM(dma_takedown)(drm_device_t *dev); extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf); extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid); +#if __HAVE_OLD_DMA +/* GH: This is a dirty hack for now... + */ extern void DRM(clear_next_buffer)(drm_device_t *dev); extern int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long)); extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma); -#if 0 extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma); #endif +#if __HAVE_DMA_IRQ +extern int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +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 ); +#if __HAVE_DMA_IRQ_BH +extern void DRM(dma_immediate_bh)( void *dev ); +#endif +#endif #if DRM_DMA_HISTOGRAM extern int DRM(histogram_slot)(unsigned long count); extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf); #endif -#endif - /* Buffer list management support (lists.c) */ + /* Buffer list support (drm_lists.h) */ #if __HAVE_DMA_WAITLIST extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count); extern int DRM(waitlist_destroy)(drm_waitlist_t *bl); @@ -877,9 +886,10 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf); extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block); #endif +#endif /* __HAVE_DMA */ #if __REALLY_HAVE_AGP - /* AGP/GART support (agpsupport.c) */ + /* AGP/GART support (drm_agpsupport.h) */ extern drm_agp_head_t *DRM(agp_init)(void); extern void DRM(agp_uninit)(void); extern int DRM(agp_acquire)(struct inode *inode, struct file *filp, @@ -903,6 +913,7 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type); extern int DRM(agp_free_memory)(agp_memory *handle); extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start); extern int DRM(agp_unbind_memory)(agp_memory *handle); +#endif /* Stub support (drm_stub.h) */ int DRM(stub_register)(const char *name, @@ -910,6 +921,14 @@ int DRM(stub_register)(const char *name, drm_device_t *dev); int DRM(stub_unregister)(int minor); -#endif -#endif + /* Proc support (drm_proc.h) */ +extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, + int minor, + struct proc_dir_entry *root, + struct proc_dir_entry **dev_root); +extern int DRM(proc_cleanup)(int minor, + struct proc_dir_entry *root, + struct proc_dir_entry *dev_root); + +#endif /* __KERNEL__ */ #endif diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h index f2613a98..38ea1ff0 100644 --- a/linux/drm_bufs.h +++ b/linux/drm_bufs.h @@ -252,7 +252,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, buf->order = order; buf->used = 0; - buf->offset = (dma->byte_count + offset); /* ******** */ + buf->offset = (dma->byte_count + offset); buf->bus_address = agp_offset + offset; buf->address = (void *)(agp_offset + offset); buf->next = NULL; @@ -266,7 +266,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, DRM_MEM_BUFS ); memset( buf->dev_private, 0, buf->dev_priv_size ); -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; buf->time_completed = 0; @@ -297,17 +297,12 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp, DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count ); DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count ); -/* GH: Please leave this disabled for now. I need to fix this properly... - */ -#if 0 - /* FIXME: work this mess out... - */ +#if __HAVE_DMA_FREELIST DRM(freelist_create)( &entry->freelist, entry->buf_count ); for ( i = 0 ; i < entry->buf_count ; i++ ) { DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - up( &dev->struct_sem ); request.count = entry->buf_count; @@ -443,11 +438,11 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, buf->pending = 0; init_waitqueue_head( &buf->dma_wait ); buf->pid = 0; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = 0; buf->time_dispatched = 0; buf->time_completed = 0; - buf->time_freed = 0; + buf->time_freed = 0; #endif DRM_DEBUG( "buffer %d @ %p\n", entry->buf_count, buf->address ); @@ -469,17 +464,12 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp, dma->page_count += entry->seg_count << page_order; dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); -/* GH: Please leave this disabled for now. I need to fix this properly... - */ -#if 0 - /* FIXME: work this mess out... - */ +#if __HAVE_DMA_FREELIST DRM(freelist_create)( &entry->freelist, entry->buf_count ); for ( i = 0 ; i < entry->buf_count ; i++ ) { DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] ); } #endif - up( &dev->struct_sem ); request.count = entry->buf_count; diff --git a/linux/drm_context.h b/linux/drm_context.h index 6bbcfca8..e2b6170a 100644 --- a/linux/drm_context.h +++ b/linux/drm_context.h @@ -29,6 +29,11 @@ * Gareth Hughes <gareth@valinux.com> */ +#define __NO_VERSION__ +#include "drmP.h" + +#if __HAVE_CTX_BITMAP + /* ================================================================ * Context bitmap support */ @@ -98,7 +103,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new ) return -EBUSY; } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM dev->ctx_start = get_cycles(); #endif @@ -131,7 +136,7 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new ) /* If a context switch is ever initiated when the kernel holds the lock, release that lock here. */ -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles() - dev->ctx_start)] ); @@ -268,3 +273,376 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, return 0; } + + +#else /* __HAVE_CTX_BITMAP */ + +/* ================================================================ + * Old-style context support + */ + + +int DRM(context_switch)(drm_device_t *dev, int old, int new) +{ + char buf[64]; + drm_queue_t *q; + +#if 0 + atomic_inc(&dev->total_ctx); +#endif + + if (test_and_set_bit(0, &dev->context_flag)) { + DRM_ERROR("Reentering -- FIXME\n"); + return -EBUSY; + } + +#if __HAVE_DMA_HISTOGRAM + dev->ctx_start = get_cycles(); +#endif + + DRM_DEBUG("Context switch from %d to %d\n", old, new); + + if (new >= dev->queue_count) { + clear_bit(0, &dev->context_flag); + return -EINVAL; + } + + if (new == dev->last_context) { + clear_bit(0, &dev->context_flag); + return 0; + } + + q = dev->queuelist[new]; + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + atomic_dec(&q->use_count); + clear_bit(0, &dev->context_flag); + return -EINVAL; + } + + if (DRM(flags) & DRM_FLAG_NOCTX) { + DRM(context_switch_complete)(dev, new); + } else { + sprintf(buf, "C %d %d\n", old, new); + DRM(write_string)(dev, buf); + } + + atomic_dec(&q->use_count); + + return 0; +} + +int DRM(context_switch_complete)(drm_device_t *dev, int new) +{ + drm_device_dma_t *dma = dev->dma; + + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ + dev->last_switch = jiffies; + + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); + } + + if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { + if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + DRM_ERROR("Cannot free lock\n"); + } + } + +#if __HAVE_DMA_HISTOGRAM + atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() + - dev->ctx_start)]); + +#endif + clear_bit(0, &dev->context_flag); + wake_up_interruptible(&dev->context_wait); + + return 0; +} + +static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) +{ + DRM_DEBUG("\n"); + + if (atomic_read(&q->use_count) != 1 + || atomic_read(&q->finalization) + || atomic_read(&q->block_count)) { + DRM_ERROR("New queue is already in use: u%d f%d b%d\n", + atomic_read(&q->use_count), + atomic_read(&q->finalization), + atomic_read(&q->block_count)); + } + + atomic_set(&q->finalization, 0); + atomic_set(&q->block_count, 0); + atomic_set(&q->block_read, 0); + atomic_set(&q->block_write, 0); + atomic_set(&q->total_queued, 0); + atomic_set(&q->total_flushed, 0); + atomic_set(&q->total_locks, 0); + + init_waitqueue_head(&q->write_queue); + init_waitqueue_head(&q->read_queue); + init_waitqueue_head(&q->flush_queue); + + q->flags = ctx->flags; + + DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count); + + return 0; +} + + +/* drm_alloc_queue: +PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not + disappear (so all deallocation must be done after IOCTLs are off) + 2) dev->queue_count < dev->queue_slots + 3) dev->queuelist[i].use_count == 0 and + dev->queuelist[i].finalization == 0 if i not in use +POST: 1) dev->queuelist[i].use_count == 1 + 2) dev->queue_count < dev->queue_slots */ + +static int DRM(alloc_queue)(drm_device_t *dev) +{ + int i; + drm_queue_t *queue; + int oldslots; + int newslots; + /* Check for a free queue */ + for (i = 0; i < dev->queue_count; i++) { + atomic_inc(&dev->queuelist[i]->use_count); + if (atomic_read(&dev->queuelist[i]->use_count) == 1 + && !atomic_read(&dev->queuelist[i]->finalization)) { + DRM_DEBUG("%d (free)\n", i); + return i; + } + atomic_dec(&dev->queuelist[i]->use_count); + } + /* Allocate a new queue */ + down(&dev->struct_sem); + + queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); + memset(queue, 0, sizeof(*queue)); + atomic_set(&queue->use_count, 1); + + ++dev->queue_count; + if (dev->queue_count >= dev->queue_slots) { + oldslots = dev->queue_slots * sizeof(*dev->queuelist); + if (!dev->queue_slots) dev->queue_slots = 1; + dev->queue_slots *= 2; + newslots = dev->queue_slots * sizeof(*dev->queuelist); + + dev->queuelist = DRM(realloc)(dev->queuelist, + oldslots, + newslots, + DRM_MEM_QUEUES); + if (!dev->queuelist) { + up(&dev->struct_sem); + DRM_DEBUG("out of memory\n"); + return -ENOMEM; + } + } + dev->queuelist[dev->queue_count-1] = queue; + + up(&dev->struct_sem); + DRM_DEBUG("%d (new)\n", dev->queue_count - 1); + return dev->queue_count - 1; +} + +int DRM(resctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_ctx_res_t res; + drm_ctx_t ctx; + int i; + + DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); + if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) + return -EFAULT; + if (res.count >= DRM_RESERVED_CONTEXTS) { + memset(&ctx, 0, sizeof(ctx)); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { + ctx.handle = i; + if (copy_to_user(&res.contexts[i], + &i, + sizeof(i))) + return -EFAULT; + } + } + res.count = DRM_RESERVED_CONTEXTS; + if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) + return -EFAULT; + return 0; +} + +int DRM(addctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) { + /* Init kernel's context and get a new one. */ + DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); + ctx.handle = DRM(alloc_queue)(dev); + } + DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx); + DRM_DEBUG("%d\n", ctx.handle); + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; + return 0; +} + +int DRM(modctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + drm_queue_t *q; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + if (DRM_BUFCOUNT(&q->waitlist)) { + atomic_dec(&q->use_count); + return -EBUSY; + } + + q->flags = ctx.flags; + + atomic_dec(&q->use_count); + return 0; +} + +int DRM(getctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + drm_queue_t *q; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + ctx.flags = q->flags; + atomic_dec(&q->use_count); + + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; + + return 0; +} + +int DRM(switchctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + return DRM(context_switch)(dev, dev->last_context, ctx.handle); +} + +int DRM(newctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + DRM(context_switch_complete)(dev, ctx.handle); + + return 0; +} + +int DRM(rmctx)(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + drm_queue_t *q; + drm_buf_t *buf; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + + if (ctx.handle >= dev->queue_count) return -EINVAL; + q = dev->queuelist[ctx.handle]; + + atomic_inc(&q->use_count); + if (atomic_read(&q->use_count) == 1) { + /* No longer in use */ + atomic_dec(&q->use_count); + return -EINVAL; + } + + atomic_inc(&q->finalization); /* Mark queue in finalization state */ + atomic_sub(2, &q->use_count); /* Mark queue as unused (pending + finalization) */ + + while (test_and_set_bit(0, &dev->interrupt_flag)) { + schedule(); + if (signal_pending(current)) { + clear_bit(0, &dev->interrupt_flag); + return -EINTR; + } + } + /* Remove queued buffers */ + while ((buf = DRM(waitlist_get)(&q->waitlist))) { + DRM(free_buffer)(dev, buf); + } + clear_bit(0, &dev->interrupt_flag); + + /* Wakeup blocked processes */ + wake_up_interruptible(&q->read_queue); + wake_up_interruptible(&q->write_queue); + wake_up_interruptible(&q->flush_queue); + + /* Finalization over. Queue is made + available when both use_count and + finalization become 0, which won't + happen until all the waiting processes + stop waiting. */ + atomic_dec(&q->finalization); + return 0; +} + +#endif /* __HAVE_CTX_BITMAP */ diff --git a/linux/drm_dma.h b/linux/drm_dma.h index 35eb896e..e715bd41 100644 --- a/linux/drm_dma.h +++ b/linux/drm_dma.h @@ -118,7 +118,7 @@ void DRM(dma_takedown)(drm_device_t *dev) } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM /* This is slow, but is useful for debugging. */ int DRM(histogram_slot)(unsigned long count) { @@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf) buf->pending = 0; buf->pid = 0; buf->used = 0; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_completed = get_cycles(); #endif @@ -231,85 +231,6 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid) */ #if __HAVE_OLD_DMA -int drm_context_switch(drm_device_t *dev, int old, int new) -{ - char buf[64]; - drm_queue_t *q; - -#if 0 - atomic_inc(&dev->total_ctx); -#endif - - if (test_and_set_bit(0, &dev->context_flag)) { - DRM_ERROR("Reentering -- FIXME\n"); - return -EBUSY; - } - -#if DRM_DMA_HISTOGRAM - dev->ctx_start = get_cycles(); -#endif - - DRM_DEBUG("Context switch from %d to %d\n", old, new); - - if (new >= dev->queue_count) { - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (new == dev->last_context) { - clear_bit(0, &dev->context_flag); - return 0; - } - - q = dev->queuelist[new]; - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - atomic_dec(&q->use_count); - clear_bit(0, &dev->context_flag); - return -EINVAL; - } - - if (DRM(flags) & DRM_FLAG_NOCTX) { - drm_context_switch_complete(dev, new); - } else { - sprintf(buf, "C %d %d\n", old, new); - DRM(write_string)(dev, buf); - } - - atomic_dec(&q->use_count); - - return 0; -} - -int drm_context_switch_complete(drm_device_t *dev, int new) -{ - drm_device_dma_t *dma = dev->dma; - - dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ - dev->last_switch = jiffies; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("Lock isn't held after context switch\n"); - } - - if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) { - if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { - DRM_ERROR("Cannot free lock\n"); - } - } - -#if DRM_DMA_HISTOGRAM - atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles() - - dev->ctx_start)]); - -#endif - clear_bit(0, &dev->context_flag); - wake_up_interruptible(&dev->context_wait); - - return 0; -} - void DRM(clear_next_buffer)(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; @@ -571,6 +492,103 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma) return 0; } -#endif +#endif /* __HAVE_OLD_DMA */ + + +#if __HAVE_DMA_IRQ + +int DRM(irq_install)( drm_device_t *dev, int irq ) +{ + int ret; + + if ( !irq ) + return -EINVAL; + + down( &dev->struct_sem ); + if ( dev->irq ) { + up( &dev->struct_sem ); + return -EBUSY; + } + dev->irq = irq; + up( &dev->struct_sem ); + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + dev->context_flag = 0; + dev->interrupt_flag = 0; + dev->dma_flag = 0; + + dev->dma->next_buffer = NULL; + dev->dma->next_queue = NULL; + dev->dma->this_buffer = NULL; +#if __HAVE_DMA_IRQ_BH + INIT_LIST_HEAD( &dev->tq.list ); + dev->tq.sync = 0; + dev->tq.routine = DRM(dma_immediate_bh); + dev->tq.data = dev; #endif + + /* Before installing handler */ + DRIVER_PREINSTALL(); + + /* Install handler */ + ret = request_irq( dev->irq, DRM(dma_service), + 0, dev->devname, dev ); + if ( ret < 0 ) { + down( &dev->struct_sem ); + dev->irq = 0; + up( &dev->struct_sem ); + return ret; + } + + /* After installing handler */ + DRIVER_POSTINSTALL(); + + return 0; +} + +int DRM(irq_uninstall)( drm_device_t *dev ) +{ + int irq; + + down( &dev->struct_sem ); + irq = dev->irq; + dev->irq = 0; + up( &dev->struct_sem ); + + if ( !irq ) + return -EINVAL; + + DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq ); + + DRIVER_UNINSTALL(); + + free_irq( irq, dev ); + + return 0; +} + +int DRM(control)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_control_t ctl; + + if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) ) + return -EFAULT; + + switch ( ctl.func ) { + case DRM_INST_HANDLER: + return DRM(irq_install)( dev, ctl.irq ); + case DRM_UNINST_HANDLER: + return DRM(irq_uninstall)( dev ); + default: + return -EINVAL; + } +} + +#endif /* __HAVE_DMA_IRQ */ + +#endif /* __HAVE_DMA */ diff --git a/linux/drm_drv.h b/linux/drm_drv.h index b24d213e..71f52276 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -687,7 +687,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_KERNEL_CONTEXT ); } } -#else +#elif __HAVE_DMA DRM(reclaim_buffers)( dev, priv->pid ); #endif @@ -794,7 +794,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, #if __HAVE_MULTIPLE_DMA_QUEUES drm_queue_t *q; #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM cycles_t start; dev->lck_start = start = get_cycles(); @@ -882,7 +882,7 @@ int DRM(lock)( struct inode *inode, struct file *filp, DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]); #endif return ret; diff --git a/linux/drm_fops.h b/linux/drm_fops.h index d646f318..dd574766 100644 --- a/linux/drm_fops.h +++ b/linux/drm_fops.h @@ -83,50 +83,6 @@ int DRM(flush)(struct file *filp) return 0; } -#if 0 -/* drm_release is called whenever a process closes /dev/drm*. Linux calls - this only if any mappings have been closed. */ - -int drm_release(struct inode *inode, struct file *filp) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - - DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", - current->pid, dev->device, dev->open_count); - - if (dev->lock.hw_lock - && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) - && dev->lock.pid == current->pid) { - DRM_ERROR("Process %d dead, freeing lock for context %d\n", - current->pid, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - drm_lock_free(dev, - &dev->lock.hw_lock->lock, - _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - - /* FIXME: may require heavy-handed reset of - hardware at this point, possibly - processed via a callback to the X - server. */ - } - drm_reclaim_buffers(dev, priv->pid); - - drm_fasync(-1, filp, 0); - - down(&dev->struct_sem); - if (priv->prev) priv->prev->next = priv->next; - else dev->file_first = priv->next; - if (priv->next) priv->next->prev = priv->prev; - else dev->file_last = priv->prev; - up(&dev->struct_sem); - - drm_free(priv, sizeof(*priv), DRM_MEM_FILES); - - return 0; -} -#endif - int DRM(fasync)(int fd, struct file *filp, int on) { drm_file_t *priv = filp->private_data; diff --git a/linux/drm_lists.h b/linux/drm_lists.h index b597ef77..f8dbaaa7 100644 --- a/linux/drm_lists.h +++ b/linux/drm_lists.h @@ -74,7 +74,7 @@ int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf) buf->idx, buf->pid); return -EINVAL; } -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_queued = get_cycles(); #endif buf->list = DRM_LIST_WAIT; @@ -106,6 +106,7 @@ drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl) #endif /* __HAVE_DMA_WAITLIST */ + #if __HAVE_DMA_FREELIST int DRM(freelist_create)(drm_freelist_t *bl, int count) @@ -142,7 +143,7 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf) buf->idx, buf->waiting, buf->pending, buf->list); } if (!bl) return 1; -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM buf->time_freed = get_cycles(); DRM(histogram_compute)(dev, buf); #endif diff --git a/linux/drm_proc.h b/linux/drm_proc.h index 634673d9..ee9c0cbc 100644 --- a/linux/drm_proc.h +++ b/linux/drm_proc.h @@ -50,7 +50,7 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset, static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM static int DRM(histo_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data); #endif @@ -68,7 +68,7 @@ struct drm_proc_list { #if DRM_DEBUG_CODE { "vma", DRM(vma_info) }, #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM { "histo", DRM(histo_info) }, #endif }; @@ -481,7 +481,7 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request, #endif -#if DRM_DMA_HISTOGRAM +#if __HAVE_DMA_HISTOGRAM static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request, int *eof, void *data) { diff --git a/linux/drm_stub.h b/linux/drm_stub.h index ed37af4d..a6a39d86 100644 --- a/linux/drm_stub.h +++ b/linux/drm_stub.h @@ -1,4 +1,4 @@ -/* drm_stub.c -- -*- linux-c -*- +/* drm_stub.h -- -*- linux-c -*- * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org * * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California. @@ -28,6 +28,9 @@ * */ +#define __NO_VERSION__ +#include "drmP.h" + #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ static struct drm_stub_list { @@ -58,7 +61,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp) filp->f_op = fops_get(old_fops); } fops_put(old_fops); - + return err; } @@ -73,7 +76,7 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, drm_device_t *dev) { int i; - + if (!DRM(stub_list)) { DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); diff --git a/linux/gamma.h b/linux/gamma.h index 5ca1f745..383c54af 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -1,3 +1,32 @@ +/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- + * Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com + * + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + */ + #ifndef __GAMMA_H__ #define __GAMMA_H__ @@ -5,18 +34,54 @@ */ #define DRM(x) gamma_##x -#define __HAVE_MTRR 1 -#define __HAVE_PCI_DMA 1 -#define __HAVE_CTX_BITMAP 0 +/* General customization: + */ +#define __HAVE_MTRR 1 + +/* DMA customization: + */ +#define __HAVE_DMA 1 +#define __HAVE_OLD_DMA 1 +#define __HAVE_PCI_DMA 1 + #define __HAVE_MULTIPLE_DMA_QUEUES 1 +#define __HAVE_DMA_WAITQUEUE 1 + +#define __HAVE_DMA_WAITLIST 1 +#define __HAVE_DMA_FREELIST 1 + #define __HAVE_DMA_FLUSH 1 -#define __HAVE_DMA_QUEUE 0 #define __HAVE_DMA_SCHEDULE 1 -#define __HAVE_DMA_WAITQUEUE 1 -#define __HAVE_DMA_WAITLIST 1 -#define __HAVE_DMA_FREELIST 1 -#define __HAVE_DMA 1 -#define __HAVE_OLD_DMA 1 -#define __HAVE_DMA_IRQ 1 -#endif +#define __HAVE_DMA_READY 1 +#define DRIVER_DMA_READY() do { \ + gamma_dma_ready(dev); \ +} while (0) + +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + /* FIXME ! */ \ + gamma_dma_quiescent_dual(dev); \ + return 0; \ +} while (0) + +#define __HAVE_DMA_IRQ 1 +#define __HAVE_DMA_IRQ_BH 1 +#define DRIVER_PREINSTALL() do { \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ +} while (0) + +#endif /* __GAMMA_H__ */ diff --git a/linux/gamma_context.c b/linux/gamma_context.c deleted file mode 100644 index d94054a2..00000000 --- a/linux/gamma_context.c +++ /dev/null @@ -1,319 +0,0 @@ -/* context.c -- IOCTLs for contexts and DMA queues -*- linux-c -*- - * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * - */ - -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" - -static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx) -{ - DRM_DEBUG("\n"); - - if (atomic_read(&q->use_count) != 1 - || atomic_read(&q->finalization) - || atomic_read(&q->block_count)) { - DRM_ERROR("New queue is already in use: u%d f%d b%d\n", - atomic_read(&q->use_count), - atomic_read(&q->finalization), - atomic_read(&q->block_count)); - } - - atomic_set(&q->finalization, 0); - atomic_set(&q->block_count, 0); - atomic_set(&q->block_read, 0); - atomic_set(&q->block_write, 0); - atomic_set(&q->total_queued, 0); - atomic_set(&q->total_flushed, 0); - atomic_set(&q->total_locks, 0); - - init_waitqueue_head(&q->write_queue); - init_waitqueue_head(&q->read_queue); - init_waitqueue_head(&q->flush_queue); - - q->flags = ctx->flags; - - gamma_waitlist_create(&q->waitlist, dev->dma->buf_count); - - return 0; -} - - -/* drm_alloc_queue: -PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not - disappear (so all deallocation must be done after IOCTLs are off) - 2) dev->queue_count < dev->queue_slots - 3) dev->queuelist[i].use_count == 0 and - dev->queuelist[i].finalization == 0 if i not in use -POST: 1) dev->queuelist[i].use_count == 1 - 2) dev->queue_count < dev->queue_slots */ - -static int drm_alloc_queue(drm_device_t *dev) -{ - int i; - drm_queue_t *queue; - int oldslots; - int newslots; - /* Check for a free queue */ - for (i = 0; i < dev->queue_count; i++) { - atomic_inc(&dev->queuelist[i]->use_count); - if (atomic_read(&dev->queuelist[i]->use_count) == 1 - && !atomic_read(&dev->queuelist[i]->finalization)) { - DRM_DEBUG("%d (free)\n", i); - return i; - } - atomic_dec(&dev->queuelist[i]->use_count); - } - /* Allocate a new queue */ - down(&dev->struct_sem); - - queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES); - memset(queue, 0, sizeof(*queue)); - atomic_set(&queue->use_count, 1); - - ++dev->queue_count; - if (dev->queue_count >= dev->queue_slots) { - oldslots = dev->queue_slots * sizeof(*dev->queuelist); - if (!dev->queue_slots) dev->queue_slots = 1; - dev->queue_slots *= 2; - newslots = dev->queue_slots * sizeof(*dev->queuelist); - - dev->queuelist = gamma_realloc(dev->queuelist, - oldslots, - newslots, - DRM_MEM_QUEUES); - if (!dev->queuelist) { - up(&dev->struct_sem); - DRM_DEBUG("out of memory\n"); - return -ENOMEM; - } - } - dev->queuelist[dev->queue_count-1] = queue; - - up(&dev->struct_sem); - DRM_DEBUG("%d (new)\n", dev->queue_count - 1); - return dev->queue_count - 1; -} - -int gamma_resctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_ctx_res_t res; - drm_ctx_t ctx; - int i; - - DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); - if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) - return -EFAULT; - if (res.count >= DRM_RESERVED_CONTEXTS) { - memset(&ctx, 0, sizeof(ctx)); - for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { - ctx.handle = i; - if (copy_to_user(&res.contexts[i], - &i, - sizeof(i))) - return -EFAULT; - } - } - res.count = DRM_RESERVED_CONTEXTS; - if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) - return -EFAULT; - return 0; -} - - -int gamma_addctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { - /* Init kernel's context and get a new one. */ - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - ctx.handle = drm_alloc_queue(dev); - } - drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx); - DRM_DEBUG("%d\n", ctx.handle); - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - return 0; -} - -int gamma_modctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - if (DRM_BUFCOUNT(&q->waitlist)) { - atomic_dec(&q->use_count); - return -EBUSY; - } - - q->flags = ctx.flags; - - atomic_dec(&q->use_count); - return 0; -} - -int gamma_getctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - ctx.flags = q->flags; - atomic_dec(&q->use_count); - - if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) - return -EFAULT; - - return 0; -} - -int gamma_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - return drm_context_switch(dev, dev->last_context, ctx.handle); -} - -int gamma_newctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - drm_context_switch_complete(dev, ctx.handle); - - return 0; -} - -int gamma_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_ctx_t ctx; - drm_queue_t *q; - drm_buf_t *buf; - - if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) - return -EFAULT; - DRM_DEBUG("%d\n", ctx.handle); - - if (ctx.handle >= dev->queue_count) return -EINVAL; - q = dev->queuelist[ctx.handle]; - - atomic_inc(&q->use_count); - if (atomic_read(&q->use_count) == 1) { - /* No longer in use */ - atomic_dec(&q->use_count); - return -EINVAL; - } - - atomic_inc(&q->finalization); /* Mark queue in finalization state */ - atomic_sub(2, &q->use_count); /* Mark queue as unused (pending - finalization) */ - - while (test_and_set_bit(0, &dev->interrupt_flag)) { - schedule(); - if (signal_pending(current)) { - clear_bit(0, &dev->interrupt_flag); - return -EINTR; - } - } - /* Remove queued buffers */ - while ((buf = gamma_waitlist_get(&q->waitlist))) { - gamma_free_buffer(dev, buf); - } - clear_bit(0, &dev->interrupt_flag); - - /* Wakeup blocked processes */ - wake_up_interruptible(&q->read_queue); - wake_up_interruptible(&q->write_queue); - wake_up_interruptible(&q->flush_queue); - - /* Finalization over. Queue is made - available when both use_count and - finalization become 0, which won't - happen until all the waiting processes - stop waiting. */ - atomic_dec(&q->finalization); - return 0; -} diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index e2ac6061..2238d126 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,7 +23,7 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * @@ -37,72 +37,6 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> -#if 0 -#define DO_IOREMAP( _map ) \ -do { \ - (_map)->handle = DRM(ioremap)( (_map)->offset, (_map)->size ); \ -} while (0) - -#define DO_IOREMAPFREE( _map ) \ -do { \ - if ( (_map)->handle && (_map)->size ) \ - DRM(ioremapfree)( (_map)->handle, (_map)->size ); \ -} while (0) - -#define DO_FIND_MAP( _map, _offset ) \ -do { \ - int _i; \ - for ( _i = 0 ; _i < dev->map_count ; _i++ ) { \ - if ( dev->maplist[_i]->offset == _offset ) { \ - _map = dev->maplist[_i]; \ - break; \ - } \ - } \ -} while (0) -#endif - -/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the - kernel must be specified here. Currently, the number is 2. This must - match the order the X server uses for instantiating register regions , - or must be passed in a new ioctl. */ -#define GAMMA_REG(reg) \ - (2 \ - + ((reg < 0x1000) \ - ? 0 \ - : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3)))) - -#define GAMMA_OFF(reg) \ - ((reg < 0x1000) \ - ? reg \ - : ((reg < 0x10000) \ - ? (reg - 0x1000) \ - : ((reg < 0x11000) \ - ? (reg - 0x10000) \ - : (reg - 0x11000)))) - -#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle) -#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) -#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) -#define GAMMA_READ(reg) GAMMA_DEREF(reg) -#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0) - -#define GAMMA_BROADCASTMASK 0x9378 -#define GAMMA_COMMANDINTENABLE 0x0c48 -#define GAMMA_DMAADDRESS 0x0028 -#define GAMMA_DMACOUNT 0x0030 -#define GAMMA_FILTERMODE 0x8c00 -#define GAMMA_GCOMMANDINTFLAGS 0x0c50 -#define GAMMA_GCOMMANDMODE 0x0c40 -#define GAMMA_GCOMMANDSTATUS 0x0c60 -#define GAMMA_GDELAYTIMER 0x0c38 -#define GAMMA_GDMACONTROL 0x0060 -#define GAMMA_GINTENABLE 0x0808 -#define GAMMA_GINTFLAGS 0x0810 -#define GAMMA_INFIFOSPACE 0x0018 -#define GAMMA_OUTFIFOWORDS 0x0020 -#define GAMMA_OUTPUTFIFO 0x2000 -#define GAMMA_SYNC 0x8c40 -#define GAMMA_SYNC_TAG 0x0188 static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, unsigned long length) @@ -122,7 +56,7 @@ void gamma_dma_quiescent_single(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; @@ -140,13 +74,13 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10); GAMMA_WRITE(GAMMA_SYNC, 0); - + /* Read from first MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS)) ; } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG); - + /* Read from second MX */ do { while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000)) @@ -165,11 +99,11 @@ static inline int gamma_dma_is_ready(drm_device_t *dev) return !GAMMA_READ(GAMMA_DMACOUNT); } -static void gamma_dma_service(int irq, void *device, struct pt_regs *regs) +void gamma_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; drm_device_dma_t *dma = dev->dma; - + atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); @@ -202,7 +136,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) #endif if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY; - + #if DRM_DMA_HISTOGRAM dma_start = get_cycles(); #endif @@ -234,7 +168,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked) clear_bit(0, &dev->dma_flag); return 0; } - + if (!gamma_dma_is_ready(dev)) { clear_bit(0, &dev->dma_flag); return -EBUSY; @@ -258,13 +192,14 @@ static int gamma_do_dma(drm_device_t *dev, int locked) && !(dev->queuelist[buf->context]->flags & _DRM_CONTEXT_PRESERVED)) { /* PRE: dev->last_context != buf->context */ - if (drm_context_switch(dev, dev->last_context, buf->context)) { - gamma_clear_next_buffer(dev); - gamma_free_buffer(dev, buf); + if (DRM(context_switch)(dev, dev->last_context, + buf->context)) { + DRM(clear_next_buffer)(dev); + DRM(free_buffer)(dev, buf); } retcode = -EBUSY; goto cleanup; - + /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == buf->context. @@ -305,12 +240,12 @@ cleanup: return retcode; } -static void gamma_dma_schedule_timer_wrapper(unsigned long dev) +static void gamma_dma_timer_bh(unsigned long dev) { gamma_dma_schedule((drm_device_t *)dev, 0); } -static void gamma_dma_schedule_tq_wrapper(void *dev) +void gamma_dma_immediate_bh(void *dev) { gamma_dma_schedule(dev, 0); } @@ -354,8 +289,7 @@ again: if (!(retcode = gamma_do_dma(dev, locked))) ++processed; } else { do { - next = gamma_select_queue(dev, - gamma_dma_schedule_timer_wrapper); + next = gamma_select_queue(dev, gamma_dma_timer_bh); if (next >= 0) { q = dev->queuelist[next]; buf = gamma_waitlist_get(&q->waitlist); @@ -383,9 +317,9 @@ again: goto again; } } - + clear_bit(0, &dev->interrupt_flag); - + #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles() - schedule_start)]); @@ -472,15 +406,15 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) goto cleanup; } buf->pending = 1; - + if (dev->last_context != buf->context && !(dev->queuelist[buf->context]->flags & _DRM_CONTEXT_PRESERVED)) { add_wait_queue(&dev->context_wait, &entry); current->state = TASK_INTERRUPTIBLE; /* PRE: dev->last_context != buf->context */ - drm_context_switch(dev, dev->last_context, - buf->context); + DRM(context_switch)(dev, dev->last_context, + buf->context); /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == buf->context. @@ -507,7 +441,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d) gamma_dma_dispatch(dev, address, length); atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */ atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */ - + if (last_buf) { gamma_free_buffer(dev, last_buf); } @@ -520,7 +454,7 @@ cleanup: gamma_dma_ready(dev); gamma_free_buffer(dev, last_buf); } - + if (must_free && !dev->context_flag) { if (gamma_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { @@ -542,15 +476,15 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) last_buf = dma->buflist[d->send_indices[d->send_count-1]]; add_wait_queue(&last_buf->dma_wait, &entry); } - + if ((retcode = gamma_dma_enqueue(dev, d))) { if (d->flags & _DRM_DMA_BLOCK) remove_wait_queue(&last_buf->dma_wait, &entry); return retcode; } - + gamma_dma_schedule(dev, 0); - + if (d->flags & _DRM_DMA_BLOCK) { DRM_DEBUG("%d waiting\n", current->pid); for (;;) { @@ -618,7 +552,7 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, if (d.send_count) { if (d.flags & _DRM_DMA_PRIORITY) retcode = gamma_dma_priority(dev, &d); - else + else retcode = gamma_dma_send_buffers(dev, &d); } @@ -635,105 +569,3 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, return retcode; } - -int gamma_irq_install(drm_device_t *dev, int irq) -{ - int retcode; - - if (!irq) return -EINVAL; - - down(&dev->struct_sem); - if (dev->irq) { - up(&dev->struct_sem); - return -EBUSY; - } - dev->irq = irq; - up(&dev->struct_sem); - - DRM_DEBUG("%d\n", irq); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - - INIT_LIST_HEAD(&dev->tq.list); - dev->tq.sync = 0; - dev->tq.routine = gamma_dma_schedule_tq_wrapper; - dev->tq.data = dev; - - - /* Before installing handler */ - GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0); - GAMMA_WRITE(GAMMA_GDMACONTROL, 0); - - /* Install handler */ - if ((retcode = request_irq(dev->irq, - gamma_dma_service, - 0, - dev->devname, - dev))) { - down(&dev->struct_sem); - dev->irq = 0; - up(&dev->struct_sem); - return retcode; - } - - /* After installing handler */ - GAMMA_WRITE(GAMMA_GINTENABLE, 0x2001); - GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008); - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0x39090); - - return 0; -} - -int gamma_irq_uninstall(drm_device_t *dev) -{ - int irq; - - down(&dev->struct_sem); - irq = dev->irq; - dev->irq = 0; - up(&dev->struct_sem); - - if (!irq) return -EINVAL; - - DRM_DEBUG("%d\n", irq); - - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0); - GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0); - GAMMA_WRITE(GAMMA_GINTENABLE, 0); - free_irq(irq, dev); - - return 0; -} - - -int gamma_control(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_control_t ctl; - int retcode; - - if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) - return -EFAULT; - - switch (ctl.func) { - case DRM_INST_HANDLER: - if ((retcode = gamma_irq_install(dev, ctl.irq))) - return retcode; - break; - case DRM_UNINST_HANDLER: - if ((retcode = gamma_irq_uninstall(dev))) - return retcode; - break; - default: - return -EINVAL; - } - return 0; -} diff --git a/linux/gamma_drm.c b/linux/gamma_drm.c deleted file mode 100644 index 4b12d8c4..00000000 --- a/linux/gamma_drm.c +++ /dev/null @@ -1,33 +0,0 @@ -#define __NO_VERSION__ -#include "gamma.h" -#include "drmP.h" -#include "gamma_drv.h" - -#define DRIVER_DEV_PRIV_T drm_gamma_private_t -#define DRIVER_AGP_BUFFER_MAP dev_priv->buffers - -#include "drm_auth.h" - -#include "drm_bufs.h" - -#include "drm_dma.h" - -#include "drm_drawable.h" - -#include "drm_fops.h" - -#include "drm_init.h" - -#include "drm_ioctl.h" - -#include "drm_lists.h" - -#include "drm_lock.h" - -#include "drm_memory.h" - -#include "drm_proc.h" - -#include "drm_vm.h" - -#include "drm_stub.h" diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c index c24d5a33..98916bc5 100644 --- a/linux/gamma_drv.c +++ b/linux/gamma_drv.c @@ -26,7 +26,7 @@ * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * Gareth Hughes <gareth@valinux.com> */ #include <linux/config.h> @@ -38,29 +38,15 @@ #define DRIVER_NAME "gamma" #define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 - #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 } -#define __HAVE_MTRR 1 -#define __HAVE_CTX_BITMAP 0 -#define __HAVE_PCI_DMA 1 -#define __HAVE_MULTIPLE_DMA_QUEUES 1 -#define __HAVE_DMA_FLUSH 1 -#define __HAVE_DMA_QUEUE 0 -#define __HAVE_DMA_SCHEDULE 1 -#define __HAVE_DMA_WAITQUEUE 1 -#define __HAVE_DMA_WAITLIST 1 -#define __HAVE_DMA_FREELIST 1 -#define __HAVE_DMA 1 -#define __HAVE_OLD_DMA 1 -#define __HAVE_DMA_IRQ 1 #define __HAVE_COUNTERS 5 #define __HAVE_COUNTER6 _DRM_STAT_IRQ @@ -69,35 +55,19 @@ #define __HAVE_COUNTER9 _DRM_STAT_SPECIAL #define __HAVE_COUNTER10 _DRM_STAT_MISSED -#define __HAVE_DMA_READY 1 -#define DRIVER_DMA_READY() \ -do { \ - gamma_dma_ready(dev); \ -} while (0) - -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() \ -do { \ - /* FIXME ! */ \ - gamma_dma_quiescent_dual(dev); \ - return 0; \ -} while (0) - -#if 0 -#define __HAVE_DRIVER_RELEASE 1 -#define DRIVER_RELEASE() do { \ - gamma_reclaim_buffers( dev, priv->pid ); \ - if ( dev->dev_private ) { \ - drm_gamma_private_t *dev_priv = dev->dev_private; \ - dev_priv->dispatch_status &= MGA_IN_DISPATCH; \ - } \ -} while (0) -#endif - -#if 0 -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) gamma_do_cleanup_dma( dev ); \ -} while (0) -#endif +#include "drm_auth.h" +#include "drm_bufs.h" +#include "drm_context.h" +#include "drm_dma.h" +#include "drm_drawable.h" #include "drm_drv.h" +#include "drm_fops.h" +#include "drm_init.h" +#include "drm_ioctl.h" +#include "drm_lists.h" +#include "drm_lock.h" +#include "drm_memory.h" +#include "drm_proc.h" +#include "drm_vm.h" +#include "drm_stub.h" diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index 1bfa2650..d8cca667 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -11,11 +11,11 @@ * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -23,10 +23,10 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - * + * * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> - * + * */ #ifndef _GAMMA_DRV_H_ @@ -47,30 +47,60 @@ do { \ } \ } while (0) + extern void gamma_dma_ready(drm_device_t *dev); extern void gamma_dma_quiescent_single(drm_device_t *dev); extern void gamma_dma_quiescent_dual(drm_device_t *dev); - /* gamma_drv.c */ -extern int gamma_version(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_open(struct inode *inode, struct file *filp); -extern int gamma_release(struct inode *inode, struct file *filp); -extern int gamma_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_lock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int gamma_unlock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); /* gamma_dma.c */ extern int gamma_dma_schedule(drm_device_t *dev, int locked); extern int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int gamma_irq_install(drm_device_t *dev, int irq); -extern int gamma_irq_uninstall(drm_device_t *dev); -extern int gamma_control(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int gamma_find_devices(void); extern int gamma_found(void); + +/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the + kernel must be specified here. Currently, the number is 2. This must + match the order the X server uses for instantiating register regions , + or must be passed in a new ioctl. */ +#define GAMMA_REG(reg) \ + (2 \ + + ((reg < 0x1000) \ + ? 0 \ + : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3)))) + +#define GAMMA_OFF(reg) \ + ((reg < 0x1000) \ + ? reg \ + : ((reg < 0x10000) \ + ? (reg - 0x1000) \ + : ((reg < 0x11000) \ + ? (reg - 0x10000) \ + : (reg - 0x11000)))) + +#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle) +#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg)) +#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg) +#define GAMMA_READ(reg) GAMMA_DEREF(reg) +#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0) + +#define GAMMA_BROADCASTMASK 0x9378 +#define GAMMA_COMMANDINTENABLE 0x0c48 +#define GAMMA_DMAADDRESS 0x0028 +#define GAMMA_DMACOUNT 0x0030 +#define GAMMA_FILTERMODE 0x8c00 +#define GAMMA_GCOMMANDINTFLAGS 0x0c50 +#define GAMMA_GCOMMANDMODE 0x0c40 +#define GAMMA_GCOMMANDSTATUS 0x0c60 +#define GAMMA_GDELAYTIMER 0x0c38 +#define GAMMA_GDMACONTROL 0x0060 +#define GAMMA_GINTENABLE 0x0808 +#define GAMMA_GINTFLAGS 0x0810 +#define GAMMA_INFIFOSPACE 0x0018 +#define GAMMA_OUTFIFOWORDS 0x0020 +#define GAMMA_OUTPUTFIFO 0x2000 +#define GAMMA_SYNC 0x8c40 +#define GAMMA_SYNC_TAG 0x0188 + #endif diff --git a/linux/i810.h b/linux/i810.h index 021d7988..303ddd5e 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -34,17 +34,77 @@ */ #define DRM(x) i810_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define __HAVE_RELEASE 1 +#define DRIVER_RELEASE() do { \ + i810_reclaim_buffers( dev, priv->pid ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 -#define __HAVE_DMA_IRQ 1 #define __HAVE_DMA_QUEUE 1 #define __HAVE_DMA_WAITLIST 1 #define __HAVE_DMA_RECLAIM 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + i810_dma_quiescent( dev ); \ +} while (0) + +#define __HAVE_DMA_IRQ 1 +#define __HAVE_DMA_IRQ_BH 1 +#define DRIVER_PREINSTALL() do { \ + u16 tmp; \ + tmp = I810_READ16( I810REG_HWSTAM ); \ + tmp = tmp & 0x6000; \ + I810_WRITE16( I810REG_HWSTAM, tmp ); \ + \ + tmp = I810_READ16( I810REG_INT_MASK_R ); \ + tmp = tmp & 0x6000; /* Unmask interrupts */ \ + I810_WRITE16( I810REG_INT_MASK_R, tmp ); \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + u16 tmp; \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; \ + tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + u16 tmp; \ + tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \ + tmp = tmp & ~(0x6000); /* Clear all interrupts */ \ + if ( tmp != 0 ) I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \ + \ + tmp = I810_READ16( I810REG_INT_ENABLE_R ); \ + tmp = tmp & 0x6000; /* Disable all interrupts */ \ + I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \ +} while (0) + +/* Buffer customization: + */ + +#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ +({ \ + drm_i810_private_t *dev_priv = (dev)->dev_private; \ + drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx]; \ + map; \ +}) + #endif diff --git a/linux/i810_dma.c b/linux/i810_dma.c index 8585fef1..e27406a6 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -48,17 +48,6 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -#define I810_REG(reg) 2 -#define I810_BASE(reg) ((unsigned long) \ - dev->maplist[I810_REG(reg)]->handle) -#define I810_ADDR(reg) (I810_BASE(reg) + reg) -#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) -#define I810_READ(reg) I810_DEREF(reg) -#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) -#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) -#define I810_READ16(reg) I810_DEREF16(reg) -#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) - #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; #define BEGIN_LP_RING(n) do { \ @@ -873,7 +862,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, /* Interrupts are only for flushing */ -static void i810_dma_service(int irq, void *device, struct pt_regs *regs) +void i810_dma_service(int irq, void *device, struct pt_regs *regs) { drm_device_t *dev = (drm_device_t *)device; u16 temp; @@ -890,7 +879,7 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs) mark_bh(IMMEDIATE_BH); } -static void i810_dma_task_queue(void *device) +void i810_dma_immediate_bh(void *device) { drm_device_t *dev = (drm_device_t *) device; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; @@ -899,129 +888,6 @@ static void i810_dma_task_queue(void *device) wake_up_interruptible(&dev_priv->flush_queue); } -int i810_irq_install(drm_device_t *dev, int irq) -{ - int retcode; - u16 temp; - - if (!irq) return -EINVAL; - - down(&dev->struct_sem); - if (dev->irq) { - up(&dev->struct_sem); - return -EBUSY; - } - dev->irq = irq; - up(&dev->struct_sem); - - DRM_DEBUG( "Interrupt Install : %d\n", irq); - DRM_DEBUG("%d\n", irq); - - dev->context_flag = 0; - dev->interrupt_flag = 0; - dev->dma_flag = 0; - - dev->dma->next_buffer = NULL; - dev->dma->next_queue = NULL; - dev->dma->this_buffer = NULL; - - INIT_LIST_HEAD(&dev->tq.list); - dev->tq.sync = 0; - dev->tq.routine = i810_dma_task_queue; - dev->tq.data = dev; - - /* Before installing handler */ - temp = I810_READ16(I810REG_HWSTAM); - temp = temp & 0x6000; - I810_WRITE16(I810REG_HWSTAM, temp); - - temp = I810_READ16(I810REG_INT_MASK_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */ - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */ - - /* Install handler */ - if ((retcode = request_irq(dev->irq, - i810_dma_service, - SA_SHIRQ, - dev->devname, - dev))) { - down(&dev->struct_sem); - dev->irq = 0; - up(&dev->struct_sem); - return retcode; - } - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - temp = temp | 0x0003; - I810_WRITE16(I810REG_INT_ENABLE_R, - temp); /* Enable bp & user interrupts */ - return 0; -} - -int i810_irq_uninstall(drm_device_t *dev) -{ - int irq; - u16 temp; - - -/* return 0; */ - - down(&dev->struct_sem); - irq = dev->irq; - dev->irq = 0; - up(&dev->struct_sem); - - if (!irq) return -EINVAL; - - DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); - DRM_DEBUG("%d\n", irq); - - temp = I810_READ16(I810REG_INT_IDENTITY_R); - temp = temp & ~(0x6000); - if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, - temp); /* Clear all interrupts */ - - temp = I810_READ16(I810REG_INT_ENABLE_R); - temp = temp & 0x6000; - I810_WRITE16(I810REG_INT_ENABLE_R, - temp); /* Disable all interrupts */ - - free_irq(irq, dev); - - return 0; -} - -int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_control_t ctl; - int retcode; - - DRM_DEBUG( "i810_control\n"); - - if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl))) - return -EFAULT; - - switch (ctl.func) { - case DRM_INST_HANDLER: - if ((retcode = i810_irq_install(dev, ctl.irq))) - return retcode; - break; - case DRM_UNINST_HANDLER: - if ((retcode = i810_irq_uninstall(dev))) - return retcode; - break; - default: - return -EINVAL; - } - return 0; -} - static inline void i810_dma_emit_flush(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 635bdc6d..12a59dbf 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -56,47 +56,26 @@ [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 }, + #define __HAVE_COUNTERS 4 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #define __HAVE_COUNTER9 _DRM_STAT_DMA -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - i810_dma_quiescent( dev ); \ -} while (0) - -#define __HAVE_RELEASE 1 -#define DRIVER_RELEASE() do { \ - i810_reclaim_buffers( dev, priv->pid ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ -({ \ - drm_i810_private_t *dev_priv = (dev)->dev_private; \ - drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx]; \ - map; \ -}) - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" #include "drm_lock.h" -#include "drm_lists.h" /* kw: added for i810_waitlist_destroy */ +#include "drm_lists.h" #include "drm_memory.h" #include "drm_proc.h" #include "drm_vm.h" diff --git a/linux/i810_drv.h b/linux/i810_drv.h index e7824093..43d44e02 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -80,12 +80,6 @@ typedef struct drm_i810_private { extern int i810_dma_schedule(drm_device_t *dev, int locked); extern int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int i810_irq_install(drm_device_t *dev, int irq); -extern int i810_irq_uninstall(drm_device_t *dev); -extern int i810_control(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int i810_lock(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern int i810_dma_init(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int i810_flush_ioctl(struct inode *inode, struct file *filp, @@ -113,6 +107,19 @@ int i810_swap_bufs(struct inode *inode, struct file *filp, int i810_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); + +#define I810_REG(reg) 2 +#define I810_BASE(reg) ((unsigned long) \ + dev->maplist[I810_REG(reg)]->handle) +#define I810_ADDR(reg) (I810_BASE(reg) + reg) +#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg) +#define I810_READ(reg) I810_DEREF(reg) +#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0) +#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg) +#define I810_READ16(reg) I810_DEREF16(reg) +#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) + + #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define CMD_REPORT_HEAD (7<<23) diff --git a/linux/mga.h b/linux/mga.h index 9b222404..277aa202 100644 --- a/linux/mga.h +++ b/linux/mga.h @@ -34,13 +34,34 @@ */ #define DRM(x) mga_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_mga_private_t *dev_priv = dev->dev_private; \ + return mga_do_wait_for_idle( dev_priv ); \ +} while (0) + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_mga_private_t *)((dev)->dev_private))->buffers + #endif diff --git a/linux/mga_dma.c b/linux/mga_dma.c index c54a588e..b1491823 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -396,7 +396,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev ) return NULL; } -static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) +int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; diff --git a/linux/mga_drv.c b/linux/mga_drv.c index 7898c744..88fa53a6 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -38,7 +38,7 @@ #define DRIVER_NAME "mga" #define DRIVER_DESC "Matrox G200/G400" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 3 #define DRIVER_MINOR 0 @@ -56,38 +56,20 @@ [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 }, + #define __HAVE_COUNTERS 3 #define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER7 _DRM_STAT_PRIMARY #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() \ -do { \ - drm_mga_private_t *dev_priv = dev->dev_private; \ - return mga_do_wait_for_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_mga_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/mga_drv.h b/linux/mga_drv.h index 7a5a1dcc..be7298df 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -102,18 +102,6 @@ typedef struct drm_mga_private { drm_map_t *agp_textures; } drm_mga_private_t; - /* mga_drv.c */ -extern int mga_version( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_open( struct inode *inode, struct file *filp ); -extern int mga_release( struct inode *inode, struct file *filp ); -extern int mga_ioctl( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_lock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int mga_unlock( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); - /* mga_dma.c */ extern int mga_dma_init( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -121,8 +109,6 @@ extern int mga_dma_flush( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int mga_dma_reset( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -extern int mga_control( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); extern int mga_dma_buffers( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -136,7 +122,8 @@ extern void mga_do_dma_flush( drm_mga_private_t *dev_priv ); extern void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ); extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ); -extern int mga_irq_uninstall( drm_device_t *dev ); +extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ); + /* mga_state.c */ extern int mga_dma_clear( struct inode *inode, struct file *filp, diff --git a/linux/r128.h b/linux/r128.h index 0440501e..2f045534 100644 --- a/linux/r128.h +++ b/linux/r128.h @@ -34,13 +34,43 @@ */ #define DRM(x) r128_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRERELEASE() do { \ + if ( dev->dev_private ) { \ + drm_r128_private_t *dev_priv = dev->dev_private; \ + if ( dev_priv->page_flipping ) { \ + r128_do_cleanup_pageflip( dev ); \ + } \ + } \ +} while (0) + +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_r128_private_t *dev_priv = dev->dev_private; \ + return r128_do_cce_idle( dev_priv ); \ +} while (0) + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_r128_private_t *)((dev)->dev_private))->buffers + #endif diff --git a/linux/r128_cce.c b/linux/r128_cce.c index 05ae9590..d1790497 100644 --- a/linux/r128_cce.c +++ b/linux/r128_cce.c @@ -25,7 +25,7 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Gareth Hughes <gareth@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #define __NO_VERSION__ diff --git a/linux/r128_drm.h b/linux/r128_drm.h index aaf2ce3e..86aba175 100644 --- a/linux/r128_drm.h +++ b/linux/r128_drm.h @@ -25,9 +25,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> */ #ifndef __R128_DRM_H__ diff --git a/linux/r128_drv.c b/linux/r128_drv.c index 3bd27ae7..e42868ed 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -38,7 +38,7 @@ #define DRIVER_NAME "r128" #define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 1 @@ -62,6 +62,7 @@ [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, + #if 0 /* GH: Count data sent to card via ring or vertex/indirect buffers. */ @@ -71,41 +72,14 @@ #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #endif -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - return r128_do_cce_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_r128_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - r128_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_r128_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/r128_drv.h b/linux/r128_drv.h index 950a4711..ba11f5b4 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -25,10 +25,9 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Rickard E. (Rik) Faith <faith@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #ifndef __R128_DRV_H__ @@ -440,8 +439,7 @@ do { \ } \ } while (0) -#define R128_WAIT_UNTIL_PAGE_FLIPPED() \ -do { \ +#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \ OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \ OUT_RING( R128_EVENT_CRTC_OFFSET ); \ } while (0) diff --git a/linux/r128_state.c b/linux/r128_state.c index a4683c4e..fa16f3ce 100644 --- a/linux/r128_state.c +++ b/linux/r128_state.c @@ -25,7 +25,6 @@ * * Authors: * Gareth Hughes <gareth@valinux.com> - * */ #define __NO_VERSION__ diff --git a/linux/radeon.h b/linux/radeon.h index 6ef99277..6062f82f 100644 --- a/linux/radeon.h +++ b/linux/radeon.h @@ -34,13 +34,43 @@ */ #define DRM(x) radeon_##x +/* General customization: + */ #define __HAVE_AGP 1 #define __MUST_HAVE_AGP 1 - #define __HAVE_MTRR 1 - #define __HAVE_CTX_BITMAP 1 +/* Driver customization: + */ +#define DRIVER_PRERELEASE() do { \ + if ( dev->dev_private ) { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + if ( dev_priv->page_flipping ) { \ + radeon_do_cleanup_pageflip( dev ); \ + } \ + } \ +} while (0) + +#define DRIVER_PRETAKEDOWN() do { \ + if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ +} while (0) + +/* DMA customization: + */ #define __HAVE_DMA 1 +#define __HAVE_DMA_QUIESCENT 1 +#define DRIVER_DMA_QUIESCENT() do { \ + drm_radeon_private_t *dev_priv = dev->dev_private; \ + return radeon_do_cp_idle( dev_priv ); \ +} while (0) + +/* Buffer customization: + */ +#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t + +#define DRIVER_AGP_BUFFERS_MAP( dev ) \ + ((drm_radeon_private_t *)((dev)->dev_private))->buffers + #endif diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c index 75b24eee..2f20806c 100644 --- a/linux/radeon_cp.c +++ b/linux/radeon_cp.c @@ -24,9 +24,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #define __NO_VERSION__ diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h index 643253d2..a7d7a71b 100644 --- a/linux/radeon_drm.h +++ b/linux/radeon_drm.h @@ -26,7 +26,6 @@ * Authors: * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> - * */ #ifndef __RADEON_DRM_H__ diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index 43f6e2e7..cf59f866 100644 --- a/linux/radeon_drv.c +++ b/linux/radeon_drv.c @@ -36,7 +36,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 @@ -59,6 +59,7 @@ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, + #if 0 /* GH: Count data sent to card via ring or vertex/indirect buffers. */ @@ -68,41 +69,14 @@ #define __HAVE_COUNTER8 _DRM_STAT_SECONDARY #endif -#define __HAVE_DMA_QUIESCENT 1 -#define DRIVER_DMA_QUIESCENT() do { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - return radeon_do_cp_idle( dev_priv ); \ -} while (0) - -#define DRIVER_PRERELEASE() do { \ - if ( dev->dev_private ) { \ - drm_radeon_private_t *dev_priv = dev->dev_private; \ - if ( dev_priv->page_flipping ) { \ - radeon_do_cleanup_pageflip( dev ); \ - } \ - } \ -} while (0) - -#define DRIVER_PRETAKEDOWN() do { \ - if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \ -} while (0) - -#include "drm_drv.h" - - -#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t - -#define DRIVER_AGP_BUFFERS_MAP( dev ) \ - ((drm_radeon_private_t *)((dev)->dev_private))->buffers - -#include "drm_bufs.h" - #include "drm_agpsupport.h" #include "drm_auth.h" +#include "drm_bufs.h" #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index 656d6e03..e67a610f 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -24,10 +24,8 @@ * DEALINGS IN THE SOFTWARE. * * Authors: - * Rickard E. (Rik) Faith <faith@valinux.com> - * Kevin E. Martin <martin@valinux.com> - * Gareth Hughes <gareth@valinux.com> - * + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> */ #ifndef __RADEON_DRV_H__ @@ -504,25 +502,23 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp, #define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle)) -#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg) +#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR(reg) -#define RADEON_READ(reg) RADEON_DEREF(reg) -#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0) +#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) +#define RADEON_READ(reg) RADEON_DEREF( reg ) +#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0) -#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR(reg) -#define RADEON_READ8(reg) RADEON_DEREF8(reg) -#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0) +#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) +#define RADEON_READ8(reg) RADEON_DEREF8( reg ) +#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0) -#define RADEON_WRITE_PLL(addr,val) \ -do { \ - RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ - ((addr) & 0x1f) | RADEON_PLL_WR_EN); \ - RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ +#define RADEON_WRITE_PLL( addr, val ) do { \ + RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \ + ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \ + RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ } while (0) -extern int RADEON_READ_PLL(drm_device_t *dev, int addr); - +extern int RADEON_READ_PLL( drm_device_t *dev, int addr ); #define CP_PACKET0( reg, n ) \ @@ -541,54 +537,46 @@ extern int RADEON_READ_PLL(drm_device_t *dev, int addr); * Engine control helper macros */ -#define RADEON_WAIT_UNTIL_2D_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_2D_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_3D_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_3D_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_IDLE() \ -do { \ +#define RADEON_WAIT_UNTIL_IDLE() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ RADEON_WAIT_3D_IDLECLEAN | \ RADEON_WAIT_HOST_IDLECLEAN) ); \ } while (0) -#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \ -do { \ +#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \ OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ } while (0) -#define RADEON_FLUSH_CACHE() \ -do { \ +#define RADEON_FLUSH_CACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB2D_DC_FLUSH ); \ } while (0) -#define RADEON_PURGE_CACHE() \ -do { \ +#define RADEON_PURGE_CACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ } while (0) -#define RADEON_FLUSH_ZCACHE() \ -do { \ +#define RADEON_FLUSH_ZCACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ } while (0) -#define RADEON_PURGE_ZCACHE() \ -do { \ +#define RADEON_PURGE_ZCACHE() do { \ OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ } while (0) @@ -627,20 +615,17 @@ do { \ } \ } while (0) -#define RADEON_DISPATCH_AGE( age ) \ -do { \ +#define RADEON_DISPATCH_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) -#define RADEON_FRAME_AGE( age ) \ -do { \ +#define RADEON_FRAME_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) -#define RADEON_CLEAR_AGE( age ) \ -do { \ +#define RADEON_CLEAR_AGE( age ) do { \ OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ OUT_RING( age ); \ } while (0) diff --git a/linux/tdfx.h b/linux/tdfx.h index 6af675ff..40aba8fb 100644 --- a/linux/tdfx.h +++ b/linux/tdfx.h @@ -34,6 +34,8 @@ */ #define DRM(x) tdfx_##x +/* General customization: + */ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c index e8d7955c..71d065f1 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -38,14 +38,12 @@ #define DRIVER_NAME "tdfx" #define DRIVER_DESC "3dfx Banshee/Voodoo3+" -#define DRIVER_DATE "20010215" +#define DRIVER_DATE "20010216" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -#include "drm_drv.h" - #include "drm_agpsupport.h" #include "drm_auth.h" @@ -53,6 +51,7 @@ #include "drm_context.h" #include "drm_dma.h" #include "drm_drawable.h" +#include "drm_drv.h" #include "drm_fops.h" #include "drm_init.h" #include "drm_ioctl.h" |