diff options
Diffstat (limited to 'sys/dev/drm/mga_dma.c')
-rw-r--r-- | sys/dev/drm/mga_dma.c | 206 |
1 files changed, 78 insertions, 128 deletions
diff --git a/sys/dev/drm/mga_dma.c b/sys/dev/drm/mga_dma.c index c6c2236..f04d166 100644 --- a/sys/dev/drm/mga_dma.c +++ b/sys/dev/drm/mga_dma.c @@ -27,7 +27,7 @@ * Authors: * Rickard E. (Rik) Faith <faith@valinux.com> * Jeff Hartmann <jhartmann@valinux.com> - * Keith Whitwell <keithw@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> * * Rewritten by: * Gareth Hughes <gareth@valinux.com> @@ -35,17 +35,12 @@ * $FreeBSD$ */ -#define __NO_VERSION__ #include "dev/drm/mga.h" #include "dev/drm/drmP.h" +#include "dev/drm/drm.h" #include "dev/drm/mga_drm.h" #include "dev/drm/mga_drv.h" -#ifdef __linux__ -#include <linux/interrupt.h> /* For task queue support */ -#include <linux/delay.h> -#endif /* __linux__ */ - #define MGA_DEFAULT_USEC_TIMEOUT 10000 #define MGA_FREELIST_DEBUG 0 @@ -58,7 +53,7 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; @@ -66,32 +61,32 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv ) MGA_WRITE8( MGA_CRTC_INDEX, 0 ); return 0; } - DRM_OS_DELAY( 1 ); + DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed!\n" ); DRM_INFO( " status=0x%08x\n", status ); #endif - return DRM_OS_ERR(EBUSY); + return DRM_ERR(EBUSY); } int mga_do_dma_idle( drm_mga_private_t *dev_priv ) { u32 status = 0; int i; - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK; if ( status == MGA_ENDPRDMASTS ) return 0; - DRM_OS_DELAY( 1 ); + DRM_UDELAY( 1 ); } #if MGA_DMA_DEBUG DRM_ERROR( "failed! status=0x%08x\n", status ); #endif - return DRM_OS_ERR(EBUSY); + return DRM_ERR(EBUSY); } int mga_do_dma_reset( drm_mga_private_t *dev_priv ) @@ -99,7 +94,7 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv ) drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_mga_primary_buffer_t *primary = &dev_priv->prim; - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); /* The primary DMA stream should look like new right about now. */ @@ -120,13 +115,13 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv ) int mga_do_engine_reset( drm_mga_private_t *dev_priv ) { - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); /* Okay, so we've completely screwed up and locked the engine. * How about we clean up after ourselves? */ MGA_WRITE( MGA_RST, MGA_SOFTRESET ); - DRM_OS_DELAY( 15 ); /* Wait at least 10 usecs */ + DRM_UDELAY( 15 ); /* Wait at least 10 usecs */ MGA_WRITE( MGA_RST, 0 ); /* Initialize the registers that get clobbered by the soft @@ -164,8 +159,17 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) { drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; - DMA_LOCALS; - DRM_DEBUG( "%s:\n", __func__ ); + u32 status = 0; + int i; + DMA_LOCALS; + DRM_DEBUG( "\n" ); + + /* We need to wait so that we can do an safe flush */ + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK; + if ( status == MGA_ENDPRDMASTS ) break; + DRM_UDELAY( 1 ); + } if ( primary->tail == primary->last_flush ) { DRM_DEBUG( " bailing out...\n" ); @@ -204,7 +208,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv ) mga_flush_write_combine(); MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); - DRM_DEBUG( "%s: done.\n", __func__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) @@ -212,7 +216,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; u32 head, tail; DMA_LOCALS; - DRM_DEBUG( "%s:\n", __func__ ); + DRM_DEBUG( "\n" ); BEGIN_DMA_WRAP(); @@ -247,7 +251,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv ) MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER ); set_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __func__ ); + DRM_DEBUG( "done.\n" ); } void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) @@ -255,7 +259,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) drm_mga_primary_buffer_t *primary = &dev_priv->prim; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; u32 head = dev_priv->primary->offset; - DRM_DEBUG( "%s:\n", __func__ ); + DRM_DEBUG( "\n" ); sarea_priv->last_wrap++; DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap ); @@ -264,7 +268,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv ) MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL ); clear_bit( 0, &primary->wrapped ); - DRM_DEBUG( "%s: done.\n", __func__ ); + DRM_DEBUG( "done.\n" ); } @@ -304,13 +308,12 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) drm_mga_buf_priv_t *buf_priv; drm_mga_freelist_t *entry; int i; - DRM_DEBUG( "%s: count=%d\n", - __func__, dma->buf_count ); + DRM_DEBUG( "count=%d\n", dma->buf_count ); dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); if ( dev_priv->head == NULL ) - return DRM_OS_ERR(ENOMEM); + return DRM_ERR(ENOMEM); memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) ); SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 ); @@ -322,7 +325,7 @@ static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv ) entry = DRM(alloc)( sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER ); if ( entry == NULL ) - return DRM_OS_ERR(ENOMEM); + return DRM_ERR(ENOMEM); memset( entry, 0, sizeof(drm_mga_freelist_t) ); @@ -351,7 +354,7 @@ static void mga_freelist_cleanup( drm_device_t *dev ) drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_freelist_t *entry; drm_mga_freelist_t *next; - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); entry = dev_priv->head; while ( entry ) { @@ -389,7 +392,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev ) drm_mga_freelist_t *prev; drm_mga_freelist_t *tail = dev_priv->tail; u32 head, wrap; - DRM_DEBUG( "%s:\n", __func__ ); + DRM_DEBUG( "\n" ); head = MGA_READ( MGA_PRIMADDRESS ); wrap = dev_priv->sarea_priv->last_wrap; @@ -421,8 +424,7 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_freelist_t *head, *entry, *prev; - DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n", - __func__, + DRM_DEBUG( "age=0x%06lx wrap=%d\n", buf_priv->list_entry->age.head - dev_priv->primary->offset, buf_priv->list_entry->age.wrap ); @@ -455,18 +457,12 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf ) static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) { drm_mga_private_t *dev_priv; -#ifdef __linux__ - struct list_head *list; -#endif /* __linux__ */ -#ifdef __FreeBSD__ - drm_map_list_entry_t *listentry; -#endif /* __FreeBSD__ */ int ret; - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER ); if ( !dev_priv ) - return DRM_OS_ERR(ENOMEM); + return DRM_ERR(ENOMEM); memset( dev_priv, 0, sizeof(drm_mga_private_t) ); @@ -496,44 +492,23 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->texture_offset = init->texture_offset[0]; dev_priv->texture_size = init->texture_size[0]; -#ifdef __linux__ - list_for_each( list, &dev->maplist->head ) { - drm_map_list_t *entry = (drm_map_list_t *)list; - if ( entry->map && - entry->map->type == _DRM_SHM && - (entry->map->flags & _DRM_CONTAINS_LOCK) ) { - dev_priv->sarea = entry->map; - break; - } - } -#endif /* __linux__ */ -#ifdef __FreeBSD__ - 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; - } - } -#endif /* __FreeBSD__ */ + DRM_GETSAREA(); if(!dev_priv->sarea) { DRM_ERROR( "failed to find sarea!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } - DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); if(!dev_priv->fb) { DRM_ERROR( "failed to find framebuffer!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); if(!dev_priv->mmio) { @@ -541,7 +516,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->status, init->status_offset ); if(!dev_priv->status) { @@ -549,15 +524,16 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } + DRM_FIND_MAP( dev_priv->warp, init->warp_offset ); if(!dev_priv->warp) { DRM_ERROR( "failed to find warp microcode region!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->primary, init->primary_offset ); if(!dev_priv->primary) { @@ -565,7 +541,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); if(!dev_priv->buffers) { @@ -573,7 +549,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } dev_priv->sarea_priv = @@ -591,25 +567,25 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(ENOMEM); + return DRM_ERR(ENOMEM); } ret = mga_warp_install_microcode( dev_priv ); - if ( ret ) { + if ( ret < 0 ) { DRM_ERROR( "failed to install WARP ucode!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(ret); + return ret; } ret = mga_warp_init( dev_priv ); - if ( ret ) { + if ( ret < 0 ) { DRM_ERROR( "failed to init WARP engine!\n" ); /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(ret); + return ret; } dev_priv->prim.status = (u32 *)dev_priv->status->handle; @@ -641,10 +617,6 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE; -#ifdef __linux__ - spin_lock_init( &dev_priv->prim.list_lock ); -#endif /* __linux__ */ - dev_priv->prim.status[0] = dev_priv->primary->offset; dev_priv->prim.status[1] = 0; @@ -657,7 +629,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) /* Assign dev_private so we can do cleanup. */ dev->dev_private = (void *)dev_priv; mga_do_cleanup_dma( dev ); - return DRM_OS_ERR(ENOMEM); + return DRM_ERR(ENOMEM); } /* Make dev_private visable to others. */ @@ -667,7 +639,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init ) int mga_do_cleanup_dma( drm_device_t *dev ) { - DRM_DEBUG( "%s\n", __func__ ); + DRM_DEBUG( "\n" ); if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; @@ -688,12 +660,12 @@ int mga_do_cleanup_dma( drm_device_t *dev ) return 0; } -int mga_dma_init( DRM_OS_IOCTL ) +int mga_dma_init( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_mga_init_t init; - DRM_OS_KRNFROMUSR( init, (drm_mga_init_t *) data, sizeof(init) ); + DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t *)data, sizeof(init) ); switch ( init.func ) { case MGA_INIT_DMA: @@ -702,7 +674,7 @@ int mga_dma_init( DRM_OS_IOCTL ) return mga_do_cleanup_dma( dev ); } - return DRM_OS_ERR(EINVAL); + return DRM_ERR(EINVAL); } @@ -710,18 +682,17 @@ int mga_dma_init( DRM_OS_IOCTL ) * Primary DMA stream management */ -int mga_dma_flush( DRM_OS_IOCTL ) +int mga_dma_flush( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_lock_t lock; LOCK_TEST_WITH_RETURN( dev ); - DRM_OS_KRNFROMUSR( lock, (drm_lock_t *) data, sizeof(lock) ); + DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) ); - DRM_DEBUG( "%s: %s%s%s\n", - __func__, + DRM_DEBUG( "%s%s%s\n", (lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "", (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "", (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" ); @@ -735,8 +706,8 @@ int mga_dma_flush( DRM_OS_IOCTL ) if ( lock.flags & _DRM_LOCK_QUIESCENT ) { #if MGA_DMA_DEBUG int ret = mga_do_wait_for_idle( dev_priv ); - if ( ret ) - DRM_INFO( "%s: -EBUSY\n", __func__ ); + if ( ret < 0 ) + DRM_INFO( "%s: -EBUSY\n", __FUNCTION__ ); return ret; #else return mga_do_wait_for_idle( dev_priv ); @@ -746,9 +717,9 @@ int mga_dma_flush( DRM_OS_IOCTL ) } } -int mga_dma_reset( DRM_OS_IOCTL ) +int mga_dma_reset( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; LOCK_TEST_WITH_RETURN( dev ); @@ -761,7 +732,6 @@ int mga_dma_reset( DRM_OS_IOCTL ) * DMA buffer management */ -#if 0 static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) { drm_buf_t *buf; @@ -769,52 +739,48 @@ static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d ) for ( i = d->granted_count ; i < d->request_count ; i++ ) { buf = mga_freelist_get( dev ); - if ( !buf ) - return DRM_OS_ERR(EAGAIN); + if ( !buf ) return DRM_ERR(EAGAIN); - buf->pid = current->pid; + buf->pid = DRM_CURRENTPID; - if ( DRM_OS_COPYTOUSR( &d->request_indices[i], + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, sizeof(buf->idx) ) ) - return DRM_OS_ERR(EFAULT); - if ( DRM_OS_COPYTOUSR( &d->request_sizes[i], + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, sizeof(buf->total) ) ) - return DRM_OS_ERR(EFAULT); + return DRM_ERR(EFAULT); d->granted_count++; } return 0; } -#endif /* 0 */ -int mga_dma_buffers( DRM_OS_IOCTL ) +int mga_dma_buffers( DRM_IOCTL_ARGS ) { - DRM_OS_DEVICE; + DRM_DEVICE; drm_device_dma_t *dma = dev->dma; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; drm_dma_t d; - drm_buf_t *buf; - int i; int ret = 0; LOCK_TEST_WITH_RETURN( dev ); - DRM_OS_KRNFROMUSR( d, (drm_dma_t *) data, sizeof(d) ); + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); /* Please don't send us buffers. */ if ( d.send_count != 0 ) { DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", - DRM_OS_CURRENTPID, d.send_count ); - return DRM_OS_ERR(EINVAL); + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(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", - DRM_OS_CURRENTPID, d.request_count, dma->buf_count ); - return DRM_OS_ERR(EINVAL); + DRM_CURRENTPID, d.request_count, dma->buf_count ); + return DRM_ERR(EINVAL); } WRAP_TEST_WITH_RETURN( dev_priv ); @@ -822,26 +788,10 @@ int mga_dma_buffers( DRM_OS_IOCTL ) d.granted_count = 0; if ( d.request_count ) { - for ( i = d.granted_count ; i < d.request_count ; i++ ) { - buf = mga_freelist_get( dev ); - if ( !buf ) - return DRM_OS_ERR(EAGAIN); - - buf->pid = DRM_OS_CURRENTPID; - - if ( DRM_OS_COPYTOUSR( &d.request_indices[i], - &buf->idx, sizeof(buf->idx) ) ) - return DRM_OS_ERR(EFAULT); - if ( DRM_OS_COPYTOUSR( &d.request_sizes[i], - &buf->total, sizeof(buf->total) ) ) - return DRM_OS_ERR(EFAULT); - - d.granted_count++; - } - ret = 0; + ret = mga_dma_get_buffers( dev, &d ); } - DRM_OS_KRNTOUSR( (drm_dma_t *) data, d, sizeof(d) ); + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); return ret; } |