summaryrefslogtreecommitdiff
path: root/bsd/i810_dma.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2002-08-28 04:33:02 +0000
committerEric Anholt <anholt@freebsd.org>2002-08-28 04:33:02 +0000
commit8a8cfd38df9a48069c4ca56006d219e0eb8ca59c (patch)
treeca8ee9851cf085e7efc05bb38b990c1a5eb030dc /bsd/i810_dma.c
parentfa560b4847fc89aa68251236d3843b97518b1853 (diff)
Remove i8x0 files from the BSD side. These were not actually ported, and
when they do get ported most of them won't live in these directories.
Diffstat (limited to 'bsd/i810_dma.c')
-rw-r--r--bsd/i810_dma.c1223
1 files changed, 0 insertions, 1223 deletions
diff --git a/bsd/i810_dma.c b/bsd/i810_dma.c
deleted file mode 100644
index d860fafe..00000000
--- a/bsd/i810_dma.c
+++ /dev/null
@@ -1,1223 +0,0 @@
-/* i810_dma.c -- DMA support for the i810 -*- linux-c -*-
- * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- * Jeff Hartmann <jhartmann@valinux.com>
- * Keith Whitwell <keithw@valinux.com>
- *
- */
-
-
-#include "i810.h"
-#include "drmP.h"
-#include "drm.h"
-#include "i810_drm.h"
-#include "i810_drv.h"
-
-#define I810_BUF_FREE 2
-#define I810_BUF_CLIENT 1
-#define I810_BUF_HARDWARE 0
-
-#define I810_BUF_UNMAPPED 0
-#define I810_BUF_MAPPED 1
-
-#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); \
- 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); \
-} 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; \
-} while (0);
-
-static __inline__ void i810_print_status_page(drm_device_t *dev)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_i810_private_t *dev_priv = dev->dev_private;
- u32 *temp = (u32 *)dev_priv->hw_status_page;
- int i;
-
- DRM_DEBUG( "hw_status: Interrupt Status : %x\n", temp[0]);
- DRM_DEBUG( "hw_status: LpRing Head ptr : %x\n", temp[1]);
- DRM_DEBUG( "hw_status: IRing Head ptr : %x\n", temp[2]);
- DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]);
- DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]);
- for(i = 6; i < dma->buf_count + 6; i++) {
- DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
- }
-}
-
-static drm_buf_t *i810_freelist_get(drm_device_t *dev)
-{
- drm_device_dma_t *dma = dev->dma;
- int i;
- char failed;
-
- /* Linear search might not be the best solution */
-
- 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;
- /* In use is already a pointer */
- _DRM_CAS(buf_priv->in_use, I810_BUF_FREE, I810_BUF_CLIENT,
- failed);
- if (!failed)
- return buf;
- }
- return NULL;
-}
-
-/* This should only be called if the buffer is not sent to the hardware
- * yet, the hardware updates in use for us once its on the ring buffer.
- */
-
-static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
-{
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- char failed;
-
- /* In use is already a pointer */
- _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE, failed);
- if(failed) {
- DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
- return DRM_ERR( EINVAL );
- }
-
- return 0;
-}
-
-#if 0
-int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
-{
- DRM_DEVICE;
- drm_i810_private_t *dev_priv;
- drm_buf_t *buf;
- drm_i810_buf_priv_t *buf_priv;
-
- lock_kernel();
- dev_priv = dev->dev_private;
- buf = dev_priv->mmap_buffer;
- buf_priv = buf->dev_private;
-
- vma->vm_flags |= (VM_IO | VM_DONTCOPY);
- vma->vm_file = filp;
-
- buf_priv->currently_mapped = I810_BUF_MAPPED;
- unlock_kernel();
-
- if (remap_page_range(vma->vm_start,
- VM_OFFSET(vma),
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot)) return DRM_ERR(EAGAIN);
- return 0;
-}
-#endif
-
-static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
-{
- DRM_DEVICE;
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- drm_i810_private_t *dev_priv = dev->dev_private;
- struct file_operations *old_fops;
- int retcode = 0;
-
- if(buf_priv->currently_mapped == I810_BUF_MAPPED) return DRM_ERR(EINVAL);
-
- if(VM_DONTCOPY != 0) {
-#if LINUX_VERSION_CODE <= 0x020402
- down( &current->mm->mmap_sem );
-#else
- down_write( &current->mm->mmap_sem );
-#endif
- old_fops = filp->f_op;
- filp->f_op = &i810_buffer_fops;
- dev_priv->mmap_buffer = buf;
- buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
- PROT_READ|PROT_WRITE,
- MAP_SHARED,
- buf->bus_address);
- dev_priv->mmap_buffer = NULL;
- filp->f_op = old_fops;
- if ((unsigned long)buf_priv->virtual > -1024UL) {
- /* Real error */
- DRM_DEBUG("mmap error\n");
- retcode = (signed int)buf_priv->virtual;
- buf_priv->virtual = 0;
- }
-#if LINUX_VERSION_CODE <= 0x020402
- up( &current->mm->mmap_sem );
-#else
- up_write( &current->mm->mmap_sem );
-#endif
- } else {
- buf_priv->virtual = buf_priv->kernel_virtual;
- buf_priv->currently_mapped = I810_BUF_MAPPED;
- }
- return retcode;
-}
-
-static int i810_unmap_buffer(drm_buf_t *buf)
-{
- drm_i810_buf_priv_t *buf_priv = buf->dev_private;
- int retcode = 0;
-
- if(VM_DONTCOPY != 0) {
- if(buf_priv->currently_mapped != I810_BUF_MAPPED)
- return DRM_ERR(EINVAL);
-#if LINUX_VERSION_CODE <= 0x020402
- down( &current->mm->mmap_sem );
-#else
- down_write( &current->mm->mmap_sem );
-#endif
- retcode = do_munmap(current->mm,
- (unsigned long)buf_priv->virtual,
- (size_t) buf->total);
-#if LINUX_VERSION_CODE <= 0x020402
- up( &current->mm->mmap_sem );
-#else
- up_write( &current->mm->mmap_sem );
-#endif
- }
- buf_priv->currently_mapped = I810_BUF_UNMAPPED;
- buf_priv->virtual = 0;
-
- return retcode;
-}
-
-static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
- struct file *filp)
-{
- drm_file_t *priv = filp->private_data;
- drm_buf_t *buf;
- drm_i810_buf_priv_t *buf_priv;
- int retcode = 0;
-
- buf = i810_freelist_get(dev);
- if (!buf) {
- retcode = -ENOMEM;
- DRM_DEBUG("retcode=%d\n", retcode);
- return DRM_ERR(retcode);
- }
-
- retcode = i810_map_buffer(buf, filp);
- if(retcode) {
- i810_freelist_put(dev, buf);
- DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
- return retcode;
- }
- buf->pid = priv->pid;
- buf_priv = buf->dev_private;
- d->granted = 1;
- d->request_idx = buf->idx;
- d->request_size = buf->total;
- d->virtual = buf_priv->virtual;
-
- return retcode;
-}
-
-static unsigned long i810_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL)
- return 0;
-
- atomic_inc(&virt_to_page(address)->count);
- set_bit(PG_locked, &virt_to_page(address)->flags);
-
- return address;
-}
-
-static void i810_free_page(drm_device_t *dev, unsigned long page)
-{
- if(page == 0UL)
- return;
-
- atomic_dec(&virt_to_page(page)->count);
- clear_bit(PG_locked, &virt_to_page(page)->flags);
- DRM_WAKEUP(&virt_to_page(page)->wait);
- free_page(page);
- return;
-}
-
-static int i810_dma_cleanup(drm_device_t *dev)
-{
- drm_device_dma_t *dma = dev->dma;
-
- if(dev->dev_private) {
- int i;
- drm_i810_private_t *dev_priv =
- (drm_i810_private_t *) dev->dev_private;
-
- if(dev_priv->ring.virtual_start) {
- DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
- dev_priv->ring.Size);
- }
- if(dev_priv->hw_status_page != 0UL) {
- i810_free_page(dev, dev_priv->hw_status_page);
- /* Need to rewrite hardware status page */
- I810_WRITE(0x02080, 0x1ffff000);
- }
- DRM(free)(dev->dev_private, sizeof(drm_i810_private_t),
- DRM_MEM_DRIVER);
- dev->dev_private = NULL;
-
- 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;
- DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total);
- }
- }
- return 0;
-}
-
-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;
- unsigned long end;
- unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
-
- end = jiffies + (HZ*3);
- while (ring->space < n) {
- int i;
-
- ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
-
- if (ring->head != last_head)
- end = jiffies + (HZ*3);
-
- iters++;
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("space: %d wanted %d\n", ring->space, n);
- DRM_ERROR("lockup\n");
- goto out_wait_ring;
- }
-
- for (i = 0 ; i < 2000 ; i++) ;
- }
-
-out_wait_ring:
- return iters;
-}
-
-static void i810_kernel_lost_context(drm_device_t *dev)
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
-
- ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->tail = I810_READ(LP_RING + RING_TAIL);
- ring->space = ring->head - (ring->tail+8);
- if (ring->space < 0) ring->space += ring->Size;
-}
-
-static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv)
-{
- drm_device_dma_t *dma = dev->dma;
- int my_idx = 24;
- u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
- int i;
-
- if(dma->buf_count > 1019) {
- /* Not enough space in the status page for the freelist */
- return DRM_ERR(EINVAL);
- }
-
- 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;
-
- buf_priv->in_use = hw_status++;
- buf_priv->my_use_idx = my_idx;
- my_idx += 4;
-
- *buf_priv->in_use = I810_BUF_FREE;
-
- buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address,
- buf->total);
- }
- return 0;
-}
-
-static int i810_dma_initialize(drm_device_t *dev,
- drm_i810_private_t *dev_priv,
- drm_i810_init_t *init)
-{
- drm_map_list_entry_t *listentry;
-
- memset(dev_priv, 0, sizeof(drm_i810_private_t));
-
- TAILQ_FOREACH(listentry, dev->maplist, link) {
- drm_map_t *map = listentry->map;
- if (map->type == _DRM_SHM &&
- map->flags & _DRM_CONTAINS_LOCK) {
- dev_priv->sarea = map;
- break;
- }
- }
-
- if(!dev_priv->sarea_map) {
- dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find sarea!\n");
- return DRM_ERR(EINVAL);
- }
- DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
- if(!dev_priv->mmio_map) {
- dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find mmio map!\n");
- return DRM_ERR(EINVAL);
- }
- DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
- if(!dev_priv->buffer_map) {
- dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not find dma buffer map!\n");
- return DRM_ERR(EINVAL);
- }
-
- dev_priv->sarea_priv = (drm_i810_sarea_t *)
- ((u8 *)dev_priv->sarea_map->handle +
- init->sarea_priv_offset);
-
- atomic_set(&dev_priv->flush_done, 0);
- init_waitqueue_head(&dev_priv->flush_queue);
-
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
- dev_priv->ring.Size = init->ring_size;
-
- dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base +
- init->ring_start,
- init->ring_size);
-
- if (dev_priv->ring.virtual_start == NULL) {
- dev->dev_private = (void *) dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("can not ioremap virtual address for"
- " ring buffer\n");
- return DRM_ERR(ENOMEM);
- }
-
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-
- dev_priv->w = init->w;
- dev_priv->h = init->h;
- dev_priv->pitch = init->pitch;
- dev_priv->back_offset = init->back_offset;
- dev_priv->depth_offset = init->depth_offset;
-
- dev_priv->front_di1 = init->front_offset | init->pitch_bits;
- dev_priv->back_di1 = init->back_offset | init->pitch_bits;
- dev_priv->zi1 = init->depth_offset | init->pitch_bits;
-
- /* Program Hardware Status Page */
- dev_priv->hw_status_page = i810_alloc_page(dev);
- if(dev_priv->hw_status_page == 0UL) {
- dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("Can not allocate hardware status page\n");
- return DRM_ERR(ENOMEM);
- }
- memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
- DRM_DEBUG("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");
-
- /* Now we need to init our freelist */
- if(i810_freelist_init(dev, dev_priv) != 0) {
- dev->dev_private = (void *)dev_priv;
- i810_dma_cleanup(dev);
- DRM_ERROR("Not enough space in the status page for"
- " the freelist\n");
- return DRM_ERR(ENOMEM);
- }
- dev->dev_private = (void *)dev_priv;
-
- return 0;
-}
-
-int i810_dma_init( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- drm_i810_private_t *dev_priv;
- drm_i810_init_t init;
- int retcode = 0;
-
- DRM_COPY_FROM_USER_IOCTL( init, (drm_i810_init_t *) data, sizeof(init) );
-
- switch(init.func) {
- case I810_INIT_DMA:
- dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
- DRM_MEM_DRIVER);
- if(dev_priv == NULL) return DRM_ERR(ENOMEM);
- retcode = i810_dma_initialize(dev, dev_priv, &init);
- break;
- case I810_CLEANUP_DMA:
- retcode = i810_dma_cleanup(dev);
- break;
- default:
- retcode = -EINVAL;
- break;
- }
-
- return DRM_ERR(retcode);
-}
-
-
-
-/* Most efficient way to verify state for the i810 is as it is
- * emitted. Non-conformant state is silently dropped.
- *
- * Use 'volatile' & local var tmp to force the emitted values to be
- * identical to the verified ones.
- */
-static void i810EmitContextVerified( drm_device_t *dev,
- volatile unsigned int *code )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- int i, j = 0;
- unsigned int tmp;
- RING_LOCALS;
-
- BEGIN_LP_RING( I810_CTX_SETUP_SIZE );
-
- OUT_RING( GFX_OP_COLOR_FACTOR );
- OUT_RING( code[I810_CTXREG_CF1] );
-
- OUT_RING( GFX_OP_STIPPLE );
- OUT_RING( code[I810_CTXREG_ST1] );
-
- for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) {
- tmp = code[i];
-
- if ((tmp & (7<<29)) == (3<<29) &&
- (tmp & (0x1f<<24)) < (0x1d<<24))
- {
- OUT_RING( tmp );
- j++;
- }
- }
-
- if (j & 1)
- OUT_RING( 0 );
-
- ADVANCE_LP_RING();
-}
-
-static void i810EmitTexVerified( drm_device_t *dev,
- volatile unsigned int *code )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- int i, j = 0;
- unsigned int tmp;
- RING_LOCALS;
-
- BEGIN_LP_RING( I810_TEX_SETUP_SIZE );
-
- OUT_RING( GFX_OP_MAP_INFO );
- OUT_RING( code[I810_TEXREG_MI1] );
- OUT_RING( code[I810_TEXREG_MI2] );
- OUT_RING( code[I810_TEXREG_MI3] );
-
- for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) {
- tmp = code[i];
-
- if ((tmp & (7<<29)) == (3<<29) &&
- (tmp & (0x1f<<24)) < (0x1d<<24))
- {
- OUT_RING( tmp );
- j++;
- }
- }
-
- if (j & 1)
- OUT_RING( 0 );
-
- ADVANCE_LP_RING();
-}
-
-
-/* Need to do some additional checking when setting the dest buffer.
- */
-static void i810EmitDestVerified( drm_device_t *dev,
- volatile unsigned int *code )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- unsigned int tmp;
- RING_LOCALS;
-
- BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
-
- tmp = code[I810_DESTREG_DI1];
- if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
- OUT_RING( CMD_OP_DESTBUFFER_INFO );
- OUT_RING( tmp );
- } else
- DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
- tmp, dev_priv->front_di1, dev_priv->back_di1);
-
- /* invarient:
- */
- OUT_RING( CMD_OP_Z_BUFFER_INFO );
- OUT_RING( dev_priv->zi1 );
-
- OUT_RING( GFX_OP_DESTBUFFER_VARS );
- OUT_RING( code[I810_DESTREG_DV1] );
-
- OUT_RING( GFX_OP_DRAWRECT_INFO );
- OUT_RING( code[I810_DESTREG_DR1] );
- OUT_RING( code[I810_DESTREG_DR2] );
- OUT_RING( code[I810_DESTREG_DR3] );
- OUT_RING( code[I810_DESTREG_DR4] );
- OUT_RING( 0 );
-
- ADVANCE_LP_RING();
-}
-
-
-
-static void i810EmitState( drm_device_t *dev )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned int dirty = sarea_priv->dirty;
-
- if (dirty & I810_UPLOAD_BUFFERS) {
- i810EmitDestVerified( dev, sarea_priv->BufferState );
- sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
- }
-
- if (dirty & I810_UPLOAD_CTX) {
- i810EmitContextVerified( dev, sarea_priv->ContextState );
- sarea_priv->dirty &= ~I810_UPLOAD_CTX;
- }
-
- if (dirty & I810_UPLOAD_TEX0) {
- i810EmitTexVerified( dev, sarea_priv->TexState[0] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
- }
-
- if (dirty & I810_UPLOAD_TEX1) {
- i810EmitTexVerified( dev, sarea_priv->TexState[1] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
- }
-}
-
-
-
-/* need to verify
- */
-static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
- unsigned int clear_color,
- unsigned int clear_zval )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int nbox = sarea_priv->nbox;
- drm_clip_rect_t *pbox = sarea_priv->boxes;
- int pitch = dev_priv->pitch;
- int cpp = 2;
- int i;
- RING_LOCALS;
-
- i810_kernel_lost_context(dev);
-
- if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
-
- for (i = 0 ; i < nbox ; i++, pbox++) {
- unsigned int x = pbox->x1;
- unsigned int y = pbox->y1;
- unsigned int width = (pbox->x2 - x) * cpp;
- unsigned int height = pbox->y2 - y;
- unsigned int start = y * pitch + x * cpp;
-
- if (pbox->x1 > pbox->x2 ||
- pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
- continue;
-
- if ( flags & I810_FRONT ) {
- DRM_DEBUG("clear front\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( start );
- OUT_RING( clear_color );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
- }
-
- if ( flags & I810_BACK ) {
- DRM_DEBUG("clear back\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( dev_priv->back_offset + start );
- OUT_RING( clear_color );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
- }
-
- if ( flags & I810_DEPTH ) {
- DRM_DEBUG("clear depth\n");
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT |
- BR00_OP_COLOR_BLT | 0x3 );
- OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
- OUT_RING( (height << 16) | width );
- OUT_RING( dev_priv->depth_offset + start );
- OUT_RING( clear_zval );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
- }
- }
-}
-
-static void i810_dma_dispatch_swap( drm_device_t *dev )
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int nbox = sarea_priv->nbox;
- drm_clip_rect_t *pbox = sarea_priv->boxes;
- int pitch = dev_priv->pitch;
- int cpp = 2;
- int ofs = dev_priv->back_offset;
- int i;
- RING_LOCALS;
-
- DRM_DEBUG("swapbuffers\n");
-
- i810_kernel_lost_context(dev);
-
- if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
-
- for (i = 0 ; i < nbox; i++, pbox++)
- {
- unsigned int w = pbox->x2 - pbox->x1;
- unsigned int h = pbox->y2 - pbox->y1;
- unsigned int dst = pbox->x1*cpp + pbox->y1*pitch;
- unsigned int start = ofs + dst;
-
- if (pbox->x1 > pbox->x2 ||
- pbox->y1 > pbox->y2 ||
- pbox->x2 > dev_priv->w ||
- pbox->y2 > dev_priv->h)
- continue;
-
- DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
- pbox[i].x1, pbox[i].y1,
- pbox[i].x2, pbox[i].y2);
-
- BEGIN_LP_RING( 6 );
- OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
- OUT_RING( pitch | (0xCC << 16));
- OUT_RING( (h << 16) | (w * cpp));
- OUT_RING( dst );
- OUT_RING( pitch );
- OUT_RING( start );
- ADVANCE_LP_RING();
- }
-}
-
-
-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_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_clip_rect_t *box = sarea_priv->boxes;
- int nbox = sarea_priv->nbox;
- unsigned long address = (unsigned long)buf->bus_address;
- unsigned long start = address - dev->agp->base;
- int i = 0;
- char failed;
- RING_LOCALS;
-
- i810_kernel_lost_context(dev);
-
- if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
-
- if (discard) {
- _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_HARDWARE, failed);
- if (failed)
- DRM_DEBUG("xxxx 2\n");
- }
-
- if (used > 4*1024)
- used = 0;
-
- if (sarea_priv->dirty)
- i810EmitState( dev );
-
- 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( "used : %d\n", used);
- DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
-
- if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
- *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
- sarea_priv->vertex_prim |
- ((used/4)-2));
-
- if (used & 4) {
- *(u32 *)((u32)buf_priv->virtual + used) = 0;
- used += 4;
- }
-
- i810_unmap_buffer(buf);
- }
-
- if (used) {
- do {
- if (i < 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-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 + used - 4 );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
-
- } while (++i < nbox);
- }
-
- 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();
-}
-
-
-/* Interrupts are only for flushing */
-void i810_dma_service(int irq, void *device, struct pt_regs *regs)
-{
- drm_device_t *dev = (drm_device_t *)device;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u16 temp;
-
- atomic_inc(&dev->counts[_DRM_STAT_IRQ]);
- temp = I810_READ16(I810REG_INT_IDENTITY_R);
- temp = temp & ~(0x6000);
- if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
- temp); /* Clear all interrupts */
- else
- return;
-
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-}
-
-void i810_dma_immediate_bh(void *device)
-{
- drm_device_t *dev = (drm_device_t *) device;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
-
- atomic_set(&dev_priv->flush_done, 1);
- DRM_WAKEUP_INT(&dev_priv->flush_queue);
-}
-
-static inline void i810_dma_emit_flush(drm_device_t *dev)
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- RING_LOCALS;
-
- i810_kernel_lost_context(dev);
-
- BEGIN_LP_RING(2);
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( GFX_OP_USER_INTERRUPT );
- ADVANCE_LP_RING();
-
-/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
-/* atomic_set(&dev_priv->flush_done, 1); */
-/* DRM_WAKEUP_INT(&dev_priv->flush_queue); */
-}
-
-static inline void i810_dma_quiescent_emit(drm_device_t *dev)
-{
- drm_i810_private_t *dev_priv = dev->dev_private;
- RING_LOCALS;
-
- i810_kernel_lost_context(dev);
-
- BEGIN_LP_RING(4);
- OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- OUT_RING( GFX_OP_USER_INTERRUPT );
- ADVANCE_LP_RING();
-
-/* i810_wait_ring( dev, dev_priv->ring.Size - 8 ); */
-/* atomic_set(&dev_priv->flush_done, 1); */
-/* DRM_WAKEUP_INT(&dev_priv->flush_queue); */
-}
-
-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;
- unsigned long end;
-
- if(dev_priv == NULL) {
- return;
- }
- atomic_set(&dev_priv->flush_done, 0);
- add_wait_queue(&dev_priv->flush_queue, &entry);
- end = jiffies + (HZ*3);
-
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- i810_dma_quiescent_emit(dev);
- if (atomic_read(&dev_priv->flush_done) == 1) break;
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("lockup\n");
- break;
- }
- schedule_timeout(HZ*3);
- if (signal_pending(current)) {
- break;
- }
- }
-
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->flush_queue, &entry);
-
- return;
-}
-
-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;
- drm_device_dma_t *dma = dev->dma;
- unsigned long end;
- int i, ret = 0;
-
- if(dev_priv == NULL) {
- return 0;
- }
- atomic_set(&dev_priv->flush_done, 0);
- add_wait_queue(&dev_priv->flush_queue, &entry);
- end = jiffies + (HZ*3);
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- i810_dma_emit_flush(dev);
- if (atomic_read(&dev_priv->flush_done) == 1) break;
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("lockup\n");
- break;
- }
- schedule_timeout(HZ*3);
- if (signal_pending(current)) {
- ret = -EINTR; /* Can't restart */
- break;
- }
- }
-
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->flush_queue, &entry);
-
-
- 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;
-
- char failed;
- _DRM_CAS(buf_priv->in_use, I810_BUF_HARDWARE,
- I810_BUF_FREE, failed);
-
- if (!failed)
- DRM_DEBUG("reclaimed from HARDWARE\n");
- if (used == I810_BUF_CLIENT)
- DRM_DEBUG("still on client HARDWARE\n");
- }
-
- return ret;
-}
-
-/* Must be called with the lock held */
-void i810_reclaim_buffers(drm_device_t *dev, pid_t pid)
-{
- drm_device_dma_t *dma = dev->dma;
- int i;
-
- if (!dma) return;
- if (!dev->dev_private) return;
- if (!dma->buflist) 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 && buf_priv) {
- char failed;
- _DRM_CAS(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_FREE, failed);
-
- if (!failed)
-
- DRM_DEBUG("reclaimed from client\n");
- if(buf_priv->currently_mapped == I810_BUF_MAPPED)
- buf_priv->currently_mapped = I810_BUF_UNMAPPED;
- }
- }
-}
-
-int i810_flush_ioctl( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
-
- 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 DRM_ERR( EINVAL );
- }
-
- i810_flush_queue(dev);
- return 0;
-}
-
-
-int i810_dma_vertex( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- drm_device_dma_t *dma = dev->dma;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
- drm_i810_vertex_t vertex;
-
- DRM_COPY_FROM_USER_IOCTL( vertex, (drm_i810_vertex_t *) data, sizeof(vertex) );
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma_vertex called without lock held\n");
- return DRM_ERR( EINVAL );
- }
-
- DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
- vertex.idx, vertex.used, vertex.discard);
-
- if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL);
-
- i810_dma_dispatch_vertex( dev,
- dma->buflist[ vertex.idx ],
- vertex.discard, vertex.used );
-
- atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
- atomic_inc(&dev->counts[_DRM_STAT_DMA]);
- sarea_priv->last_enqueue = dev_priv->counter-1;
- sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
-}
-
-
-
-int i810_clear_bufs( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- drm_i810_clear_t clear;
-
- DRM_COPY_FROM_USER_IOCTL( clear, (drm_i810_clear_t *) data, sizeof(clear) );
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_clear_bufs called without lock held\n");
- return DRM_ERR( EINVAL );
- }
-
- /* GH: Someone's doing nasty things... */
- if (!dev->dev_private) {
- return DRM_ERR(EINVAL);
- }
-
- i810_dma_dispatch_clear( dev, clear.flags,
- clear.clear_color,
- clear.clear_depth );
- return 0;
-}
-
-int i810_swap_bufs( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
-
- DRM_DEBUG("i810_swap_bufs\n");
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_swap_buf called without lock held\n");
- return DRM_ERR( EINVAL );
- }
-
- i810_dma_dispatch_swap( dev );
- return 0;
-}
-
-int i810_getage( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
-
- sarea_priv->last_dispatch = (int) hw_status[5];
- return 0;
-}
-
-int i810_getbuf( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- int retcode = 0;
- drm_i810_dma_t d;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
-
- DRM_DEBUG("getbuf\n");
- DRM_COPY_FROM_USER_IOCTL( d, (drm_i810_dma_t *) data, sizeof(d) );
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma called without lock held\n");
- return DRM_ERR( EINVAL );
- }
-
- d.granted = 0;
-
- retcode = i810_dma_get_buffer(dev, &d, filp);
-
- DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
- DRM_CURRENTPID, retcode, d.granted);
-
- DRM_COPY_TO_USER_IOCTL( (drm_dma_t *) data, d, sizeof(d) );
- sarea_priv->last_dispatch = (int) hw_status[5];
-
- return DRM_ERR(retcode);
-}
-
-int i810_copybuf( DRM_IOCTL_ARGS )
-{
- DRM_DEVICE;
- drm_i810_copy_t d;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
- drm_buf_t *buf;
- drm_i810_buf_priv_t *buf_priv;
- drm_device_dma_t *dma = dev->dma;
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma called without lock held\n");
- return DRM_ERR( EINVAL );
- }
-
- DRM_COPY_FROM_USER_IOCTL( d, (drm_i810_copy_t *) data, sizeof(d) );
-
- if(d.idx < 0 || d.idx > dma->buf_count) return DRM_ERR(EINVAL);
- buf = dma->buflist[ d.idx ];
- buf_priv = buf->dev_private;
- if (buf_priv->currently_mapped != I810_BUF_MAPPED) return DRM_ERR(EPERM);
- if(d.used < 0 || d.used > buf->total) return DRM_ERR(EINVAL);
-
- if (DRM_COPY_FROM_USER(buf_priv->virtual, d.address, d.used))
- return DRM_ERR( EFAULT );
-
- sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
-}
-
-int i810_docopy( DRM_IOCTL_ARGS )
-{
- if(VM_DONTCOPY == 0) return 1;
- return 0;
-}