diff options
author | Kevin E Martin <kem@kem.org> | 2000-04-12 06:22:02 +0000 |
---|---|---|
committer | Kevin E Martin <kem@kem.org> | 2000-04-12 06:22:02 +0000 |
commit | 49b16eebb78a289f6ec2430c966650a6470a6fed (patch) | |
tree | 7ae2c82849210b43a8072e7f0c1fbc13c0ade31c | |
parent | e0ec09d9087b8c9ad95f3600207ebc90f816bcf1 (diff) |
- Added kernel functions to initialize the driver, reset the drawing
engine, wait for CCE idle and submit a buffer of CCE packets
- Modified the CCE packet dispatch mechanism to use a single submission
function that can send the packets to the CCE in either PIO mode or
using the ring buffer
- Moved CCE packet dispatch to the kernel driver
- Simplified the CCE macros and made them work with the new CCE packet
dispatch mechanism
- Added an option to only allow legal/secure CCE packets
- Merged the os-support dir from the trunk into the ATI branch
- Fixed some of the engine hangs by reseting the engine when switching to
non-CCE mode (Gareth Hughes)
- Fixed a bug where I wasn't grabbing HW lock around calls to WaitForIdle
- Fixed vertex buffer bug where it would wrap around and start reusing
buffers that had yet to be processed (this is a temporary fix until
vertex buffer allocation can be added to kernel driver)
- Added HW accel lines and points
- Added configuration support for selecting CCE mode, CCE security, AGP
mode, AGP size, ring buffer size, and vertex buffers size in the
"Device" section of XF86Config file
- Changed to map each region of AGP space separately (for security)
- Changed MMIO region mapping to be read-only (in secure mode)
- Fixed problem where swap buffers could be called when no back buffer
exists
- Fixed resetting of the ring buffer in the client, X server and kernel
drivers (also now correctly reinitialize the ring buffer read/write
indices)
40 files changed, 2567 insertions, 3022 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index ae81192b..6529d2b6 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -817,7 +817,7 @@ int drmAgpVersionMajor(int fd) { drm_agp_info_t i; - if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0; + if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno; return i.agp_version_major; } diff --git a/linux-core/drmP.h b/linux-core/drmP.h index c00d3bb0..f8e78eab 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -53,7 +53,7 @@ #include <linux/agp_backend.h> #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -#include <linux/spinlock.h> +#include <linux/tqueue.h> #include <linux/poll.h> #endif #include "drm.h" @@ -93,7 +93,7 @@ #define DRM_MEM_BOUNDAGP 17 #define DRM_MEM_CTXBITMAP 18 -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 4 * 8) +#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) /* Backward compatibility section */ /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index e79f7ff5..6ac4d2ee 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -24,21 +24,18 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Jeff Hartmann <jhartmann@precisioninsight.com> + * Jeff Hartmann <jhartmann@precisioninsight.com> * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c,v 1.1 2000/02/11 17:26:04 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" -#include "i810_drm_public.h" #include "i810_drv.h" -#include "i810_dma.h" #include <linux/interrupt.h> /* For task queue support */ -#include <linux/time.h> /* For do_gettimeofday */ #define I810_BUF_FREE 1 #define I810_BUF_USED 0 @@ -56,27 +53,29 @@ #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) i810_wait_ring(dev, n*4, 0); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ } while (0) #define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ + if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ +#define OUT_RING(n) do { \ + if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0); static inline void i810_print_status_page(drm_device_t *dev) @@ -111,7 +110,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_USED); if(used == I810_BUF_FREE) { - return buf; + return buf; } } return NULL; @@ -160,28 +159,28 @@ static int i810_dma_get_buffers(drm_device_t *dev, drm_dma_t *d) static unsigned long i810_alloc_page(drm_device_t *dev) { - unsigned long address; + unsigned long address; - address = __get_free_page(GFP_KERNEL); - if(address == 0UL) { - return 0; - } - atomic_inc(&mem_map[MAP_NR((void *) address)].count); - set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&mem_map[MAP_NR((void *) address)].count); + set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); - return address; + return address; } static void i810_free_page(drm_device_t *dev, unsigned long page) { - if(page == 0UL) { - return; - } - atomic_dec(&mem_map[MAP_NR((void *) page)].count); - clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); - wake_up(&mem_map[MAP_NR((void *) page)].wait); - free_page(page); - return; + if(page == 0UL) + return; + + atomic_dec(&mem_map[MAP_NR((void *) page)].count); + clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); + wake_up(&mem_map[MAP_NR((void *) page)].wait); + free_page(page); + return; } static int i810_dma_cleanup(drm_device_t *dev) @@ -206,24 +205,14 @@ static int i810_dma_cleanup(drm_device_t *dev) return 0; } -static int __gettimeinmillis(void) -{ - int millis; - - millis = ((jiffies / HZ) * 1000) + ((jiffies % HZ) * (1000 / HZ)); - return millis; -} - -static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) +static int i810_wait_ring(drm_device_t *dev, int n) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); int iters = 0; - int startTime = 0; - int curTime = 0; - - if (timeout_millis == 0) timeout_millis = 3000; - + unsigned long end; + + end = jiffies + (HZ*3); while (ring->space < n) { int i; @@ -233,10 +222,7 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) if (ring->space < 0) ring->space += ring->Size; iters++; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; @@ -244,8 +230,8 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) for (i = 0 ; i < 2000 ; i++) ; } -out_wait_ring: - + +out_wait_ring: return iters; } @@ -380,27 +366,27 @@ int i810_dma_init(struct inode *inode, struct file *filp, return retcode; } -static inline void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) +static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf, + int used ) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int length = buf->used; RING_LOCALS; dev_priv->counter++; DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); DRM_DEBUG( "i810_dma_dispatch\n"); DRM_DEBUG( "start : 0x%lx\n", start); - DRM_DEBUG( "length : 0x%x\n", length); - DRM_DEBUG( "start + length - 4 : 0x%lx\n", start + length - 4); + DRM_DEBUG( "used : 0x%x\n", used); + DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4); i810_kernel_lost_context(dev); BEGIN_LP_RING(10); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + length - 4 ); + OUT_RING( start + used - 4 ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( 20 ); OUT_RING( dev_priv->counter ); @@ -411,35 +397,37 @@ static inline void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) ADVANCE_LP_RING(); } -static inline void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) +static void i810_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_buf_t *real_buf = dev->dma->buflist[ buf_priv->vertex_real_idx ]; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *box = sarea_priv->boxes; + drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; - unsigned long address = (unsigned long)real_buf->bus_address; - unsigned long start = address - dev->agp->base; - int length = buf->used; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; int i = 0; RING_LOCALS; - if(nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; - DRM_DEBUG("dispatch vertex addr 0x%lx, length 0x%x nbox %d\n", - address, length, buf_priv->nbox); + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); dev_priv->counter++; DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); DRM_DEBUG( "i810_dma_dispatch\n"); DRM_DEBUG( "start : %lx\n", start); - DRM_DEBUG( "length : %d\n", length); - DRM_DEBUG( "start + length - 4 : %ld\n", start + length - 4); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); i810_kernel_lost_context(dev); - if (!buf_priv->vertex_discard) { + if (used) { do { if (i < nbox) { BEGIN_LP_RING(4); @@ -447,27 +435,33 @@ static inline void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) SC_ENABLE ); OUT_RING( GFX_OP_SCISSOR_INFO ); OUT_RING( box[i].x1 | (box[i].y1 << 16) ); - OUT_RING( (box[i].x2-1) | ((box[i].y2-1) << 16) ); + OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } BEGIN_LP_RING(4); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + length - 4 ); + OUT_RING( start + used - 4 ); OUT_RING( 0 ); ADVANCE_LP_RING(); } while (++i < nbox); } - BEGIN_LP_RING(8); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( buf_priv->my_use_idx ); - OUT_RING( I810_BUF_FREE ); + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); + + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( 0 ); + } + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); ADVANCE_LP_RING(); @@ -649,10 +643,7 @@ static void i810_dma_quiescent(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; - + unsigned long end; if(dev_priv == NULL) { return; @@ -660,13 +651,12 @@ static void i810_dma_quiescent(drm_device_t *dev) atomic_set(&dev_priv->flush_done, 0); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { i810_dma_quiescent_emit(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; } @@ -686,11 +676,8 @@ static int i810_flush_queue(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int ret = 0; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; - + unsigned long end; + int ret = 0; if(dev_priv == NULL) { return 0; @@ -698,13 +685,11 @@ static int i810_flush_queue(drm_device_t *dev) atomic_set(&dev_priv->flush_done, 0); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); for (;;) { i810_dma_emit_flush(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; } @@ -729,17 +714,17 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) if (!dma) return; if(dev->dev_private == NULL) return; - + if(dma->buflist == NULL) return; i810_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->pid == pid) { - /* Only buffers that need to get reclaimed ever - * get set to free */ - if(buf_priv == NULL) return; + + /* Only buffers that need to get reclaimed ever + * get set to free + */ + if (buf->pid == pid && buf_priv) { cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE); } @@ -835,6 +820,11 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return -EINVAL; + } + i810_flush_queue(dev); return 0; } @@ -844,41 +834,22 @@ static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args) drm_device_dma_t *dma = dev->dma; drm_buf_t *buf = dma->buflist[ args->idx ]; - buf->used = args->used; - - DRM_DEBUG("i810DmaGeneral idx %d used %d\n", args->idx, buf->used); - - if (!buf->used) { - DRM_ERROR("0 length buffer\n"); + if (!args->used) { i810_freelist_put(dev, buf); - return 0; + } else { + i810_dma_dispatch_general( dev, buf, args->used ); + atomic_add(args->used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); } - - i810_dma_dispatch_general( dev, buf ); - atomic_add(buf->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - return 0; } static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) { drm_device_dma_t *dma = dev->dma; - drm_i810_buf_priv_t *buf_priv; - drm_buf_t *buf; - - - buf = dma->buflist[ args->idx ]; - buf->used = args->real_used; - - DRM_DEBUG("i810DmaVertex idx %d used %d\n", args->idx, buf->used); - - buf_priv = buf->dev_private; - buf_priv->vertex_real_idx = args->real_idx; - buf_priv->vertex_discard = args->discard; - - i810_dma_dispatch_vertex( dev, buf); - atomic_add(buf->used, &dma->total_bytes); + drm_buf_t *buf = dma->buflist[ args->idx ]; + i810_dma_dispatch_vertex( dev, buf, args->discard, args->used ); + atomic_add(args->used, &dma->total_bytes); atomic_inc(&dma->total_dmas); return 0; } @@ -902,7 +873,13 @@ int i810_dma_general(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma general idx %d used %d\n", general.idx, general.used); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_general called without lock held\n"); + return -EINVAL; + } + retcode = i810DmaGeneral(dev, &general); + sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -922,12 +899,16 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - - DRM_DEBUG("i810 dma vertex, idx %d used %d real_idx %d discard %d\n", - vertex.idx, vertex.real_used, vertex.real_idx, - vertex.discard); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); retcode = i810DmaVertex(dev, &vertex); + sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -965,6 +946,11 @@ int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return -EINVAL; + } /* Please don't send us buffers. */ diff --git a/linux-core/i810_drm.h b/linux-core/i810_drm.h new file mode 100644 index 00000000..0754874c --- /dev/null +++ b/linux-core/i810_drm.h @@ -0,0 +1,93 @@ +#ifndef _I810_DRM_H_ +#define _I810_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +/* Might one day want to support the client-side ringbuffer code again. + */ +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ + +#define I810_USE_BATCH 1 +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 256 +#define I810_NR_SAREA_CLIPRECTS 2 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ + +#define I810_NR_TEX_REGIONS 64 +#define I810_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drm_i810_init { + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 + } func; + int ring_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + unsigned long ring_start; + unsigned long ring_end; + unsigned long ring_size; +} drm_i810_init_t; + +/* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +typedef struct _drm_i810_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} drm_i810_tex_region_t; + +typedef struct _drm_i810_sarea { + unsigned int nbox; + drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + + drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ +} drm_i810_sarea_t; + +typedef struct _drm_i810_general { + int idx; + int used; +} drm_i810_general_t; + +/* These may be placeholders if we have more cliprects than + * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to + * false, indicating that the buffer will be dispatched again with a + * new set of cliprects. + */ +typedef struct _drm_i810_vertex { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int discard; /* client is finished with the buffer? */ +} drm_i810_vertex_t; + +#endif /* _I810_DRM_H_ */ diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index 179b8714..f1c83250 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -33,7 +33,6 @@ #define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" -#include "i810_dma.h" EXPORT_SYMBOL(i810_init); @@ -500,7 +499,7 @@ int i810_release(struct inode *inode, struct file *filp) DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); - if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) + if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.pid == current->pid) { i810_reclaim_buffers(dev, priv->pid); DRM_ERROR("Process %d dead, freeing lock for context %d\n", @@ -514,7 +513,7 @@ int i810_release(struct inode *inode, struct file *filp) hardware at this point, possibly processed via a callback to the X server. */ - } else { + } else if (dev->lock.hw_lock) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE(entry, current); add_wait_queue(&dev->lock.lock_queue, &entry); diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index d3dc6906..1badd36b 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -31,7 +31,6 @@ #ifndef _I810_DRV_H_ #define _I810_DRV_H_ -#include "i810_drm_public.h" typedef struct _drm_i810_ring_buffer{ int tail_mask; @@ -124,4 +123,82 @@ extern int i810_context_switch_complete(drm_device_t *dev, int new); + +/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer. + * This can be fixed by emitting directly to the ringbuffer in the + * 'vertex_dma' ioctl. +*/ +typedef struct { + u32 *in_use; + int my_use_idx; +} drm_i810_buf_priv_t; + + +#define I810_DMA_GENERAL 0 +#define I810_DMA_VERTEX 1 +#define I810_DMA_DISCARD 2 /* not used */ + +#define I810_VERBOSE 0 + + +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +int i810_dma_general(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) +#define CMD_REPORT_HEAD (7<<23) +#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + + +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +#define I810REG_HWSTAM 0x02098 +#define I810REG_INT_IDENTITY_R 0x020a4 +#define I810REG_INT_MASK_R 0x020a8 +#define I810REG_INT_ENABLE_R 0x020a0 + +#define LP_RING 0x2030 +#define HP_RING 0x2040 +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) + #endif + diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index 48041354..82dda64d 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -510,27 +510,86 @@ int mga_release(struct inode *inode, struct file *filp) drm_device_t *dev = priv->dev; int retcode = 0; - DRM_DEBUG("open_count = %d\n", dev->open_count); - if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; - atomic_inc(&dev->total_close); - spin_lock(&dev->count_lock); - if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count) || dev->blocked) { - DRM_ERROR("Device busy: %d %d\n", - atomic_read(&dev->ioctl_count), - dev->blocked); - spin_unlock(&dev->count_lock); - return -EBUSY; + 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) { + mga_reclaim_buffers(dev, priv->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. */ + } else if (dev->lock.hw_lock) { + /* The lock is required to reclaim buffers */ + DECLARE_WAITQUEUE(entry, current); + add_wait_queue(&dev->lock.lock_queue, &entry); + for (;;) { + if (!dev->lock.hw_lock) { + /* Device has been unregistered */ + retcode = -EINTR; + break; + } + if (drm_lock_take(&dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + dev->lock.pid = priv->pid; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->total_locks); + break; /* Got lock */ + } + /* Contention */ + atomic_inc(&dev->total_sleeps); + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (signal_pending(current)) { + retcode = -ERESTARTSYS; + break; } - spin_unlock(&dev->count_lock); - return mga_takedown(dev); } - spin_unlock(&dev->count_lock); + current->state = TASK_RUNNING; + remove_wait_queue(&dev->lock.lock_queue, &entry); + if(!retcode) { + mga_reclaim_buffers(dev, priv->pid); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + } + } + 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); + MOD_DEC_USE_COUNT; + atomic_inc(&dev->total_close); + spin_lock(&dev->count_lock); + if (!--dev->open_count) { + if (atomic_read(&dev->ioctl_count) || dev->blocked) { + DRM_ERROR("Device busy: %d %d\n", + atomic_read(&dev->ioctl_count), + dev->blocked); + spin_unlock(&dev->count_lock); + return -EBUSY; + } + spin_unlock(&dev->count_lock); + return mga_takedown(dev); } + spin_unlock(&dev->count_lock); return retcode; } + /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index d477a70d..764f7bd8 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -23,7 +23,8 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> * * $XFree86$ * @@ -37,10 +38,10 @@ EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" #define R128_DESC "r128" -#define R128_DATE "19991213" +#define R128_DATE "20000405" #define R128_MAJOR 0 #define R128_MINOR 0 -#define R128_PATCHLEVEL 1 +#define R128_PATCHLEVEL 2 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -95,6 +96,11 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_ENGINE_RESET)] = { r128_engine_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_SUBMIT_PACKETS)] = { r128_submit_packets, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_WAIT_FOR_IDLE)] = { r128_wait_for_idle, 1, 0 }, }; #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 17c65454..af657365 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -118,13 +118,13 @@ DRMOBJS += agpsupport.o MODS += mga.o i810.o r128.o MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o -MGAHEADERS= mga_drv.h mga_drm_public.h $(DRMHEADERS) +MGAHEADERS= mga_drv.h $(DRMHEADERS) I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o -I810HEADERS= i810_drv.h i810_drm_public.h $(DRMHEADERS) +I810HEADERS= i810_drv.h $(DRMHEADERS) -R128OBJS= r128_drv.o r128_context.o -R128HEADERS= r128_drv.h $(DRMHEADERS) +R128OBJS= r128_drv.o r128_dma.o r128_context.o +R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) endif all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS} \ diff --git a/linux/agpsupport.c b/linux/agpsupport.c index e5793d81..14fb8b53 100644 --- a/linux/agpsupport.c +++ b/linux/agpsupport.c @@ -239,6 +239,8 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd, page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE; if ((retcode = drm_bind_agp(entry->memory, page))) return retcode; entry->bound = dev->agp->base + (page << PAGE_SHIFT); + DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", + dev->agp->base, entry->bound); return 0; } @@ -255,22 +257,11 @@ int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd, -EFAULT); if (!(entry = drm_agp_lookup_entry(dev, request.handle))) return -EINVAL; -#if 0 -#if 0 - if (entry->bound) drm_unbind_agp(entry->memory); -#endif - if(entry->prev) entry->prev->next = entry->next; - if(entry->next) entry->next->prev = entry->prev; - if((entry->next == NULL) && - (entry->prev == NULL)) { - dev->agp->memory = NULL; - } -#else if (entry->bound) drm_unbind_agp(entry->memory); + if (entry->prev) entry->prev->next = entry->next; else dev->agp->memory = entry->next; if (entry->next) entry->next->prev = entry->prev; -#endif drm_free_agp(entry->memory, entry->pages); drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); return 0; diff --git a/linux/ctxbitmap.c b/linux/ctxbitmap.c index c3e64a31..781984f1 100644 --- a/linux/ctxbitmap.c +++ b/linux/ctxbitmap.c @@ -64,12 +64,12 @@ int drm_ctxbitmap_init(drm_device_t *dev) int i; int temp; - dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE * 4, + dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE, DRM_MEM_CTXBITMAP); if(dev->ctx_bitmap == NULL) { return -ENOMEM; } - memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE * 4); + memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE); for(i = 0; i < DRM_RESERVED_CONTEXTS; i++) { temp = drm_ctxbitmap_next(dev); DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp); @@ -80,7 +80,7 @@ int drm_ctxbitmap_init(drm_device_t *dev) void drm_ctxbitmap_cleanup(drm_device_t *dev) { - drm_free((void *)dev->ctx_bitmap, PAGE_SIZE * 4, + drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); } diff --git a/linux/drm.h b/linux/drm.h index ebc6f7e7..ecb23555 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Mon Feb 14 00:15:23 2000 by kevin@precisioninsight.com + * Revised: Sun Apr 9 20:33:27 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -61,6 +61,20 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" +#include "r128_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -321,5 +335,25 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) -/* 0x40 is reserved for mga dma init */ +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + +/* Rage 128 specific ioctls */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_ENGINE_RESET DRM_IO( 0x41) +#define DRM_IOCTL_R128_SUBMIT_PACKETS DRM_IOW( 0x42, drm_r128_packet_t) +#define DRM_IOCTL_R128_WAIT_FOR_IDLE DRM_IO( 0x43) + #endif diff --git a/linux/drmP.h b/linux/drmP.h index c00d3bb0..f8e78eab 100644 --- a/linux/drmP.h +++ b/linux/drmP.h @@ -53,7 +53,7 @@ #include <linux/agp_backend.h> #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) -#include <linux/spinlock.h> +#include <linux/tqueue.h> #include <linux/poll.h> #endif #include "drm.h" @@ -93,7 +93,7 @@ #define DRM_MEM_BOUNDAGP 17 #define DRM_MEM_CTXBITMAP 18 -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 4 * 8) +#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) /* Backward compatibility section */ /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */ diff --git a/linux/fops.c b/linux/fops.c index 2a064e5d..1c1a3584 100644 --- a/linux/fops.c +++ b/linux/fops.c @@ -211,10 +211,11 @@ int drm_write_string(drm_device_t *dev, const char *s) send -= count; } -#if LINUX_VERSION_CODE < 0x020315 +#if LINUX_VERSION_CODE < 0x02020e || \ + ( LINUX_VERSION_CODE > 0x020300 && LINUX_VERSION_CODE < 0x020315 ) if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); #else - /* Parameter added in 2.3.21 */ + /* Parameter added in 2.2.14 and 2.3.21 */ if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN); #endif DRM_DEBUG("waking\n"); diff --git a/linux/i810_bufs.c b/linux/i810_bufs.c index be041f14..c025e400 100644 --- a/linux/i810_bufs.c +++ b/linux/i810_bufs.c @@ -33,152 +33,152 @@ #define __NO_VERSION__ #include "drmP.h" #include "i810_drv.h" -#include "i810_dma.h" #include "linux/un.h" int i810_addbufs_agp(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_device_dma_t *dma = dev->dma; - drm_buf_desc_t request; - drm_buf_entry_t *entry; - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - - if (!dma) return -EINVAL; - - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); - - count = request.count; - order = drm_order(request.size); - size = 1 << order; - agp_offset = request.agp_start; - alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - byte_count = 0; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; + + if (!dma) return -EINVAL; + + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); + + count = request.count; + order = drm_order(request.size); + size = 1 << order; + agp_offset = request.agp_start; + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; + page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; + total = PAGE_SIZE << page_order; + byte_count = 0; - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; - if (dev->queue_count) return -EBUSY; /* Not while in use */ - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down(&dev->struct_sem); - entry = &dma->bufs[order]; - if (entry->buf_count) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } + down(&dev->struct_sem); + entry = &dma->bufs[order]; + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ + } - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; + } + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - entry->buf_size = size; - entry->page_order = page_order; - offset = 0; + entry->buf_size = size; + entry->page_order = page_order; + offset = 0; - while(entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - buf->offset = offset; - buf->bus_address = dev->agp->base + agp_offset + offset; - buf->address = (void *)(agp_offset + offset + dev->agp->base); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->pid = 0; - - buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t), DRM_MEM_BUFS); - buf->dev_priv_size = sizeof(drm_i810_buf_priv_t); + while(entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + buf->offset = offset; + buf->bus_address = dev->agp->base + agp_offset + offset; + buf->address = (void *)(agp_offset + offset + dev->agp->base); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t), + DRM_MEM_BUFS); + buf->dev_priv_size = sizeof(drm_i810_buf_priv_t); #if DRM_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; #endif - offset = offset + alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; + offset = offset + alignment; + entry->buf_count++; + byte_count += PAGE_SIZE << page_order; - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); + } - dma->buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS); - for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) - dma->buflist[i] = &entry->buflist[i - dma->buf_count]; + dma->buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), + DRM_MEM_BUFS); + for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) + dma->buflist[i] = &entry->buflist[i - dma->buf_count]; - dma->buf_count += entry->buf_count; - dma->byte_count += byte_count; - 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]); - } + dma->buf_count += entry->buf_count; + dma->byte_count += byte_count; + 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]); + } - up(&dev->struct_sem); + up(&dev->struct_sem); - request.count = entry->buf_count; - request.size = size; + request.count = entry->buf_count; + request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_desc_t *)arg, + &request, + sizeof(request), + -EFAULT); - atomic_dec(&dev->buf_alloc); - dma->flags = _DRM_DMA_USE_AGP; - return 0; + atomic_dec(&dev->buf_alloc); + dma->flags = _DRM_DMA_USE_AGP; + return 0; } int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_buf_desc_t request; + drm_buf_desc_t request; - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); - if(request.flags & _DRM_AGP_BUFFER) - return i810_addbufs_agp(inode, filp, cmd, arg); - else - return -EINVAL; + if(request.flags & _DRM_AGP_BUFFER) + return i810_addbufs_agp(inode, filp, cmd, arg); + else + return -EINVAL; } int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, @@ -333,7 +333,7 @@ int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd, } int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; @@ -352,7 +352,7 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, spin_lock(&dev->count_lock); if (atomic_read(&dev->buf_alloc)) { spin_unlock(&dev->count_lock); - DRM_DEBUG("Busy\n"); + DRM_DEBUG("Busy\n"); return -EBUSY; } ++dev->buf_use; /* Can't allocate more after this call */ @@ -364,77 +364,81 @@ int i810_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, -EFAULT); DRM_DEBUG("dma->flags : %lx\n", dma->flags); if (request.count >= dma->buf_count) { - if(dma->flags & _DRM_DMA_USE_AGP) { - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - drm_map_t *map = NULL; + if(dma->flags & _DRM_DMA_USE_AGP) { + drm_i810_private_t *dev_priv = + (drm_i810_private_t *)dev->dev_private; + drm_map_t *map = NULL; - map = dev->maplist[dev_priv->buffer_map_idx]; - if (!map) { - DRM_DEBUG("map is null\n"); - retcode = -EINVAL; - goto done; - } - DRM_DEBUG("map->offset : %lx\n", map->offset); - DRM_DEBUG("map->size : %lx\n", map->size); - DRM_DEBUG("map->type : %d\n", map->type); - DRM_DEBUG("map->flags : %x\n", map->flags); - DRM_DEBUG("map->handle : %lx\n", map->handle); - DRM_DEBUG("map->mtrr : %d\n", map->mtrr); - down(¤t->mm->mmap_sem); - virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE, - MAP_SHARED, (unsigned long)map->offset); - up(¤t->mm->mmap_sem); - } else { - down(¤t->mm->mmap_sem); - virtual = do_mmap(filp, 0, dma->byte_count, - PROT_READ|PROT_WRITE, MAP_SHARED, 0); - up(¤t->mm->mmap_sem); - } - if (virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed long)virtual; - goto done; - } - request.virtual = (void *)virtual; + map = dev->maplist[dev_priv->buffer_map_idx]; + if (!map) { + DRM_DEBUG("map is null\n"); + retcode = -EINVAL; + goto done; + } + DRM_DEBUG("map->offset : %lx\n", map->offset); + DRM_DEBUG("map->size : %lx\n", map->size); + DRM_DEBUG("map->type : %d\n", map->type); + DRM_DEBUG("map->flags : %x\n", map->flags); + DRM_DEBUG("map->handle : %lx\n", map->handle); + DRM_DEBUG("map->mtrr : %d\n", map->mtrr); + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + (unsigned long)map->offset); + + up(¤t->mm->mmap_sem); + } else { + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); + } + if (virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed long)virtual; + goto done; + } + request.virtual = (void *)virtual; - for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request.list[i].idx, - &dma->buflist[i]->idx, - sizeof(request.list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].total, - &dma->buflist[i]->total, - sizeof(request.list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].used, - &zero, - sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; - if (copy_to_user(&request.list[i].address, - &address, - sizeof(address))) { - retcode = -EFAULT; - goto done; - } - } + for (i = 0; i < dma->buf_count; i++) { + if (copy_to_user(&request.list[i].idx, + &dma->buflist[i]->idx, + sizeof(request.list[0].idx))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].total, + &dma->buflist[i]->total, + sizeof(request.list[0].total))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].used, + &zero, + sizeof(zero))) { + retcode = -EFAULT; + goto done; + } + address = virtual + dma->buflist[i]->offset; + if (copy_to_user(&request.list[i].address, + &address, + sizeof(address))) { + retcode = -EFAULT; + goto done; + } + } } - done: - request.count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); + done: + request.count = dma->buf_count; + DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_map_t *)arg, + &request, + sizeof(request), + -EFAULT); - DRM_DEBUG("retcode : %d\n", retcode); - return retcode; + DRM_DEBUG("retcode : %d\n", retcode); + return retcode; } diff --git a/linux/i810_dma.c b/linux/i810_dma.c index e79f7ff5..6ac4d2ee 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -24,21 +24,18 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Jeff Hartmann <jhartmann@precisioninsight.com> + * Jeff Hartmann <jhartmann@precisioninsight.com> * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c,v 1.1 2000/02/11 17:26:04 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" -#include "i810_drm_public.h" #include "i810_drv.h" -#include "i810_dma.h" #include <linux/interrupt.h> /* For task queue support */ -#include <linux/time.h> /* For do_gettimeofday */ #define I810_BUF_FREE 1 #define I810_BUF_USED 0 @@ -56,27 +53,29 @@ #define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define BEGIN_LP_RING(n) do { \ - if (I810_VERBOSE) \ - DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ - if (dev_priv->ring.space < n*4) i810_wait_ring(dev, n*4, 0); \ - dev_priv->ring.space -= n*4; \ - outring = dev_priv->ring.tail; \ - ringmask = dev_priv->ring.tail_mask; \ - virt = dev_priv->ring.virtual_start; \ +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i810_wait_ring(dev, n*4); \ + dev_priv->ring.space -= n*4; \ + outring = dev_priv->ring.tail; \ + ringmask = dev_priv->ring.tail_mask; \ + virt = dev_priv->ring.virtual_start; \ } while (0) #define ADVANCE_LP_RING() do { \ - if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ + if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \ + dev_priv->ring.tail = outring; \ + I810_WRITE(LP_RING + RING_TAIL, outring); \ } while(0) -#define OUT_RING(n) do { \ - if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ +#define OUT_RING(n) do { \ + if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ } while (0); static inline void i810_print_status_page(drm_device_t *dev) @@ -111,7 +110,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, I810_BUF_USED); if(used == I810_BUF_FREE) { - return buf; + return buf; } } return NULL; @@ -160,28 +159,28 @@ static int i810_dma_get_buffers(drm_device_t *dev, drm_dma_t *d) static unsigned long i810_alloc_page(drm_device_t *dev) { - unsigned long address; + unsigned long address; - address = __get_free_page(GFP_KERNEL); - if(address == 0UL) { - return 0; - } - atomic_inc(&mem_map[MAP_NR((void *) address)].count); - set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) + return 0; + + atomic_inc(&mem_map[MAP_NR((void *) address)].count); + set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); - return address; + return address; } static void i810_free_page(drm_device_t *dev, unsigned long page) { - if(page == 0UL) { - return; - } - atomic_dec(&mem_map[MAP_NR((void *) page)].count); - clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); - wake_up(&mem_map[MAP_NR((void *) page)].wait); - free_page(page); - return; + if(page == 0UL) + return; + + atomic_dec(&mem_map[MAP_NR((void *) page)].count); + clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); + wake_up(&mem_map[MAP_NR((void *) page)].wait); + free_page(page); + return; } static int i810_dma_cleanup(drm_device_t *dev) @@ -206,24 +205,14 @@ static int i810_dma_cleanup(drm_device_t *dev) return 0; } -static int __gettimeinmillis(void) -{ - int millis; - - millis = ((jiffies / HZ) * 1000) + ((jiffies % HZ) * (1000 / HZ)); - return millis; -} - -static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) +static int i810_wait_ring(drm_device_t *dev, int n) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_ring_buffer_t *ring = &(dev_priv->ring); int iters = 0; - int startTime = 0; - int curTime = 0; - - if (timeout_millis == 0) timeout_millis = 3000; - + unsigned long end; + + end = jiffies + (HZ*3); while (ring->space < n) { int i; @@ -233,10 +222,7 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) if (ring->space < 0) ring->space += ring->Size; iters++; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); goto out_wait_ring; @@ -244,8 +230,8 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) for (i = 0 ; i < 2000 ; i++) ; } -out_wait_ring: - + +out_wait_ring: return iters; } @@ -380,27 +366,27 @@ int i810_dma_init(struct inode *inode, struct file *filp, return retcode; } -static inline void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) +static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf, + int used ) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int length = buf->used; RING_LOCALS; dev_priv->counter++; DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); DRM_DEBUG( "i810_dma_dispatch\n"); DRM_DEBUG( "start : 0x%lx\n", start); - DRM_DEBUG( "length : 0x%x\n", length); - DRM_DEBUG( "start + length - 4 : 0x%lx\n", start + length - 4); + DRM_DEBUG( "used : 0x%x\n", used); + DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4); i810_kernel_lost_context(dev); BEGIN_LP_RING(10); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + length - 4 ); + OUT_RING( start + used - 4 ); OUT_RING( CMD_STORE_DWORD_IDX ); OUT_RING( 20 ); OUT_RING( dev_priv->counter ); @@ -411,35 +397,37 @@ static inline void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) ADVANCE_LP_RING(); } -static inline void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) +static void i810_dma_dispatch_vertex(drm_device_t *dev, + drm_buf_t *buf, + int discard, + int used) { drm_i810_private_t *dev_priv = dev->dev_private; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_buf_t *real_buf = dev->dma->buflist[ buf_priv->vertex_real_idx ]; drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *box = sarea_priv->boxes; + drm_clip_rect_t *box = sarea_priv->boxes; int nbox = sarea_priv->nbox; - unsigned long address = (unsigned long)real_buf->bus_address; - unsigned long start = address - dev->agp->base; - int length = buf->used; + unsigned long address = (unsigned long)buf->bus_address; + unsigned long start = address - dev->agp->base; int i = 0; RING_LOCALS; - if(nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; - DRM_DEBUG("dispatch vertex addr 0x%lx, length 0x%x nbox %d\n", - address, length, buf_priv->nbox); + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + address, used, nbox); dev_priv->counter++; DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); DRM_DEBUG( "i810_dma_dispatch\n"); DRM_DEBUG( "start : %lx\n", start); - DRM_DEBUG( "length : %d\n", length); - DRM_DEBUG( "start + length - 4 : %ld\n", start + length - 4); + DRM_DEBUG( "used : %d\n", used); + DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); i810_kernel_lost_context(dev); - if (!buf_priv->vertex_discard) { + if (used) { do { if (i < nbox) { BEGIN_LP_RING(4); @@ -447,27 +435,33 @@ static inline void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) SC_ENABLE ); OUT_RING( GFX_OP_SCISSOR_INFO ); OUT_RING( box[i].x1 | (box[i].y1 << 16) ); - OUT_RING( (box[i].x2-1) | ((box[i].y2-1) << 16) ); + OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } BEGIN_LP_RING(4); OUT_RING( CMD_OP_BATCH_BUFFER ); OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + length - 4 ); + OUT_RING( start + used - 4 ); OUT_RING( 0 ); ADVANCE_LP_RING(); } while (++i < nbox); } - BEGIN_LP_RING(8); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( 20 ); - OUT_RING( dev_priv->counter ); - OUT_RING( CMD_STORE_DWORD_IDX ); - OUT_RING( buf_priv->my_use_idx ); - OUT_RING( I810_BUF_FREE ); + BEGIN_LP_RING(10); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( 0 ); + + if (discard) { + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( buf_priv->my_use_idx ); + OUT_RING( I810_BUF_FREE ); + OUT_RING( 0 ); + } + OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); ADVANCE_LP_RING(); @@ -649,10 +643,7 @@ static void i810_dma_quiescent(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; - + unsigned long end; if(dev_priv == NULL) { return; @@ -660,13 +651,12 @@ static void i810_dma_quiescent(drm_device_t *dev) atomic_set(&dev_priv->flush_done, 0); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); + for (;;) { i810_dma_quiescent_emit(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; } @@ -686,11 +676,8 @@ static int i810_flush_queue(drm_device_t *dev) { DECLARE_WAITQUEUE(entry, current); drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - int ret = 0; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; - + unsigned long end; + int ret = 0; if(dev_priv == NULL) { return 0; @@ -698,13 +685,11 @@ static int i810_flush_queue(drm_device_t *dev) atomic_set(&dev_priv->flush_done, 0); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&dev_priv->flush_queue, &entry); + end = jiffies + (HZ*3); for (;;) { i810_dma_emit_flush(dev); if (atomic_read(&dev_priv->flush_done) == 1) break; - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { + if((signed)(end - jiffies) <= 0) { DRM_ERROR("lockup\n"); break; } @@ -729,17 +714,17 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) if (!dma) return; if(dev->dev_private == NULL) return; - + if(dma->buflist == NULL) return; i810_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - - if (buf->pid == pid) { - /* Only buffers that need to get reclaimed ever - * get set to free */ - if(buf_priv == NULL) return; + + /* Only buffers that need to get reclaimed ever + * get set to free + */ + if (buf->pid == pid && buf_priv) { cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE); } @@ -835,6 +820,11 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, drm_device_t *dev = priv->dev; DRM_DEBUG("i810_flush_ioctl\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_flush_ioctl called without lock held\n"); + return -EINVAL; + } + i810_flush_queue(dev); return 0; } @@ -844,41 +834,22 @@ static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args) drm_device_dma_t *dma = dev->dma; drm_buf_t *buf = dma->buflist[ args->idx ]; - buf->used = args->used; - - DRM_DEBUG("i810DmaGeneral idx %d used %d\n", args->idx, buf->used); - - if (!buf->used) { - DRM_ERROR("0 length buffer\n"); + if (!args->used) { i810_freelist_put(dev, buf); - return 0; + } else { + i810_dma_dispatch_general( dev, buf, args->used ); + atomic_add(args->used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); } - - i810_dma_dispatch_general( dev, buf ); - atomic_add(buf->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - return 0; } static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) { drm_device_dma_t *dma = dev->dma; - drm_i810_buf_priv_t *buf_priv; - drm_buf_t *buf; - - - buf = dma->buflist[ args->idx ]; - buf->used = args->real_used; - - DRM_DEBUG("i810DmaVertex idx %d used %d\n", args->idx, buf->used); - - buf_priv = buf->dev_private; - buf_priv->vertex_real_idx = args->real_idx; - buf_priv->vertex_discard = args->discard; - - i810_dma_dispatch_vertex( dev, buf); - atomic_add(buf->used, &dma->total_bytes); + drm_buf_t *buf = dma->buflist[ args->idx ]; + i810_dma_dispatch_vertex( dev, buf, args->discard, args->used ); + atomic_add(args->used, &dma->total_bytes); atomic_inc(&dma->total_dmas); return 0; } @@ -902,7 +873,13 @@ int i810_dma_general(struct inode *inode, struct file *filp, DRM_DEBUG("i810 dma general idx %d used %d\n", general.idx, general.used); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_general called without lock held\n"); + return -EINVAL; + } + retcode = i810DmaGeneral(dev, &general); + sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -922,12 +899,16 @@ int i810_dma_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - - DRM_DEBUG("i810 dma vertex, idx %d used %d real_idx %d discard %d\n", - vertex.idx, vertex.real_used, vertex.real_idx, - vertex.discard); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma_vertex called without lock held\n"); + return -EINVAL; + } + + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); retcode = i810DmaVertex(dev, &vertex); + sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; return retcode; @@ -965,6 +946,11 @@ int i810_dma(struct inode *inode, struct file *filp, unsigned int cmd, copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_dma called without lock held\n"); + return -EINVAL; + } /* Please don't send us buffers. */ diff --git a/linux/i810_dma.h b/linux/i810_dma.h deleted file mode 100644 index 0f79b6ab..00000000 --- a/linux/i810_dma.h +++ /dev/null @@ -1,118 +0,0 @@ -/* i810_dma.h -- DMA support for the i810 -*- linux-c -*- - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * 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: Keith Whitwell <keithw@precisioninsight.com> - * - * $XFree86$ - * - */ - - -#ifndef I810_DMA_H -#define I810_DMA_H - -#include "i810_drm_public.h" - - -/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer. - * This can be fixed by emitting directly to the ringbuffer in the - * 'vertex_dma' ioctl. -*/ -typedef struct { - int vertex_real_idx; - int vertex_discard; - u32 *in_use; - int my_use_idx; - unsigned int nbox; - xf86drmClipRectRec boxes[I810_NR_SAREA_CLIPRECTS]; -} drm_i810_buf_priv_t; - - -#define I810_DMA_GENERAL 0 -#define I810_DMA_VERTEX 1 -#define I810_DMA_DISCARD 2 /* not used */ - -#define I810_VERBOSE 0 - - -int i810_dma_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); - -int i810_dma_general(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); - - -#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) -#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) -#define CMD_REPORT_HEAD (7<<23) -#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) -#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) - -#define INST_PARSER_CLIENT 0x00000000 -#define INST_OP_FLUSH 0x02000000 -#define INST_FLUSH_MAP_CACHE 0x00000001 - - -#define BB1_START_ADDR_MASK (~0x7) -#define BB1_PROTECTED (1<<0) -#define BB1_UNPROTECTED (0<<0) -#define BB2_END_ADDR_MASK (~0x7) - -#define I810REG_HWSTAM 0x02098 -#define I810REG_INT_IDENTITY_R 0x020a4 -#define I810REG_INT_MASK_R 0x020a8 -#define I810REG_INT_ENABLE_R 0x020a0 - -#define LP_RING 0x2030 -#define HP_RING 0x2040 -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define RING_START 0x08 -#define START_ADDR 0x00FFFFF8 -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x000FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - -#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) -#define SC_UPDATE_SCISSOR (0x1<<1) -#define SC_ENABLE_MASK (0x1<<0) -#define SC_ENABLE (0x1<<0) - -#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) -#define SCI_YMIN_MASK (0xffff<<16) -#define SCI_XMIN_MASK (0xffff<<0) -#define SCI_YMAX_MASK (0xffff<<16) -#define SCI_XMAX_MASK (0xffff<<0) - -#endif diff --git a/linux/i810_drm.h b/linux/i810_drm.h new file mode 100644 index 00000000..0754874c --- /dev/null +++ b/linux/i810_drm.h @@ -0,0 +1,93 @@ +#ifndef _I810_DRM_H_ +#define _I810_DRM_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +/* Might one day want to support the client-side ringbuffer code again. + */ +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ + +#define I810_USE_BATCH 1 +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 256 +#define I810_NR_SAREA_CLIPRECTS 2 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ + +#define I810_NR_TEX_REGIONS 64 +#define I810_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drm_i810_init { + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 + } func; + int ring_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + unsigned long ring_start; + unsigned long ring_end; + unsigned long ring_size; +} drm_i810_init_t; + +/* Warning: If you change the SAREA structure you must change the Xserver + * structure as well */ + +typedef struct _drm_i810_tex_region { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} drm_i810_tex_region_t; + +typedef struct _drm_i810_sarea { + unsigned int nbox; + drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + + drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ +} drm_i810_sarea_t; + +typedef struct _drm_i810_general { + int idx; + int used; +} drm_i810_general_t; + +/* These may be placeholders if we have more cliprects than + * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to + * false, indicating that the buffer will be dispatched again with a + * new set of cliprects. + */ +typedef struct _drm_i810_vertex { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int discard; /* client is finished with the buffer? */ +} drm_i810_vertex_t; + +#endif /* _I810_DRM_H_ */ diff --git a/linux/i810_drm_public.h b/linux/i810_drm_public.h deleted file mode 100644 index 7213def1..00000000 --- a/linux/i810_drm_public.h +++ /dev/null @@ -1,139 +0,0 @@ -/* i810_drm_public.h -- Public header for the i810 driver -*- linux-c -*- - * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * 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: Jeff Hartmann <jhartmann@precisioninsight.com> - * Keith Whitwell <keithw@precisioninsight.com> - * - * $XFree86$ - */ - -#ifndef _I810_DRM_H_ -#define _I810_DRM_H_ - -typedef struct drm_i810_init { - enum { - I810_INIT_DMA = 0x01, - I810_CLEANUP_DMA = 0x02 - } func; - int ring_map_idx; - int buffer_map_idx; - int sarea_priv_offset; - unsigned long ring_start; - unsigned long ring_end; - unsigned long ring_size; - -} drm_i810_init_t; - -typedef struct _xf86drmClipRectRec { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -} xf86drmClipRectRec; - -/* Might one day want to support the client-side ringbuffer code again. - */ - -#define I810_USE_BATCH 1 - -#define I810_DMA_BUF_ORDER 12 -#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) -#define I810_DMA_BUF_NR 256 - -#define I810_NR_SAREA_CLIPRECTS 2 - -/* Each region is a minimum of 64k, and there are at most 64 of them. - */ -#define I810_NR_TEX_REGIONS 64 -#define I810_LOG_MIN_TEX_REGION_SIZE 16 - -typedef struct { - unsigned char next, prev; /* indices to form a circular LRU */ - unsigned char in_use; /* owned by a client, or free? */ - int age; /* tracked by clients to update local LRU's */ -} i810TexRegion; - -typedef struct { - unsigned int nbox; - xf86drmClipRectRec boxes[I810_NR_SAREA_CLIPRECTS]; - - /* Maintain an LRU of contiguous regions of texture space. If - * you think you own a region of texture memory, and it has an - * age different to the one you set, then you are mistaken and - * it has been stolen by another client. If global texAge - * hasn't changed, there is no need to walk the list. - * - * These regions can be used as a proxy for the fine-grained - * texture information of other clients - by maintaining them - * in the same lru which is used to age their own textures, - * clients have an approximate lru for the whole of global - * texture space, and can make informed decisions as to which - * areas to kick out. There is no need to choose whether to - * kick out your own texture or someone else's - simply eject - * them all in LRU order. - */ - i810TexRegion texList[I810_NR_TEX_REGIONS+1]; /* Last elt is sentinal */ - - int texAge; /* last time texture was uploaded */ - - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int last_quiescent; /* */ - - int ctxOwner; /* last context to upload state */ -} drm_i810_sarea_t; - - -typedef struct { - int idx; - int used; - int age; -} drm_i810_general_t; - - -/* These may be placeholders if we have more cliprects than - * I810_NR_SAREA_CLIPRECTS. In that case, idx != real_idx; idx is the - * number of a placeholder buffer, real_idx is the real buffer to be - * rendered multiple times. - * - * This is a hack to work around the fact that the drm considers - * buffers to be only in a single state (ie on a single queue). - */ -typedef struct { - int idx; /* buffer to queue and free on completion */ - int real_idx; /* buffer to execute */ - int real_used; /* buf->used in for real buffer */ - int discard; /* don't execute the commands */ - int age; -} drm_i810_vertex_t; - - - -#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) -#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) -#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) -#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) -#endif /* _I810_DRM_H_ */ diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 179b8714..f1c83250 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -33,7 +33,6 @@ #define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" -#include "i810_dma.h" EXPORT_SYMBOL(i810_init); @@ -500,7 +499,7 @@ int i810_release(struct inode *inode, struct file *filp) DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n", current->pid, dev->device, dev->open_count); - if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) + if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && dev->lock.pid == current->pid) { i810_reclaim_buffers(dev, priv->pid); DRM_ERROR("Process %d dead, freeing lock for context %d\n", @@ -514,7 +513,7 @@ int i810_release(struct inode *inode, struct file *filp) hardware at this point, possibly processed via a callback to the X server. */ - } else { + } else if (dev->lock.hw_lock) { /* The lock is required to reclaim buffers */ DECLARE_WAITQUEUE(entry, current); add_wait_queue(&dev->lock.lock_queue, &entry); diff --git a/linux/i810_drv.h b/linux/i810_drv.h index d3dc6906..1badd36b 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -31,7 +31,6 @@ #ifndef _I810_DRV_H_ #define _I810_DRV_H_ -#include "i810_drm_public.h" typedef struct _drm_i810_ring_buffer{ int tail_mask; @@ -124,4 +123,82 @@ extern int i810_context_switch_complete(drm_device_t *dev, int new); + +/* Copy the outstanding cliprects for every I810_DMA_VERTEX buffer. + * This can be fixed by emitting directly to the ringbuffer in the + * 'vertex_dma' ioctl. +*/ +typedef struct { + u32 *in_use; + int my_use_idx; +} drm_i810_buf_priv_t; + + +#define I810_DMA_GENERAL 0 +#define I810_DMA_VERTEX 1 +#define I810_DMA_DISCARD 2 /* not used */ + +#define I810_VERBOSE 0 + + +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +int i810_dma_general(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) +#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) +#define CMD_REPORT_HEAD (7<<23) +#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + + +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +#define I810REG_HWSTAM 0x02098 +#define I810REG_INT_IDENTITY_R 0x020a4 +#define I810REG_INT_MASK_R 0x020a8 +#define I810REG_INT_ENABLE_R 0x020a0 + +#define LP_RING 0x2030 +#define HP_RING 0x2040 +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) + #endif + diff --git a/linux/mga_bufs.c b/linux/mga_bufs.c index 89e4090d..3ce428b2 100644 --- a/linux/mga_bufs.c +++ b/linux/mga_bufs.c @@ -33,169 +33,168 @@ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mga_dma.h" #include "linux/un.h" int mga_addbufs_agp(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_device_dma_t *dma = dev->dma; - drm_buf_desc_t request; - drm_buf_entry_t *entry; - drm_buf_t *buf; - unsigned long offset; - unsigned long agp_offset; - int count; - int order; - int size; - int alignment; - int page_order; - int total; - int byte_count; - int i; - - if (!dma) return -EINVAL; - - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); - - count = request.count; - order = drm_order(request.size); - size = 1 << order; - agp_offset = request.agp_start; - alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; - page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; - total = PAGE_SIZE << page_order; - byte_count = 0; - - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %ld\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - DRM_DEBUG("byte_count: %d\n", byte_count); - - if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; - if (dev->queue_count) return -EBUSY; /* Not while in use */ - spin_lock(&dev->count_lock); - if (dev->buf_use) { - spin_unlock(&dev->count_lock); - return -EBUSY; - } - atomic_inc(&dev->buf_alloc); - spin_unlock(&dev->count_lock); + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; + + if (!dma) return -EINVAL; + + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); + + count = request.count; + order = drm_order(request.size); + size = 1 << order; + agp_offset = request.agp_start; + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size; + page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; + total = PAGE_SIZE << page_order; + byte_count = 0; + + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + DRM_DEBUG("byte_count: %d\n", byte_count); + + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); - down(&dev->struct_sem); - entry = &dma->bufs[order]; - if (entry->buf_count) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; /* May only call once for each order */ - } + down(&dev->struct_sem); + entry = &dma->bufs[order]; + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ + } - entry->buflist = drm_alloc(count * sizeof(*entry->buflist), - DRM_MEM_BUFS); - if (!entry->buflist) { - up(&dev->struct_sem); - atomic_dec(&dev->buf_alloc); - return -ENOMEM; - } - memset(entry->buflist, 0, count * sizeof(*entry->buflist)); + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; + } + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); - entry->buf_size = size; - entry->page_order = page_order; - offset = 0; + entry->buf_size = size; + entry->page_order = page_order; + offset = 0; - while(entry->buf_count < count) { - buf = &entry->buflist[entry->buf_count]; - buf->idx = dma->buf_count + entry->buf_count; - buf->total = alignment; - buf->order = order; - buf->used = 0; - - DRM_DEBUG("offset : %ld\n", offset); - - buf->offset = offset; /* Hrm */ - buf->bus_address = dev->agp->base + agp_offset + offset; - buf->address = (void *)(agp_offset + offset + dev->agp->base); - buf->next = NULL; - buf->waiting = 0; - buf->pending = 0; - init_waitqueue_head(&buf->dma_wait); - buf->pid = 0; - - buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS); - buf->dev_priv_size = sizeof(drm_mga_buf_priv_t); + while(entry->buf_count < count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + + DRM_DEBUG("offset : %ld\n", offset); + + buf->offset = offset; /* Hrm */ + buf->bus_address = dev->agp->base + agp_offset + offset; + buf->address = (void *)(agp_offset + offset + dev->agp->base); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS); + buf->dev_priv_size = sizeof(drm_mga_buf_priv_t); #if DRM_DMA_HISTOGRAM - buf->time_queued = 0; - buf->time_dispatched = 0; - buf->time_completed = 0; - buf->time_freed = 0; + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; #endif - offset = offset + alignment; - entry->buf_count++; - byte_count += PAGE_SIZE << page_order; + offset = offset + alignment; + entry->buf_count++; + byte_count += PAGE_SIZE << page_order; - DRM_DEBUG("buffer %d @ %p\n", - entry->buf_count, buf->address); - } + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); + } - dma->buflist = drm_realloc(dma->buflist, - dma->buf_count * sizeof(*dma->buflist), - (dma->buf_count + entry->buf_count) - * sizeof(*dma->buflist), - DRM_MEM_BUFS); - for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) - dma->buflist[i] = &entry->buflist[i - dma->buf_count]; + dma->buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), + DRM_MEM_BUFS); + for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) + dma->buflist[i] = &entry->buflist[i - dma->buf_count]; - dma->buf_count += entry->buf_count; + dma->buf_count += entry->buf_count; - DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); + DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); - dma->byte_count += byte_count; + dma->byte_count += byte_count; - DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); + DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); - 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]); - } + 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]); + } - up(&dev->struct_sem); + up(&dev->struct_sem); - request.count = entry->buf_count; - request.size = size; + request.count = entry->buf_count; + request.size = size; - copy_to_user_ret((drm_buf_desc_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_desc_t *)arg, + &request, + sizeof(request), + -EFAULT); - atomic_dec(&dev->buf_alloc); + atomic_dec(&dev->buf_alloc); - DRM_DEBUG("count: %d\n", count); - DRM_DEBUG("order: %d\n", order); - DRM_DEBUG("size: %d\n", size); - DRM_DEBUG("agp_offset: %ld\n", agp_offset); - DRM_DEBUG("alignment: %d\n", alignment); - DRM_DEBUG("page_order: %d\n", page_order); - DRM_DEBUG("total: %d\n", total); - DRM_DEBUG("byte_count: %d\n", byte_count); + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + DRM_DEBUG("byte_count: %d\n", byte_count); - dma->flags = _DRM_DMA_USE_AGP; + dma->flags = _DRM_DMA_USE_AGP; - DRM_DEBUG("dma->flags : %x\n", dma->flags); + DRM_DEBUG("dma->flags : %x\n", dma->flags); - return 0; + return 0; } int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, @@ -362,17 +361,17 @@ int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd, int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_buf_desc_t request; + drm_buf_desc_t request; - copy_from_user_ret(&request, - (drm_buf_desc_t *)arg, - sizeof(request), - -EFAULT); + copy_from_user_ret(&request, + (drm_buf_desc_t *)arg, + sizeof(request), + -EFAULT); - if(request.flags & _DRM_AGP_BUFFER) - return mga_addbufs_agp(inode, filp, cmd, arg); - else - return mga_addbufs_pci(inode, filp, cmd, arg); + if(request.flags & _DRM_AGP_BUFFER) + return mga_addbufs_agp(inode, filp, cmd, arg); + else + return mga_addbufs_pci(inode, filp, cmd, arg); } int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd, @@ -546,7 +545,7 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, spin_lock(&dev->count_lock); if (atomic_read(&dev->buf_alloc)) { spin_unlock(&dev->count_lock); - DRM_DEBUG("Busy\n"); + DRM_DEBUG("Busy\n"); return -EBUSY; } ++dev->buf_use; /* Can't allocate more after this call */ @@ -560,80 +559,82 @@ int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("mga_mapbufs\n"); DRM_DEBUG("dma->flags : %x\n", dma->flags); - if (request.count >= dma->buf_count) { - if(dma->flags & _DRM_DMA_USE_AGP) { - drm_mga_private_t *dev_priv = dev->dev_private; - drm_map_t *map = NULL; + if (request.count >= dma->buf_count) { + if(dma->flags & _DRM_DMA_USE_AGP) { + drm_mga_private_t *dev_priv = dev->dev_private; + drm_map_t *map = NULL; - map = dev->maplist[dev_priv->buffer_map_idx]; - if (!map) { - DRM_DEBUG("map is null\n"); - retcode = -EINVAL; - goto done; - } - - DRM_DEBUG("map->offset : %lx\n", map->offset); - DRM_DEBUG("map->size : %lx\n", map->size); - DRM_DEBUG("map->type : %d\n", map->type); - DRM_DEBUG("map->flags : %x\n", map->flags); - DRM_DEBUG("map->handle : %p\n", map->handle); - DRM_DEBUG("map->mtrr : %d\n", map->mtrr); - down(¤t->mm->mmap_sem); - virtual = do_mmap(filp, 0, map->size, PROT_READ|PROT_WRITE, - MAP_SHARED, (unsigned long)map->offset); - up(¤t->mm->mmap_sem); - } else { - down(¤t->mm->mmap_sem); - virtual = do_mmap(filp, 0, dma->byte_count, - PROT_READ|PROT_WRITE, MAP_SHARED, 0); - up(¤t->mm->mmap_sem); - } - if (virtual > -1024UL) { - /* Real error */ - DRM_DEBUG("mmap error\n"); - retcode = (signed long)virtual; - goto done; - } - request.virtual = (void *)virtual; + map = dev->maplist[dev_priv->buffer_map_idx]; + if (!map) { + DRM_DEBUG("map is null\n"); + retcode = -EINVAL; + goto done; + } + + DRM_DEBUG("map->offset : %lx\n", map->offset); + DRM_DEBUG("map->size : %lx\n", map->size); + DRM_DEBUG("map->type : %d\n", map->type); + DRM_DEBUG("map->flags : %x\n", map->flags); + DRM_DEBUG("map->handle : %p\n", map->handle); + DRM_DEBUG("map->mtrr : %d\n", map->mtrr); + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + (unsigned long)map->offset); + up(¤t->mm->mmap_sem); + } else { + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); + } + if (virtual > -1024UL) { + /* Real error */ + DRM_DEBUG("mmap error\n"); + retcode = (signed long)virtual; + goto done; + } + request.virtual = (void *)virtual; - for (i = 0; i < dma->buf_count; i++) { - if (copy_to_user(&request.list[i].idx, - &dma->buflist[i]->idx, - sizeof(request.list[0].idx))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].total, - &dma->buflist[i]->total, - sizeof(request.list[0].total))) { - retcode = -EFAULT; - goto done; - } - if (copy_to_user(&request.list[i].used, - &zero, - sizeof(zero))) { - retcode = -EFAULT; - goto done; - } - address = virtual + dma->buflist[i]->offset; - if (copy_to_user(&request.list[i].address, - &address, - sizeof(address))) { - retcode = -EFAULT; - goto done; - } - } - } - done: - request.count = dma->buf_count; - DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); + for (i = 0; i < dma->buf_count; i++) { + if (copy_to_user(&request.list[i].idx, + &dma->buflist[i]->idx, + sizeof(request.list[0].idx))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].total, + &dma->buflist[i]->total, + sizeof(request.list[0].total))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].used, + &zero, + sizeof(zero))) { + retcode = -EFAULT; + goto done; + } + address = virtual + dma->buflist[i]->offset; + if (copy_to_user(&request.list[i].address, + &address, + sizeof(address))) { + retcode = -EFAULT; + goto done; + } + } + } + done: + request.count = dma->buf_count; + DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); - copy_to_user_ret((drm_buf_map_t *)arg, - &request, - sizeof(request), - -EFAULT); + copy_to_user_ret((drm_buf_map_t *)arg, + &request, + sizeof(request), + -EFAULT); - DRM_DEBUG("retcode : %d\n", retcode); + DRM_DEBUG("retcode : %d\n", retcode); - return retcode; + return retcode; } diff --git a/linux/mga_clear.c b/linux/mga_clear.c deleted file mode 100644 index 05895415..00000000 --- a/linux/mga_clear.c +++ /dev/null @@ -1,417 +0,0 @@ -/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*- - * - * Created: February 2000 by keithw@precisioninsight.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * 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: - * Keith Whitwell <keithw@precisioninsight.com> - * - */ - -#define __NO_VERSION__ -#include "drmP.h" -#include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" -#include "mga_state.h" - -#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ - DC_solid_enable | DC_transc_enable) - - -#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ - DC_solid_disable | DC_arzero_disable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ - DC_pattern_disable | DC_transc_disable | \ - DC_clipdis_enable) \ - - - -/* Build and queue a TT_GENERAL secondary buffer to do the clears. - * With Jeff's ringbuffer idea, it might make sense if there are only - * one or two cliprects to emit straight to the primary buffer. - */ -static int mgaClearBuffers(drm_device_t *dev, - int clear_color, - int clear_depth, - int flags) -{ - int cmd, i; - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - drm_buf_t *buf; - drm_dma_t d; - int order = 10; /* ??? what orders do we have ???*/ - DMALOCALS; - - - if (!nbox) - return -EINVAL; - - if ( dev_priv->sgram ) - cmd = MGA_CLEAR_CMD | DC_atype_blk; - else - cmd = MGA_CLEAR_CMD | DC_atype_rstr; - - buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); - - - DMAGETPTR( buf ); - - for (i = 0 ; i < nbox ; i++) { - unsigned int height = pbox[i].y2 - pbox[i].y1; - - /* Is it necessary to be this paranoid? I don't think so. - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); - DMAOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); - - if ( flags & MGA_CLEAR_FRONT ) { - DMAOUTREG(MGAREG_FCOL, clear_color); - DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - - if ( flags & MGA_CLEAR_BACK ) { - DMAOUTREG(MGAREG_FCOL, clear_color); - DMAOUTREG(MGAREG_DSTORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - - if ( flags & MGA_CLEAR_DEPTH ) - { - DMAOUTREG(MGAREG_FCOL, clear_depth); - DMAOUTREG(MGAREG_DSTORG, dev_priv->depthOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - } - - DMAADVANCE( buf ); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; - - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; - - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - return 0; -} - -int mgaSwapBuffers(drm_device_t *dev, int flags) -{ - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; - drm_buf_t *buf; - drm_dma_t d; - int order = 10; /* ??? */ - int i; - DMALOCALS; - - if (!nbox) - return -EINVAL; - - buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); - - DMAGETPTR(buf); - - DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); - DMAOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - DMAOUTREG(MGAREG_SRCORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_AR5, dev_priv->stride); /* unnecessary? */ - DMAOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); - - for (i = 0 ; i < nbox; i++) { - unsigned int h = pbox[i].y2 - pbox[i].y1; - unsigned int start = pbox[i].y1 * dev_priv->stride; - - /* - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); - DMAOUTREG(MGAREG_AR3, start + pbox[i].x1); - DMAOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16)); - DMAOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h); - } - - DMAOUTREG(MGAREG_SRCORG, 0); - DMAADVANCE( buf ); - - /* Make sure we restore the 3D state next time. - */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; - - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; - - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - return 0; -} - - -static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - drm_mga_buf_priv_t *buf_priv = (drm_mga_buf_priv_t *)buf->dev_private; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_dma_t d; - int pixperdword; - - buf_priv->dma_type = MGA_DMA_ILOAD; - buf_priv->boxes[0].y1 = args->texture.y1; - buf_priv->boxes[0].y2 = args->texture.y2; - buf_priv->boxes[0].x1 = args->texture.x1; - buf_priv->boxes[0].x2 = args->texture.x2; - buf_priv->ContextState[MGA_CTXREG_DSTORG] = args->destOrg; - buf_priv->ContextState[MGA_CTXREG_MACCESS] = args->mAccess; - buf_priv->ServerState[MGA_2DREG_PITCH] = args->pitch; - buf_priv->nbox = 1; - sarea_priv->dirty |= (MGASAREA_NEW_CONTEXT | MGASAREA_NEW_2D); - switch((args->mAccess & 0x00000003)) { - case 0: - pixperdword = 4; - break; - case 1: - pixperdword = 2; - break; - case 2: - pixperdword = 1; - break; - default: - DRM_ERROR("Invalid maccess value passed" - " to mgaIload\n"); - return -EINVAL; - } - buf->used = ((args->texture.y2 - args->texture.y1) * - (args->texture.x2 - args->texture.x1) / - pixperdword); - DRM_DEBUG("buf->used : %d\n", buf->used); - d.context = DRM_KERNEL_CONTEXT; - d.send_count = 1; - d.send_indices = &buf->idx; - d.send_sizes = &buf->used; - d.flags = 0; - d.request_count = 0; - d.request_size = 0; - d.request_indices = NULL; - d.request_sizes = NULL; - d.granted_count = 0; - - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - - return 0; -} - - -/* Necessary? Not necessary?? - */ -static int check_lock(void) -{ - return 1; -} - -int mga_clear_bufs(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_mga_clear_t clear; - int retcode; - - copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, - sizeof(clear), -EFAULT); - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - retcode = mgaClearBuffers(dev, clear.clear_color, - clear.clear_depth, - clear.flags); - - return retcode; -} - -int mga_swap_bufs(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_mga_swap_t swap; - int retcode = 0; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - copy_from_user_ret(&swap, (drm_mga_swap_t *)arg, - sizeof(swap), -EFAULT); - - retcode = mgaSwapBuffers(dev, swap.flags); - - return retcode; -} - -int mga_iload(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_mga_iload_t iload; - int retcode = 0; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, - sizeof(iload), -EFAULT); - - retcode = mgaIload(dev, &iload); - - return retcode; -} - - -int mga_dma(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_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_dma_t d; - - copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT); - DRM_DEBUG("%d %d: %d send, %d req\n", - current->pid, d.context, d.send_count, d.request_count); - - /* Per-context queues are unworkable if you are trying to do - * state management from the client. - */ - d.context = DRM_KERNEL_CONTEXT; - d.flags &= ~_DRM_DMA_WHILE_LOCKED; - - /* Maybe multiple buffers is useful for iload... - * But this ioctl is only for *despatching* vertex data... - */ - if (d.send_count < 0 || d.send_count > 1) { - DRM_ERROR("Process %d trying to send %d buffers (max 1)\n", - current->pid, d.send_count); - return -EINVAL; - } - - - /* But it *is* used to request buffers for all types of dma: - */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { - DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count); - return -EINVAL; - } - - if (d.send_count) { - int idx = d.send_indices[0]; - drm_mga_buf_priv_t *buf_priv = dma->buflist[ idx ]->dev_private; - drm_mga_private_t *dev_priv = dev->dev_private; - - buf_priv->dma_type = MGA_DMA_VERTEX; - -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - - /* Snapshot the relevent bits of the sarea... - */ - mgaCopyAndVerifyState( dev_priv, buf_priv ); - - atomic_inc(&dev_priv->pending_bufs); - retcode = drm_dma_enqueue(dev, &d); - if(retcode != 0) - atomic_dec(&dev_priv->pending_bufs); - mga_dma_schedule(dev, 1); - } - - d.granted_count = 0; - - if (!retcode && d.request_count) { - retcode = drm_dma_get_buffers(dev, &d); - } - - DRM_DEBUG("%d returning, granted = %d\n", - current->pid, d.granted_count); - copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); - - return retcode; -} diff --git a/linux/mga_dma.c b/linux/mga_dma.c index 70cd98b1..371706f4 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -24,18 +24,16 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Jeff Hartmann <jhartmann@precisioninsight.com> - * Keith Whitwell <keithw@precisioninsight.com> + * Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_dma.c,v 1.1 2000/02/11 17:26:07 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" #include <linux/interrupt.h> /* For task queue support */ @@ -53,28 +51,28 @@ static int mga_flush_queue(drm_device_t *dev); static unsigned long mga_alloc_page(drm_device_t *dev) { - unsigned long address; + unsigned long address; - address = __get_free_page(GFP_KERNEL); - if(address == 0UL) { - return 0; - } - atomic_inc(&mem_map[MAP_NR((void *) address)].count); - set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); + address = __get_free_page(GFP_KERNEL); + if(address == 0UL) { + return 0; + } + atomic_inc(&mem_map[MAP_NR((void *) address)].count); + set_bit(PG_locked, &mem_map[MAP_NR((void *) address)].flags); - return address; + return address; } static void mga_free_page(drm_device_t *dev, unsigned long page) { - if(page == 0UL) { - return; - } - atomic_dec(&mem_map[MAP_NR((void *) page)].count); - clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); - wake_up(&mem_map[MAP_NR((void *) page)].wait); - free_page(page); - return; + if(page == 0UL) { + return; + } + atomic_dec(&mem_map[MAP_NR((void *) page)].count); + clear_bit(PG_locked, &mem_map[MAP_NR((void *) page)].flags); + wake_up(&mem_map[MAP_NR((void *) page)].wait); + free_page(page); + return; } static void mga_delay(void) @@ -90,6 +88,7 @@ static void mga_flush_write_combine(void) " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" " pop %%eax" : /* no outputs */ : /* no inputs */ ); } + /* These are two age tags that will never be sent to * the hardware */ #define MGA_BUF_USED 0xffffffff @@ -132,17 +131,18 @@ static int mga_freelist_init(drm_device_t *dev) item->prev = dev_priv->head; item->next = dev_priv->head->next; if(dev_priv->head->next != NULL) - dev_priv->head->next->prev = item; + dev_priv->head->next->prev = item; if(item->next == NULL) dev_priv->tail = item; item->buf = buf; buf_priv->my_freelist = item; + buf_priv->discard = 0; dev_priv->head->next = item; } item = dev_priv->head; while(item) { - mga_freelist_debug(item); - item = item->next; + mga_freelist_debug(item); + item = item->next; } DRM_DEBUG("Head\n"); mga_freelist_debug(dev_priv->head); @@ -162,70 +162,53 @@ static void mga_freelist_cleanup(drm_device_t *dev) while(item) { prev = item; item = item->next; - drm_free(prev, - sizeof(drm_mga_freelist_t), - DRM_MEM_DRIVER); + drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); } dev_priv->head = dev_priv->tail = NULL; } -static int __gettimeinmillis(void) -{ - int millis; - - millis = ((jiffies / HZ) * 1000) + ((jiffies % HZ) * (1000 / HZ)); - return millis; -} - /* Frees dispatch lock */ static inline void mga_dma_quiescent(drm_device_t *dev) { - drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - __volatile__ unsigned int *status = - (__volatile__ unsigned int *)dev_priv->status_page; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; - int i; - + drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + __volatile__ unsigned int *status = + (__volatile__ unsigned int *)dev_priv->status_page; + unsigned long end; + int i; + + end = jiffies + (HZ*3); while(1) { - if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) { - break; - } - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup\n"); - goto out_nolock; - } - for (i = 0 ; i < 2000 ; i++) mga_delay(); + if(!test_and_set_bit(0, &dev_priv->dispatch_lock)) { + break; + } + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup\n"); + goto out_nolock; + } + for (i = 0 ; i < 2000 ; i++) mga_delay(); } - startTime = 0; - + end = jiffies + (HZ*3); DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS)); while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup\n"); - goto out_status; - } - for (i = 0 ; i < 2000 ; i++) mga_delay(); + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup\n"); + goto out_status; + } + for (i = 0 ; i < 2000 ; i++) mga_delay(); } DRM_DEBUG("status[1] : %x last_sync_tag : %x\n", status[1], - dev_priv->last_sync_tag); + dev_priv->last_sync_tag); sarea_priv->dirty |= MGA_DMA_FLUSH; + out_status: clear_bit(0, &dev_priv->dispatch_lock); out_nolock: @@ -254,9 +237,9 @@ unsigned int mga_create_sync_tag(drm_device_t *dev) mga_dma_quiescent(dev); for (i = 0; i < dma->buf_count; i++) { - buf = dma->buflist[ i ]; - buf_priv = buf->dev_private; - buf_priv->my_freelist->age = MGA_BUF_FREE; + buf = dma->buflist[ i ]; + buf_priv = buf->dev_private; + buf_priv->my_freelist->age = MGA_BUF_FREE; } dev_priv->sync_tag = FREELIST_INITIAL; @@ -277,14 +260,12 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev) { drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; __volatile__ unsigned int *status = (__volatile__ unsigned int *)dev_priv->status_page; drm_mga_freelist_t *prev; drm_mga_freelist_t *next; if((dev_priv->tail->age >> 2) <= FREELIST_COMPARE(status[1])) { - drm_mga_buf_priv_t *buf_priv; prev = dev_priv->tail->prev; next = dev_priv->tail; prev->next = NULL; @@ -293,13 +274,7 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev) next->age = MGA_BUF_USED; return next->buf; } -#if 0 - else { - mga_freelist_debug(dev_priv->tail); - DRM_DEBUG("sarea->last_dispatch %x\n", sarea_priv->last_dispatch); - mga_freelist_debug(dev_priv->tail->prev); - } -#endif + return NULL; } @@ -313,26 +288,26 @@ int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf) drm_mga_freelist_t *next; if(buf_priv->my_freelist->age == MGA_BUF_USED) { - /* Discarded buffer, put it on the tail */ - next = buf_priv->my_freelist; - next->age = MGA_BUF_FREE; - prev = dev_priv->tail; - prev->next = next; - next->prev = prev; - next->next = NULL; - dev_priv->tail = next; - DRM_DEBUG("Discarded\n"); + /* Discarded buffer, put it on the tail */ + next = buf_priv->my_freelist; + next->age = MGA_BUF_FREE; + prev = dev_priv->tail; + prev->next = next; + next->prev = prev; + next->next = NULL; + dev_priv->tail = next; + DRM_DEBUG("Discarded\n"); } else { - /* Normally aged buffer, put it on the head + 1, - * as the real head is a sentinal element - */ - next = buf_priv->my_freelist; - head = dev_priv->head; - prev = head->next; - head->next = next; - prev->prev = next; - next->prev = head; - next->next = prev; + /* Normally aged buffer, put it on the head + 1, + * as the real head is a sentinal element + */ + next = buf_priv->my_freelist; + head = dev_priv->head; + prev = head->next; + head->next = next; + prev->prev = next; + next->prev = head; + next->next = prev; } return 0; @@ -346,17 +321,22 @@ static void mga_print_all_primary(drm_device_t *dev) DRM_DEBUG("Full list of primarys\n"); for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { - prim = dev_priv->prim_bufs[i]; - DRM_DEBUG("index : %d num_dwords : %d max_dwords : %d phy_head : %lx\n", - prim->idx, prim->num_dwords, prim->max_dwords, prim->phys_head); - DRM_DEBUG("sec_used : %d swap_pending : %x in_use : %lx force_fire : %d\n", - prim->sec_used, prim->swap_pending, prim->in_use, atomic_read(&prim->force_fire)); - DRM_DEBUG("needs_overflow : %d\n", atomic_read(&prim->needs_overflow)); + prim = dev_priv->prim_bufs[i]; + DRM_DEBUG("index : %d num_dwords : %d " + "max_dwords : %d phy_head : %x\n", + prim->idx, prim->num_dwords, + prim->max_dwords, prim->phys_head); + DRM_DEBUG("sec_used : %d swap_pending : %x " + "in_use : %x force_fire : %d\n", + prim->sec_used, prim->swap_pending, + prim->in_use, atomic_read(&prim->force_fire)); + DRM_DEBUG("needs_overflow : %d\n", + atomic_read(&prim->needs_overflow)); } DRM_DEBUG("current_idx : %d, next_idx : %d, last_idx : %d\n", - dev_priv->next_prim->idx, dev_priv->last_prim->idx, - dev_priv->current_prim->idx); + dev_priv->next_prim->idx, dev_priv->last_prim->idx, + dev_priv->current_prim->idx); } static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) @@ -376,16 +356,15 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) (MGA_NUM_PRIM_BUFS + 1), DRM_MEM_DRIVER); if(dev_priv->prim_bufs == NULL) { - DRM_ERROR("Unable to allocate memory for prim_buf\n"); - return -ENOMEM; + DRM_ERROR("Unable to allocate memory for prim_buf\n"); + return -ENOMEM; } DRM_DEBUG("memset\n"); memset(dev_priv->prim_bufs, 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1)); temp = init->warp_ucode_size + dev_priv->primary_size; - temp = ((temp + PAGE_SIZE - 1) / - PAGE_SIZE) * PAGE_SIZE; + temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; DRM_DEBUG("temp : %x\n", temp); DRM_DEBUG("dev->agp->base: %lx\n", dev->agp->base); @@ -402,13 +381,17 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) { DRM_DEBUG("For loop\n"); - prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), DRM_MEM_DRIVER); + prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t), + DRM_MEM_DRIVER); if(prim_buffer == NULL) return -ENOMEM; DRM_DEBUG("memset\n"); memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t)); prim_buffer->phys_head = offset + dev->agp->base; - prim_buffer->current_dma_ptr = prim_buffer->head = (u32 *) - (dev_priv->ioremap + (offset - init->reserved_map_agpstart)); + prim_buffer->current_dma_ptr = + prim_buffer->head = + (u32 *) (dev_priv->ioremap + + offset - + init->reserved_map_agpstart); prim_buffer->num_dwords = 0; prim_buffer->max_dwords = size_of_buf / sizeof(u32); prim_buffer->max_dwords -= 5; /* Leave room for the softrap */ @@ -419,7 +402,9 @@ static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init) DRM_DEBUG("Looping\n"); } dev_priv->current_prim_idx = 0; - dev_priv->next_prim = dev_priv->last_prim = dev_priv->current_prim = + dev_priv->next_prim = + dev_priv->last_prim = + dev_priv->current_prim = dev_priv->prim_bufs[0]; set_bit(0, &dev_priv->current_prim->in_use); DRM_DEBUG("init done\n"); @@ -432,9 +417,7 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) drm_device_dma_t *dma = dev->dma; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; int use_agp = PDEA_pagpxfer_enable; - int startTime = 0; - int curTime = 0; - int timeout_millis = 3000; + unsigned long end; int i; int next_idx; PRIMLOCALS; @@ -446,8 +429,8 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) /* We never check for overflow, b/c there is always room */ PRIMPTR(prim); if(num_dwords <= 0) { - DRM_DEBUG("num_dwords == 0 when dispatched\n"); - goto out_prim_wait; + DRM_DEBUG("num_dwords == 0 when dispatched\n"); + goto out_prim_wait; } PRIMOUTREG( MGAREG_DMAPAD, 0); PRIMOUTREG( MGAREG_DMAPAD, 0); @@ -455,39 +438,36 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) PRIMOUTREG( MGAREG_SOFTRAP, 0); PRIMFINISH(prim); + end = jiffies + (HZ*3); if(sarea_priv->dirty & MGA_DMA_FLUSH) { - DRM_DEBUG("Dma top flush\n"); - while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup in fire primary (Dma Top Flush)\n"); - goto out_prim_wait; - } + DRM_DEBUG("Dma top flush\n"); + while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) { + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup in fire primary " + "(Dma Top Flush)\n"); + goto out_prim_wait; + } - for (i = 0 ; i < 4096 ; i++) mga_delay(); - } - sarea_priv->dirty &= ~(MGA_DMA_FLUSH); + for (i = 0 ; i < 4096 ; i++) mga_delay(); + } + sarea_priv->dirty &= ~(MGA_DMA_FLUSH); } else { - DRM_DEBUG("Status wait\n"); - while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) { - curTime = __gettimeinmillis(); - if (startTime == 0 || curTime < startTime /*wrap case*/) { - startTime = curTime; - } else if (curTime - startTime > timeout_millis) { - DRM_ERROR("irqs: %d wanted %d\n", - atomic_read(&dev->total_irq), - atomic_read(&dma->total_lost)); - DRM_ERROR("lockup in fire primary (Status Wait)\n"); - goto out_prim_wait; - } + DRM_DEBUG("Status wait\n"); + while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) { + if((signed)(end - jiffies) <= 0) { + DRM_ERROR("irqs: %d wanted %d\n", + atomic_read(&dev->total_irq), + atomic_read(&dma->total_lost)); + DRM_ERROR("lockup in fire primary " + "(Status Wait)\n"); + goto out_prim_wait; + } - for (i = 0 ; i < 4096 ; i++) mga_delay(); - } + for (i = 0 ; i < 4096 ; i++) mga_delay(); + } } mga_flush_write_combine(); @@ -495,27 +475,23 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim) atomic_inc(&dma->total_lost); MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL); MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); - DRM_DEBUG("Primarys at fire\n"); prim->num_dwords = 0; next_idx = prim->idx + 1; - if(next_idx >= MGA_NUM_PRIM_BUFS) { - next_idx = 0; - } - dev_priv->next_prim = dev_priv->prim_bufs[next_idx]; + if(next_idx >= MGA_NUM_PRIM_BUFS) + next_idx = 0; -/* mga_print_all_primary(dev); */ + dev_priv->next_prim = dev_priv->prim_bufs[next_idx]; return; -out_prim_wait: - { - prim->num_dwords = 0; - prim->sec_used = 0; - clear_bit(0, &prim->in_use); - clear_bit(0, &prim->swap_pending); - clear_bit(0, &dev_priv->dispatch_lock); - atomic_dec(&dev_priv->pending_bufs); - } + out_prim_wait: + prim->num_dwords = 0; + prim->sec_used = 0; + clear_bit(0, &prim->in_use); + wake_up_interruptible(&dev_priv->wait_queue); + clear_bit(0, &prim->swap_pending); + clear_bit(0, &dev_priv->dispatch_lock); + atomic_dec(&dev_priv->pending_bufs); } int mga_advance_primary(drm_device_t *dev) @@ -579,29 +555,37 @@ static inline int mga_decide_to_fire(drm_device_t *dev) drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_device_dma_t *dma = dev->dma; - if(atomic_read(&dev_priv->next_prim->force_fire) || - (atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords)) { + if(atomic_read(&dev_priv->next_prim->force_fire)) + { atomic_inc(&dma->total_prio); return 1; - } - if(atomic_read(&dev_priv->pending_bufs) <= (MGA_NUM_PRIM_BUFS - 1)) { - - if(test_bit(0, &dev_priv->next_prim->swap_pending)) { - atomic_inc(&dma->total_dmas); - return 1; - } } - if(atomic_read(&dev_priv->pending_bufs) <= (MGA_NUM_PRIM_BUFS / 2)) { - if(dev_priv->next_prim->sec_used >= (MGA_DMA_BUF_NR / 8)) { - atomic_inc(&dma->total_hit); - return 1; - } + + if (atomic_read(&dev_priv->in_flush) && dev_priv->next_prim->num_dwords) + { + atomic_inc(&dma->total_prio); + return 1; + } + + if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) { + if(test_bit(0, &dev_priv->next_prim->swap_pending)) { + atomic_inc(&dma->total_dmas); + return 1; + } } - if(atomic_read(&dev_priv->pending_bufs) >= (MGA_NUM_PRIM_BUFS / 2)) { - if(dev_priv->next_prim->sec_used >= (MGA_DMA_BUF_NR / 4)) { - atomic_inc(&dma->total_missed_free); - return 1; - } + + if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) { + if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) { + atomic_inc(&dma->total_hit); + return 1; + } + } + + if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) { + if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) { + atomic_inc(&dma->total_missed_free); + return 1; + } } atomic_inc(&dma->total_tried); @@ -622,12 +606,11 @@ int mga_dma_schedule(drm_device_t *dev, int locked) if(atomic_read(&dev_priv->in_flush) || atomic_read(&dev_priv->in_wait)) { - locked = 1; + locked = 1; } if (!locked && - !drm_lock_take(&dev->lock.hw_lock->lock, - DRM_KERNEL_CONTEXT)) { + !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { atomic_inc(&dma->total_missed_lock); clear_bit(0, &dev->dma_flag); return -EBUSY; @@ -643,17 +626,17 @@ int mga_dma_schedule(drm_device_t *dev, int locked) atomic_set(&dev_priv->next_prim->force_fire, 0); if(dev_priv->current_prim == dev_priv->next_prim && dev_priv->next_prim->num_dwords != 0) { - /* Schedule overflow for a later time */ - atomic_set(&dev_priv->current_prim->needs_overflow, - 1); + /* Schedule overflow for a later time */ + atomic_set( + &dev_priv->current_prim->needs_overflow, + 1); } - mga_fire_primary(dev, - dev_priv->next_prim); + mga_fire_primary(dev, dev_priv->next_prim); } else { - clear_bit(0, &dev_priv->dispatch_lock); + clear_bit(0, &dev_priv->dispatch_lock); } } else { - DRM_DEBUG("I can't get the dispatch lock\n"); + DRM_DEBUG("I can't get the dispatch lock\n"); } if (!locked) { @@ -691,6 +674,7 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs) last_prim_buffer->num_dwords = 0; last_prim_buffer->sec_used = 0; clear_bit(0, &last_prim_buffer->in_use); + wake_up_interruptible(&dev_priv->wait_queue); clear_bit(0, &last_prim_buffer->swap_pending); clear_bit(0, &dev_priv->dispatch_lock); atomic_dec(&dev_priv->pending_bufs); @@ -702,10 +686,8 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs) static void mga_dma_task_queue(void *device) { drm_device_t *dev = (drm_device_t *) device; - drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; mga_dma_schedule(dev, 0); - wake_up_interruptible(&dev_priv->wait_queue); } int mga_dma_cleanup(drm_device_t *dev) @@ -805,53 +787,58 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { dev_priv->mAccess); memcpy(&dev_priv->WarpIndex, &init->WarpIndex, - sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); + sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES); for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) - DRM_DEBUG("warp pipe %d: installed: %d phys_addr: %lx size: %x\n", - i, - dev_priv->WarpIndex[i].installed, - dev_priv->WarpIndex[i].phys_addr, - dev_priv->WarpIndex[i].size); + DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n", + i, + dev_priv->WarpIndex[i].installed, + dev_priv->WarpIndex[i].phys_addr, + dev_priv->WarpIndex[i].size); DRM_DEBUG("Doing init prim buffers\n"); if(mga_init_primary_bufs(dev, init) != 0) { - DRM_ERROR("Can not initialize primary buffers\n"); - mga_dma_cleanup(dev); - return -ENOMEM; + DRM_ERROR("Can not initialize primary buffers\n"); + mga_dma_cleanup(dev); + return -ENOMEM; } DRM_DEBUG("Done with init prim buffers\n"); dev_priv->real_status_page = mga_alloc_page(dev); if(dev_priv->real_status_page == 0UL) { - mga_dma_cleanup(dev); - DRM_ERROR("Can not allocate status page\n"); - return -ENOMEM; + mga_dma_cleanup(dev); + DRM_ERROR("Can not allocate status page\n"); + return -ENOMEM; } DRM_DEBUG("Status page at %lx\n", dev_priv->real_status_page); - dev_priv->status_page = ioremap_nocache(virt_to_bus((void *) dev_priv->real_status_page), - PAGE_SIZE); + + dev_priv->status_page = + ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page), + PAGE_SIZE); + if(dev_priv->status_page == NULL) { - mga_dma_cleanup(dev); - DRM_ERROR("Can not remap status page\n"); - return -ENOMEM; + mga_dma_cleanup(dev); + DRM_ERROR("Can not remap status page\n"); + return -ENOMEM; } DRM_DEBUG("Status page remapped to %p\n", dev_priv->status_page); /* Write status page when secend or softrap occurs */ - MGA_WRITE(MGAREG_PRIMPTR, virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); + MGA_WRITE(MGAREG_PRIMPTR, + virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); dev_priv->device = pci_find_device(0x102b, 0x0525, NULL); if(dev_priv->device == NULL) { - DRM_ERROR("Could not find pci device for card\n"); - mga_dma_cleanup(dev); - return -EINVAL; + DRM_ERROR("Could not find pci device for card\n"); + mga_dma_cleanup(dev); + return -EINVAL; } DRM_DEBUG("dma initialization\n"); /* Private is now filled in, initialize the hardware */ { - __volatile__ unsigned int *status = (unsigned int *)dev_priv->status_page; + __volatile__ unsigned int *status = + (unsigned int *)dev_priv->status_page; PRIMLOCALS; PRIMGETPTR( dev_priv ); @@ -1004,11 +991,11 @@ static int mga_flush_queue(drm_device_t *dev) add_wait_queue(&dev_priv->flush_queue, &entry); for (;;) { mga_dma_schedule(dev, 0); - if (atomic_read(&dev_priv->in_flush) == 0 || - dev_priv->next_prim->num_dwords == 0) break; + if (atomic_read(&dev_priv->in_flush) == 0) + break; atomic_inc(&dev->total_sleeps); DRM_DEBUG("Schedule in flush_queue\n"); - schedule_timeout(HZ/60); + schedule_timeout(HZ*3); if (signal_pending(current)) { ret = -EINTR; /* Can't restart */ break; @@ -1029,6 +1016,7 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid) if (!dma) return; if(dev->dev_private == NULL) return; + if(dma->buflist == NULL) return; mga_flush_queue(dev); @@ -1036,10 +1024,10 @@ void mga_reclaim_buffers(drm_device_t *dev, pid_t pid) drm_buf_t *buf = dma->buflist[ i ]; drm_mga_buf_priv_t *buf_priv = buf->dev_private; - if (buf->pid == pid) { - if(buf_priv == NULL) return; - /* Only buffers that need to get reclaimed ever - * get set to free */ + /* Only buffers that need to get reclaimed ever + * get set to free + */ + if (buf->pid == pid && buf_priv) { if(buf_priv->my_freelist->age == MGA_BUF_USED) buf_priv->my_freelist->age = MGA_BUF_FREE; } @@ -1121,7 +1109,6 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; drm_lock_t lock; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; @@ -1130,23 +1117,36 @@ int mga_flush_ioctl(struct inode *inode, struct file *filp, int i; copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT); - + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_flush_ioctl called without lock held\n"); + return -EINVAL; + } + if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) { - mga_flush_queue(dev); - if((MGA_READ(MGAREG_STATUS) & 0x00030001) == 0x00020000 && - status[1] != dev_priv->last_sync_tag) { - DRM_DEBUG("Reseting hardware status\n"); - MGA_WRITE(MGAREG_DWGSYNC, dev_priv->last_sync_tag); - while(MGA_READ(MGAREG_DWGSYNC) != dev_priv->last_sync_tag) { - for(i = 0; i < 4096; i++) mga_delay(); - } - status[1] = sarea_priv->last_dispatch = dev_priv->last_sync_tag; - } else { - sarea_priv->last_dispatch = status[1]; - } + mga_flush_queue(dev); + + if((MGA_READ(MGAREG_STATUS) & 0x00030001) == 0x00020000 && + status[1] != dev_priv->last_sync_tag) + { + DRM_DEBUG("Reseting hardware status\n"); + MGA_WRITE(MGAREG_DWGSYNC, dev_priv->last_sync_tag); + + while(MGA_READ(MGAREG_DWGSYNC) != + dev_priv->last_sync_tag) + { + for(i = 0; i < 4096; i++) mga_delay(); + } + + status[1] = + sarea_priv->last_dispatch = + dev_priv->last_sync_tag; + } else { + sarea_priv->last_dispatch = status[1]; + } } if(lock.flags & _DRM_LOCK_QUIESCENT) { - mga_dma_quiescent(dev); + mga_dma_quiescent(dev); } return 0; diff --git a/linux/mga_dma.h b/linux/mga_dma.h deleted file mode 100644 index 97d83005..00000000 --- a/linux/mga_dma.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef MGA_DMA_H -#define MGA_DMA_H - -#include "mga_drm_public.h" -typedef enum { - TT_GENERAL, - TT_BLIT, - TT_VECTOR, - TT_VERTEX -} transferType_t; - -typedef struct { - drm_mga_freelist_t *my_freelist; -} drm_mga_buf_priv_t; - -#define MGA_DMA_GENERAL 0 /* not used */ -#define MGA_DMA_VERTEX 1 -#define MGA_DMA_SETUP 2 -#define MGA_DMA_ILOAD 3 -#define MGA_DMA_CLEAR 4 /* placeholder */ -#define MGA_DMA_SWAP 5 /* placeholder */ -#define MGA_DMA_DISCARD 6 - -#define DWGREG0 0x1c00 -#define DWGREG0_END 0x1dff -#define DWGREG1 0x2c00 -#define DWGREG1_END 0x2dff - -#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) -#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) -#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) -#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) - -#define MGA_VERBOSE 0 - -#define MGA_NUM_PRIM_BUFS 8 -/* Primary buffer versions of above -- pretty similar really. - */ - -#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ - int outcount, num_dwords - -#define PRIM_OVERFLOW(dev, dev_priv, length) do { \ -drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ -if( (tmp_buf->max_dwords - tmp_buf->num_dwords) < length || \ -tmp_buf->sec_used > (MGA_DMA_BUF_NR / 2)) { \ - atomic_set(&tmp_buf->force_fire, 1); \ - mga_advance_primary(dev); \ - mga_dma_schedule(dev, 1); \ - } else if( atomic_read(&tmp_buf->needs_overflow)) { \ - mga_advance_primary(dev); \ - mga_dma_schedule(dev, 1); \ -} \ -} while(0) - -#define PRIMGETPTR(dev_priv) do { \ -drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ -if(MGA_VERBOSE) \ -DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \ -dma_ptr = tmp_buf->current_dma_ptr; \ -num_dwords = tmp_buf->num_dwords; \ -phys_head = tmp_buf->phys_head; \ -outcount = 0; \ -} while(0) - -#define PRIMPTR(prim_buf) do { \ -if(MGA_VERBOSE) \ -DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \ -dma_ptr = prim_buf->current_dma_ptr; \ -num_dwords = prim_buf->num_dwords; \ -phys_head = prim_buf->phys_head; \ -outcount = 0; \ -} while(0) - -#define PRIMFINISH(prim_buf) do { \ - if (MGA_VERBOSE) { \ - DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \ - if (outcount & 3) \ - DRM_DEBUG(" --- truncation\n"); \ - } \ - prim_buf->num_dwords = num_dwords; \ - prim_buf->current_dma_ptr = dma_ptr; \ -} while(0) - -#define PRIMADVANCE(dev_priv) do { \ -drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - if (MGA_VERBOSE) { \ - DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \ - if (outcount & 3) \ - DRM_DEBUG(" --- truncation\n"); \ - } \ - tmp_buf->num_dwords = num_dwords; \ - tmp_buf->current_dma_ptr = dma_ptr; \ -} while (0) - -#define PRIMUPDATE(dev_priv) do { \ -drm_mga_prim_buf_t *tmp_buf = \ - dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ - tmp_buf->sec_used++; \ -} while (0) - -#define PRIMOUTREG(reg, val) do { \ - tempIndex[outcount]=ADRINDEX(reg); \ - dma_ptr[1+outcount] = val; \ - if (MGA_VERBOSE) \ - DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \ - num_dwords + 1 + outcount, ADRINDEX(reg), val); \ - if( ++outcount == 4) { \ - outcount = 0; \ - dma_ptr[0] = *(u32 *)tempIndex; \ - dma_ptr+=5; \ - num_dwords += 5; \ - } \ -}while (0) - -#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ - DC_solid_enable | DC_transc_enable) - - -#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ - DC_solid_disable | DC_arzero_disable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ - DC_pattern_disable | DC_transc_disable | \ - DC_clipdis_enable) \ - -#endif diff --git a/linux/mga_drm_public.h b/linux/mga_drm.h index 0e91656c..12a858e7 100644 --- a/linux/mga_drm_public.h +++ b/linux/mga_drm.h @@ -1,4 +1,4 @@ -/* mga_drm_public.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- +/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*- * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -26,12 +26,17 @@ * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drm_public.h,v 1.1 2000/02/11 17:26:07 dawes Exp $ + * $XFree86$ */ -#ifndef _MGA_DRM_PUBLIC_H_ -#define _MGA_DRM_PUBLIC_H_ +#ifndef _MGA_DRM_H_ +#define _MGA_DRM_H_ +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmMga.h) + */ +#ifndef _MGA_DEFINES_ +#define _MGA_DEFINES_ #define MGA_F 0x1 /* fog */ #define MGA_A 0x2 /* alpha */ #define MGA_S 0x4 /* specular */ @@ -61,52 +66,10 @@ #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 - - -typedef struct _drm_mga_warp_index { - int installed; - unsigned long phys_addr; - int size; -} mgaWarpIndex; - -typedef struct drm_mga_init { - enum { - MGA_INIT_DMA = 0x01, - MGA_CLEANUP_DMA = 0x02 - } func; - int reserved_map_agpstart; - int reserved_map_idx; - int buffer_map_idx; - int sarea_priv_offset; - int primary_size; - int warp_ucode_size; - int frontOffset; - int backOffset; - int depthOffset; - int textureOffset; - int textureSize; - int agpTextureOffset; - int agpTextureSize; - int cpp; - int stride; - int sgram; - int chipset; - mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES]; - int mAccess; -} drm_mga_init_t; - -typedef struct _xf86drmClipRectRec { - unsigned short x1; - unsigned short y1; - unsigned short x2; - unsigned short y2; -} xf86drmClipRectRec; - #define MGA_FRONT 0x1 #define MGA_BACK 0x2 #define MGA_DEPTH 0x4 - /* 3d state excluding texture units: */ #define MGA_CTXREG_DSTORG 0 /* validated */ @@ -155,42 +118,72 @@ typedef struct _xf86drmClipRectRec { #define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock quiescent */ - /* 64 buffers of 16k each, total 1 meg. */ #define MGA_DMA_BUF_ORDER 14 #define MGA_DMA_BUF_SZ (1<<MGA_DMA_BUF_ORDER) #define MGA_DMA_BUF_NR 63 - /* Keep these small for testing. */ #define MGA_NR_SAREA_CLIPRECTS 8 - - /* 2 heaps (1 for card, 1 for agp), each divided into upto 128 * regions, subject to a minimum region size of (1<<16) == 64k. * * Clients may subdivide regions internally, but when sharing between * clients, the region size is the minimum granularity. */ + #define MGA_CARD_HEAP 0 #define MGA_AGP_HEAP 1 #define MGA_NR_TEX_HEAPS 2 #define MGA_NR_TEX_REGIONS 16 #define MGA_LOG_MIN_TEX_REGION_SIZE 16 +#endif + +typedef struct _drm_mga_warp_index { + int installed; + unsigned long phys_addr; + int size; +} drm_mga_warp_index_t; + +typedef struct drm_mga_init { + enum { + MGA_INIT_DMA = 0x01, + MGA_CLEANUP_DMA = 0x02 + } func; + int reserved_map_agpstart; + int reserved_map_idx; + int buffer_map_idx; + int sarea_priv_offset; + int primary_size; + int warp_ucode_size; + int frontOffset; + int backOffset; + int depthOffset; + int textureOffset; + int textureSize; + int agpTextureOffset; + int agpTextureSize; + int cpp; + int stride; + int sgram; + int chipset; + drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES]; + int mAccess; +} drm_mga_init_t; + +/* Warning: if you change the sarea structure, you must change the Xserver + * structures as well */ -typedef struct { +typedef struct _drm_mga_tex_region { unsigned char next, prev; unsigned char in_use; int age; -} mgaTexRegion; - - +} drm_mga_tex_region_t; -typedef struct -{ +typedef struct _drm_mga_sarea { /* The channel for communication of state information to the kernel * on firing a vertex dma buffer. */ @@ -201,7 +194,7 @@ typedef struct unsigned int dirty; unsigned int nbox; - xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; + drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS]; /* Information about the most recently used 3d drawable. The @@ -222,7 +215,7 @@ typedef struct unsigned int exported_nback; int exported_back_x, exported_front_x, exported_w; int exported_back_y, exported_front_y, exported_h; - xf86drmClipRectRec exported_boxes[MGA_NR_SAREA_CLIPRECTS]; + drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS]; /* Counters for aging textures and for client-side throttling. */ @@ -233,58 +226,36 @@ typedef struct /* LRU lists for texture memory in agp space and on the card */ - mgaTexRegion texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; - unsigned int texAge[MGA_NR_TEX_HEAPS]; + drm_mga_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1]; + unsigned int texAge[MGA_NR_TEX_HEAPS]; /* Mechanism to validate card state. */ - int ctxOwner; - - + int ctxOwner; } drm_mga_sarea_t; - /* Device specific ioctls: */ -typedef struct { - int idx; +typedef struct _drm_mga_clear { int clear_color; int clear_depth; int flags; } drm_mga_clear_t; -typedef struct { - int idx; +typedef struct _drm_mga_swap { + int dummy; } drm_mga_swap_t; -typedef struct { - unsigned int destOrg; +typedef struct _drm_mga_iload { int idx; int length; + unsigned int destOrg; } drm_mga_iload_t; - -/* These may be placeholders if we have more cliprects than - * MGA_NR_SAREA_CLIPRECTS. In that case, idx != real_idx; idx is - * the number of a bogus buffer, real_idx is the real buffer to be - * rendered multiple times. - * - * This is a hack to work around assumptions built into the drm, and - * may shortly be removed. - */ -typedef struct { - int idx; /* buffer to queue and free on completion */ - int real_idx; /* buffer to execute */ - int real_used; /* buf->used in for real buffer */ - int discard; /* */ +typedef struct _drm_mga_vertex { + int idx; /* buffer to queue */ + int used; /* bytes in use */ + int discard; /* client finished with buffer? */ } drm_mga_vertex_t; - -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) - #endif diff --git a/linux/mga_drv.c b/linux/mga_drv.c index 48041354..82dda64d 100644 --- a/linux/mga_drv.c +++ b/linux/mga_drv.c @@ -510,27 +510,86 @@ int mga_release(struct inode *inode, struct file *filp) drm_device_t *dev = priv->dev; int retcode = 0; - DRM_DEBUG("open_count = %d\n", dev->open_count); - if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; - atomic_inc(&dev->total_close); - spin_lock(&dev->count_lock); - if (!--dev->open_count) { - if (atomic_read(&dev->ioctl_count) || dev->blocked) { - DRM_ERROR("Device busy: %d %d\n", - atomic_read(&dev->ioctl_count), - dev->blocked); - spin_unlock(&dev->count_lock); - return -EBUSY; + 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) { + mga_reclaim_buffers(dev, priv->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. */ + } else if (dev->lock.hw_lock) { + /* The lock is required to reclaim buffers */ + DECLARE_WAITQUEUE(entry, current); + add_wait_queue(&dev->lock.lock_queue, &entry); + for (;;) { + if (!dev->lock.hw_lock) { + /* Device has been unregistered */ + retcode = -EINTR; + break; + } + if (drm_lock_take(&dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + dev->lock.pid = priv->pid; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->total_locks); + break; /* Got lock */ + } + /* Contention */ + atomic_inc(&dev->total_sleeps); + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (signal_pending(current)) { + retcode = -ERESTARTSYS; + break; } - spin_unlock(&dev->count_lock); - return mga_takedown(dev); } - spin_unlock(&dev->count_lock); + current->state = TASK_RUNNING; + remove_wait_queue(&dev->lock.lock_queue, &entry); + if(!retcode) { + mga_reclaim_buffers(dev, priv->pid); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + } + } + 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); + MOD_DEC_USE_COUNT; + atomic_inc(&dev->total_close); + spin_lock(&dev->count_lock); + if (!--dev->open_count) { + if (atomic_read(&dev->ioctl_count) || dev->blocked) { + DRM_ERROR("Device busy: %d %d\n", + atomic_read(&dev->ioctl_count), + dev->blocked); + spin_unlock(&dev->count_lock); + return -EBUSY; + } + spin_unlock(&dev->count_lock); + return mga_takedown(dev); } + spin_unlock(&dev->count_lock); return retcode; } + /* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */ int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux/mga_drv.h b/linux/mga_drv.h index 60c00f93..801e707d 100644 --- a/linux/mga_drv.h +++ b/linux/mga_drv.h @@ -24,14 +24,13 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> - * Jeff Hartmann <jhartmann@precisioninsight.com> + * Jeff Hartmann <jhartmann@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_drv.h,v 1.1 2000/02/11 17:26:08 dawes Exp $ + * $XFree86$ */ #ifndef _MGA_DRV_H_ #define _MGA_DRV_H_ -#include "mga_drm_public.h" typedef struct { unsigned int num_dwords; @@ -70,7 +69,7 @@ typedef struct _drm_mga_private { int stride; int sgram; int use_agp; - mgaWarpIndex WarpIndex[MGA_MAX_G400_PIPES]; + drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES]; unsigned int WarpPipe; __volatile__ unsigned long softrap_age; u32 dispatch_lock; @@ -132,6 +131,7 @@ extern unsigned int mga_create_sync_tag(drm_device_t *dev); extern drm_buf_t *mga_freelist_get(drm_device_t *dev); extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf); extern int mga_advance_primary(drm_device_t *dev); +extern void mga_reclaim_buffers(drm_device_t *dev, pid_t pid); /* mga_bufs.c */ @@ -176,13 +176,115 @@ extern int mga_context_switch(drm_device_t *dev, int old, int new); extern int mga_context_switch_complete(drm_device_t *dev, int new); +typedef enum { + TT_GENERAL, + TT_BLIT, + TT_VECTOR, + TT_VERTEX +} transferType_t; + +typedef struct { + drm_mga_freelist_t *my_freelist; + int discard; +} drm_mga_buf_priv_t; + +#define DWGREG0 0x1c00 +#define DWGREG0_END 0x1dff +#define DWGREG1 0x2c00 +#define DWGREG1_END 0x2dff + +#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END) +#define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2) +#define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80) +#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r)) + +#define MGA_VERBOSE 0 +#define MGA_NUM_PRIM_BUFS 8 + +#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ + int outcount, num_dwords + +#define PRIM_OVERFLOW(dev, dev_priv, length) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \ + tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \ + atomic_set(&tmp_buf->force_fire, 1); \ + mga_advance_primary(dev); \ + mga_dma_schedule(dev, 1); \ + } else if( atomic_read(&tmp_buf->needs_overflow)) { \ + mga_advance_primary(dev); \ + mga_dma_schedule(dev, 1); \ + } \ +} while(0) + +#define PRIMGETPTR(dev_priv) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if(MGA_VERBOSE) \ + DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \ + dma_ptr = tmp_buf->current_dma_ptr; \ + num_dwords = tmp_buf->num_dwords; \ + phys_head = tmp_buf->phys_head; \ + outcount = 0; \ +} while(0) + +#define PRIMPTR(prim_buf) do { \ + if(MGA_VERBOSE) \ + DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \ + dma_ptr = prim_buf->current_dma_ptr; \ + num_dwords = prim_buf->num_dwords; \ + phys_head = prim_buf->phys_head; \ + outcount = 0; \ +} while(0) + +#define PRIMFINISH(prim_buf) do { \ + if (MGA_VERBOSE) { \ + DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \ + if (outcount & 3) \ + DRM_DEBUG(" --- truncation\n"); \ + } \ + prim_buf->num_dwords = num_dwords; \ + prim_buf->current_dma_ptr = dma_ptr; \ +} while(0) + +#define PRIMADVANCE(dev_priv) do { \ +drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + if (MGA_VERBOSE) { \ + DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \ + if (outcount & 3) \ + DRM_DEBUG(" --- truncation\n"); \ + } \ + tmp_buf->num_dwords = num_dwords; \ + tmp_buf->current_dma_ptr = dma_ptr; \ +} while (0) + +#define PRIMUPDATE(dev_priv) do { \ + drm_mga_prim_buf_t *tmp_buf = \ + dev_priv->prim_bufs[dev_priv->current_prim_idx]; \ + tmp_buf->sec_used++; \ +} while (0) + +#define PRIMOUTREG(reg, val) do { \ + tempIndex[outcount]=ADRINDEX(reg); \ + dma_ptr[1+outcount] = val; \ + if (MGA_VERBOSE) \ + DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \ + num_dwords + 1 + outcount, ADRINDEX(reg), val); \ + if( ++outcount == 4) { \ + outcount = 0; \ + dma_ptr[0] = *(u32 *)tempIndex; \ + dma_ptr+=5; \ + num_dwords += 5; \ + } \ +}while (0) + +/* A reduced set of the mga registers. + */ #define MGAREG_MGA_EXEC 0x0100 -#define MGAREG_AGP_PLL 0x1e4c #define MGAREG_ALPHACTRL 0x2c7c -#define MGAREG_ALPHASTART 0x2c70 -#define MGAREG_ALPHAXINC 0x2c74 -#define MGAREG_ALPHAYINC 0x2c78 #define MGAREG_AR0 0x1c60 #define MGAREG_AR1 0x1c64 #define MGAREG_AR2 0x1c68 @@ -190,39 +292,16 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_AR4 0x1c70 #define MGAREG_AR5 0x1c74 #define MGAREG_AR6 0x1c78 -#define MGAREG_BCOL 0x1c20 #define MGAREG_CXBNDRY 0x1c80 #define MGAREG_CXLEFT 0x1ca0 #define MGAREG_CXRIGHT 0x1ca4 #define MGAREG_DMAPAD 0x1c54 -#define MGAREG_DR0_Z32LSB 0x2c50 -#define MGAREG_DR0_Z32MSB 0x2c54 -#define MGAREG_DR2_Z32LSB 0x2c60 -#define MGAREG_DR2_Z32MSB 0x2c64 -#define MGAREG_DR3_Z32LSB 0x2c68 -#define MGAREG_DR3_Z32MSB 0x2c6c -#define MGAREG_DR0 0x1cc0 -#define MGAREG_DR2 0x1cc8 -#define MGAREG_DR3 0x1ccc -#define MGAREG_DR4 0x1cd0 -#define MGAREG_DR6 0x1cd8 -#define MGAREG_DR7 0x1cdc -#define MGAREG_DR8 0x1ce0 -#define MGAREG_DR10 0x1ce8 -#define MGAREG_DR11 0x1cec -#define MGAREG_DR12 0x1cf0 -#define MGAREG_DR14 0x1cf8 -#define MGAREG_DR15 0x1cfc #define MGAREG_DSTORG 0x2cb8 -#define MGAREG_DWG_INDIR_WT 0x1e80 #define MGAREG_DWGCTL 0x1c00 #define MGAREG_DWGSYNC 0x2c4c #define MGAREG_FCOL 0x1c24 #define MGAREG_FIFOSTATUS 0x1e10 #define MGAREG_FOGCOL 0x1cf4 -#define MGAREG_FOGSTART 0x1cc4 -#define MGAREG_FOGXINC 0x1cd4 -#define MGAREG_FOGYINC 0x1ce4 #define MGAREG_FXBNDRY 0x1c84 #define MGAREG_FXLEFT 0x1ca8 #define MGAREG_FXRIGHT 0x1cac @@ -230,44 +309,22 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_IEN 0x1e1c #define MGAREG_LEN 0x1c5c #define MGAREG_MACCESS 0x1c04 -#define MGAREG_MCTLWTST 0x1c08 -#define MGAREG_MEMRDBK 0x1e44 -#define MGAREG_OPMODE 0x1e54 -#define MGAREG_PAT0 0x1c10 -#define MGAREG_PAT1 0x1c14 #define MGAREG_PITCH 0x1c8c #define MGAREG_PLNWT 0x1c1c #define MGAREG_PRIMADDRESS 0x1e58 #define MGAREG_PRIMEND 0x1e5c #define MGAREG_PRIMPTR 0x1e50 -#define MGAREG_RST 0x1e40 #define MGAREG_SECADDRESS 0x2c40 #define MGAREG_SECEND 0x2c44 #define MGAREG_SETUPADDRESS 0x2cd0 #define MGAREG_SETUPEND 0x2cd4 -#define MGAREG_SGN 0x1c58 -#define MGAREG_SHIFT 0x1c50 #define MGAREG_SOFTRAP 0x2c48 -#define MGAREG_SPECBSTART 0x2c98 -#define MGAREG_SPECBXINC 0x2c9c -#define MGAREG_SPECBYINC 0x2ca0 -#define MGAREG_SPECGSTART 0x2c8c -#define MGAREG_SPECGXINC 0x2c90 -#define MGAREG_SPECGYINC 0x2c94 -#define MGAREG_SPECRSTART 0x2c80 -#define MGAREG_SPECRXINC 0x2c84 -#define MGAREG_SPECRYINC 0x2c88 -#define MGAREG_SRC0 0x1c30 -#define MGAREG_SRC1 0x1c34 -#define MGAREG_SRC2 0x1c38 -#define MGAREG_SRC3 0x1c3c #define MGAREG_SRCORG 0x2cb4 #define MGAREG_STATUS 0x1e14 #define MGAREG_STENCIL 0x2cc8 #define MGAREG_STENCILCTL 0x2ccc #define MGAREG_TDUALSTAGE0 0x2cf8 #define MGAREG_TDUALSTAGE1 0x2cfc -#define MGAREG_TEST0 0x1e48 #define MGAREG_TEXBORDERCOL 0x2c5c #define MGAREG_TEXCTL 0x2c30 #define MGAREG_TEXCTL2 0x2c3c @@ -281,18 +338,6 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_TEXTRANS 0x2c34 #define MGAREG_TEXTRANSHIGH 0x2c38 #define MGAREG_TEXWIDTH 0x2c28 -#define MGAREG_TMR0 0x2c00 -#define MGAREG_TMR1 0x2c04 -#define MGAREG_TMR2 0x2c08 -#define MGAREG_TMR3 0x2c0c -#define MGAREG_TMR4 0x2c10 -#define MGAREG_TMR5 0x2c14 -#define MGAREG_TMR6 0x2c18 -#define MGAREG_TMR7 0x2c1c -#define MGAREG_TMR8 0x2c20 -#define MGAREG_VBIADDR0 0x3e08 -#define MGAREG_VBIADDR1 0x3e0c -#define MGAREG_VCOUNT 0x1e20 #define MGAREG_WACCEPTSEQ 0x1dd4 #define MGAREG_WCODEADDR 0x1e6c #define MGAREG_WFLAG 0x1dc4 @@ -302,18 +347,8 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_WGETMSB 0x1dc8 #define MGAREG_WIADDR 0x1dc0 #define MGAREG_WIADDR2 0x1dd8 -#define MGAREG_WIADDRNB 0x1e60 -#define MGAREG_WIADDRNB1 0x1e04 -#define MGAREG_WIADDRNB2 0x1e00 -#define MGAREG_WIMEMADDR 0x1e68 -#define MGAREG_WIMEMDATA 0x2000 -#define MGAREG_WIMEMDATA1 0x2100 #define MGAREG_WMISC 0x1e70 -#define MGAREG_WR 0x2d00 #define MGAREG_WVRTXSZ 0x1dcc -#define MGAREG_XDST 0x1cb0 -#define MGAREG_XYEND 0x1c44 -#define MGAREG_XYSTRT 0x1c40 #define MGAREG_YBOT 0x1c9c #define MGAREG_YDST 0x1c90 #define MGAREG_YDSTLEN 0x1c88 @@ -321,4 +356,40 @@ extern int mga_context_switch_complete(drm_device_t *dev, int new); #define MGAREG_YTOP 0x1c98 #define MGAREG_ZORG 0x1c0c +#define DC_atype_rstr 0x10 +#define DC_atype_blk 0x40 +#define PDEA_pagpxfer_enable 0x2 +#define WIA_wmode_suspend 0x0 +#define WIA_wmode_start 0x3 +#define WIA_wagp_agp 0x4 +#define DC_opcod_trap 0x4 +#define DC_arzero_enable 0x1000 +#define DC_sgnzero_enable 0x2000 +#define DC_shftzero_enable 0x4000 +#define DC_bop_SHIFT 16 +#define DC_clipdis_enable 0x80000000 +#define DC_solid_enable 0x800 +#define DC_transc_enable 0x40000000 +#define DC_opcod_bitblt 0x8 +#define DC_atype_rpl 0x0 +#define DC_linear_xy 0x0 +#define DC_solid_disable 0x0 +#define DC_arzero_disable 0x0 +#define DC_bltmod_bfcol 0x4000000 +#define DC_pattern_disable 0x0 +#define DC_transc_disable 0x0 + +#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ + DC_solid_enable | DC_transc_enable) + + +#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ + DC_solid_disable | DC_arzero_disable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ + DC_pattern_disable | DC_transc_disable | \ + DC_clipdis_enable) \ + #endif diff --git a/linux/mga_state.c b/linux/mga_state.c index 941ca4d0..a70f86d2 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -24,20 +24,19 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> - * Keith Whitwell <keithw@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * - * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/mga_state.c,v 1.1 2000/02/11 17:26:08 dawes Exp $ + * $XFree86$ * */ #define __NO_VERSION__ #include "drmP.h" #include "mga_drv.h" -#include "mgareg_flags.h" -#include "mga_dma.h" #include "drm.h" -static void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ) +static void mgaEmitClipRect( drm_mga_private_t *dev_priv, + drm_clip_rect_t *box ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; @@ -299,9 +298,6 @@ static void mgaEmitState( drm_mga_private_t *dev_priv ) if (dev_priv->chipset == MGA_CARD_TYPE_G400) { int multitex = sarea_priv->WarpPipe & MGA_T2; -/* DRM_DEBUG("BUF PIPE: %x LOADED PIPE: %x\n", */ -/* sarea_priv->WarpPipe, dev_priv->WarpPipe); */ - if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { mgaG400EmitPipe( dev_priv ); dev_priv->WarpPipe = sarea_priv->WarpPipe; @@ -339,15 +335,6 @@ static void mgaEmitState( drm_mga_private_t *dev_priv ) } } -/* WARNING if you change any of the state functions - * verify these numbers */ - -static int mgaCalcState( drm_mga_private_t *dev_priv ) -{ - /* It doesn't hurt to overestimate. - */ - return 25+15+30+25; -} /* Disallow all write destinations except the front and backbuffer. */ @@ -392,7 +379,7 @@ static int mgaVerifyState( drm_mga_private_t *dev_priv ) unsigned int dirty = sarea_priv->dirty; int rv = 0; - if (sarea_priv->nbox >= MGA_NR_SAREA_CLIPRECTS) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; if (dirty & MGA_UPLOAD_CTX) @@ -436,10 +423,10 @@ static int mgaVerifyIload( drm_mga_private_t *dev_priv, /* This copies a 64 byte aligned agp region to the frambuffer * with a standard blit, the ioctl needs to do checking */ -static inline void mga_dma_dispatch_tex_blit( drm_device_t *dev, - unsigned long bus_address, - int length, - unsigned int destOrg ) +static void mga_dma_dispatch_tex_blit( drm_device_t *dev, + unsigned long bus_address, + int length, + unsigned int destOrg ) { drm_mga_private_t *dev_priv = dev->dev_private; int use_agp = PDEA_pagpxfer_enable | 0x00000001; @@ -476,9 +463,8 @@ static inline void mga_dma_dispatch_tex_blit( drm_device_t *dev, PRIMADVANCE(dev_priv); } -static inline void mga_dma_dispatch_vertex(drm_device_t *dev, - drm_buf_t *buf, int real_idx, - int idx) +static void mga_dma_dispatch_vertex(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; @@ -490,17 +476,22 @@ static inline void mga_dma_dispatch_vertex(drm_device_t *dev, int primary_needed; PRIMLOCALS; - DRM_DEBUG("dispatch vertex %d addr 0x%lx, length 0x%x nbox %d dirty %x\n", - buf->idx, address, length, sarea_priv->nbox, sarea_priv->dirty); + DRM_DEBUG("dispatch vertex %d addr 0x%lx, " + "length 0x%x nbox %d dirty %x\n", + buf->idx, address, length, + sarea_priv->nbox, sarea_priv->dirty); dev_priv->last_sync_tag = mga_create_sync_tag(dev); - if(real_idx == idx) { + + if (buf_priv->discard) { buf_priv->my_freelist->age = dev_priv->last_sync_tag; mga_freelist_put(dev, buf); } - /* Overestimating this doesn't hurt. + + /* WARNING: if you change any of the state functions verify + * these numbers (Overestimating this doesn't hurt). */ primary_needed = (25+15+30+25+ 10 + @@ -509,31 +500,34 @@ static inline void mga_dma_dispatch_vertex(drm_device_t *dev, PRIM_OVERFLOW(dev, dev_priv, primary_needed); mgaEmitState( dev_priv ); - do { - if (i < sarea_priv->nbox) { - DRM_DEBUG("idx %d Emit box %d/%d:" - "%d,%d - %d,%d\n", - buf->idx, - i, sarea_priv->nbox, - sarea_priv->boxes[i].x1, - sarea_priv->boxes[i].y1, - sarea_priv->boxes[i].x2, - sarea_priv->boxes[i].y2); - - mgaEmitClipRect( dev_priv, - &sarea_priv->boxes[i] ); - } - PRIMGETPTR(dev_priv); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, - ((__u32)address) | TT_VERTEX); - PRIMOUTREG( MGAREG_SECEND, - (((__u32)(address + length)) | - use_agp)); - PRIMADVANCE( dev_priv ); - } while (++i < sarea_priv->nbox); + if (buf->used) { + do { + if (i < sarea_priv->nbox) { + DRM_DEBUG("idx %d Emit box %d/%d:" + "%d,%d - %d,%d\n", + buf->idx, + i, sarea_priv->nbox, + sarea_priv->boxes[i].x1, + sarea_priv->boxes[i].y1, + sarea_priv->boxes[i].x2, + sarea_priv->boxes[i].y2); + + mgaEmitClipRect( dev_priv, + &sarea_priv->boxes[i] ); + } + + PRIMGETPTR(dev_priv); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_SECADDRESS, + ((__u32)address) | TT_VERTEX); + PRIMOUTREG( MGAREG_SECEND, + (((__u32)(address + length)) | + use_agp)); + PRIMADVANCE( dev_priv ); + } while (++i < sarea_priv->nbox); + } PRIMGETPTR( dev_priv ); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -543,44 +537,16 @@ static inline void mga_dma_dispatch_vertex(drm_device_t *dev, PRIMADVANCE( dev_priv ); } -/* Not currently used - */ -static inline void mga_dma_dispatch_general(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; - unsigned long address = (unsigned long)buf->bus_address; - int length = buf->used; - int use_agp = PDEA_pagpxfer_enable; - PRIMLOCALS; - - PRIM_OVERFLOW(dev, dev_priv, 10); - PRIMGETPTR(dev_priv); - - dev_priv->last_sync_tag = mga_create_sync_tag(dev); - buf_priv->my_freelist->age = dev_priv->last_sync_tag; - mga_freelist_put(dev, buf); - - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, ((__u32)address) | TT_GENERAL); - PRIMOUTREG( MGAREG_SECEND, (((__u32)(address + length)) | use_agp)); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_DWGSYNC, dev_priv->last_sync_tag); - PRIMADVANCE(dev_priv); -} -static inline void mga_dma_dispatch_clear( drm_device_t *dev, int flags, - unsigned int clear_color, - unsigned int clear_zval ) +static void mga_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; int nbox = sarea_priv->nbox; - xf86drmClipRectRec *pbox = sarea_priv->boxes; + drm_clip_rect_t *pbox = sarea_priv->boxes; unsigned int cmd; int i; int primary_needed; @@ -657,13 +623,13 @@ static inline void mga_dma_dispatch_clear( drm_device_t *dev, int flags, PRIMADVANCE(dev_priv); } -static inline void mga_dma_dispatch_swap( drm_device_t *dev ) +static void mga_dma_dispatch_swap( drm_device_t *dev ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; int nbox = sarea_priv->nbox; - xf86drmClipRectRec *pbox = sarea_priv->boxes; + drm_clip_rect_t *pbox = sarea_priv->boxes; int i; int primary_needed; PRIMLOCALS; @@ -690,8 +656,8 @@ static inline void mga_dma_dispatch_swap( drm_device_t *dev ) unsigned int start = pbox[i].y1 * dev_priv->stride/2; DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", - pbox[i].x1, pbox[i].y1, - pbox[i].x2, pbox[i].y2); + pbox[i].x1, pbox[i].y1, + pbox[i].x2, pbox[i].y2); PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1); @@ -721,13 +687,17 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; __volatile__ unsigned int *status = (__volatile__ unsigned int *)dev_priv->status_page; - drm_mga_clear_t clear; copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear), -EFAULT); + + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_clear_bufs called without lock held\n"); + return -EINVAL; + } - if (sarea_priv->nbox >= MGA_NR_SAREA_CLIPRECTS) + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; /* Make sure we restore the 3D state next time. @@ -752,7 +722,12 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, __volatile__ unsigned int *status = (__volatile__ unsigned int *)dev_priv->status_page; - if (sarea_priv->nbox >= MGA_NR_SAREA_CLIPRECTS) + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_swap_bufs called without lock held\n"); + return -EINVAL; + } + + if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; /* Make sure we restore the 3D state next time. @@ -786,6 +761,11 @@ int mga_iload(struct inode *inode, struct file *filp, copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_iload called without lock held\n"); + return -EINVAL; + } + buf = dma->buflist[ iload.idx ]; buf_priv = buf->dev_private; bus_address = buf->bus_address; @@ -805,6 +785,7 @@ int mga_iload(struct inode *inode, struct file *filp, mga_dma_dispatch_tex_blit(dev, bus_address, iload.length, iload.destOrg); buf_priv->my_freelist->age = dev_priv->last_sync_tag; + buf_priv->discard = 1; mga_freelist_put(dev, buf); mga_dma_schedule(dev, 1); sarea_priv->last_dispatch = status[1]; @@ -828,27 +809,29 @@ int mga_vertex(struct inode *inode, struct file *filp, copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_vertex called without lock held\n"); + return -EINVAL; + } DRM_DEBUG("mga_vertex\n"); - buf = dma->buflist[ vertex.real_idx ]; + + buf = dma->buflist[ vertex.idx ]; buf_priv = buf->dev_private; + + buf->used = vertex.used; + buf_priv->discard = vertex.discard; if (!mgaVerifyState(dev_priv)) { - if(vertex.real_idx == vertex.idx) { + if (vertex.discard) { buf_priv->my_freelist->age = dev_priv->last_sync_tag; mga_freelist_put(dev, buf); } return -EINVAL; } - buf->used = vertex.real_used; - if(vertex.discard) { - buf_priv->my_freelist->age = dev_priv->last_sync_tag; - mga_freelist_put(dev, buf); - } else { - mga_dma_dispatch_vertex(dev, buf, vertex.real_idx, - vertex.idx); - } + mga_dma_dispatch_vertex(dev, buf); + PRIMUPDATE(dev_priv); mga_dma_schedule(dev, 1); sarea_priv->last_dispatch = status[1]; @@ -857,13 +840,13 @@ int mga_vertex(struct inode *inode, struct file *filp, static int mga_dma_get_buffers(drm_device_t *dev, drm_dma_t *d) { - int i; - drm_buf_t *buf; + int i; + drm_buf_t *buf; for (i = d->granted_count; i < d->request_count; i++) { buf = mga_freelist_get(dev); if (!buf) break; - buf->pid = current->pid; + buf->pid = current->pid; copy_to_user_ret(&d->request_indices[i], &buf->idx, sizeof(buf->idx), @@ -894,6 +877,11 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, DRM_DEBUG("%d %d: %d send, %d req\n", current->pid, d.context, d.send_count, d.request_count); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("mga_dma called without lock held\n"); + return -EINVAL; + } + /* Please don't send us buffers. */ if (d.send_count != 0) { diff --git a/linux/mga_state.h b/linux/mga_state.h deleted file mode 100644 index 40fa1451..00000000 --- a/linux/mga_state.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef MGA_STATE_H -#define MGA_STATE_H - -#include "mga_drv.h" - -void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ); - -void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv ); - -#endif diff --git a/linux/mgareg_flags.h b/linux/mgareg_flags.h deleted file mode 100644 index 901f1831..00000000 --- a/linux/mgareg_flags.h +++ /dev/null @@ -1,930 +0,0 @@ -/* author: stephen crowley, crow@debian.org */ - -/* - * 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 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 - * STEPHEN CROWLEY, OR ANY OTHER CONTRIBUTORS 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. - */ - -#ifndef _MGAREGS_H_ -#define _MGAREGS_H_ - -/*************** (START) AUTOMATICLY GENERATED REGISTER FILE *****************/ -/* - * Generated on Sat Nov 20 21:25:36 CST 1999 - */ - - - -/* - * Power Graphic Mode Memory Space Registers - */ - - #define AGP_PLL_agp2xpllen_MASK 0xfffffffe /* bit 0 */ - #define AGP_PLL_agp2xpllen_disable 0x0 - #define AGP_PLL_agp2xpllen_enable 0x1 - - #define AC_src_MASK 0xfffffff0 /* bits 0-3 */ - #define AC_src_zero 0x0 /* val 0, shift 0 */ - #define AC_src_one 0x1 /* val 1, shift 0 */ - #define AC_src_dst_color 0x2 /* val 2, shift 0 */ - #define AC_src_om_dst_color 0x3 /* val 3, shift 0 */ - #define AC_src_src_alpha 0x4 /* val 4, shift 0 */ - #define AC_src_om_src_alpha 0x5 /* val 5, shift 0 */ - #define AC_src_dst_alpha 0x6 /* val 6, shift 0 */ - #define AC_src_om_dst_alpha 0x7 /* val 7, shift 0 */ - #define AC_src_src_alpha_sat 0x8 /* val 8, shift 0 */ - #define AC_dst_MASK 0xffffff0f /* bits 4-7 */ - #define AC_dst_zero 0x0 /* val 0, shift 4 */ - #define AC_dst_one 0x10 /* val 1, shift 4 */ - #define AC_dst_src_color 0x20 /* val 2, shift 4 */ - #define AC_dst_om_src_color 0x30 /* val 3, shift 4 */ - #define AC_dst_src_alpha 0x40 /* val 4, shift 4 */ - #define AC_dst_om_src_alpha 0x50 /* val 5, shift 4 */ - #define AC_dst_dst_alpha 0x60 /* val 6, shift 4 */ - #define AC_dst_om_dst_alpha 0x70 /* val 7, shift 4 */ - #define AC_amode_MASK 0xfffffcff /* bits 8-9 */ - #define AC_amode_FCOL 0x0 /* val 0, shift 8 */ - #define AC_amode_alpha_channel 0x100 /* val 1, shift 8 */ - #define AC_amode_video_alpha 0x200 /* val 2, shift 8 */ - #define AC_amode_RSVD 0x300 /* val 3, shift 8 */ - #define AC_astipple_MASK 0xfffff7ff /* bit 11 */ - #define AC_astipple_disable 0x0 - #define AC_astipple_enable 0x800 - #define AC_aten_MASK 0xffffefff /* bit 12 */ - #define AC_aten_disable 0x0 - #define AC_aten_enable 0x1000 - #define AC_atmode_MASK 0xffff1fff /* bits 13-15 */ - #define AC_atmode_noacmp 0x0 /* val 0, shift 13 */ - #define AC_atmode_ae 0x4000 /* val 2, shift 13 */ - #define AC_atmode_ane 0x6000 /* val 3, shift 13 */ - #define AC_atmode_alt 0x8000 /* val 4, shift 13 */ - #define AC_atmode_alte 0xa000 /* val 5, shift 13 */ - #define AC_atmode_agt 0xc000 /* val 6, shift 13 */ - #define AC_atmode_agte 0xe000 /* val 7, shift 13 */ - #define AC_atref_MASK 0xff00ffff /* bits 16-23 */ - #define AC_atref_SHIFT 16 - #define AC_alphasel_MASK 0xfcffffff /* bits 24-25 */ - #define AC_alphasel_fromtex 0x0 /* val 0, shift 24 */ - #define AC_alphasel_diffused 0x1000000 /* val 1, shift 24 */ - #define AC_alphasel_modulated 0x2000000 /* val 2, shift 24 */ - #define AC_alphasel_trans 0x3000000 /* val 3, shift 24 */ - - #define AR0_ar0_MASK 0xfffc0000 /* bits 0-17 */ - #define AR0_ar0_SHIFT 0 - - #define AR1_ar1_MASK 0xff000000 /* bits 0-23 */ - #define AR1_ar1_SHIFT 0 - - #define AR2_ar2_MASK 0xfffc0000 /* bits 0-17 */ - #define AR2_ar2_SHIFT 0 - - #define AR3_ar3_MASK 0xff000000 /* bits 0-23 */ - #define AR3_ar3_SHIFT 0 - #define AR3_spage_MASK 0xf8ffffff /* bits 24-26 */ - #define AR3_spage_SHIFT 24 - - #define AR4_ar4_MASK 0xfffc0000 /* bits 0-17 */ - #define AR4_ar4_SHIFT 0 - - #define AR5_ar5_MASK 0xfffc0000 /* bits 0-17 */ - #define AR5_ar5_SHIFT 0 - - #define AR6_ar6_MASK 0xfffc0000 /* bits 0-17 */ - #define AR6_ar6_SHIFT 0 - - #define BC_besen_MASK 0xfffffffe /* bit 0 */ - #define BC_besen_disable 0x0 - #define BC_besen_enable 0x1 - #define BC_besv1srcstp_MASK 0xffffffbf /* bit 6 */ - #define BC_besv1srcstp_even 0x0 - #define BC_besv1srcstp_odd 0x40 - #define BC_besv2srcstp_MASK 0xfffffeff /* bit 8 */ - #define BC_besv2srcstp_disable 0x0 - #define BC_besv2srcstp_enable 0x100 - #define BC_beshfen_MASK 0xfffffbff /* bit 10 */ - #define BC_beshfen_disable 0x0 - #define BC_beshfen_enable 0x400 - #define BC_besvfen_MASK 0xfffff7ff /* bit 11 */ - #define BC_besvfen_disable 0x0 - #define BC_besvfen_enable 0x800 - #define BC_beshfixc_MASK 0xffffefff /* bit 12 */ - #define BC_beshfixc_weight 0x0 - #define BC_beshfixc_coeff 0x1000 - #define BC_bescups_MASK 0xfffeffff /* bit 16 */ - #define BC_bescups_disable 0x0 - #define BC_bescups_enable 0x10000 - #define BC_bes420pl_MASK 0xfffdffff /* bit 17 */ - #define BC_bes420pl_422 0x0 - #define BC_bes420pl_420 0x20000 - #define BC_besdith_MASK 0xfffbffff /* bit 18 */ - #define BC_besdith_disable 0x0 - #define BC_besdith_enable 0x40000 - #define BC_beshmir_MASK 0xfff7ffff /* bit 19 */ - #define BC_beshmir_disable 0x0 - #define BC_beshmir_enable 0x80000 - #define BC_besbwen_MASK 0xffefffff /* bit 20 */ - #define BC_besbwen_color 0x0 - #define BC_besbwen_bw 0x100000 - #define BC_besblank_MASK 0xffdfffff /* bit 21 */ - #define BC_besblank_disable 0x0 - #define BC_besblank_enable 0x200000 - #define BC_besfselm_MASK 0xfeffffff /* bit 24 */ - #define BC_besfselm_soft 0x0 - #define BC_besfselm_hard 0x1000000 - #define BC_besfsel_MASK 0xf9ffffff /* bits 25-26 */ - #define BC_besfsel_a1 0x0 /* val 0, shift 25 */ - #define BC_besfsel_a2 0x2000000 /* val 1, shift 25 */ - #define BC_besfsel_b1 0x4000000 /* val 2, shift 25 */ - #define BC_besfsel_b2 0x6000000 /* val 3, shift 25 */ - - #define BGC_beshzoom_MASK 0xfffffffe /* bit 0 */ - #define BGC_beshzoom_disable 0x0 - #define BGC_beshzoom_enable 0x1 - #define BGC_beshzoomf_MASK 0xfffffffd /* bit 1 */ - #define BGC_beshzoomf_disable 0x0 - #define BGC_beshzoomf_enable 0x2 - #define BGC_bescorder_MASK 0xfffffff7 /* bit 3 */ - #define BGC_bescorder_even 0x0 - #define BGC_bescorder_odd 0x8 - #define BGC_besreghup_MASK 0xffffffef /* bit 4 */ - #define BGC_besreghup_disable 0x0 - #define BGC_besreghup_enable 0x10 - #define BGC_besvcnt_MASK 0xf000ffff /* bits 16-27 */ - #define BGC_besvcnt_SHIFT 16 - - #define BHC_besright_MASK 0xfffff800 /* bits 0-10 */ - #define BHC_besright_SHIFT 0 - #define BHC_besleft_MASK 0xf800ffff /* bits 16-26 */ - #define BHC_besleft_SHIFT 16 - - #define BHISF_beshiscal_MASK 0xffe00003 /* bits 2-20 */ - #define BHISF_beshiscal_SHIFT 2 - - #define BHSE_beshsrcend_MASK 0xfc000003 /* bits 2-25 */ - #define BHSE_beshsrcend_SHIFT 2 - - #define BHSL_beshsrclst_MASK 0xfc00ffff /* bits 16-25 */ - #define BHSL_beshsrclst_SHIFT 16 - - #define BHSS_beshsrcst_MASK 0xfc000003 /* bits 2-25 */ - #define BHSS_beshsrcst_SHIFT 2 - - #define BP_bespitch_MASK 0xfffff000 /* bits 0-11 */ - #define BP_bespitch_SHIFT 0 - - #define BS_besstat_MASK 0xfffffffc /* bits 0-1 */ - #define BS_besstat_a1 0x0 /* val 0, shift 0 */ - #define BS_besstat_a2 0x1 /* val 1, shift 0 */ - #define BS_besstat_b1 0x2 /* val 2, shift 0 */ - #define BS_besstat_b2 0x3 /* val 3, shift 0 */ - - #define BSF_besv1srclast_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv1srclast_SHIFT 0 - - #define BSF_besv2srclst_MASK 0xfffffc00 /* bits 0-9 */ - #define BSF_besv2srclst_SHIFT 0 - - #define BSF_besv1wght_MASK 0xffff0003 /* bits 2-15 */ - #define BSF_besv1wght_SHIFT 2 - #define BSF_besv1wghts_MASK 0xfffeffff /* bit 16 */ - #define BSF_besv1wghts_disable 0x0 - #define BSF_besv1wghts_enable 0x10000 - - #define BSF_besv2wght_MASK 0xffff0003 /* bits 2-15 */ - #define BSF_besv2wght_SHIFT 2 - #define BSF_besv2wghts_MASK 0xfffeffff /* bit 16 */ - #define BSF_besv2wghts_disable 0x0 - #define BSF_besv2wghts_enable 0x10000 - - #define BVC_besbot_MASK 0xfffff800 /* bits 0-10 */ - #define BVC_besbot_SHIFT 0 - #define BVC_bestop_MASK 0xf800ffff /* bits 16-26 */ - #define BVC_bestop_SHIFT 16 - - #define BVISF_besviscal_MASK 0xffe00003 /* bits 2-20 */ - #define BVISF_besviscal_SHIFT 2 - - #define CXB_cxleft_MASK 0xfffff000 /* bits 0-11 */ - #define CXB_cxleft_SHIFT 0 - #define CXB_cxright_MASK 0xf000ffff /* bits 16-27 */ - #define CXB_cxright_SHIFT 16 - - #define DO_dstmap_MASK 0xfffffffe /* bit 0 */ - #define DO_dstmap_fb 0x0 - #define DO_dstmap_sys 0x1 - #define DO_dstacc_MASK 0xfffffffd /* bit 1 */ - #define DO_dstacc_pci 0x0 - #define DO_dstacc_agp 0x2 - #define DO_dstorg_MASK 0x7 /* bits 3-31 */ - #define DO_dstorg_SHIFT 3 - - #define DC_opcod_MASK 0xfffffff0 /* bits 0-3 */ - #define DC_opcod_line_open 0x0 /* val 0, shift 0 */ - #define DC_opcod_autoline_open 0x1 /* val 1, shift 0 */ - #define DC_opcod_line_close 0x2 /* val 2, shift 0 */ - #define DC_opcod_autoline_close 0x3 /* val 3, shift 0 */ - #define DC_opcod_trap 0x4 /* val 4, shift 0 */ - #define DC_opcod_texture_trap 0x6 /* val 6, shift 0 */ - #define DC_opcod_bitblt 0x8 /* val 8, shift 0 */ - #define DC_opcod_iload 0x9 /* val 9, shift 0 */ - #define DC_atype_MASK 0xffffff8f /* bits 4-6 */ - #define DC_atype_rpl 0x0 /* val 0, shift 4 */ - #define DC_atype_rstr 0x10 /* val 1, shift 4 */ - #define DC_atype_zi 0x30 /* val 3, shift 4 */ - #define DC_atype_blk 0x40 /* val 4, shift 4 */ - #define DC_atype_i 0x70 /* val 7, shift 4 */ - #define DC_linear_MASK 0xffffff7f /* bit 7 */ - #define DC_linear_xy 0x0 - #define DC_linear_linear 0x80 - #define DC_zmode_MASK 0xfffff8ff /* bits 8-10 */ - #define DC_zmode_nozcmp 0x0 /* val 0, shift 8 */ - #define DC_zmode_ze 0x200 /* val 2, shift 8 */ - #define DC_zmode_zne 0x300 /* val 3, shift 8 */ - #define DC_zmode_zlt 0x400 /* val 4, shift 8 */ - #define DC_zmode_zlte 0x500 /* val 5, shift 8 */ - #define DC_zmode_zgt 0x600 /* val 6, shift 8 */ - #define DC_zmode_zgte 0x700 /* val 7, shift 8 */ - #define DC_solid_MASK 0xfffff7ff /* bit 11 */ - #define DC_solid_disable 0x0 - #define DC_solid_enable 0x800 - #define DC_arzero_MASK 0xffffefff /* bit 12 */ - #define DC_arzero_disable 0x0 - #define DC_arzero_enable 0x1000 - #define DC_sgnzero_MASK 0xffffdfff /* bit 13 */ - #define DC_sgnzero_disable 0x0 - #define DC_sgnzero_enable 0x2000 - #define DC_shftzero_MASK 0xffffbfff /* bit 14 */ - #define DC_shftzero_disable 0x0 - #define DC_shftzero_enable 0x4000 - #define DC_bop_MASK 0xfff0ffff /* bits 16-19 */ - #define DC_bop_SHIFT 16 - #define DC_trans_MASK 0xff0fffff /* bits 20-23 */ - #define DC_trans_SHIFT 20 - #define DC_bltmod_MASK 0xe1ffffff /* bits 25-28 */ - #define DC_bltmod_bmonolef 0x0 /* val 0, shift 25 */ - #define DC_bltmod_bmonowf 0x8000000 /* val 4, shift 25 */ - #define DC_bltmod_bplan 0x2000000 /* val 1, shift 25 */ - #define DC_bltmod_bfcol 0x4000000 /* val 2, shift 25 */ - #define DC_bltmod_bu32bgr 0x6000000 /* val 3, shift 25 */ - #define DC_bltmod_bu32rgb 0xe000000 /* val 7, shift 25 */ - #define DC_bltmod_bu24bgr 0x16000000 /* val 11, shift 25 */ - #define DC_bltmod_bu24rgb 0x1e000000 /* val 15, shift 25 */ - #define DC_pattern_MASK 0xdfffffff /* bit 29 */ - #define DC_pattern_disable 0x0 - #define DC_pattern_enable 0x20000000 - #define DC_transc_MASK 0xbfffffff /* bit 30 */ - #define DC_transc_disable 0x0 - #define DC_transc_enable 0x40000000 - #define DC_clipdis_MASK 0x7fffffff /* bit 31 */ - #define DC_clipdis_disable 0x0 - #define DC_clipdis_enable 0x80000000 - - #define DS_dwgsyncaddr_MASK 0x3 /* bits 2-31 */ - #define DS_dwgsyncaddr_SHIFT 2 - - #define FS_fifocount_MASK 0xffffff80 /* bits 0-6 */ - #define FS_fifocount_SHIFT 0 - #define FS_bfull_MASK 0xfffffeff /* bit 8 */ - #define FS_bfull_disable 0x0 - #define FS_bfull_enable 0x100 - #define FS_bempty_MASK 0xfffffdff /* bit 9 */ - #define FS_bempty_disable 0x0 - #define FS_bempty_enable 0x200 - - #define XA_fxleft_MASK 0xffff0000 /* bits 0-15 */ - #define XA_fxleft_SHIFT 0 - #define XA_fxright_MASK 0xffff /* bits 16-31 */ - #define XA_fxright_SHIFT 16 - - #define IC_softrapiclr_MASK 0xfffffffe /* bit 0 */ - #define IC_softrapiclr_disable 0x0 - #define IC_softrapiclr_enable 0x1 - #define IC_pickiclr_MASK 0xfffffffb /* bit 2 */ - #define IC_pickiclr_disable 0x0 - #define IC_pickiclr_enable 0x4 - #define IC_vlineiclr_MASK 0xffffffdf /* bit 5 */ - #define IC_vlineiclr_disable 0x0 - #define IC_vlineiclr_enable 0x20 - #define IC_wiclr_MASK 0xffffff7f /* bit 7 */ - #define IC_wiclr_disable 0x0 - #define IC_wiclr_enable 0x80 - #define IC_wciclr_MASK 0xfffffeff /* bit 8 */ - #define IC_wciclr_disable 0x0 - #define IC_wciclr_enable 0x100 - - #define IE_softrapien_MASK 0xfffffffe /* bit 0 */ - #define IE_softrapien_disable 0x0 - #define IE_softrapien_enable 0x1 - #define IE_pickien_MASK 0xfffffffb /* bit 2 */ - #define IE_pickien_disable 0x0 - #define IE_pickien_enable 0x4 - #define IE_vlineien_MASK 0xffffffdf /* bit 5 */ - #define IE_vlineien_disable 0x0 - #define IE_vlineien_enable 0x20 - #define IE_extien_MASK 0xffffffbf /* bit 6 */ - #define IE_extien_disable 0x0 - #define IE_extien_enable 0x40 - #define IE_wien_MASK 0xffffff7f /* bit 7 */ - #define IE_wien_disable 0x0 - #define IE_wien_enable 0x80 - #define IE_wcien_MASK 0xfffffeff /* bit 8 */ - #define IE_wcien_disable 0x0 - #define IE_wcien_enable 0x100 - - #define MA_pwidth_MASK 0xfffffffc /* bits 0-1 */ - #define MA_pwidth_8 0x0 /* val 0, shift 0 */ - #define MA_pwidth_16 0x1 /* val 1, shift 0 */ - #define MA_pwidth_32 0x2 /* val 2, shift 0 */ - #define MA_pwidth_24 0x3 /* val 3, shift 0 */ - #define MA_zwidth_MASK 0xffffffe7 /* bits 3-4 */ - #define MA_zwidth_16 0x0 /* val 0, shift 3 */ - #define MA_zwidth_32 0x8 /* val 1, shift 3 */ - #define MA_zwidth_15 0x10 /* val 2, shift 3 */ - #define MA_zwidth_24 0x18 /* val 3, shift 3 */ - #define MA_memreset_MASK 0xffff7fff /* bit 15 */ - #define MA_memreset_disable 0x0 - #define MA_memreset_enable 0x8000 - #define MA_fogen_MASK 0xfbffffff /* bit 26 */ - #define MA_fogen_disable 0x0 - #define MA_fogen_enable 0x4000000 - #define MA_tlutload_MASK 0xdfffffff /* bit 29 */ - #define MA_tlutload_disable 0x0 - #define MA_tlutload_enable 0x20000000 - #define MA_nodither_MASK 0xbfffffff /* bit 30 */ - #define MA_nodither_disable 0x0 - #define MA_nodither_enable 0x40000000 - #define MA_dit555_MASK 0x7fffffff /* bit 31 */ - #define MA_dit555_disable 0x0 - #define MA_dit555_enable 0x80000000 - - #define MCWS_casltncy_MASK 0xfffffff8 /* bits 0-2 */ - #define MCWS_casltncy_SHIFT 0 - #define MCWS_rrddelay_MASK 0xffffffcf /* bits 4-5 */ - #define MCWS_rcddelay_MASK 0xfffffe7f /* bits 7-8 */ - #define MCWS_rasmin_MASK 0xffffe3ff /* bits 10-12 */ - #define MCWS_rasmin_SHIFT 10 - #define MCWS_rpdelay_MASK 0xffff3fff /* bits 14-15 */ - #define MCWS_wrdelay_MASK 0xfff3ffff /* bits 18-19 */ - #define MCWS_rddelay_MASK 0xffdfffff /* bit 21 */ - #define MCWS_rddelay_disable 0x0 - #define MCWS_rddelay_enable 0x200000 - #define MCWS_smrdelay_MASK 0xfe7fffff /* bits 23-24 */ - #define MCWS_bwcdelay_MASK 0xf3ffffff /* bits 26-27 */ - #define MCWS_bpldelay_MASK 0x1fffffff /* bits 29-31 */ - #define MCWS_bpldelay_SHIFT 29 - - #define MRB_mclkbrd0_MASK 0xfffffff0 /* bits 0-3 */ - #define MRB_mclkbrd0_SHIFT 0 - #define MRB_mclkbrd1_MASK 0xfffffe1f /* bits 5-8 */ - #define MRB_mclkbrd1_SHIFT 5 - #define MRB_strmfctl_MASK 0xff3fffff /* bits 22-23 */ - #define MRB_mrsopcod_MASK 0xe1ffffff /* bits 25-28 */ - #define MRB_mrsopcod_SHIFT 25 - - #define OM_dmamod_MASK 0xfffffff3 /* bits 2-3 */ - #define OM_dmamod_general 0x0 /* val 0, shift 2 */ - #define OM_dmamod_blit 0x4 /* val 1, shift 2 */ - #define OM_dmamod_vector 0x8 /* val 2, shift 2 */ - #define OM_dmamod_vertex 0xc /* val 3, shift 2 */ - #define OM_dmadatasiz_MASK 0xfffffcff /* bits 8-9 */ - #define OM_dmadatasiz_8 0x0 /* val 0, shift 8 */ - #define OM_dmadatasiz_16 0x100 /* val 1, shift 8 */ - #define OM_dmadatasiz_32 0x200 /* val 2, shift 8 */ - #define OM_dirdatasiz_MASK 0xfffcffff /* bits 16-17 */ - #define OM_dirdatasiz_8 0x0 /* val 0, shift 16 */ - #define OM_dirdatasiz_16 0x10000 /* val 1, shift 16 */ - #define OM_dirdatasiz_32 0x20000 /* val 2, shift 16 */ - - #define P_iy_MASK 0xffffe000 /* bits 0-12 */ - #define P_iy_SHIFT 0 - #define P_ylin_MASK 0xffff7fff /* bit 15 */ - #define P_ylin_disable 0x0 - #define P_ylin_enable 0x8000 - - #define PDCA_primod_MASK 0xfffffffc /* bits 0-1 */ - #define PDCA_primod_general 0x0 /* val 0, shift 0 */ - #define PDCA_primod_blit 0x1 /* val 1, shift 0 */ - #define PDCA_primod_vector 0x2 /* val 2, shift 0 */ - #define PDCA_primod_vertex 0x3 /* val 3, shift 0 */ - #define PDCA_primaddress_MASK 0x3 /* bits 2-31 */ - #define PDCA_primaddress_SHIFT 2 - - #define PDEA_primnostart_MASK 0xfffffffe /* bit 0 */ - #define PDEA_primnostart_disable 0x0 - #define PDEA_primnostart_enable 0x1 - #define PDEA_pagpxfer_MASK 0xfffffffd /* bit 1 */ - #define PDEA_pagpxfer_disable 0x0 - #define PDEA_pagpxfer_enable 0x2 - #define PDEA_primend_MASK 0x3 /* bits 2-31 */ - #define PDEA_primend_SHIFT 2 - - #define PLS_primptren0_MASK 0xfffffffe /* bit 0 */ - #define PLS_primptren0_disable 0x0 - #define PLS_primptren0_enable 0x1 - #define PLS_primptren1_MASK 0xfffffffd /* bit 1 */ - #define PLS_primptren1_disable 0x0 - #define PLS_primptren1_enable 0x2 - #define PLS_primptr_MASK 0x7 /* bits 3-31 */ - #define PLS_primptr_SHIFT 3 - - #define R_softreset_MASK 0xfffffffe /* bit 0 */ - #define R_softreset_disable 0x0 - #define R_softreset_enable 0x1 - #define R_softextrst_MASK 0xfffffffd /* bit 1 */ - #define R_softextrst_disable 0x0 - #define R_softextrst_enable 0x2 - - #define SDCA_secmod_MASK 0xfffffffc /* bits 0-1 */ - #define SDCA_secmod_general 0x0 /* val 0, shift 0 */ - #define SDCA_secmod_blit 0x1 /* val 1, shift 0 */ - #define SDCA_secmod_vector 0x2 /* val 2, shift 0 */ - #define SDCA_secmod_vertex 0x3 /* val 3, shift 0 */ - #define SDCA_secaddress_MASK 0x3 /* bits 2-31 */ - #define SDCA_secaddress_SHIFT 2 - - #define SDEA_sagpxfer_MASK 0xfffffffd /* bit 1 */ - #define SDEA_sagpxfer_disable 0x0 - #define SDEA_sagpxfer_enable 0x2 - #define SDEA_secend_MASK 0x3 /* bits 2-31 */ - #define SDEA_secend_SHIFT 2 - - #define SETDCA_setupmod_MASK 0xfffffffc /* bits 0-1 */ - #define SETDCA_setupmod_vertlist 0x0 /* val 0, shift 0 */ - #define SETDCA_setupaddress_MASK 0x3 /* bits 2-31 */ - #define SETDCA_setupaddress_SHIFT 2 - - #define SETDEA_setupagpxfer_MASK 0xfffffffd /* bit 1 */ - #define SETDEA_setupagpxfer_disable 0x0 - #define SETDEA_setupagpxfer_enable 0x2 - #define SETDEA_setupend_MASK 0x3 /* bits 2-31 */ - #define SETDEA_setupend_SHIFT 2 - - #define S_sdydxl_MASK 0xfffffffe /* bit 0 */ - #define S_sdydxl_y 0x0 - #define S_sdydxl_x 0x1 - #define S_scanleft_MASK 0xfffffffe /* bit 0 */ - #define S_scanleft_disable 0x0 - #define S_scanleft_enable 0x1 - #define S_sdxl_MASK 0xfffffffd /* bit 1 */ - #define S_sdxl_pos 0x0 - #define S_sdxl_neg 0x2 - #define S_sdy_MASK 0xfffffffb /* bit 2 */ - #define S_sdy_pos 0x0 - #define S_sdy_neg 0x4 - #define S_sdxr_MASK 0xffffffdf /* bit 5 */ - #define S_sdxr_pos 0x0 - #define S_sdxr_neg 0x20 - #define S_brkleft_MASK 0xfffffeff /* bit 8 */ - #define S_brkleft_disable 0x0 - #define S_brkleft_enable 0x100 - #define S_errorinit_MASK 0x7fffffff /* bit 31 */ - #define S_errorinit_disable 0x0 - #define S_errorinit_enable 0x80000000 - - #define FSC_x_off_MASK 0xfffffff0 /* bits 0-3 */ - #define FSC_x_off_SHIFT 0 - #define FSC_funcnt_MASK 0xffffff80 /* bits 0-6 */ - #define FSC_funcnt_SHIFT 0 - #define FSC_y_off_MASK 0xffffff8f /* bits 4-6 */ - #define FSC_y_off_SHIFT 4 - #define FSC_funoff_MASK 0xffc0ffff /* bits 16-21 */ - #define FSC_funoff_SHIFT 16 - #define FSC_stylelen_MASK 0xffc0ffff /* bits 16-21 */ - #define FSC_stylelen_SHIFT 16 - - - #define STH_softraphand_MASK 0x3 /* bits 2-31 */ - #define STH_softraphand_SHIFT 2 - - #define SO_srcmap_MASK 0xfffffffe /* bit 0 */ - #define SO_srcmap_fb 0x0 - #define SO_srcmap_sys 0x1 - #define SO_srcacc_MASK 0xfffffffd /* bit 1 */ - #define SO_srcacc_pci 0x0 - #define SO_srcacc_agp 0x2 - #define SO_srcorg_MASK 0x7 /* bits 3-31 */ - #define SO_srcorg_SHIFT 3 - - #define STAT_softrapen_MASK 0xfffffffe /* bit 0 */ - #define STAT_softrapen_disable 0x0 - #define STAT_softrapen_enable 0x1 - #define STAT_pickpen_MASK 0xfffffffb /* bit 2 */ - #define STAT_pickpen_disable 0x0 - #define STAT_pickpen_enable 0x4 - #define STAT_vsyncsts_MASK 0xfffffff7 /* bit 3 */ - #define STAT_vsyncsts_disable 0x0 - #define STAT_vsyncsts_enable 0x8 - #define STAT_vsyncpen_MASK 0xffffffef /* bit 4 */ - #define STAT_vsyncpen_disable 0x0 - #define STAT_vsyncpen_enable 0x10 - #define STAT_vlinepen_MASK 0xffffffdf /* bit 5 */ - #define STAT_vlinepen_disable 0x0 - #define STAT_vlinepen_enable 0x20 - #define STAT_extpen_MASK 0xffffffbf /* bit 6 */ - #define STAT_extpen_disable 0x0 - #define STAT_extpen_enable 0x40 - #define STAT_wpen_MASK 0xffffff7f /* bit 7 */ - #define STAT_wpen_disable 0x0 - #define STAT_wpen_enable 0x80 - #define STAT_wcpen_MASK 0xfffffeff /* bit 8 */ - #define STAT_wcpen_disable 0x0 - #define STAT_wcpen_enable 0x100 - #define STAT_dwgengsts_MASK 0xfffeffff /* bit 16 */ - #define STAT_dwgengsts_disable 0x0 - #define STAT_dwgengsts_enable 0x10000 - #define STAT_endprdmasts_MASK 0xfffdffff /* bit 17 */ - #define STAT_endprdmasts_disable 0x0 - #define STAT_endprdmasts_enable 0x20000 - #define STAT_wbusy_MASK 0xfffbffff /* bit 18 */ - #define STAT_wbusy_disable 0x0 - #define STAT_wbusy_enable 0x40000 - #define STAT_swflag_MASK 0xfffffff /* bits 28-31 */ - #define STAT_swflag_SHIFT 28 - - #define S_sref_MASK 0xffffff00 /* bits 0-7 */ - #define S_sref_SHIFT 0 - #define S_smsk_MASK 0xffff00ff /* bits 8-15 */ - #define S_smsk_SHIFT 8 - #define S_swtmsk_MASK 0xff00ffff /* bits 16-23 */ - #define S_swtmsk_SHIFT 16 - - #define SC_smode_MASK 0xfffffff8 /* bits 0-2 */ - #define SC_smode_salways 0x0 /* val 0, shift 0 */ - #define SC_smode_snever 0x1 /* val 1, shift 0 */ - #define SC_smode_se 0x2 /* val 2, shift 0 */ - #define SC_smode_sne 0x3 /* val 3, shift 0 */ - #define SC_smode_slt 0x4 /* val 4, shift 0 */ - #define SC_smode_slte 0x5 /* val 5, shift 0 */ - #define SC_smode_sgt 0x6 /* val 6, shift 0 */ - #define SC_smode_sgte 0x7 /* val 7, shift 0 */ - #define SC_sfailop_MASK 0xffffffc7 /* bits 3-5 */ - #define SC_sfailop_keep 0x0 /* val 0, shift 3 */ - #define SC_sfailop_zero 0x8 /* val 1, shift 3 */ - #define SC_sfailop_replace 0x10 /* val 2, shift 3 */ - #define SC_sfailop_incrsat 0x18 /* val 3, shift 3 */ - #define SC_sfailop_decrsat 0x20 /* val 4, shift 3 */ - #define SC_sfailop_invert 0x28 /* val 5, shift 3 */ - #define SC_sfailop_incr 0x30 /* val 6, shift 3 */ - #define SC_sfailop_decr 0x38 /* val 7, shift 3 */ - #define SC_szfailop_MASK 0xfffffe3f /* bits 6-8 */ - #define SC_szfailop_keep 0x0 /* val 0, shift 6 */ - #define SC_szfailop_zero 0x40 /* val 1, shift 6 */ - #define SC_szfailop_replace 0x80 /* val 2, shift 6 */ - #define SC_szfailop_incrsat 0xc0 /* val 3, shift 6 */ - #define SC_szfailop_decrsat 0x100 /* val 4, shift 6 */ - #define SC_szfailop_invert 0x140 /* val 5, shift 6 */ - #define SC_szfailop_incr 0x180 /* val 6, shift 6 */ - #define SC_szfailop_decr 0x1c0 /* val 7, shift 6 */ - #define SC_szpassop_MASK 0xfffff1ff /* bits 9-11 */ - #define SC_szpassop_keep 0x0 /* val 0, shift 9 */ - #define SC_szpassop_zero 0x200 /* val 1, shift 9 */ - #define SC_szpassop_replace 0x400 /* val 2, shift 9 */ - #define SC_szpassop_incrsat 0x600 /* val 3, shift 9 */ - #define SC_szpassop_decrsat 0x800 /* val 4, shift 9 */ - #define SC_szpassop_invert 0xa00 /* val 5, shift 9 */ - #define SC_szpassop_incr 0xc00 /* val 6, shift 9 */ - #define SC_szpassop_decr 0xe00 /* val 7, shift 9 */ - - #define TD1_color1arg2selMASK 0xfffffffc /* bits 0-1 */ - #define TD1_color1alphaselMASK 0xffffffe3 /* bits 2-4 */ - #define TD1_color1alphaselSHIFT 2 - #define TD1_color1arg1alphaMASK 0xffffffdf /* bit 5 */ - #define TD1_color1arg1alphadisable 0x0 - #define TD1_color1arg1alphaenable 0x20 - #define TD1_color1arg1invMASK 0xffffffbf /* bit 6 */ - #define TD1_color1arg1invdisable 0x0 - #define TD1_color1arg1invenable 0x40 - #define TD1_color1arg2alphaMASK 0xffffff7f /* bit 7 */ - #define TD1_color1arg2alphadisable 0x0 - #define TD1_color1arg2alphaenable 0x80 - #define TD1_color1arg2invMASK 0xfffffeff /* bit 8 */ - #define TD1_color1arg2invdisable 0x0 - #define TD1_color1arg2invenable 0x100 - #define TD1_color1alpha1invMASK 0xfffffdff /* bit 9 */ - #define TD1_color1alpha1invdisable 0x0 - #define TD1_color1alpha1invenable 0x200 - #define TD1_color1alpha2invMASK 0xfffffbff /* bit 10 */ - #define TD1_color1alpha2invdisable 0x0 - #define TD1_color1alpha2invenable 0x400 - #define TD1_color1selMASK 0xff9fffff /* bits 21-22 */ - #define TD1_color1selarg1 0x0 /* val 0, shift 21 */ - #define TD1_color1selarg2 0x200000 /* val 1, shift 21 */ - #define TD1_color1seladd 0x400000 /* val 2, shift 21 */ - #define TD1_color1selmul 0x600000 /* val 3, shift 21 */ - #define TD1_alpha1selMASK 0x3fffffff /* bits 30-31 */ - #define TD1_alpha1selarg1 0x0 /* val 0, shift 30 */ - #define TD1_alpha1selarg2 0x40000000 /* val 1, shift 30 */ - #define TD1_alpha1seladd 0x80000000 /* val 2, shift 30 */ - #define TD1_alpha1selmul 0xc0000000 /* val 3, shift 30 */ - - #define TST_ramtsten_MASK 0xfffffffe /* bit 0 */ - #define TST_ramtsten_disable 0x0 - #define TST_ramtsten_enable 0x1 - #define TST_ramtstdone_MASK 0xfffffffd /* bit 1 */ - #define TST_ramtstdone_disable 0x0 - #define TST_ramtstdone_enable 0x2 - #define TST_wramtstpass_MASK 0xfffffffb /* bit 2 */ - #define TST_wramtstpass_disable 0x0 - #define TST_wramtstpass_enable 0x4 - #define TST_tcachetstpass_MASK 0xfffffff7 /* bit 3 */ - #define TST_tcachetstpass_disable 0x0 - #define TST_tcachetstpass_enable 0x8 - #define TST_tluttstpass_MASK 0xffffffef /* bit 4 */ - #define TST_tluttstpass_disable 0x0 - #define TST_tluttstpass_enable 0x10 - #define TST_luttstpass_MASK 0xffffffdf /* bit 5 */ - #define TST_luttstpass_disable 0x0 - #define TST_luttstpass_enable 0x20 - #define TST_besramtstpass_MASK 0xffffffbf /* bit 6 */ - #define TST_besramtstpass_disable 0x0 - #define TST_besramtstpass_enable 0x40 - #define TST_ringen_MASK 0xfffffeff /* bit 8 */ - #define TST_ringen_disable 0x0 - #define TST_ringen_enable 0x100 - #define TST_apllbyp_MASK 0xfffffdff /* bit 9 */ - #define TST_apllbyp_disable 0x0 - #define TST_apllbyp_enable 0x200 - #define TST_hiten_MASK 0xfffffbff /* bit 10 */ - #define TST_hiten_disable 0x0 - #define TST_hiten_enable 0x400 - #define TST_tmode_MASK 0xffffc7ff /* bits 11-13 */ - #define TST_tmode_SHIFT 11 - #define TST_tclksel_MASK 0xfffe3fff /* bits 14-16 */ - #define TST_tclksel_SHIFT 14 - #define TST_ringcnten_MASK 0xfffdffff /* bit 17 */ - #define TST_ringcnten_disable 0x0 - #define TST_ringcnten_enable 0x20000 - #define TST_ringcnt_MASK 0xc003ffff /* bits 18-29 */ - #define TST_ringcnt_SHIFT 18 - #define TST_ringcntclksl_MASK 0xbfffffff /* bit 30 */ - #define TST_ringcntclksl_disable 0x0 - #define TST_ringcntclksl_enable 0x40000000 - #define TST_biosboot_MASK 0x7fffffff /* bit 31 */ - #define TST_biosboot_disable 0x0 - #define TST_biosboot_enable 0x80000000 - - #define TMC_tformat_MASK 0xfffffff0 /* bits 0-3 */ - #define TMC_tformat_tw4 0x0 /* val 0, shift 0 */ - #define TMC_tformat_tw8 0x1 /* val 1, shift 0 */ - #define TMC_tformat_tw15 0x2 /* val 2, shift 0 */ - #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ - #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ - #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ - #define TMC_tformat_tw422 0xa /* val 10, shift 0 */ - #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ - #define TMC_tpitchlin_disable 0x0 - #define TMC_tpitchlin_enable 0x100 - #define TMC_tpitchext_MASK 0xfff001ff /* bits 9-19 */ - #define TMC_tpitchext_SHIFT 9 - #define TMC_tpitch_MASK 0xfff8ffff /* bits 16-18 */ - #define TMC_tpitch_SHIFT 16 - #define TMC_owalpha_MASK 0xffbfffff /* bit 22 */ - #define TMC_owalpha_disable 0x0 - #define TMC_owalpha_enable 0x400000 - #define TMC_azeroextend_MASK 0xff7fffff /* bit 23 */ - #define TMC_azeroextend_disable 0x0 - #define TMC_azeroextend_enable 0x800000 - #define TMC_decalckey_MASK 0xfeffffff /* bit 24 */ - #define TMC_decalckey_disable 0x0 - #define TMC_decalckey_enable 0x1000000 - #define TMC_takey_MASK 0xfdffffff /* bit 25 */ - #define TMC_takey_0 0x0 - #define TMC_takey_1 0x2000000 - #define TMC_tamask_MASK 0xfbffffff /* bit 26 */ - #define TMC_tamask_0 0x0 - #define TMC_tamask_1 0x4000000 - #define TMC_clampv_MASK 0xf7ffffff /* bit 27 */ - #define TMC_clampv_disable 0x0 - #define TMC_clampv_enable 0x8000000 - #define TMC_clampu_MASK 0xefffffff /* bit 28 */ - #define TMC_clampu_disable 0x0 - #define TMC_clampu_enable 0x10000000 - #define TMC_tmodulate_MASK 0xdfffffff /* bit 29 */ - #define TMC_tmodulate_disable 0x0 - #define TMC_tmodulate_enable 0x20000000 - #define TMC_strans_MASK 0xbfffffff /* bit 30 */ - #define TMC_strans_disable 0x0 - #define TMC_strans_enable 0x40000000 - #define TMC_itrans_MASK 0x7fffffff /* bit 31 */ - #define TMC_itrans_disable 0x0 - #define TMC_itrans_enable 0x80000000 - - #define TMC_decalblend_MASK 0xfffffffe /* bit 0 */ - #define TMC_decalblend_disable 0x0 - #define TMC_decalblend_enable 0x1 - #define TMC_idecal_MASK 0xfffffffd /* bit 1 */ - #define TMC_idecal_disable 0x0 - #define TMC_idecal_enable 0x2 - #define TMC_decaldis_MASK 0xfffffffb /* bit 2 */ - #define TMC_decaldis_disable 0x0 - #define TMC_decaldis_enable 0x4 - #define TMC_ckstransdis_MASK 0xffffffef /* bit 4 */ - #define TMC_ckstransdis_disable 0x0 - #define TMC_ckstransdis_enable 0x10 - #define TMC_borderen_MASK 0xffffffdf /* bit 5 */ - #define TMC_borderen_disable 0x0 - #define TMC_borderen_enable 0x20 - #define TMC_specen_MASK 0xffffffbf /* bit 6 */ - #define TMC_specen_disable 0x0 - #define TMC_specen_enable 0x40 - - #define TF_minfilter_MASK 0xfffffff0 /* bits 0-3 */ - #define TF_minfilter_nrst 0x0 /* val 0, shift 0 */ - #define TF_minfilter_bilin 0x2 /* val 2, shift 0 */ - #define TF_minfilter_cnst 0x3 /* val 3, shift 0 */ - #define TF_minfilter_mm1s 0x8 /* val 8, shift 0 */ - #define TF_minfilter_mm2s 0x9 /* val 9, shift 0 */ - #define TF_minfilter_mm4s 0xa /* val 10, shift 0 */ - #define TF_minfilter_mm8s 0xc /* val 12, shift 0 */ - #define TF_magfilter_MASK 0xffffff0f /* bits 4-7 */ - #define TF_magfilter_nrst 0x0 /* val 0, shift 4 */ - #define TF_magfilter_bilin 0x20 /* val 2, shift 4 */ - #define TF_magfilter_cnst 0x30 /* val 3, shift 4 */ - #define TF_avgstride_MASK 0xfff7ffff /* bit 19 */ - #define TF_avgstride_disable 0x0 - #define TF_avgstride_enable 0x80000 - #define TF_filteralpha_MASK 0xffefffff /* bit 20 */ - #define TF_filteralpha_disable 0x0 - #define TF_filteralpha_enable 0x100000 - #define TF_fthres_MASK 0xe01fffff /* bits 21-28 */ - #define TF_fthres_SHIFT 21 - #define TF_mapnb_MASK 0x1fffffff /* bits 29-31 */ - #define TF_mapnb_SHIFT 29 - - #define TH_th_MASK 0xffffffc0 /* bits 0-5 */ - #define TH_th_SHIFT 0 - #define TH_rfh_MASK 0xffff81ff /* bits 9-14 */ - #define TH_rfh_SHIFT 9 - #define TH_thmask_MASK 0xe003ffff /* bits 18-28 */ - #define TH_thmask_SHIFT 18 - - #define TO_texorgmap_MASK 0xfffffffe /* bit 0 */ - #define TO_texorgmap_fb 0x0 - #define TO_texorgmap_sys 0x1 - #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ - #define TO_texorgacc_pci 0x0 - #define TO_texorgacc_agp 0x2 - #define TO_texorg_MASK 0x1f /* bits 5-31 */ - #define TO_texorg_SHIFT 5 - - #define TT_tckey_MASK 0xffff0000 /* bits 0-15 */ - #define TT_tckey_SHIFT 0 - #define TT_tkmask_MASK 0xffff /* bits 16-31 */ - #define TT_tkmask_SHIFT 16 - - #define TT_tckeyh_MASK 0xffff0000 /* bits 0-15 */ - #define TT_tckeyh_SHIFT 0 - #define TT_tkmaskh_MASK 0xffff /* bits 16-31 */ - #define TT_tkmaskh_SHIFT 16 - - #define TW_tw_MASK 0xffffffc0 /* bits 0-5 */ - #define TW_tw_SHIFT 0 - #define TW_rfw_MASK 0xffff81ff /* bits 9-14 */ - #define TW_rfw_SHIFT 9 - #define TW_twmask_MASK 0xe003ffff /* bits 18-28 */ - #define TW_twmask_SHIFT 18 - - #define WAS_seqdst0_MASK 0xffffffc0 /* bits 0-5 */ - #define WAS_seqdst0_SHIFT 0 - #define WAS_seqdst1_MASK 0xfffff03f /* bits 6-11 */ - #define WAS_seqdst1_SHIFT 6 - #define WAS_seqdst2_MASK 0xfffc0fff /* bits 12-17 */ - #define WAS_seqdst2_SHIFT 12 - #define WAS_seqdst3_MASK 0xff03ffff /* bits 18-23 */ - #define WAS_seqdst3_SHIFT 18 - #define WAS_seqlen_MASK 0xfcffffff /* bits 24-25 */ - #define WAS_wfirsttag_MASK 0xfbffffff /* bit 26 */ - #define WAS_wfirsttag_disable 0x0 - #define WAS_wfirsttag_enable 0x4000000 - #define WAS_wsametag_MASK 0xf7ffffff /* bit 27 */ - #define WAS_wsametag_disable 0x0 - #define WAS_wsametag_enable 0x8000000 - #define WAS_seqoff_MASK 0xefffffff /* bit 28 */ - #define WAS_seqoff_disable 0x0 - #define WAS_seqoff_enable 0x10000000 - - #define WMA_wcodeaddr_MASK 0xff /* bits 8-31 */ - #define WMA_wcodeaddr_SHIFT 8 - - #define WF_walustsflag_MASK 0xffffff00 /* bits 0-7 */ - #define WF_walustsflag_SHIFT 0 - #define WF_walucfgflag_MASK 0xffff00ff /* bits 8-15 */ - #define WF_walucfgflag_SHIFT 8 - #define WF_wprgflag_MASK 0xffff /* bits 16-31 */ - #define WF_wprgflag_SHIFT 16 - - #define WF1_walustsflag1_MASK 0xffffff00 /* bits 0-7 */ - #define WF1_walustsflag1_SHIFT 0 - #define WF1_walucfgflag1_MASK 0xffff00ff /* bits 8-15 */ - #define WF1_walucfgflag1_SHIFT 8 - #define WF1_wprgflag1_MASK 0xffff /* bits 16-31 */ - #define WF1_wprgflag1_SHIFT 16 - - #define WGV_wgetmsbmin_MASK 0xffffffe0 /* bits 0-4 */ - #define WGV_wgetmsbmin_SHIFT 0 - #define WGV_wgetmsbmax_MASK 0xffffe0ff /* bits 8-12 */ - #define WGV_wgetmsbmax_SHIFT 8 - #define WGV_wbrklefttop_MASK 0xfffeffff /* bit 16 */ - #define WGV_wbrklefttop_disable 0x0 - #define WGV_wbrklefttop_enable 0x10000 - #define WGV_wfastcrop_MASK 0xfffdffff /* bit 17 */ - #define WGV_wfastcrop_disable 0x0 - #define WGV_wfastcrop_enable 0x20000 - #define WGV_wcentersnap_MASK 0xfffbffff /* bit 18 */ - #define WGV_wcentersnap_disable 0x0 - #define WGV_wcentersnap_enable 0x40000 - #define WGV_wbrkrighttop_MASK 0xfff7ffff /* bit 19 */ - #define WGV_wbrkrighttop_disable 0x0 - #define WGV_wbrkrighttop_enable 0x80000 - - #define WIA_wmode_MASK 0xfffffffc /* bits 0-1 */ - #define WIA_wmode_suspend 0x0 /* val 0, shift 0 */ - #define WIA_wmode_resume 0x1 /* val 1, shift 0 */ - #define WIA_wmode_jump 0x2 /* val 2, shift 0 */ - #define WIA_wmode_start 0x3 /* val 3, shift 0 */ - #define WIA_wagp_MASK 0xfffffffb /* bit 2 */ - #define WIA_wagp_pci 0x0 - #define WIA_wagp_agp 0x4 - #define WIA_wiaddr_MASK 0x7 /* bits 3-31 */ - #define WIA_wiaddr_SHIFT 3 - - #define WIA2_wmode_MASK 0xfffffffc /* bits 0-1 */ - #define WIA2_wmode_suspend 0x0 /* val 0, shift 0 */ - #define WIA2_wmode_resume 0x1 /* val 1, shift 0 */ - #define WIA2_wmode_jump 0x2 /* val 2, shift 0 */ - #define WIA2_wmode_start 0x3 /* val 3, shift 0 */ - #define WIA2_wagp_MASK 0xfffffffb /* bit 2 */ - #define WIA2_wagp_pci 0x0 - #define WIA2_wagp_agp 0x4 - #define WIA2_wiaddr_MASK 0x7 /* bits 3-31 */ - #define WIA2_wiaddr_SHIFT 3 - - #define WIMA_wimemaddr_MASK 0xffffff00 /* bits 0-7 */ - #define WIMA_wimemaddr_SHIFT 0 - - #define WM_wucodecache_MASK 0xfffffffe /* bit 0 */ - #define WM_wucodecache_disable 0x0 - #define WM_wucodecache_enable 0x1 - #define WM_wmaster_MASK 0xfffffffd /* bit 1 */ - #define WM_wmaster_disable 0x0 - #define WM_wmaster_enable 0x2 - #define WM_wcacheflush_MASK 0xfffffff7 /* bit 3 */ - #define WM_wcacheflush_disable 0x0 - #define WM_wcacheflush_enable 0x8 - - #define WVS_wvrtxsz_MASK 0xffffffc0 /* bits 0-5 */ - #define WVS_wvrtxsz_SHIFT 0 - #define WVS_primsz_MASK 0xffffc0ff /* bits 8-13 */ - #define WVS_primsz_SHIFT 8 - - #define XYEA_x_end_MASK 0xffff0000 /* bits 0-15 */ - #define XYEA_x_end_SHIFT 0 - #define XYEA_y_end_MASK 0xffff /* bits 16-31 */ - #define XYEA_y_end_SHIFT 16 - - #define XYSA_x_start_MASK 0xffff0000 /* bits 0-15 */ - #define XYSA_x_start_SHIFT 0 - #define XYSA_y_start_MASK 0xffff /* bits 16-31 */ - #define XYSA_y_start_SHIFT 16 - - #define YA_ydst_MASK 0xff800000 /* bits 0-22 */ - #define YA_ydst_SHIFT 0 - #define YA_sellin_MASK 0x1fffffff /* bits 29-31 */ - #define YA_sellin_SHIFT 29 - - #define YDL_length_MASK 0xffff0000 /* bits 0-15 */ - #define YDL_length_SHIFT 0 - #define YDL_yval_MASK 0xffff /* bits 16-31 */ - #define YDL_yval_SHIFT 16 - - #define ZO_zorgmap_MASK 0xfffffffe /* bit 0 */ - #define ZO_zorgmap_fb 0x0 - #define ZO_zorgmap_sys 0x1 - #define ZO_zorgacc_MASK 0xfffffffd /* bit 1 */ - #define ZO_zorgacc_pci 0x0 - #define ZO_zorgacc_agp 0x2 - #define ZO_zorg_MASK 0x3 /* bits 2-31 */ - #define ZO_zorg_SHIFT 2 - - - - -/**************** (END) AUTOMATICLY GENERATED REGISTER FILE ******************/ - -#endif /* _MGAREGS_H_ */ - diff --git a/linux/proc.c b/linux/proc.c index db98fd6a..3b07eedf 100644 --- a/linux/proc.c +++ b/linux/proc.c @@ -1,6 +1,6 @@ /* proc.c -- /proc support for DRM -*- linux-c -*- * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com - * Revised: Sun Feb 13 23:41:04 2000 by kevin@precisioninsight.com + * Revised: Mon Apr 10 23:22:15 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -400,6 +400,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len, pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); #endif DRM_PROC_PRINT("\n"); +#if 0 for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) { pgd = pgd_offset(vma->vm_mm, i); pmd = pmd_offset(pgd, i); @@ -420,6 +421,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len, DRM_PROC_PRINT(" 0x%08lx\n", i); } } +#endif } return len; diff --git a/linux/r128_context.c b/linux/r128_context.c index d146035a..d288fd28 100644 --- a/linux/r128_context.c +++ b/linux/r128_context.c @@ -39,7 +39,9 @@ extern drm_ctx_t r128_res_ctx; static int r128_alloc_queue(drm_device_t *dev) { +#if 0 static int context = 0; +#endif return drm_ctxbitmap_next(dev); } diff --git a/linux/r128_dma.c b/linux/r128_dma.c new file mode 100644 index 00000000..b64fc14e --- /dev/null +++ b/linux/r128_dma.c @@ -0,0 +1,612 @@ +/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*- + * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * 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@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * $XFree86$ + * + */ + +#define __NO_VERSION__ +#include "drmP.h" +#include "r128_drv.h" + +#include <linux/interrupt.h> /* For task queue support */ + + + +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) + +#define R128_CLOCK_CNTL_INDEX 0x0008 +#define R128_CLOCK_CNTL_DATA 0x000c +# define R128_PLL_WR_EN (1 << 7) + +#define R128_MCLK_CNTL 0x000f +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CPP (1 << 17) + +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) + +#define R128_PM4_BUFFER_CNTL 0x0704 +# define R128_PM4_NONPM4 (0 << 28) +# define R128_PM4_192PIO (1 << 28) +# define R128_PM4_192BM (2 << 28) +# define R128_PM4_128PIO_64INDBM (3 << 28) +# define R128_PM4_128BM_64INDBM (4 << 28) +# define R128_PM4_64PIO_128INDBM (5 << 28) +# define R128_PM4_64BM_128INDBM (6 << 28) +# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) +# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) +# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) + + +#define R128_PM4_BUFFER_DL_RPTR 0x0710 +#define R128_PM4_BUFFER_DL_WPTR 0x0714 +# define R128_PM4_BUFFER_DL_DONE (1 << 31) + +#define R128_PM4_VC_FPU_SETUP 0x071c + +#define R128_PM4_STAT 0x07b8 +# define R128_PM4_FIFOCNT_MASK 0x0fff +# define R128_PM4_BUSY (1 << 16) +# define R128_PM4_GUI_ACTIVE (1 << 31) + +#define R128_PM4_FIFO_DATA_EVEN 0x1000 +#define R128_PM4_FIFO_DATA_ODD 0x1004 + +#define R128_CCE_PACKET0 0x00000000 +#define R128_CCE_PACKET1 0x40000000 +#define R128_CCE_PACKET2 0x80000000 +# define R128_CCE_PACKET_MASK 0xC0000000 +# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define R128_CCE_PACKET0_REG_MASK 0x000007ff +# define R128_CCE_PACKET1_REG0_MASK 0x000007ff +# define R128_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define R128_TIMEOUT 2000000 + +/* WARNING!!! MAGIC NUMBERS!!! The number of regions already added to + the kernel must be specified here. This must match the order the X + server uses for instantiating register regions, or must be passed in + a new ioctl. */ +#define R128_SAREA() 0 +#define R128_FB() 1 +#define R128_AGP_RING() 2 +#define R128_AGP_READ_PTR() 3 +#define R128_AGP_VERTBUFS() 4 +#define R128_AGP_INDIRECTBUFS() 5 +#define R128_AGP_TEXTURES() 6 +#define R128_REG(reg) 7 + +#define R128_BASE(reg) ((u32)((drm_device_t *)dev)->maplist[R128_REG(reg)]->handle) +#define R128_ADDR(reg) (R128_BASE(reg) + reg) + +#define R128_DEREF(reg) *(__volatile__ int *)R128_ADDR(reg) +#define R128_READ(reg) R128_DEREF(reg) +#define R128_WRITE(reg,val) do { R128_DEREF(reg) = val; } while (0) + +#define R128_DEREF8(reg) *(__volatile__ char *)R128_ADDR(reg) +#define R128_READ8(reg) R128_DEREF8(reg) +#define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0) + +#define R128_WRITE_PLL(addr,val) \ +do { \ + R128_WRITE8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \ + R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \ +} while (0) + +static int R128_READ_PLL(drm_device_t *dev, int addr) +{ + R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return R128_READ(R128_CLOCK_CNTL_DATA); +} + +static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init) +{ + drm_r128_private_t *dev_priv; + drm_map_t *map = NULL; + + dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); + if (dev_priv == NULL) return -ENOMEM; + dev->dev_private = (void *)dev_priv; + + memset(dev_priv, 0, sizeof(drm_r128_private_t)); + + dev_priv->cce_mode = init->cce_mode; + dev_priv->cce_fifo_size = init->cce_fifo_size; + dev_priv->cce_is_bm_mode = + ((init->cce_mode == R128_PM4_192BM) || + (init->cce_mode == R128_PM4_128BM_64INDBM) || + (init->cce_mode == R128_PM4_64BM_128INDBM) || + (init->cce_mode == R128_PM4_64BM_64VCBM_64INDBM)); + dev_priv->cce_secure = init->cce_secure; + + map = dev->maplist[R128_SAREA()]; + dev_priv->sarea_priv = (drm_r128_sarea_t *)((u8 *)map->handle + + init->sarea_priv_offset); + +#define DO_REMAP(v) \ + do { \ + drm_map_t *_m; \ + _m = dev->maplist[(v)]; \ + _m->handle = drm_ioremap(_m->offset, _m->size); \ + } while (0) + + DO_REMAP(R128_AGP_RING()); + DO_REMAP(R128_AGP_READ_PTR()); + DO_REMAP(R128_AGP_VERTBUFS()); +#if 0 + DO_REMAP(R128_AGP_INDIRECTBUFS()); + DO_REMAP(R128_AGP_TEXTURES()); +#endif + + dev_priv->ring_size = init->ring_size; + dev_priv->ring_entries = init->ring_size/sizeof(u32); + dev_priv->ring_read_ptr = (__volatile__ u32 *) + dev->maplist[R128_AGP_READ_PTR()]->handle; + dev_priv->ring_start = (u32 *)dev->maplist[R128_AGP_RING()]->handle; + dev_priv->ring_end = ((u32 *)dev->maplist[R128_AGP_RING()]->handle + + dev_priv->ring_entries); + + return 0; +} + +static int r128_do_cleanup_cce(drm_device_t *dev) +{ +#define DO_REMAPFREE(v) \ + do { \ + drm_map_t *_m; \ + _m = dev->maplist[(v)]; \ + drm_ioremapfree(_m->handle, _m->size); \ + } while (0) + + DO_REMAPFREE(R128_AGP_RING()); + DO_REMAPFREE(R128_AGP_READ_PTR()); + DO_REMAPFREE(R128_AGP_VERTBUFS()); +#if 0 + DO_REMAPFREE(R128_AGP_INDIRECTBUFS()); + DO_REMAPFREE(R128_AGP_TEXTURES()); +#endif + + return 0; +} + +int r128_init_cce(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_r128_init_t init; + + copy_from_user_ret(&init, (drm_r128_init_t *)arg, sizeof(init), + -EFAULT); + + switch (init.func) { + case R128_INIT_CCE: + return r128_do_init_cce(dev, &init); + case R128_CLEANUP_CCE: + return r128_do_cleanup_cce(dev); + } + + return -EINVAL; +} + +static int r128_do_engine_flush(drm_device_t *dev) +{ + u32 tmp; + int i; + + tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL; + R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp); + + for (i = 0; i < R128_TIMEOUT; i++) + if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) + return 0; + + return -EBUSY; +} + +int r128_do_engine_reset(drm_device_t *dev) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *)dev->dev_private; + u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; + int ret; + + ret = r128_do_engine_flush(dev); + + clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); + mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); + + R128_WRITE_PLL(R128_MCLK_CNTL, + mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CPP); + + gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL); + + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + (void)R128_READ(R128_GEN_RESET_CNTL); + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + (void)R128_READ(R128_GEN_RESET_CNTL); + + R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl); + R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl); + + /* For CCE ring buffer only */ + if (dev_priv->cce_is_bm_mode) { + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0); + R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0); + *dev_priv->ring_read_ptr = 0; + dev_priv->sarea_priv->ring_write = 0; + } + + return 0; +} + +int r128_engine_reset(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; + + return r128_do_engine_reset(dev); +} + +static int r128_do_wait_for_fifo(drm_device_t *dev, int entries) +{ + int i; + + for (i = 0; i < R128_TIMEOUT; i++) { + int slots = R128_READ(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK; + if (slots >= entries) return 0; + } + (void)r128_do_engine_reset(dev); + return -EBUSY; +} + +int r128_do_wait_for_idle(drm_device_t *dev) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *)dev->dev_private; + int i; + + if (dev_priv->cce_is_bm_mode) { + u32 tmp; + tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR); + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, + tmp | R128_PM4_BUFFER_DL_DONE); + + for (i = 0; i < R128_TIMEOUT; i++) { + if (*dev_priv->ring_read_ptr == dev_priv->sarea_priv->ring_write) { + int pm4stat = R128_READ(R128_PM4_STAT); + if ((pm4stat & R128_PM4_FIFOCNT_MASK) == dev_priv->cce_fifo_size && + !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) + return 0; + } + } + (void)r128_do_engine_reset(dev); + return -EBUSY; + } else { + int ret = r128_do_wait_for_fifo(dev, dev_priv->cce_fifo_size); + if (ret < 0) return ret; + + for (i = 0; i < R128_TIMEOUT; i++) { + int pm4stat = R128_READ(R128_PM4_STAT); + if (!(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { + return r128_do_engine_flush(dev); + } + } + (void)r128_do_engine_reset(dev); + return -EBUSY; + } +} + +int r128_wait_for_idle(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; + + return r128_do_wait_for_idle(dev); +} + +static int r128_submit_packets_ring_secure(drm_device_t *dev, + drm_r128_packet_t *packet) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *)dev->dev_private; + int write = dev_priv->sarea_priv->ring_write; + int *write_ptr = dev_priv->ring_start + write; + int count = packet->count; + int ret = 0; + int timeout; + u32 *buffer, *commands; + int size; + u32 tmp = 0; + int psize = 0; + int writing = 1; + + if (count >= dev_priv->ring_entries) { + count = dev_priv->ring_entries-1; + ret = packet->count - count; + } + + size = count * sizeof(u32); + if ((commands = buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; + copy_from_user_ret(buffer, packet->buffer, size, -EFAULT); + + while (count > 0) { + tmp = *commands++; + if (!psize) { + writing = 1; + + if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <= + (0x1004 << 9)) { + if ((tmp & R128_CCE_PACKET1_REG1_MASK) != + (R128_PM4_VC_FPU_SETUP << 9)) { + writing = 0; + } + } + psize = 3; + } else { + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } + } + psize--; + + if (writing) { + write++; + *write_ptr++ = tmp; + } + if (write >= dev_priv->ring_entries) { + write = 0; + write_ptr = dev_priv->ring_start; + } + timeout = 0; + while (write == *dev_priv->ring_read_ptr) { + (void)R128_READ(R128_PM4_BUFFER_DL_RPTR); + if (timeout++ >= R128_TIMEOUT) { + kfree(buffer); + return r128_do_engine_reset(dev); + } + } + count--; + } + + if (write < 32) { + memcpy(dev_priv->ring_end, + dev_priv->ring_start, + write * sizeof(u32)); + } + + dev_priv->sarea_priv->ring_write = write; + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); + + kfree(buffer); + + return ret; +} + +static int r128_submit_packets_pio_secure(drm_device_t *dev, + drm_r128_packet_t *packet) +{ + u32 *buffer, *commands; + int count = packet->count; + int size; + int ret; + u32 tmp = 0; + int psize = 0; + int writing = 1; + int addr = R128_PM4_FIFO_DATA_EVEN; + + size = count * sizeof(u32); + if ((commands = buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; + copy_from_user_ret(buffer, packet->buffer, size, -EFAULT); + + while (count > 0) { + tmp = *commands++; + if (!psize) { + writing = 1; + + if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET0) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET0_REG_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } else if ((tmp & R128_CCE_PACKET_MASK) == R128_CCE_PACKET1) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2)) { + if ((tmp & R128_CCE_PACKET1_REG0_MASK) != + (R128_PM4_VC_FPU_SETUP >> 2)) { + writing = 0; + } + } else if ((tmp & R128_CCE_PACKET1_REG1_MASK) <= + (0x1004 << 9)) { + if ((tmp & R128_CCE_PACKET1_REG1_MASK) != + (R128_PM4_VC_FPU_SETUP << 9)) { + writing = 0; + } + } + psize = 3; + } else { + psize = ((tmp & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; + } + } + psize--; + + if (writing) { + if ((ret = r128_do_wait_for_fifo(dev, 1)) < 0) { + kfree(buffer); + return ret; + } + R128_WRITE(addr, tmp); + addr ^= 0x0004; + } + + count--; + } + + if (addr == R128_PM4_FIFO_DATA_ODD) { + if ((ret = r128_do_wait_for_fifo(dev, 1)) < 0) { + kfree(buffer); + return ret; + } + R128_WRITE(addr, R128_CCE_PACKET2); + } + + kfree(buffer); + + return 0; +} + +static int r128_submit_packets_ring(drm_device_t *dev, + drm_r128_packet_t *packet) +{ + drm_r128_private_t *dev_priv = (drm_r128_private_t *)dev->dev_private; + int write = dev_priv->sarea_priv->ring_write; + int *write_ptr = dev_priv->ring_start + write; + int count = packet->count; + int ret = 0; + int timeout; + u32 *buffer, *commands; + int size; + + if (count >= dev_priv->ring_entries) { + count = dev_priv->ring_entries-1; + ret = packet->count - count; + } + + size = count * sizeof(u32); + if ((commands = buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; + copy_from_user_ret(buffer, packet->buffer, size, -EFAULT); + + while (count > 0) { + write++; + *write_ptr++ = *commands++; + if (write >= dev_priv->ring_entries) { + write = 0; + write_ptr = dev_priv->ring_start; + } + timeout = 0; + while (write == *dev_priv->ring_read_ptr) { + (void)R128_READ(R128_PM4_BUFFER_DL_RPTR); + if (timeout++ >= R128_TIMEOUT) { + kfree(buffer); + return r128_do_engine_reset(dev); + } + } + count--; + } + + if (write < 32) { + memcpy(dev_priv->ring_end, + dev_priv->ring_start, + write * sizeof(u32)); + } + + dev_priv->sarea_priv->ring_write = write; + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, write); + + kfree(buffer); + + return ret; +} + +static int r128_submit_packets_pio(drm_device_t *dev, + drm_r128_packet_t *packet) +{ + u32 *buffer, *commands; + int count = packet->count; + int size; + int ret; + + size = count * sizeof(u32); + if ((commands = buffer = kmalloc(size, 0)) == NULL) return -ENOMEM; + copy_from_user_ret(buffer, packet->buffer, size, -EFAULT); + + while (count > 1) { + if ((ret = r128_do_wait_for_fifo(dev, 2)) < 0) { + kfree(buffer); + return ret; + } + R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++); + R128_WRITE(R128_PM4_FIFO_DATA_ODD, *commands++); + count -= 2; + } + + if (count) { + if ((ret = r128_do_wait_for_fifo(dev, 2)) < 0) { + kfree(buffer); + return ret; + } + R128_WRITE(R128_PM4_FIFO_DATA_EVEN, *commands++); + R128_WRITE(R128_PM4_FIFO_DATA_ODD, R128_CCE_PACKET2); + } + + kfree(buffer); + + return 0; +} + +int r128_submit_packets(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_r128_private_t *dev_priv = (drm_r128_private_t *)dev->dev_private; + drm_r128_packet_t packet; + + copy_from_user_ret(&packet, (drm_r128_packet_t *)arg, sizeof(packet), + -EFAULT); + + if (dev_priv->cce_secure) { + if (dev_priv->cce_is_bm_mode) + return r128_submit_packets_ring_secure(dev, &packet); + else + return r128_submit_packets_pio_secure(dev, &packet); + } else { + if (dev_priv->cce_is_bm_mode) + return r128_submit_packets_ring(dev, &packet); + else + return r128_submit_packets_pio(dev, &packet); + } +} diff --git a/linux/r128_drm.h b/linux/r128_drm.h new file mode 100644 index 00000000..634349c6 --- /dev/null +++ b/linux/r128_drm.h @@ -0,0 +1,77 @@ +/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*- + * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * 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: Kevin E. Martin <kevin@precisioninsight.com> + * + * $XFree86$ + */ + +#ifndef _R128_DRM_H_ +#define _R128_DRM_H_ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmR128.h) + */ +typedef struct drm_r128_init { + enum { + R128_INIT_CCE = 0x01, + R128_CLEANUP_CCE = 0x02 + } func; + int sarea_priv_offset; + int cce_mode; + int cce_fifo_size; + int cce_secure; + int ring_size; +} drm_r128_init_t; + +typedef struct drm_r128_packet { + unsigned long *buffer; + int count; + int flags; +} drm_r128_packet_t; + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (r128_sarea.h) + */ +#define R128_LOCAL_TEX_HEAP 0 +#define R128_AGP_TEX_HEAP 1 +#define R128_NR_TEX_HEAPS 2 +#define R128_NR_TEX_REGIONS 64 +#define R128_LOG_TEX_GRANULARITY 16 + +typedef struct drm_tex_region { + unsigned char next, prev; + unsigned char in_use; + int age; +} drm_tex_region_t; + +typedef struct drm_r128_sarea { + drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + int tex_age[R128_NR_TEX_HEAPS]; + int ctx_owner; + int ring_write; +} drm_r128_sarea_t; + +#endif diff --git a/linux/r128_drv.c b/linux/r128_drv.c index d477a70d..764f7bd8 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -23,7 +23,8 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> * * $XFree86$ * @@ -37,10 +38,10 @@ EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" #define R128_DESC "r128" -#define R128_DATE "19991213" +#define R128_DATE "20000405" #define R128_MAJOR 0 #define R128_MINOR 0 -#define R128_PATCHLEVEL 1 +#define R128_PATCHLEVEL 2 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -95,6 +96,11 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_ENGINE_RESET)] = { r128_engine_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_SUBMIT_PACKETS)] = { r128_submit_packets, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_WAIT_FOR_IDLE)] = { r128_wait_for_idle, 1, 0 }, }; #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) diff --git a/linux/r128_drv.h b/linux/r128_drv.h index c1faf764..597c4686 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -23,7 +23,8 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * Author: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> * * $XFree86$ * @@ -32,6 +33,21 @@ #ifndef _R128_DRV_H_ #define _R128_DRV_H_ +typedef struct drm_r128_private { + int cce_mode; + int cce_fifo_size; + int cce_is_bm_mode; + int cce_secure; + + drm_r128_sarea_t *sarea_priv; + + __volatile__ u32 *ring_read_ptr; + + u32 *ring_start; + u32 *ring_end; + int ring_size; + int ring_entries; +} drm_r128_private_t; /* r128_drv.c */ extern int r128_init(void); extern void r128_cleanup(void); @@ -46,8 +62,17 @@ extern int r128_lock(struct inode *inode, struct file *filp, extern int r128_unlock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); - /* r128_context.c */ + /* r128_dma.c */ +extern int r128_init_cce(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int r128_engine_reset(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int r128_submit_packets(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int r128_wait_for_idle(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + /* r128_context.c */ extern int r128_resctx(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int r128_addctx(struct inode *inode, struct file *filp, @@ -1,6 +1,6 @@ /* vm.c -- Memory mapping for DRM -*- linux-c -*- * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com - * Revised: Mon Feb 14 00:16:45 2000 by kevin@precisioninsight.com + * Revised: Tue Apr 11 01:55:12 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -265,6 +265,10 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; + DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," + " offset = 0x%lx\n", + map->type, + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); vma->vm_ops = &drm_vm_ops; break; case _DRM_SHM: diff --git a/shared-core/drm.h b/shared-core/drm.h index ebc6f7e7..ecb23555 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Mon Feb 14 00:15:23 2000 by kevin@precisioninsight.com + * Revised: Sun Apr 9 20:33:27 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -61,6 +61,20 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" +#include "r128_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -321,5 +335,25 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) -/* 0x40 is reserved for mga dma init */ +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + +/* Rage 128 specific ioctls */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_ENGINE_RESET DRM_IO( 0x41) +#define DRM_IOCTL_R128_SUBMIT_PACKETS DRM_IOW( 0x42, drm_r128_packet_t) +#define DRM_IOCTL_R128_WAIT_FOR_IDLE DRM_IO( 0x43) + #endif diff --git a/shared/drm.h b/shared/drm.h index ebc6f7e7..ecb23555 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Mon Feb 14 00:15:23 2000 by kevin@precisioninsight.com + * Revised: Sun Apr 9 20:33:27 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -61,6 +61,20 @@ typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; +/* Warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well */ + +typedef struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +} drm_clip_rect_t; + +/* Seperate include files for the i810/mga specific structures */ +#include "mga_drm.h" +#include "i810_drm.h" +#include "r128_drm.h" typedef struct drm_version { int version_major; /* Major version */ @@ -321,5 +335,25 @@ typedef struct drm_agp_info { #define DRM_IOCTL_AGP_BIND DRM_IOWR(0x36, drm_agp_binding_t) #define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) -/* 0x40 is reserved for mga dma init */ +/* Mga specific ioctls */ +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) + +/* I810 specific ioctls */ +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) + +/* Rage 128 specific ioctls */ +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_ENGINE_RESET DRM_IO( 0x41) +#define DRM_IOCTL_R128_SUBMIT_PACKETS DRM_IOW( 0x42, drm_r128_packet_t) +#define DRM_IOCTL_R128_WAIT_FOR_IDLE DRM_IO( 0x43) + #endif |