diff options
author | Kevin E Martin <kem@kem.org> | 2001-03-07 21:47:43 +0000 |
---|---|---|
committer | Kevin E Martin <kem@kem.org> | 2001-03-07 21:47:43 +0000 |
commit | 5d66ea4fb42214c09449bb4a45c359440757ae5c (patch) | |
tree | e7baf1af0f35b1e1277d2cb535390a31c7d4de20 /linux | |
parent | 7e820fc7d89d06a11f448d7093469a0c765a84a6 (diff) |
- Merge from trunk into branchsarea-1-0-0-20010307
Diffstat (limited to 'linux')
43 files changed, 1235 insertions, 1413 deletions
diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 26eed9a5..d022557d 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -47,38 +47,34 @@ # **** End of SMP/MODVERSIONS detection -#MODS= gamma.o tdfx.o -MODS= 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 @@ -134,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 @@ -144,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 @@ -177,7 +174,7 @@ all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${A all::;@echo === kill_fasync has $(PARAMS) parameters all::;@echo === Compiling for machine $(MACHINE) all::;@echo === WARNING -all::;@echo === WARNING 2.4.0 kernels before test11 DONT WORK +all::;@echo === WARNING 2.4.0 kernels before 2.4.0-test11 DO NOT WORK all::;@echo === WARNING ifeq ($(MODULES),0) @@ -205,17 +202,13 @@ endif # **** End of configuration -libdrm.a: $(DRMOBJS) - -$(RM) -f $@ - $(AR) rcs $@ $(DRMOBJS) - dristat: dristat.c $(CC) $(PRGCFLAGS) $< -o $@ -#gamma_drv.o: gamma_drv.c -# $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -#gamma.o: $(GAMMAOBJS) -# $(LD) -r $^ -o $@ +gamma_drv.o: gamma_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ +gamma.o: $(GAMMAOBJS) + $(LD) -r $^ -o $@ tdfx_drv.o: tdfx_drv.c $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ @@ -260,8 +253,7 @@ ChangeLog: %.o: %.c $(CC) $(MODCFLAGS) -I$(TREE) -c $< -o $@ -$(DRMOBJS): $(DRMHEADERS) -#$(GAMMAOBJS): $(GAMMAHEADERS) +$(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) ifeq ($(AGP),1) $(MGAOBJS): $(MGAHEADERS) diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h index f6dae008..0ad96b12 100644 --- a/linux/compat-pre24.h +++ b/linux/compat-pre24.h @@ -45,6 +45,7 @@ /* This is a hack that only works for this code base -- because we always call this with dev->tq.* */ +#undef INIT_LIST_HEAD #define INIT_LIST_HEAD(pointer) dev->tq.next = NULL #endif diff --git a/linux/drm.h b/linux/drm.h index 7c65f5fc..ddabc277 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -44,11 +44,8 @@ #define DRM_IOCTL_NR(n) ((n) & 0xff) #endif -#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) -#define DRM_DEV_UID 0 -#define DRM_DEV_GID 0 - #define DRM_MAJOR 226 +#define DRM_MAX_MINOR 15 #define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */ #define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */ @@ -453,7 +450,7 @@ typedef struct drm_agp_info { #define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) #define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) #define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) -#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t) +#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t) #define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) #define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) diff --git a/linux/drmP.h b/linux/drmP.h index 804df409..a7e4d573 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -84,15 +84,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))) @@ -104,7 +113,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 */ @@ -643,7 +651,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 @@ -667,9 +675,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 ); @@ -686,7 +696,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); @@ -698,7 +708,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, @@ -728,17 +738,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); @@ -761,7 +761,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, @@ -775,7 +775,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, @@ -794,14 +794,24 @@ 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 + +extern int DRM(setsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int DRM(getsareactx)( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + + /* 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); @@ -811,7 +821,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, @@ -832,20 +842,13 @@ 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 ); -extern int DRM(setsareactx)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); -extern int DRM(getsareactx)( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); - - /* 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 ); extern int DRM(rmmap)( 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, @@ -857,27 +860,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); @@ -891,9 +904,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, @@ -917,6 +931,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, @@ -924,6 +939,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_agpsupport.h b/linux/drm_agpsupport.h index b070a59e..dfd0d8fc 100644 --- a/linux/drm_agpsupport.h +++ b/linux/drm_agpsupport.h @@ -77,7 +77,7 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; int retcode; - if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL; + if (!dev->agp|| dev->agp->acquired || !drm_agp->acquire) return -EINVAL; if ((retcode = drm_agp->acquire())) return retcode; dev->agp->acquired = 1; return 0; diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h index 02694f46..1d540322 100644 --- a/linux/drm_bufs.h +++ b/linux/drm_bufs.h @@ -135,6 +135,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp, #if __REALLY_HAVE_AGP case _DRM_AGP: map->offset = map->offset + dev->agp->base; + map->mtrr = dev->agp->agp_mtrr; /* for getmap */ break; #endif default: @@ -332,7 +333,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; @@ -346,7 +347,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; @@ -377,17 +378,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; @@ -523,11 +519,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 ); @@ -549,17 +545,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 8f891fd2..4ac896ef 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 */ @@ -210,7 +215,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 @@ -243,7 +248,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)] ); @@ -380,3 +385,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 05923b50..7447ca6d 100644 --- a/linux/drm_drv.h +++ b/linux/drm_drv.h @@ -492,7 +492,8 @@ static int __init drm_init( void ) } #endif #if __REALLY_HAVE_MTRR - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, + if (dev->agp) + dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, dev->agp->agp_info.aper_size*1024*1024, MTRR_TYPE_WRCOMB, 1 ); @@ -646,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) 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", + DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", current->pid, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); #if __HAVE_RELEASE @@ -697,7 +698,7 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM_KERNEL_CONTEXT ); } } -#else +#elif __HAVE_DMA DRM(reclaim_buffers)( dev, priv->pid ); #endif @@ -804,7 +805,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(); @@ -892,7 +893,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_memory.h b/linux/drm_memory.h index caf05394..1763d9b4 100644 --- a/linux/drm_memory.h +++ b/linux/drm_memory.h @@ -351,8 +351,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size) } } -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) -#if __MUST_HAVE_AGP +#if __REALLY_HAVE_AGP agp_memory *DRM(alloc_agp)(int pages, u32 type) { @@ -457,4 +456,3 @@ int DRM(unbind_agp)(agp_memory *handle) return retcode; } #endif -#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */ diff --git a/linux/drm_proc.h b/linux/drm_proc.h index 60628660..f65f42b7 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 }; @@ -488,7 +488,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..bc958796 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,13 @@ * */ +#define __NO_VERSION__ +#include "drmP.h" + +#if LINUX_VERSION_CODE < 0x020400 +#include "stubsupport-pre24.h" +#endif + #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ static struct drm_stub_list { @@ -58,7 +65,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 +80,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); @@ -117,10 +124,13 @@ static int DRM(stub_putminor)(int minor) int DRM(stub_register)(const char *name, struct file_operations *fops, drm_device_t *dev) { - if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) { - /* Already registered */ - struct drm_stub_info *i; + struct drm_stub_info *i = NULL; + + if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) i = (struct drm_stub_info *)inter_module_get("drm"); + + if (i) { + /* Already registered */ DRM(stub_info).info_register = i->info_register; DRM(stub_info).info_unregister = i->info_unregister; } else { diff --git a/linux/gamma.h b/linux/gamma.h index 5ca1f745..232ed018 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,60 @@ */ #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 { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ +} while (0) + +#define DRIVER_POSTINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ +} while (0) + +#define DRIVER_UNINSTALL() do { \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + 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..d3a9414d 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,76 +37,13 @@ #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) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4) ; @@ -115,6 +52,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, void gamma_dma_quiescent_single(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -122,7 +62,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)) ; @@ -131,6 +71,9 @@ void gamma_dma_quiescent_single(drm_device_t *dev) void gamma_dma_quiescent_dual(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3) @@ -140,13 +83,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)) @@ -156,20 +99,28 @@ void gamma_dma_quiescent_dual(drm_device_t *dev) void gamma_dma_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + while (GAMMA_READ(GAMMA_DMACOUNT)) ; } static inline int gamma_dma_is_ready(drm_device_t *dev) { + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + 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; - + drm_device_t *dev = (drm_device_t *)device; + drm_device_dma_t *dma = dev->dma; + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; + atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); @@ -202,7 +153,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 +185,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 +209,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 +257,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 +306,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 +334,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 +423,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 +458,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 +471,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 +493,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 +569,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 +586,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_drm.h b/linux/gamma_drm.h deleted file mode 100644 index b4acd70a..00000000 --- a/linux/gamma_drm.h +++ /dev/null @@ -1,41 +0,0 @@ -/* gamma_drm.h -- Public header for the Gamma driver -*- linux-c -*- - * Created: Tue Jan 25 01:50:01 1999 by jhartmann@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 - * VA LINUX SYSTEMS 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: - * Jeff Hartmann <jhartmann@valinux.com> - */ - -#ifndef __GAMMA_DRM_H__ -#define __GAMMA_DRM_H__ - -typedef struct drm_gamma_init { - unsigned long hControlRegs0; - unsigned long hControlRegs1; - unsigned long hControlRegs2; - unsigned long hControlRegs3; -} drm_gamma_init_t; - -#endif 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..68b52070 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_ @@ -35,6 +35,10 @@ typedef struct drm_gamma_private { drm_map_t *buffers; + drm_map_t *mmio0; + drm_map_t *mmio1; + drm_map_t *mmio2; + drm_map_t *mmio3; } drm_gamma_private_t; #define LOCK_TEST_WITH_RETURN( dev ) \ @@ -47,30 +51,55 @@ 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); + +#define GAMMA_OFF(reg) \ + ((reg < 0x1000) \ + ? reg \ + : ((reg < 0x10000) \ + ? (reg - 0x1000) \ + : ((reg < 0x11000) \ + ? (reg - 0x10000) \ + : (reg - 0x11000)))) + +#define GAMMA_BASE(reg) ((unsigned long) \ + ((reg < 0x1000) ? dev_priv->mmio0->handle : \ + ((reg < 0x10000) ? dev_priv->mmio1->handle : \ + ((reg < 0x11000) ? dev_priv->mmio2->handle : \ + dev_priv->mmio3->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..ed25b2a9 100644 --- a/linux/i810.h +++ b/linux/i810.h @@ -34,17 +34,79 @@ */ #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 { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + 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 { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + 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 { \ + drm_i810_private_t *dev_priv = \ + (drm_i810_private_t *)dev->dev_private; \ + 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)->dev_private))->buffer_map + #endif diff --git a/linux/i810_dma.c b/linux/i810_dma.c index 8c50b320..4c90496a 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -48,16 +48,6 @@ #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 -#define I810_BASE(reg) ((unsigned long) \ - dev_priv->mmio_map->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 { \ @@ -875,7 +865,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; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; @@ -893,7 +883,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; @@ -902,131 +892,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) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - 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) -{ - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - 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 86ab394d..12a59dbf 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -56,42 +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)->dev_private))->buffer_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" #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 1f6e1468..e1b17148 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -81,12 +81,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, @@ -114,6 +108,18 @@ 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_BASE(reg) ((unsigned long) \ + dev_priv->mmio_map->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 275495dc..21e14f37 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -57,7 +57,6 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) { - /* printk("I'm not busy, flushing pixel cache\n"); */ MGA_WRITE8( MGA_CRTC_INDEX, 0 ); return 0; } @@ -273,7 +272,8 @@ static void mga_freelist_print( drm_device_t *dev ) DRM_INFO( "\n" ); DRM_INFO( "current dispatch: last=0x%x done=0x%x\n", dev_priv->sarea_priv->last_dispatch, - *dev_priv->prim.head - dev_priv->primary->offset ); + (unsigned int)(*dev_priv->prim.head - + dev_priv->primary->offset) ); DRM_INFO( "current freelist:\n" ); for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) { @@ -354,7 +354,6 @@ static void mga_freelist_cleanup( drm_device_t *dev ) static void mga_freelist_reset( drm_device_t *dev ) { drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; int i; @@ -400,7 +399,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; @@ -412,15 +411,17 @@ static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); - if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { - SET_AGE( &next->age, MGA_BUFFER_FREE, 0 ); - } - /* Put buffer on the head + 1, as the head is a sentinal. */ + next = buf_priv->list_entry; head = dev_priv->head; prev = head->next; + + if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) { + SET_AGE( &next->age, MGA_BUFFER_FREE, 0 ); + } + head->next = next; prev->prev = next; next->prev = head; 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 ab6d9edb..f56186e1 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..83e002af 100644 --- a/linux/r128.h +++ b/linux/r128.h @@ -34,13 +34,46 @@ */ #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 +#if 0 +/* GH: Remove this for now... */ +#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) +#endif + +/* 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 5ffc1d0e..f4b4f0c4 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..9f53746f 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) @@ -456,7 +454,8 @@ do { \ #define R128_VERBOSE 0 -#define RING_LOCALS int write; unsigned int tail_mask; volatile u32 *ring; +#define RING_LOCALS \ + int write; unsigned int tail_mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ @@ -472,11 +471,23 @@ do { \ tail_mask = dev_priv->ring.tail_mask; \ } while (0) +/* You can set this to zero if you want. If the card locks up, you'll + * need to keep this set. It works around a bug in early revs of the + * Rage 128 chipset, where the CCE would read 32 dwords past the end of + * the ring buffer before wrapping around. + */ +#define R128_BROKEN_CCE 1 + #define ADVANCE_RING() do { \ if ( R128_VERBOSE ) { \ DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \ write, dev_priv->ring.tail ); \ } \ + if ( R128_BROKEN_CCE && write < 32 ) { \ + memcpy( dev_priv->ring.end, \ + dev_priv->ring.start, \ + write * sizeof(u32) ); \ + } \ r128_flush_write_combine(); \ dev_priv->ring.tail = write; \ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \ 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..db238b1b 100644 --- a/linux/radeon.h +++ b/linux/radeon.h @@ -34,13 +34,46 @@ */ #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 +#if 0 +/* GH: Remove this for now... */ +#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) +#endif + +/* 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 28e64284..c80665ca 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__ @@ -844,11 +843,8 @@ int radeon_cp_start( struct inode *inode, struct file *filp, drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( dev_priv->cp_running ) { DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); return 0; @@ -877,11 +873,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp, int ret; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) ) return -EFAULT; @@ -923,11 +915,8 @@ int radeon_cp_reset( struct inode *inode, struct file *filp, drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv ) { DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); return -EINVAL; @@ -949,11 +938,7 @@ int radeon_cp_idle( struct inode *inode, struct file *filp, drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); return radeon_do_cp_idle( dev_priv ); } @@ -965,11 +950,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); return radeon_do_engine_reset( dev ); } @@ -1019,11 +1000,7 @@ int radeon_fullscreen( struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; drm_radeon_fullscreen_t fs; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg, sizeof(fs) ) ) @@ -1247,14 +1224,10 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp, int ret = 0; drm_dma_t d; - if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) ) - return -EFAULT; + LOCK_TEST_WITH_RETURN( dev ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) ) + return -EFAULT; /* Please don't send us buffers. */ @@ -1278,7 +1251,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp, ret = radeon_cp_get_buffers( dev, &d ); } - if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) ) + if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) ) return -EFAULT; return ret; diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h index 643253d2..50a7d6ed 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__ @@ -74,7 +73,7 @@ /* Vertex/indirect buffer size */ -#define RADEON_BUFFER_SIZE 16384 +#define RADEON_BUFFER_SIZE 65536 /* Byte offsets for indirect buffer data */ @@ -305,14 +304,20 @@ typedef struct drm_radeon_indices { int discard; /* Client finished with buffer? */ } drm_radeon_indices_t; -typedef struct drm_radeon_blit { - int idx; - int pitch; +typedef struct drm_radeon_tex_image { + unsigned int x, y; /* Blit coordinates */ + unsigned int width, height; + const void *data; +} drm_radeon_tex_image_t; + +typedef struct drm_radeon_texture { int offset; + int pitch; int format; - unsigned short x, y; - unsigned short width, height; -} drm_radeon_blit_t; + int width; /* Texture image coordinates */ + int height; + drm_radeon_tex_image_t *image; +} drm_radeon_texture_t; typedef struct drm_radeon_stipple { unsigned int *mask; diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index 43f6e2e7..1aa889ae 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 "20010305" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 @@ -55,10 +55,11 @@ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \ - [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \ [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..d279b046 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__ @@ -163,8 +161,8 @@ extern int radeon_cp_vertex( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int radeon_cp_indices( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -extern int radeon_cp_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ); +extern int radeon_cp_texture( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); extern int radeon_cp_stipple( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int radeon_cp_indirect( struct inode *inode, struct file *filp, @@ -480,14 +478,14 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp, #define RADEON_COLOR_FORMAT_RGB8 9 #define RADEON_COLOR_FORMAT_ARGB4444 15 -#define RADEON_TXF_8BPP_I 0 -#define RADEON_TXF_16BPP_AI88 1 -#define RADEON_TXF_8BPP_RGB332 2 -#define RADEON_TXF_16BPP_ARGB1555 3 -#define RADEON_TXF_16BPP_RGB565 4 -#define RADEON_TXF_16BPP_ARGB4444 5 -#define RADEON_TXF_32BPP_ARGB8888 6 -#define RADEON_TXF_32BPP_RGBA8888 7 +#define RADEON_TXFORMAT_I8 0 +#define RADEON_TXFORMAT_AI88 1 +#define RADEON_TXFORMAT_RGB332 2 +#define RADEON_TXFORMAT_ARGB1555 3 +#define RADEON_TXFORMAT_RGB565 4 +#define RADEON_TXFORMAT_ARGB4444 5 +#define RADEON_TXFORMAT_ARGB8888 6 +#define RADEON_TXFORMAT_RGBA8888 7 /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -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) @@ -598,6 +586,16 @@ do { \ * Misc helper macros */ +#define LOCK_TEST_WITH_RETURN( dev ) \ +do { \ + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ + dev->lock.pid != current->pid ) { \ + DRM_ERROR( "%s called without lock held\n", \ + __FUNCTION__ ); \ + return -EINVAL; \ + } \ +} while (0) + #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ do { \ drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \ @@ -627,20 +625,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/radeon_state.c b/linux/radeon_state.c index 9b84a739..ff1b3512 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -972,50 +972,67 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, sarea_priv->nbox = 0; } -static int radeon_cp_dispatch_blit( drm_device_t *dev, - drm_radeon_blit_t *blit ) +#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32)) + +static int radeon_cp_dispatch_texture( drm_device_t *dev, + drm_radeon_texture_t *tex, + drm_radeon_tex_image_t *image ) { drm_radeon_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; u32 format; - u32 *data; - int dword_shift, dwords; + u32 *buffer; + u8 *data; + int size, dwords, tex_width, blit_width; + u32 y, height; + int ret = 0, i; RING_LOCALS; - DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", - blit->offset >> 10, blit->pitch, blit->format, - blit->x, blit->y, blit->width, blit->height ); - radeon_update_ring_snapshot( dev_priv ); + /* FIXME: Be smarter about this... + */ + buf = radeon_freelist_get( dev ); + if ( !buf ) return -EAGAIN; + + DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + tex->offset >> 10, tex->pitch, tex->format, + image->x, image->y, image->width, image->height ); + + buf_priv = buf->dev_private; /* The compiler won't optimize away a division by a variable, * even if the only legal values are powers of two. Thus, we'll * use a shift instead. */ - switch ( blit->format ) { - case RADEON_TXF_32BPP_ARGB8888: - case RADEON_TXF_32BPP_RGBA8888: + switch ( tex->format ) { + case RADEON_TXFORMAT_ARGB8888: + case RADEON_TXFORMAT_RGBA8888: format = RADEON_COLOR_FORMAT_ARGB8888; - dword_shift = 0; + tex_width = tex->width * 4; + blit_width = image->width * 4; break; - case RADEON_TXF_16BPP_AI88: - case RADEON_TXF_16BPP_ARGB1555: - case RADEON_TXF_16BPP_RGB565: - case RADEON_TXF_16BPP_ARGB4444: + case RADEON_TXFORMAT_AI88: + case RADEON_TXFORMAT_ARGB1555: + case RADEON_TXFORMAT_RGB565: + case RADEON_TXFORMAT_ARGB4444: format = RADEON_COLOR_FORMAT_RGB565; - dword_shift = 1; + tex_width = tex->width * 2; + blit_width = image->width * 2; break; - case RADEON_TXF_8BPP_I: - case RADEON_TXF_8BPP_RGB332: + case RADEON_TXFORMAT_I8: + case RADEON_TXFORMAT_RGB332: format = RADEON_COLOR_FORMAT_CI8; - dword_shift = 2; + tex_width = tex->width * 1; + blit_width = image->width * 1; break; default: - DRM_ERROR( "invalid blit format %d\n", blit->format ); + DRM_ERROR( "invalid texture format %d\n", tex->format ); return -EINVAL; } + DRM_DEBUG( " tex=%dx%d blit=%d\n", + tex_width, tex->height, blit_width ); + /* Flush the pixel cache. This ensures no pixel data gets mixed * up with the texture data from the host data blit, otherwise * part of the texture image may be corrupted. @@ -1027,46 +1044,81 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev, ADVANCE_RING(); - /* Dispatch the indirect buffer. + /* Make a copy of the parameters in case we have to update them + * for a multi-pass texture blit. */ - buf = dma->buflist[blit->idx]; - buf_priv = buf->dev_private; + y = image->y; + height = image->height; + data = (u8 *)image->data; - if ( buf->pid != current->pid ) { - DRM_ERROR( "process %d using buffer owned by %d\n", - current->pid, buf->pid ); - return -EINVAL; - } - if ( buf->pending ) { - DRM_ERROR( "sending pending buffer %d\n", blit->idx ); - return -EINVAL; - } + size = height * blit_width; - buf_priv->discard = 1; + if ( size > RADEON_MAX_TEXTURE_SIZE ) { + /* Texture image is too large, do a multipass upload */ + ret = -EAGAIN; - dwords = (blit->width * blit->height) >> dword_shift; - if ( !dwords ) dwords = 1; + /* Adjust the blit size to fit the indirect buffer */ + height = RADEON_MAX_TEXTURE_SIZE / blit_width; + size = height * blit_width; - data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); + /* Update the input parameters for next time */ + image->y += height; + image->height -= height; + image->data = (char *)image->data + size; - data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); - data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_NONE | - (format << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_S | - RADEON_DP_SRC_SOURCE_HOST_DATA | - RADEON_GMC_CLR_CMP_CNTL_DIS | - RADEON_GMC_WR_MSK_DIS); + if ( copy_to_user( tex->image, image, sizeof(*image) ) ) + return -EFAULT; + } else if ( size < 4 ) { + size = 4; + } - data[2] = (blit->pitch << 22) | (blit->offset >> 10); - data[3] = 0xffffffff; - data[4] = 0xffffffff; - data[5] = (blit->y << 16) | blit->x; - data[6] = (blit->height << 16) | blit->width; - data[7] = dwords; + dwords = size / 4; + + /* Dispatch the indirect buffer. + */ + buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); + + buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); + buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (format << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_HOST_DATA | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS); + + buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); + buffer[3] = 0xffffffff; + buffer[4] = 0xffffffff; + buffer[5] = (y << 16) | image->x; + buffer[6] = (height << 16) | image->width; + buffer[7] = dwords; + + buffer += 8; + + if ( tex_width >= 32 ) { + /* Texture image width is larger than the minimum, so we + * can upload it directly. + */ + if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) + return -EFAULT; + } else { + /* Texture image width is less than the minimum, so we + * need to pad out each image scanline to the minimum + * width. + */ + for ( i = 0 ; i < tex->height ; i++ ) { + if ( copy_from_user( buffer, data, tex_width ) ) + return -EFAULT; + buffer += 8; + data += tex_width; + } + } + buf->pid = current->pid; buf->used = (dwords + 8) * sizeof(u32); + buf_priv->discard = 1; radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); @@ -1081,7 +1133,7 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev, ADVANCE_RING(); - return 0; + return ret; } static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) @@ -1122,11 +1174,7 @@ int radeon_cp_clear( struct inode *inode, struct file *filp, drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS]; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg, sizeof(clear) ) ) @@ -1156,11 +1204,7 @@ int radeon_cp_swap( struct inode *inode, struct file *filp, drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "%s\n", __FUNCTION__ ); - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1189,11 +1233,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, drm_radeon_buf_priv_t *buf_priv; drm_radeon_vertex_t vertex; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv || dev_priv->is_pci ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; @@ -1255,11 +1296,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, drm_radeon_indices_t elts; int count; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv || dev_priv->is_pci ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; @@ -1321,38 +1359,34 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, return 0; } -int radeon_cp_blit( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) +int radeon_cp_texture( 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_radeon_private_t *dev_priv = dev->dev_private; - drm_device_dma_t *dma = dev->dma; - drm_radeon_blit_t blit; + drm_radeon_texture_t tex; + drm_radeon_tex_image_t image; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); - if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg, - sizeof(blit) ) ) + if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) ) return -EFAULT; - DRM_DEBUG( "%s: pid=%d index=%d\n", - __FUNCTION__, current->pid, blit.idx ); - - if ( blit.idx < 0 || blit.idx > dma->buf_count ) { - DRM_ERROR( "sending %d buffers (of %d max)\n", - blit.idx, dma->buf_count ); + if ( tex.image == NULL ) { + DRM_ERROR( "null texture image!\n" ); return -EINVAL; } + if ( copy_from_user( &image, + (drm_radeon_tex_image_t *)tex.image, + sizeof(image) ) ) + return -EFAULT; + RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return radeon_cp_dispatch_blit( dev, &blit ); + return radeon_cp_dispatch_texture( dev, &tex, &image ); } int radeon_cp_stipple( struct inode *inode, struct file *filp, @@ -1364,18 +1398,13 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp, drm_radeon_stipple_t stipple; u32 mask[32]; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg, sizeof(stipple) ) ) return -EFAULT; - if ( copy_from_user( &mask, stipple.mask, - 32 * sizeof(u32) ) ) + if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) ) return -EFAULT; RING_SPACE_TEST_WITH_RETURN( dev_priv ); @@ -1397,11 +1426,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp, drm_radeon_indirect_t indirect; RING_LOCALS; - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); + if ( !dev_priv || dev_priv->is_pci ) { DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); return -EINVAL; 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..f478395f 100644 --- a/linux/tdfx_drv.c +++ b/linux/tdfx_drv.c @@ -38,21 +38,19 @@ #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" #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" |