diff options
author | keithw <keithw> | 2000-02-13 01:29:40 +0000 |
---|---|---|
committer | keithw <keithw> | 2000-02-13 01:29:40 +0000 |
commit | f7ca93f0b878a335e2667fb1222b2ec1675cc2cd (patch) | |
tree | 15a3e7f4f2eccda9f0498086d256b5b53396b41c | |
parent | 294128fe578a2bd4855b913e8d70cd8b8e82656f (diff) |
Working dma solution (has texture errors)
7 files changed, 701 insertions, 247 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c index a46cf3f1f..d77d3fa82 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_bufs.c @@ -33,6 +33,7 @@ #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, @@ -118,9 +119,6 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, buf->total = alignment; buf->order = order; buf->used = 0; -#if 0 - printk("offset : %d\n", offset); -#endif buf->offset = offset; /* Hrm */ buf->bus_address = dev->agp->base + agp_offset + offset; buf->address = (void *)(agp_offset + offset + dev->agp->base); @@ -129,6 +127,10 @@ int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, 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; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_clear.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_clear.c new file mode 100644 index 000000000..88ec13cd5 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_clear.c @@ -0,0 +1,279 @@ +/* i810_state.c -- State support for i810 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 "i810_drv.h" +#include "i810_dma.h" +#include "i810_drm_public.h" + + + +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 ]; + drm_i810_buf_priv_t *buf_priv = (drm_i810_buf_priv_t *)buf->dev_private; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_dma_t d; + + buf_priv->dma_type = I810_DMA_GENERAL; + buf->used = args->used; + + if (I810_VERBOSE) + printk("i810DmaGeneral idx %d used %d\n", args->idx, 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); + i810_dma_schedule(dev, 1); + + return 0; +} + + +static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) +{ + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_i810_buf_priv_t *buf_priv; + drm_buf_t *buf; + drm_dma_t d; + + + buf = dma->buflist[ args->idx ]; + buf->used = args->real_used; + + if (I810_VERBOSE) + printk("i810DmaVertex idx %d used %d\n", args->idx, buf->used); + + buf_priv = buf->dev_private; + buf_priv->dma_type = I810_DMA_VERTEX; + buf_priv->vertex_real_idx = args->real_idx; + buf_priv->vertex_discard = args->discard; + buf_priv->nbox = sarea_priv->nbox; + + if (buf_priv->nbox >= I810_NR_SAREA_CLIPRECTS) + buf_priv->nbox = I810_NR_SAREA_CLIPRECTS; + + if (buf_priv->nbox) + memcpy( buf_priv->boxes, + sarea_priv->boxes, + buf_priv->nbox * sizeof(xf86drmClipRectRec)); + + 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); + i810_dma_schedule(dev, 1); + return 0; +} + + + + +int i810_dma_general(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_i810_general_t general; + int retcode = 0; + + copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general), + -EFAULT); + + printk("i810 dma general idx %d used %d\n", + general.idx, general.used); + + retcode = i810DmaGeneral(dev, &general); + + return retcode; +} + +int i810_dma_vertex(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_i810_vertex_t vertex; + int retcode = 0; + + copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), + -EFAULT); + + printk("i810 dma vertex, idx %d used %d real_idx %d discard %d\n", + vertex.idx, vertex.real_used, vertex.real_idx, + vertex.discard); + + retcode = i810DmaVertex(dev, &vertex); + + return retcode; + +} + + +int i810_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; + + /* Please don't send us buffers. + */ + if (d.send_count != 0) { + DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", + current->pid, d.send_count); + return -EINVAL; + } + + /* We'll send you buffers. + */ + 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; + } + + d.granted_count = 0; + + if (!retcode && d.request_count) { + retcode = drm_dma_get_buffers(dev, &d); + } + + printk("i810_dma: %d returning, granted = %d\n", + current->pid, d.granted_count); + + copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT); + + return retcode; +} + + +#if 0 + +static int i810_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) +{ + DECLARE_WAITQUEUE(entry, current); + drm_buf_t *last_buf = NULL; + int retcode = 0; + drm_device_dma_t *dma = dev->dma; + drm_i810_private_t *dev_priv = dev->dev_private; + + d->context = DRM_KERNEL_CONTEXT; + + if ((retcode = drm_dma_enqueue(dev, d))) { + return retcode; + } + + atomic_inc(&dev_priv->pending_bufs); + i810_dma_schedule(dev, 1); + return retcode; +} + +int i810_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; + + DRM_DEBUG("i810_dma start\n"); + 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 (d.send_count < 0 || d.send_count > dma->buf_count) { + DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n", + current->pid, d.send_count, dma->buf_count); + return -EINVAL; + } + 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) { + retcode = i810_dma_send_buffers(dev, &d); + } + + 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); + + DRM_DEBUG("i810_dma end (granted)\n"); + return retcode; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c index 22c43ba37..bda2ad01b 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.c @@ -25,6 +25,7 @@ * * Authors: Rickard E. (Rik) Faith <faith@precisioninsight.com> * Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * * $XFree86$ * @@ -34,6 +35,7 @@ #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 */ @@ -49,24 +51,31 @@ #define I810_READ16(reg) I810_DEREF16(reg) #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) -#define RING_LOCALS() unsigned int outring, ringmask; volatile char *virt; -#define BEGIN_LP_RING(n) \ - 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 ADVANCE_LP_RING() { \ - dev_priv->ring.tail = outring; \ - I810_WRITE(LP_RING + RING_TAIL, outring); \ -} +#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; -#define OUT_RING(n) { \ - *(volatile unsigned int *)(virt + outring) = n; \ - outring += 4; \ - outring &= ringmask; \ -} + +#define BEGIN_LP_RING(n) do { \ + if (I810_VERBOSE) \ + printk("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; \ +} while (0) + +#define ADVANCE_LP_RING() do { \ + if (I810_VERBOSE) printk("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) printk(" OUT_RING %x\n", (int)(n)); \ + *(volatile unsigned int *)(virt + outring) = n; \ + outring += 4; \ + outring &= ringmask; \ +} while (0); static unsigned long i810_alloc_page(drm_device_t *dev) { @@ -101,28 +110,28 @@ static int i810_alloc_kernel_queue(drm_device_t *dev) down(&dev->struct_sem); if(dev->queue_count != 0) { - /* Reseting the kernel context here is not - * a race, since it can only happen when that - * queue is empty. - */ - queue = dev->queuelist[DRM_KERNEL_CONTEXT]; - printk("Kernel queue already allocated\n"); + /* Reseting the kernel context here is not + * a race, since it can only happen when that + * queue is empty. + */ + queue = dev->queuelist[DRM_KERNEL_CONTEXT]; + printk("Kernel queue already allocated\n"); } else { - queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES); - if(!queue) { - up(&dev->struct_sem); - printk("out of memory\n"); - return -ENOMEM; - } - ++dev->queue_count; - dev->queuelist = drm_alloc(sizeof(*dev->queuelist), - DRM_MEM_QUEUES); - if(!dev->queuelist) { - up(&dev->struct_sem); - drm_free(queue, sizeof(*queue), DRM_MEM_QUEUES); - printk("out of memory\n"); - return -ENOMEM; - } + queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES); + if(!queue) { + up(&dev->struct_sem); + printk("out of memory\n"); + return -ENOMEM; + } + ++dev->queue_count; + dev->queuelist = drm_alloc(sizeof(*dev->queuelist), + DRM_MEM_QUEUES); + if(!dev->queuelist) { + up(&dev->struct_sem); + drm_free(queue, sizeof(*queue), DRM_MEM_QUEUES); + printk("out of memory\n"); + return -ENOMEM; + } } memset(queue, 0, sizeof(*queue)); @@ -154,7 +163,7 @@ static int i810_alloc_kernel_queue(drm_device_t *dev) static int i810_dma_cleanup(drm_device_t *dev) { - DRM_DEBUG("i810_dma_cleanup\n"); + printk("i810_dma_cleanup\n"); if(dev->dev_private) { drm_i810_private_t *dev_priv = @@ -178,8 +187,7 @@ static int i810_dma_cleanup(drm_device_t *dev) static int __gettimeinmillis(void) { - struct timeval timep; - + struct timeval timep; do_gettimeofday(&timep); return(timep.tv_sec * 1000) + (timep.tv_usec / 1000); } @@ -187,14 +195,14 @@ static int __gettimeinmillis(void) static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) { drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer *ring = &(dev_priv->ring); + 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; - DRM_DEBUG( "i810_wait_ring %d\n", n); + printk( "i810_wait_ring %d\n", n); while (ring->space < n) { int i; @@ -211,8 +219,9 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) } else if (curTime - startTime > timeout_millis) { DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("lockup\n"); + schedule(); /* JEFF - what to do here ??? */ } - + for (i = 0 ; i < 2000 ; i++) ; } @@ -222,9 +231,9 @@ static int i810_wait_ring(drm_device_t *dev, int n, int timeout_millis) static void i810_kernel_lost_context(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_ring_buffer *ring = &(dev_priv->ring); + drm_i810_ring_buffer_t *ring = &(dev_priv->ring); - DRM_DEBUG("i810_kernel_lost_context, old ring (%x,%x)\n", + printk("i810_kernel_lost_context, old ring (%x,%x)\n", ring->head, ring->tail); ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; @@ -232,49 +241,26 @@ static void i810_kernel_lost_context(drm_device_t *dev) ring->space = ring->head - (ring->tail+8); if (ring->space < 0) ring->space += ring->Size; - DRM_DEBUG("new ring (%x,%x)\n", ring->head, ring->tail); + printk("new ring (%x,%x)\n", ring->head, ring->tail); } static inline void i810_ring_write_status(drm_device_t *dev) { drm_i810_private_t *dev_priv = dev->dev_private; - RING_LOCALS(); + RING_LOCALS; i810_kernel_lost_context(dev); dev_priv->counter++; -#if 1 - BEGIN_LP_RING(8); -#else - BEGIN_LP_RING(16); -#endif + + BEGIN_LP_RING(6); OUT_RING(CMD_REPORT_HEAD); - OUT_RING(0); -#if 1 OUT_RING(CMD_STORE_DWORD_IDX); OUT_RING(5 * sizeof(unsigned long)); OUT_RING(dev_priv->counter); - OUT_RING(0); - -#endif - /* Add a breakpoint interrupt at the end */ -#if 1 - OUT_RING(0); OUT_RING(GFX_OP_BREAKPOINT_INTERRUPT); -#endif - /* Add a blit here just to see if my commands work */ -#if 0 - OUT_RING(0x02000000); - OUT_RING(0); - OUT_RING(0x50c00004); - OUT_RING(0xcc0800); - OUT_RING(0x1900320); - OUT_RING(0); - OUT_RING(0x800); - OUT_RING(0xb80000); - OUT_RING(0x02000000); - OUT_RING(0); -#endif + OUT_RING(0); ADVANCE_LP_RING(); + /* Wait for ring to complete */ i810_wait_ring(dev, dev_priv->ring.Size - 8, 0); } @@ -284,35 +270,42 @@ static inline void i810_print_status_page(drm_device_t *dev) drm_i810_private_t *dev_priv = dev->dev_private; u32 *temp = (u32 *)dev_priv->hw_status_page; - DRM_DEBUG( "hw_status: Interrupt Status : %lx\n", temp[0]); - DRM_DEBUG( "hw_status: LpRing Head ptr : %lx\n", temp[1]); - DRM_DEBUG( "hw_status: IRing Head ptr : %lx\n", temp[2]); - DRM_DEBUG( "hw_status: Reserved : %lx\n", temp[3]); - DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); + printk( "hw_status: Interrupt Status : %x\n", temp[0]); + printk( "hw_status: LpRing Head ptr : %x\n", temp[1]); + printk( "hw_status: IRing Head ptr : %x\n", temp[2]); + printk( "hw_status: Reserved : %x\n", temp[3]); + printk( "hw_status: Driver Counter : %d\n", temp[5]); } static int i810_dma_initialize(drm_device_t *dev, drm_i810_private_t *dev_priv, drm_i810_init_t *init) { - DRM_DEBUG( "i810_dma_init\n"); + drm_map_t *sarea_map; + + printk( "i810_dma_init\n"); dev->dev_private = (void *) dev_priv; memset(dev_priv, 0, sizeof(drm_i810_private_t)); - if((init->ring_map_idx >= dev->map_count) || - (init->buffer_map_idx >= dev->map_count)) { + + if (init->ring_map_idx >= dev->map_count || + init->buffer_map_idx >= dev->map_count) { i810_dma_cleanup(dev); DRM_ERROR("ring_map or buffer_map are invalid\n"); return -EINVAL; } - if(i810_alloc_kernel_queue(dev) != DRM_KERNEL_CONTEXT) { - i810_dma_cleanup(dev); - DRM_ERROR("Kernel context queue not present\n"); - return -ENOMEM; + if (i810_alloc_kernel_queue(dev) != DRM_KERNEL_CONTEXT) { + i810_dma_cleanup(dev); + DRM_ERROR("Kernel context queue not present\n"); + return -ENOMEM; } dev_priv->ring_map_idx = init->ring_map_idx; dev_priv->buffer_map_idx = init->buffer_map_idx; + sarea_map = dev->maplist[0]; + dev_priv->sarea_priv = (drm_i810_sarea_t *) + ((u8 *)sarea_map->handle + + init->sarea_priv_offset); atomic_set(&dev_priv->pending_bufs, 0); atomic_set(&dev_priv->dispatch_lock, 0); @@ -326,7 +319,7 @@ static int i810_dma_initialize(drm_device_t *dev, init->ring_size); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - if(dev_priv->ring.virtual_start == NULL) { + if (dev_priv->ring.virtual_start == NULL) { i810_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -337,20 +330,20 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->hw_status_page = i810_alloc_page(dev); memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); if(dev_priv->hw_status_page == 0UL) { - i810_dma_cleanup(dev); - DRM_ERROR("Can not allocate hardware status page\n"); - return -ENOMEM; + i810_dma_cleanup(dev); + DRM_ERROR("Can not allocate hardware status page\n"); + return -ENOMEM; } - DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); + printk("hw status page @ %lx\n", dev_priv->hw_status_page); I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page)); - DRM_DEBUG("Enabled hardware status page\n"); + printk("Enabled hardware status page\n"); #if 0 - DRM_DEBUG("Doing first ring buffer write\n"); + printk("Doing first ring buffer write\n"); i810_ring_write_status(dev); - DRM_DEBUG("First ring write succeeded\n"); + printk("First ring write succeeded\n"); i810_print_status_page(dev); - DRM_DEBUG("Status page dump succeeded\n"); + printk("Status page dump succeeded\n"); #endif return 0; } @@ -385,48 +378,106 @@ int i810_dma_init(struct inode *inode, struct file *filp, return retcode; } -static inline void i810_dma_dispatch(drm_device_t *dev, unsigned long address, - unsigned long length) +static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) { drm_i810_private_t *dev_priv = dev->dev_private; + unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - RING_LOCALS(); + int length = buf->used; + RING_LOCALS; dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %d\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 : %d\n", start + length - 4); + printk( "dispatch counter : %ld\n", dev_priv->counter); + printk( "i810_dma_dispatch\n"); + printk( "start : 0x%lx\n", start); + printk( "length : 0x%x\n", length); + printk( "start + length - 4 : 0x%lx\n", start + length - 4); i810_kernel_lost_context(dev); + + BEGIN_LP_RING(8); - OUT_RING(CMD_OP_BATCH_BUFFER); - OUT_RING(start | BB1_PROTECTED); - OUT_RING((start + length) - 4); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(5 * sizeof(unsigned long)); - OUT_RING(dev_priv->counter); - /* Add a breakpoint interrupt at the end */ - OUT_RING(CMD_REPORT_HEAD); - OUT_RING(GFX_OP_BREAKPOINT_INTERRUPT); + OUT_RING( CMD_OP_BATCH_BUFFER ); + OUT_RING( start | BB1_PROTECTED ); + OUT_RING( start + length - 4 ); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_BREAKPOINT_INTERRUPT ); ADVANCE_LP_RING(); - /* Wait for ring to flush */ -#if 0 - i810_wait_ring(dev, dev_priv->ring.Size - 8, 0); - i810_ring_write_status(dev); - DRM_DEBUG("ring write succeeded\n"); - i810_print_status_page(dev); - DRM_DEBUG("Status page dump succeeded\n"); -#endif i810_print_status_page(dev); } + + + + +static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) +{ + 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 ]; + unsigned long address = (unsigned long)real_buf->bus_address; + unsigned long start = address - dev->agp->base; + xf86drmClipRectRec *box = buf_priv->boxes; + int length = buf->used; + int i = 0; + RING_LOCALS; + + if (I810_VERBOSE) + printk("dispatch vertex addr 0x%lx, length 0x%x nbox %d\n", + address, length, buf_priv->nbox); + + dev_priv->counter++; + printk( "dispatch counter : %ld\n", dev_priv->counter); + printk( "i810_dma_dispatch\n"); + printk( "start : %lx\n", start); + printk( "length : %d\n", length); + printk( "start + length - 4 : %ld\n", start + length - 4); + i810_kernel_lost_context(dev); + + if (!buf_priv->vertex_discard) { + do { + if (i < buf_priv->nbox) { + BEGIN_LP_RING(4); + OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | + SC_ENABLE ); + OUT_RING( GFX_OP_SCISSOR_INFO ); + OUT_RING( box[i].x1 | (box[i].y1 << 16) ); + OUT_RING( box[i].x2 | (box[i].y2 << 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( 0 ); + ADVANCE_LP_RING(); + + } while (++i < buf_priv->nbox); + } + + BEGIN_LP_RING( 6 ); + OUT_RING( CMD_STORE_DWORD_IDX ); + OUT_RING( 20 ); + OUT_RING( dev_priv->counter ); + OUT_RING( CMD_REPORT_HEAD ); + OUT_RING( GFX_OP_BREAKPOINT_INTERRUPT ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); +} + + + + + static inline void i810_dma_quiescent(drm_device_t *dev) { drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - DRM_DEBUG( "i810_dma_quiescent\n"); + printk( "i810_dma_quiescent\n"); while(1) { atomic_inc(&dev_priv->dispatch_lock); if(atomic_read(&dev_priv->dispatch_lock) == 1) { @@ -441,13 +492,13 @@ static inline void i810_dma_quiescent(drm_device_t *dev) static inline void i810_dma_ready(drm_device_t *dev) { i810_dma_quiescent(dev); - DRM_DEBUG( "i810_dma_ready\n"); + printk( "i810_dma_ready\n"); } static inline int i810_dma_is_ready(drm_device_t *dev) { drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - DRM_DEBUG( "i810_dma_is_ready\n"); + printk( "i810_dma_is_ready\n"); atomic_inc(&dev_priv->dispatch_lock); if(atomic_read(&dev_priv->dispatch_lock) == 1) { /* We got the lock */ @@ -480,7 +531,7 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs) u16 temp; atomic_inc(&dev->total_irq); - DRM_DEBUG("Interrupt Handler\n"); + printk("Interrupt Handler\n"); i810_print_status_page(dev); temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); @@ -511,8 +562,8 @@ static int i810_do_dma(drm_device_t *dev, int locked) int retcode = 0; drm_device_dma_t *dma = dev->dma; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - unsigned long address; - unsigned long length; + drm_i810_buf_priv_t *buf_priv; + printk("i810_do_dma\n"); if (test_and_set_bit(0, &dev->dma_flag)) { @@ -570,12 +621,23 @@ static int i810_do_dma(drm_device_t *dev, int locked) buf->pending = 1; buf->waiting = 0; buf->list = DRM_LIST_PEND; - address = buf->bus_address; - length = buf->used; - printk("dispatch!\n"); - i810_dma_dispatch(dev, address, length); - + buf_priv = buf->dev_private; + if (I810_VERBOSE) printk("i810_do_dma - type %d\n", buf_priv->dma_type); + + switch (buf_priv->dma_type) { + case I810_DMA_GENERAL: + i810_dma_dispatch_general( dev, buf ); + break; + case I810_DMA_VERTEX: + i810_dma_dispatch_vertex( dev, buf ); + break; + default: + printk("bad buffer type %x in dispatch\n", buf_priv->dma_type); + break; + } + + atomic_dec(&dev_priv->pending_bufs); if(dma->this_buffer) { @@ -685,67 +747,6 @@ again: return retcode; } -static int i810_dma_send_buffers(drm_device_t *dev, drm_dma_t *d) -{ - DECLARE_WAITQUEUE(entry, current); - drm_buf_t *last_buf = NULL; - int retcode = 0; - drm_device_dma_t *dma = dev->dma; - drm_i810_private_t *dev_priv = dev->dev_private; - - d->context = DRM_KERNEL_CONTEXT; - - if ((retcode = drm_dma_enqueue(dev, d))) { - return retcode; - } - - atomic_inc(&dev_priv->pending_bufs); - i810_dma_schedule(dev, 1); - return retcode; -} - -int i810_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; - - DRM_DEBUG("i810_dma start\n"); - 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 (d.send_count < 0 || d.send_count > dma->buf_count) { - DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n", - current->pid, d.send_count, dma->buf_count); - return -EINVAL; - } - 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) { - retcode = i810_dma_send_buffers(dev, &d); - } - - 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); - - DRM_DEBUG("i810_dma end (granted)\n"); - return retcode; -} int i810_irq_install(drm_device_t *dev, int irq) { @@ -762,8 +763,8 @@ int i810_irq_install(drm_device_t *dev, int irq) dev->irq = irq; up(&dev->struct_sem); - DRM_DEBUG( "Interrupt Install : %d\n", irq); - DRM_DEBUG("%d\n", irq); + printk( "Interrupt Install : %d\n", irq); + printk("%d\n", irq); dev->context_flag = 0; dev->interrupt_flag = 0; @@ -821,10 +822,10 @@ int i810_irq_uninstall(drm_device_t *dev) if (!irq) return -EINVAL; - DRM_DEBUG( "Interrupt UnInstall: %d\n", irq); + printk( "Interrupt UnInstall: %d\n", irq); - DRM_DEBUG("%d\n", irq); + printk("%d\n", irq); temp = I810_READ16(I810REG_INT_IDENTITY_R); temp = temp & ~(0x6000); @@ -849,7 +850,7 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd, drm_control_t ctl; int retcode; - DRM_DEBUG( "i810_control\n"); + printk( "i810_control\n"); copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT); diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.h new file mode 100644 index 000000000..d2c5e53c7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_dma.h @@ -0,0 +1,113 @@ +/* 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 dma_type; + int vertex_real_idx; + int vertex_discard; + 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 1 + + +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 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/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm_public.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm_public.h index e91d0fd93..a9577e146 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm_public.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drm_public.h @@ -24,6 +24,7 @@ * DEALINGS IN THE SOFTWARE. * * Authors: Jeff Hartmann <jhartmann@precisioninsight.com> + * Keith Whitwell <keithw@precisioninsight.com> * * $XFree86$ */ @@ -38,11 +39,95 @@ typedef struct drm_i810_init { } 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; + + +#define I810_DMA_BUF_ORDER 16 +#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) +#define I810_DMA_BUF_NR 63 + +#define I810_NR_SAREA_CLIPRECTS 2 + + +/* Each region is a minimum of 32k, and there are at most 128 of them. + */ +#define I810_NR_TEX_REGIONS 128 +#define I810_LOG_MIN_TEX_REGION_SIZE 18 + + + +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 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; /* Current age counter */ + + + int lastDispatch; + int lastGetBuffer; /* dodgy - not needed if dma uploads used */ + int ctxOwner; /* last context to upload state */ + +} drm_i810_sarea_t; + + +typedef struct { + 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, 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 */ +} 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) #endif /* _I810_DRM_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c index 15c68ddfa..b7625a848 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.c @@ -33,6 +33,9 @@ #define EXPORT_SYMTAB #include "drmP.h" #include "i810_drv.h" +#include "i810_dma.h" + + EXPORT_SYMBOL(i810_init); EXPORT_SYMBOL(i810_cleanup); @@ -105,6 +108,8 @@ static drm_ioctl_desc_t i810_ioctls[] = { [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_I810_INIT)] = { i810_dma_init, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general, 1, 1 }, }; #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h index 82546976e..d0e7ddd7e 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/i810_drv.h @@ -34,25 +34,30 @@ #include "i810_drm_public.h" typedef struct _drm_i810_ring_buffer{ - int tail_mask; - unsigned long Start; - unsigned long End; - unsigned long Size; - u8 *virtual_start; - int head; - int tail; - int space; -} drm_i810_ring_buffer; + int tail_mask; + unsigned long Start; + unsigned long End; + unsigned long Size; + u8 *virtual_start; + int head; + int tail; + int space; +} drm_i810_ring_buffer_t; typedef struct drm_i810_private { int ring_map_idx; int buffer_map_idx; - drm_i810_ring_buffer ring; + + drm_i810_ring_buffer_t ring; + drm_i810_sarea_t *sarea_priv; + unsigned long hw_status_page; unsigned long counter; + atomic_t dispatch_lock; atomic_t pending_bufs; atomic_t in_flush; + } drm_i810_private_t; /* i810_drv.c */ @@ -115,41 +120,5 @@ extern int i810_context_switch(drm_device_t *dev, int old, int new); extern int i810_context_switch_complete(drm_device_t *dev, int new); -#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 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 #endif |