mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-21 06:28:20 +02:00
More hacking on mga kernel module v3.0.0, basic (non-textured) apps work
great. Animation still needs sorting out, most apps run fine for a
while and then lock up. This is just a snapshot, lots more stuff to
come.
This commit is contained in:
parent
4840ecda0b
commit
0bdc7bf06f
14 changed files with 3416 additions and 271 deletions
|
|
@ -831,6 +831,7 @@ extern int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf);
|
|||
extern drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl);
|
||||
#endif
|
||||
#if __HAVE_DMA_FREELIST
|
||||
#error "wtf???"
|
||||
extern int DRM(freelist_create)(drm_freelist_t *bl, int count);
|
||||
extern int DRM(freelist_destroy)(drm_freelist_t *bl);
|
||||
extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
|
|||
buf->used = 0;
|
||||
|
||||
buf->offset = (dma->byte_count + offset); /* ******** */
|
||||
buf->bus_address = agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + offset);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 },
|
||||
#if 0
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
#endif
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 },
|
||||
|
|
@ -99,9 +97,9 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
|
||||
#if 0
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -47,12 +47,14 @@
|
|||
|
||||
# **** End of SMP/MODVERSIONS detection
|
||||
|
||||
MODS= gamma.o tdfx.o r128.o radeon.o
|
||||
LIBS= libdrm.a
|
||||
#MODS= gamma.o tdfx.o r128.o radeon.o
|
||||
#LIBS= libdrm.a
|
||||
MODS=
|
||||
LIBS=
|
||||
|
||||
DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
#DRMHEADERS= drm.h drmP.h compat-pre24.h
|
||||
#DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
|
||||
# lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
|
||||
DRMOBS=
|
||||
DRMTEMPLATES= drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \
|
||||
drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \
|
||||
drm_fops.h drm_vm.h drm_dma.h
|
||||
|
|
@ -132,11 +134,11 @@ endif
|
|||
|
||||
ifeq ($(AGP),1)
|
||||
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
|
||||
DRMOBJS += agpsupport.o
|
||||
#DRMOBJS += agpsupport.o
|
||||
MODS += mga.o
|
||||
ifeq ($(MACHINE),i386)
|
||||
MODS += i810.o
|
||||
endif
|
||||
#ifeq ($(MACHINE),i386)
|
||||
#MODS += i810.o
|
||||
#endif
|
||||
|
||||
|
||||
MGAOBJS= mga_drv.o mga_drm.o mga_dma.o mga_state.o mga_warp.o
|
||||
|
|
|
|||
|
|
@ -831,6 +831,7 @@ extern int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf);
|
|||
extern drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl);
|
||||
#endif
|
||||
#if __HAVE_DMA_FREELIST
|
||||
#error "wtf???"
|
||||
extern int DRM(freelist_create)(drm_freelist_t *bl, int count);
|
||||
extern int DRM(freelist_destroy)(drm_freelist_t *bl);
|
||||
extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
|
|||
buf->used = 0;
|
||||
|
||||
buf->offset = (dma->byte_count + offset); /* ******** */
|
||||
buf->bus_address = agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + offset);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
|
|
|
|||
133
linux/mga_dma.c
133
linux/mga_dma.c
|
|
@ -24,9 +24,10 @@
|
|||
* 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>
|
||||
* Authors:
|
||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Jeff Hartmann <jhartmann@valinux.com>
|
||||
* Keith Whitwell <keithw@valinux.com>
|
||||
*
|
||||
* Rewritten by:
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
|
|
@ -1052,7 +1053,7 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
|
|||
{
|
||||
u32 status = 0;
|
||||
int i;
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
|
||||
status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
|
||||
|
|
@ -1068,7 +1069,7 @@ int mga_do_dma_idle( drm_mga_private_t *dev_priv )
|
|||
{
|
||||
u32 status = 0;
|
||||
int i;
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
|
||||
status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK;
|
||||
|
|
@ -1082,7 +1083,7 @@ int mga_do_dma_idle( drm_mga_private_t *dev_priv )
|
|||
|
||||
int mga_do_dma_reset( drm_mga_private_t *dev_priv )
|
||||
{
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
/* The primary DMA stream should look like new right about now.
|
||||
*/
|
||||
|
|
@ -1107,7 +1108,7 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv )
|
|||
|
||||
int mga_do_engine_reset( drm_mga_private_t *dev_priv )
|
||||
{
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
/* Okay, so we've completely screwed up and locked the engine.
|
||||
* How about we clean up after ourselves?
|
||||
|
|
@ -1157,12 +1158,25 @@ static inline void mga_do_dma( drm_mga_private_t *dev_priv,
|
|||
/* Only flush the primary DMA stream if there are new commands.
|
||||
*/
|
||||
if ( head == tail ) {
|
||||
PRINT_DMA_STATE( dev_priv );
|
||||
DRM_INFO( " bailing out...\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
DRM_INFO( " head = 0x%08x\n", head );
|
||||
DRM_INFO( " tail = 0x%08x\n", tail );
|
||||
{
|
||||
u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
|
||||
if ( status != MGA_ENDPRDMASTS ) {
|
||||
panic( "DMA engine not idle!\n" );
|
||||
}
|
||||
if ( MGA_READ( MGA_STATUS ) & MGA_SOFTRAPEN ) {
|
||||
panic( "DMA engine SOFTRAP interrupt pending!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
DRM_INFO( " head = 0x%08x 0x%04x\n",
|
||||
head, head - dev_priv->primary->offset );
|
||||
DRM_INFO( " tail = 0x%08x 0x%04x\n",
|
||||
tail, tail - dev_priv->primary->offset );
|
||||
|
||||
mga_flush_write_combine();
|
||||
|
||||
|
|
@ -1183,7 +1197,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
|
|||
* function being called, even if there are no new commands.
|
||||
*/
|
||||
if ( test_and_clear_bit( MGA_DMA_FLUSH, &primary->state ) ) {
|
||||
DRM_INFO( " got DMA flush...\n" );
|
||||
DRM_DEBUG( " got DMA flush...\n" );
|
||||
}
|
||||
|
||||
/* Only flush the primary DMA stream if there are new commands.
|
||||
|
|
@ -1288,6 +1302,9 @@ void mga_dma_wrap_or_wait( drm_mga_private_t *dev_priv, int n )
|
|||
primary->tail = 0;
|
||||
primary->last_flush = 0;
|
||||
|
||||
while ( mga_do_wait_for_idle( dev_priv ) < 0 )
|
||||
;
|
||||
|
||||
/* Kick off the last chunk of commands immediately if
|
||||
* the primary DMA stream is idle. This makes wrapping
|
||||
* nice and simple.
|
||||
|
|
@ -1302,7 +1319,7 @@ void mga_dma_wrap_or_wait( drm_mga_private_t *dev_priv, int n )
|
|||
} else {
|
||||
/* FIXME: This is terribly broken...
|
||||
*/
|
||||
DRM_INFO( "*** WTF??? ***\n" );
|
||||
panic( "*** WTF??? ***\n" );
|
||||
while ( mga_do_wait_for_idle( dev_priv ) < 0 )
|
||||
;
|
||||
|
||||
|
|
@ -1366,7 +1383,9 @@ int mga_dma_schedule( drm_device_t *dev, int locked )
|
|||
DRM_INFO( "%s: prim=0x%x low=0x%x\n",
|
||||
__FUNCTION__,
|
||||
dev_priv->prim.tail - dev_priv->prim.last_flush,
|
||||
dev_priv->prim.low_mark );
|
||||
dev_priv->prim.low_mark);
|
||||
|
||||
set_bit( MGA_DMA_IDLE, &primary->state );
|
||||
|
||||
if ( dev_priv->prim.wrap ) {
|
||||
DRM_INFO( " wrapping primary DMA...\n" );
|
||||
|
|
@ -1380,9 +1399,10 @@ int mga_dma_schedule( drm_device_t *dev, int locked )
|
|||
mga_do_dma_flush( dev_priv );
|
||||
} else {
|
||||
DRM_INFO( " going idle...\n" );
|
||||
set_bit( MGA_DMA_IDLE, &primary->state );
|
||||
}
|
||||
|
||||
PRINT_DMA_STATE( dev_priv );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1394,6 +1414,26 @@ int mga_dma_schedule( drm_device_t *dev, int locked )
|
|||
#define MGA_BUFFER_USED ~0
|
||||
#define MGA_BUFFER_FREE 0
|
||||
|
||||
static void mga_freelist_print( drm_device_t *dev )
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_freelist_t *entry;
|
||||
int i;
|
||||
|
||||
DRM_INFO( "\n" );
|
||||
DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
|
||||
dev_priv->sarea_priv->last_dispatch,
|
||||
dev_priv->prim.status[1] );
|
||||
DRM_INFO( "current freelist:\n" );
|
||||
|
||||
for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
|
||||
DRM_INFO( " %p idx=%2d age=0x%x\n",
|
||||
entry, entry->buf->idx, entry->age );
|
||||
}
|
||||
DRM_INFO( "\n" );
|
||||
}
|
||||
|
||||
static int mga_freelist_init( drm_device_t *dev )
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -1402,6 +1442,7 @@ static int mga_freelist_init( drm_device_t *dev )
|
|||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_freelist_t *entry;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
|
||||
DRM_MEM_DRIVER );
|
||||
|
|
@ -1447,6 +1488,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", __FUNCTION__ );
|
||||
|
||||
entry = dev_priv->head;
|
||||
while ( entry ) {
|
||||
|
|
@ -1472,13 +1514,19 @@ static void mga_freelist_reset( drm_device_t *dev )
|
|||
}
|
||||
}
|
||||
|
||||
drm_buf_t *mga_freelist_get( drm_device_t *dev )
|
||||
static drm_buf_t *mga_freelist_get( drm_device_t *dev )
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_freelist_t *next;
|
||||
drm_mga_freelist_t *prev;
|
||||
DRM_DEBUG( "%s: tail=0x%x status=0x%x\n",
|
||||
__FUNCTION__, dev_priv->tail->age,
|
||||
dev_priv->prim.status[1] );
|
||||
|
||||
if ( dev_priv->tail->age < dev_priv->last_prim_age ) {
|
||||
#if 0
|
||||
mga_freelist_print( dev );
|
||||
#endif
|
||||
if ( dev_priv->tail->age <= dev_priv->prim.status[1] ) {
|
||||
prev = dev_priv->tail->prev;
|
||||
next = dev_priv->tail;
|
||||
prev->next = NULL;
|
||||
|
|
@ -1488,16 +1536,19 @@ drm_buf_t *mga_freelist_get( drm_device_t *dev )
|
|||
return next->buf;
|
||||
}
|
||||
|
||||
DRM_ERROR( "returning NULL!\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
|
||||
static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
|
||||
drm_mga_freelist_t *head;
|
||||
drm_mga_freelist_t *next;
|
||||
drm_mga_freelist_t *prev;
|
||||
DRM_DEBUG( "%s: age=0x%x\n",
|
||||
__FUNCTION__, buf_priv->list_entry->age );
|
||||
|
||||
if ( buf_priv->list_entry->age == MGA_BUFFER_USED ) {
|
||||
/* Discarded buffer, put it on the tail.
|
||||
|
|
@ -1534,7 +1585,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
{
|
||||
drm_mga_private_t *dev_priv;
|
||||
int ret;
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
|
||||
if ( dev_priv == NULL )
|
||||
|
|
@ -1553,6 +1604,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
} else {
|
||||
dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
|
||||
}
|
||||
dev_priv->maccess = init->maccess;
|
||||
|
||||
dev_priv->fb_cpp = init->fb_cpp;
|
||||
dev_priv->front_offset = init->front_offset;
|
||||
|
|
@ -1564,6 +1616,14 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
dev_priv->depth_offset = init->depth_offset;
|
||||
dev_priv->depth_pitch = init->depth_pitch;
|
||||
|
||||
DRM_INFO( " macces = 0x%08x\n", init->maccess );
|
||||
DRM_INFO( "front offset = 0x%08x\n", init->front_offset );
|
||||
DRM_INFO( "front pitch = 0x%08x\n", init->front_pitch );
|
||||
DRM_INFO( " back offset = 0x%08x\n", init->back_offset );
|
||||
DRM_INFO( " back pitch = 0x%08x\n", init->back_pitch );
|
||||
DRM_INFO( "depth offset = 0x%08x\n", init->depth_offset );
|
||||
DRM_INFO( "depth pitch = 0x%08x\n", init->depth_pitch );
|
||||
|
||||
dev_priv->sarea = dev->maplist[0];
|
||||
|
||||
DO_FIND_MAP( dev_priv->fb, init->fb_offset );
|
||||
|
|
@ -1628,7 +1688,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
dev_priv->prim.space = dev_priv->prim.size - MGA_DMA_SOFTRAP_SIZE;
|
||||
|
||||
dev_priv->prim.last_flush = 0;
|
||||
dev_priv->prim.low_mark = 4096;
|
||||
dev_priv->prim.low_mark = 32 * DMA_BLOCK_SIZE;
|
||||
dev_priv->prim.mid_mark = dev_priv->prim.space / 4;
|
||||
dev_priv->prim.high_mark = 0;
|
||||
|
||||
|
|
@ -1640,12 +1700,21 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
|
|||
*/
|
||||
*dev_priv->prim.head = dev_priv->primary->offset;
|
||||
|
||||
dev_priv->sarea_priv->last_dispatch = 0;
|
||||
dev_priv->prim.status[1] = 0;
|
||||
|
||||
if ( mga_freelist_init( dev ) < 0 ) {
|
||||
DRM_ERROR( "could not initialize freelist\n" );
|
||||
mga_do_cleanup_dma( dev );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_do_cleanup_dma( drm_device_t *dev )
|
||||
{
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( dev->dev_private ) {
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
|
|
@ -1665,6 +1734,10 @@ int mga_do_cleanup_dma( drm_device_t *dev )
|
|||
*/
|
||||
if ( dev->irq ) mga_irq_uninstall( dev );
|
||||
|
||||
if ( dev_priv->head != NULL ) {
|
||||
mga_freelist_cleanup( dev );
|
||||
}
|
||||
|
||||
DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),
|
||||
DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
|
|
@ -1707,16 +1780,12 @@ int mga_dma_flush( struct inode *inode, struct file *filp,
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_lock_t lock;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
|
||||
return -EFAULT;
|
||||
|
||||
if( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) &&
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_INFO( "%s: %s%s%s\n",
|
||||
DRM_DEBUG( "%s: %s%s%s\n",
|
||||
__FUNCTION__,
|
||||
(lock.flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
|
||||
(lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
|
||||
|
|
@ -1757,11 +1826,7 @@ int mga_dma_reset( struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
|
||||
if( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) &&
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
return mga_do_dma_reset( dev_priv );
|
||||
}
|
||||
|
|
@ -2010,11 +2075,7 @@ int mga_dma_buffers( struct inode *inode, struct file *filp,
|
|||
drm_dma_t d;
|
||||
int ret = 0;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
|
||||
return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 },
|
||||
#if 0
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma, 1, 0 },
|
||||
#endif
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 },
|
||||
|
|
@ -99,9 +97,9 @@ static drm_ioctl_desc_t mga_ioctls[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
|
||||
#if 0
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ typedef struct drm_mga_private {
|
|||
int usec_timeout;
|
||||
|
||||
u32 clear_cmd;
|
||||
u32 maccess;
|
||||
|
||||
unsigned int fb_cpp;
|
||||
unsigned int front_offset;
|
||||
|
|
@ -189,6 +190,8 @@ extern int mga_dma_reset( struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_control( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_dma_buffers( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
|
||||
extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
|
||||
|
|
@ -205,6 +208,8 @@ extern int mga_dma_clear( struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_dma_swap( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_dma_vertex( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
#if 0
|
||||
extern int mga_clear_bufs( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
|
@ -212,8 +217,6 @@ extern int mga_swap_bufs( struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_iload( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_vertex( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int mga_indices( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
#endif
|
||||
|
|
@ -350,7 +353,49 @@ drm_mga_prim_buf_t *tmp_buf = \
|
|||
|
||||
|
||||
|
||||
#define MGA_VERBOSE 1
|
||||
/* ================================================================
|
||||
* Helper macross...
|
||||
*/
|
||||
|
||||
#define MGA_EMIT_STATE( dev_priv, dirty ) \
|
||||
do { \
|
||||
if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \
|
||||
if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { \
|
||||
mga_g400_emit_state( dev_priv ); \
|
||||
} else { \
|
||||
mga_g200_emit_state( dev_priv ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOCK_TEST_WITH_RETURN( dev ) \
|
||||
do { \
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
|
||||
dev->lock.pid != current->pid ) { \
|
||||
DRM_ERROR( "%s called without lock held\n", \
|
||||
__FUNCTION__ ); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PRINT_DMA_STATE( dev_priv ) \
|
||||
do { \
|
||||
DRM_INFO( " state: %d %s%s%s\n", \
|
||||
dev_priv->prim.state, \
|
||||
test_bit( MGA_DMA_IDLE, &dev_priv->prim.state ) \
|
||||
? "idle, " : "active, ", \
|
||||
test_bit( MGA_DMA_FLUSH, &dev_priv->prim.state ) \
|
||||
? "flush, " : "", \
|
||||
test_bit( MGA_DMA_WRAP, &dev_priv->prim.state ) \
|
||||
? "wrap, " : "" ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Primary DMA command stream
|
||||
*/
|
||||
|
||||
#define MGA_VERBOSE 0
|
||||
|
||||
#define DMA_LOCALS unsigned int write; volatile u8 *prim;
|
||||
#define DMA_BLOCK_SIZE (5 * sizeof(u32))
|
||||
|
|
@ -360,6 +405,8 @@ do { \
|
|||
if ( MGA_VERBOSE ) { \
|
||||
DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \
|
||||
(n), __FUNCTION__ ); \
|
||||
DRM_INFO( " space=0x%x req=0x%x\n", \
|
||||
dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
|
||||
} \
|
||||
if ( dev_priv->prim.space < (int)((n) * DMA_BLOCK_SIZE) ) { \
|
||||
mga_dma_wrap_or_wait( dev_priv, \
|
||||
|
|
@ -430,23 +477,12 @@ do { \
|
|||
#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \
|
||||
MGA_ENDPRDMASTS)
|
||||
|
||||
#define MGA_DMA_SOFTRAP_SIZE DMA_BLOCK_SIZE
|
||||
#define MGA_DMA_SOFTRAP_SIZE 32 * DMA_BLOCK_SIZE
|
||||
|
||||
#define MGA_DMA_IS_IDLE( dev_priv ) test_bit( MGA_DMA_IDLE, \
|
||||
&dev_priv->prim.state )
|
||||
|
||||
|
||||
#define MGA_EMIT_STATE( dev_priv, dirty ) \
|
||||
do { \
|
||||
if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \
|
||||
if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { \
|
||||
mga_g400_emit_state( dev_priv ); \
|
||||
} else { \
|
||||
mga_g200_emit_state( dev_priv ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* A reduced set of the mga registers.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
|
|||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
|
||||
unsigned int pitch = dev_priv->front_pitch;
|
||||
unsigned int pitch = dev_priv->front_pitch / dev_priv->fb_cpp;
|
||||
DMA_LOCALS;
|
||||
|
||||
BEGIN_DMA( 2 );
|
||||
|
|
@ -81,8 +81,8 @@ static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
|
|||
}
|
||||
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
|
||||
MGA_CXBNDRY, (box->x2 << 16) | box->x1,
|
||||
MGA_YTOP, box->y1 * pitch / dev_priv->cpp,
|
||||
MGA_YBOT, box->y2 * pitch / dev_priv->cpp );
|
||||
MGA_YTOP, box->y1 * pitch,
|
||||
MGA_YBOT, box->y2 * pitch );
|
||||
|
||||
ADVANCE_DMA();
|
||||
}
|
||||
|
|
@ -317,7 +317,8 @@ static inline void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
|
|||
MGA_DWGCTL, MGA_DWGCTL_FLUSH );
|
||||
|
||||
DMA_BLOCK( MGA_LEN + MGA_EXEC, 0x00000001,
|
||||
MGA_DWGSYNC, 0x00007000,
|
||||
/*MGA_DWGSYNC, 0x00007000,*/
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
|
||||
MGA_LEN + MGA_EXEC, 0x00000000 );
|
||||
|
||||
|
|
@ -522,7 +523,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev,
|
|||
int nbox = sarea_priv->nbox;
|
||||
int i;
|
||||
DMA_LOCALS;
|
||||
DRM_INFO( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
for ( i = 0 ; i < nbox ; i++ ) {
|
||||
unsigned int height = pbox[i].y2 - pbox[i].y1;
|
||||
|
|
@ -570,72 +571,110 @@ static void mga_dma_dispatch_clear( drm_device_t *dev,
|
|||
|
||||
ADVANCE_DMA();
|
||||
}
|
||||
#if 0
|
||||
/* Force reset of DWGCTL.
|
||||
*/
|
||||
BEGIN_DMA( 1 );
|
||||
}
|
||||
|
||||
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;
|
||||
drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
|
||||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
int nbox = sarea_priv->nbox;
|
||||
u32 pitch = dev_priv->front_pitch / dev_priv->fb_cpp;
|
||||
int i;
|
||||
DMA_LOCALS;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
BEGIN_DMA( 2 + nbox );
|
||||
|
||||
DMA_BLOCK( MGA_MACCESS, dev_priv->maccess,
|
||||
MGA_SRCORG, dev_priv->back_offset,
|
||||
MGA_DSTORG, dev_priv->front_offset,
|
||||
MGA_AR5, pitch );
|
||||
|
||||
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_DWGCTL, ctx->dwgctl );
|
||||
MGA_DWGCTL, MGA_DWGCTL_COPY );
|
||||
|
||||
ADVANCE_DMA();
|
||||
#endif
|
||||
}
|
||||
for ( i = 0 ; i < nbox ; i++ ) {
|
||||
u32 h = pbox[i].y2 - pbox[i].y1;
|
||||
u32 start = pbox[i].y1 * pitch;
|
||||
|
||||
#if 0
|
||||
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;
|
||||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
int i;
|
||||
int pixel_stride = dev_priv->stride / dev_priv->cpp;
|
||||
|
||||
PRIMLOCALS;
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
|
||||
PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
|
||||
PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
|
||||
PRIMOUTREG(MGAREG_AR5, pixel_stride);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(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 * pixel_stride;
|
||||
|
||||
PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
|
||||
PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
|
||||
PRIMOUTREG(MGAREG_FXBNDRY,
|
||||
pbox[i].x1 | ((pbox[i].x2 - 1) << 16));
|
||||
PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC,
|
||||
(pbox[i].y1 << 16) | h);
|
||||
DMA_BLOCK( MGA_AR0, start + pbox[i].x2 - 1,
|
||||
MGA_AR3, start + pbox[i].x1,
|
||||
MGA_FXBNDRY, ((pbox[i].x2 - 1) << 16) | pbox[i].x1,
|
||||
MGA_YDSTLEN + MGA_EXEC,
|
||||
(pbox[i].y1 << 16) | h );
|
||||
}
|
||||
|
||||
/* Force reset of DWGCTL */
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
|
||||
|
||||
PRIMADVANCE(dev_priv);
|
||||
ADVANCE_DMA();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
u32 address = (u32) buf->bus_address;
|
||||
u32 length = (u32) buf->used;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int i = 0;
|
||||
DMA_LOCALS;
|
||||
|
||||
DRM_DEBUG( "%s: buf=%d used=%d\n",
|
||||
__FUNCTION__, buf->idx, buf->used );
|
||||
|
||||
if ( buf->used ) {
|
||||
buf_priv->dispatched = 1;
|
||||
|
||||
MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
|
||||
|
||||
#if 0
|
||||
do {
|
||||
if ( i < sarea_priv->nbox ) {
|
||||
mga_emit_clip_rect( dev_priv,
|
||||
&sarea_priv->boxes[i] );
|
||||
}
|
||||
|
||||
BEGIN_DMA( 1 );
|
||||
|
||||
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_SECADDRESS, (address |
|
||||
MGA_DMA_VERTEX),
|
||||
MGA_SECEND, ((address + length) |
|
||||
MGA_PAGPXFER) );
|
||||
|
||||
ADVANCE_DMA();
|
||||
} while ( ++i < sarea_priv->nbox );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( buf_priv->discard ) {
|
||||
if ( buf_priv->dispatched == 1 ) {
|
||||
buf_priv->list_entry->age = sarea_priv->last_dispatch;
|
||||
|
||||
BEGIN_DMA( 1 );
|
||||
|
||||
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_DMAPAD, 0x00000000,
|
||||
MGA_DWGSYNC, sarea_priv->last_dispatch );
|
||||
|
||||
ADVANCE_DMA();
|
||||
|
||||
sarea_priv->last_dispatch += 4;
|
||||
}
|
||||
|
||||
buf->pending = 0;
|
||||
buf->used = 0;
|
||||
buf_priv->dispatched = 0;
|
||||
|
||||
mga_freelist_put( dev, buf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -680,56 +719,6 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
|
|||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
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;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned long address = (unsigned long) buf->bus_address;
|
||||
int length = buf->used;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int i = 0;
|
||||
PRIMLOCALS;
|
||||
|
||||
if (buf->used) {
|
||||
/* WARNING: if you change any of the state functions verify
|
||||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
buf_priv->dispatched = 1;
|
||||
PRIM_OVERFLOW(dev, dev_priv,
|
||||
(MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
|
||||
mgaEmitState(dev_priv);
|
||||
|
||||
#if 0
|
||||
length = dev_priv->vertexsize * 3 * 4;
|
||||
#endif
|
||||
|
||||
do {
|
||||
if (i < sarea_priv->nbox) {
|
||||
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_priv->discard) {
|
||||
if (buf_priv->dispatched == 1)
|
||||
AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void mga_dma_dispatch_indices(drm_device_t * dev,
|
||||
drm_buf_t * buf,
|
||||
|
|
@ -798,11 +787,7 @@ int mga_dma_clear( struct inode *inode, struct file *filp,
|
|||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_mga_clear_t clear;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
|
||||
dev->lock.pid != current->pid ) {
|
||||
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &clear, (drm_mga_clear_t *) arg, sizeof(clear) ) )
|
||||
return -EFAULT;
|
||||
|
|
@ -816,40 +801,81 @@ int mga_dma_clear( struct inode *inode, struct file *filp,
|
|||
*/
|
||||
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
|
||||
|
||||
MAYBE_FLUSH_DMA();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int mga_dma_swap( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
#if 0
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("mga_swap_bufs called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
|
||||
if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
|
||||
sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
|
||||
|
||||
mga_dma_dispatch_swap( dev );
|
||||
|
||||
/* Make sure we restore the 3D state next time.
|
||||
*/
|
||||
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
|
||||
mga_dma_dispatch_swap(dev);
|
||||
PRIMUPDATE(dev_priv);
|
||||
set_bit(MGA_BUF_SWAP_PENDING,
|
||||
&dev_priv->current_prim->buffer_status);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
|
||||
|
||||
MAYBE_FLUSH_DMA();
|
||||
|
||||
mga_do_wait_for_idle( dev_priv );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_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_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_vertex_t vertex;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( copy_from_user( &vertex,
|
||||
(drm_mga_vertex_t *)arg,
|
||||
sizeof(vertex) ) )
|
||||
return -EFAULT;
|
||||
|
||||
/* HACK: Force this for now...
|
||||
*/
|
||||
if ( mga_do_wait_for_idle( dev_priv ) < 0 )
|
||||
return -EBUSY;
|
||||
|
||||
buf = dma->buflist[vertex.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
buf->used = vertex.used;
|
||||
buf_priv->discard = vertex.discard;
|
||||
|
||||
if ( !mga_verify_state( dev_priv ) ) {
|
||||
if ( vertex.discard ) {
|
||||
#if 0
|
||||
if ( buf_priv->dispatched == 1 )
|
||||
AGEBUF(dev_priv, buf_priv);
|
||||
#endif
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put( dev, buf );
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mga_dma_dispatch_vertex( dev, buf );
|
||||
|
||||
MAYBE_FLUSH_DMA();
|
||||
|
||||
mga_do_wait_for_idle( dev_priv );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -902,50 +928,6 @@ int mga_iload(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mga_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_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_mga_buf_priv_t *buf_priv;
|
||||
drm_mga_vertex_t vertex;
|
||||
|
||||
if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("mga_vertex called without lock held\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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.discard) {
|
||||
if (buf_priv->dispatched == 1)
|
||||
AGEBUF(dev_priv, buf_priv);
|
||||
buf_priv->dispatched = 0;
|
||||
mga_freelist_put(dev, buf);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mga_dma_dispatch_vertex(dev, buf);
|
||||
|
||||
PRIMUPDATE(dev_priv);
|
||||
mga_flush_write_combine();
|
||||
mga_dma_schedule(dev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mga_indices(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
|
|
|
|||
1314
linux/radeon_cp.c
Normal file
1314
linux/radeon_cp.c
Normal file
File diff suppressed because it is too large
Load diff
325
linux/radeon_drm.h
Normal file
325
linux/radeon_drm.h
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*-
|
||||
*
|
||||
* Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Fremont, 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:
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RADEON_DRM_H__
|
||||
#define __RADEON_DRM_H__
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the X server file (radeon_sarea.h)
|
||||
*/
|
||||
#ifndef __RADEON_SAREA_DEFINES__
|
||||
#define __RADEON_SAREA_DEFINES__
|
||||
|
||||
/* What needs to be changed for the current vertex buffer?
|
||||
*/
|
||||
#define RADEON_UPLOAD_CONTEXT 0x00000001
|
||||
#define RADEON_UPLOAD_VERTFMT 0x00000002
|
||||
#define RADEON_UPLOAD_LINE 0x00000004
|
||||
#define RADEON_UPLOAD_BUMPMAP 0x00000008
|
||||
#define RADEON_UPLOAD_MASKS 0x00000010
|
||||
#define RADEON_UPLOAD_VIEWPORT 0x00000020
|
||||
#define RADEON_UPLOAD_SETUP 0x00000040
|
||||
#define RADEON_UPLOAD_TCL 0x00000080
|
||||
#define RADEON_UPLOAD_MISC 0x00000100
|
||||
#define RADEON_UPLOAD_TEX0 0x00000200
|
||||
#define RADEON_UPLOAD_TEX1 0x00000400
|
||||
#define RADEON_UPLOAD_TEX2 0x00000800
|
||||
#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
|
||||
#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
|
||||
#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
|
||||
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
|
||||
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
|
||||
#define RADEON_UPLOAD_ALL 0x0001ffff
|
||||
|
||||
#define RADEON_FRONT 0x1
|
||||
#define RADEON_BACK 0x2
|
||||
#define RADEON_DEPTH 0x4
|
||||
|
||||
/* Primitive types
|
||||
*/
|
||||
#define RADEON_POINTS 0x1
|
||||
#define RADEON_LINES 0x2
|
||||
#define RADEON_LINE_STRIP 0x3
|
||||
#define RADEON_TRIANGLES 0x4
|
||||
#define RADEON_TRIANGLE_FAN 0x5
|
||||
#define RADEON_TRIANGLE_STRIP 0x6
|
||||
|
||||
/* Vertex/indirect buffer size
|
||||
*/
|
||||
#define RADEON_BUFFER_SIZE 16384
|
||||
|
||||
/* Byte offsets for indirect buffer data
|
||||
*/
|
||||
#define RADEON_INDEX_PRIM_OFFSET 20
|
||||
#define RADEON_HOSTDATA_BLIT_OFFSET 32
|
||||
|
||||
#define RADEON_SCRATCH_REG_OFFSET 32
|
||||
|
||||
/* Keep these small for testing
|
||||
*/
|
||||
#define RADEON_NR_SAREA_CLIPRECTS 12
|
||||
|
||||
/* There are 2 heaps (local/AGP). Each region within a heap is a
|
||||
* minimum of 64k, and there are at most 64 of them per heap.
|
||||
*/
|
||||
#define RADEON_LOCAL_TEX_HEAP 0
|
||||
#define RADEON_AGP_TEX_HEAP 1
|
||||
#define RADEON_NR_TEX_HEAPS 2
|
||||
#define RADEON_NR_TEX_REGIONS 64
|
||||
#define RADEON_LOG_TEX_GRANULARITY 16
|
||||
|
||||
#define RADEON_MAX_TEXTURE_LEVELS 11
|
||||
#define RADEON_MAX_TEXTURE_UNITS 3
|
||||
|
||||
#endif /* __RADEON_SAREA_DEFINES__ */
|
||||
|
||||
typedef struct {
|
||||
unsigned int red;
|
||||
unsigned int green;
|
||||
unsigned int blue;
|
||||
unsigned int alpha;
|
||||
} radeon_color_regs_t;
|
||||
|
||||
typedef struct {
|
||||
/* Context state */
|
||||
unsigned int pp_misc; /* 0x1c14 */
|
||||
unsigned int pp_fog_color;
|
||||
unsigned int re_solid_color;
|
||||
unsigned int rb3d_blendcntl;
|
||||
unsigned int rb3d_depthoffset;
|
||||
unsigned int rb3d_depthpitch;
|
||||
unsigned int rb3d_zstencilcntl;
|
||||
|
||||
unsigned int pp_cntl; /* 0x1c38 */
|
||||
unsigned int rb3d_cntl;
|
||||
unsigned int rb3d_coloroffset;
|
||||
unsigned int re_width_height;
|
||||
unsigned int rb3d_colorpitch;
|
||||
unsigned int se_cntl;
|
||||
|
||||
/* Vertex format state */
|
||||
unsigned int se_coord_fmt; /* 0x1c50 */
|
||||
|
||||
/* Line state */
|
||||
unsigned int re_line_pattern; /* 0x1cd0 */
|
||||
unsigned int re_line_state;
|
||||
|
||||
unsigned int se_line_width; /* 0x1db8 */
|
||||
|
||||
/* Bumpmap state */
|
||||
unsigned int pp_lum_matrix; /* 0x1d00 */
|
||||
|
||||
unsigned int pp_rot_matrix_0; /* 0x1d58 */
|
||||
unsigned int pp_rot_matrix_1;
|
||||
|
||||
/* Mask state */
|
||||
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
|
||||
unsigned int rb3d_ropcntl;
|
||||
unsigned int rb3d_planemask;
|
||||
|
||||
/* Viewport state */
|
||||
unsigned int se_vport_xscale; /* 0x1d98 */
|
||||
unsigned int se_vport_xoffset;
|
||||
unsigned int se_vport_yscale;
|
||||
unsigned int se_vport_yoffset;
|
||||
unsigned int se_vport_zscale;
|
||||
unsigned int se_vport_zoffset;
|
||||
|
||||
/* Setup state */
|
||||
unsigned int se_cntl_status; /* 0x2140 */
|
||||
|
||||
#ifdef TCL_ENABLE
|
||||
/* TCL state */
|
||||
radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */
|
||||
radeon_color_regs_t se_tcl_material_ambient;
|
||||
radeon_color_regs_t se_tcl_material_diffuse;
|
||||
radeon_color_regs_t se_tcl_material_specular;
|
||||
unsigned int se_tcl_shininess;
|
||||
unsigned int se_tcl_output_vtx_fmt;
|
||||
unsigned int se_tcl_output_vtx_sel;
|
||||
unsigned int se_tcl_matrix_select_0;
|
||||
unsigned int se_tcl_matrix_select_1;
|
||||
unsigned int se_tcl_ucp_vert_blend_ctl;
|
||||
unsigned int se_tcl_texture_proc_ctl;
|
||||
unsigned int se_tcl_light_model_ctl;
|
||||
unsigned int se_tcl_per_light_ctl[4];
|
||||
#endif
|
||||
|
||||
/* Misc state */
|
||||
unsigned int re_top_left; /* 0x26c0 */
|
||||
unsigned int re_misc;
|
||||
} drm_radeon_context_regs_t;
|
||||
|
||||
/* Setup registers for each texture unit
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int pp_txfilter;
|
||||
unsigned int pp_txformat;
|
||||
unsigned int pp_txoffset;
|
||||
unsigned int pp_txcblend;
|
||||
unsigned int pp_txablend;
|
||||
unsigned int pp_tfactor;
|
||||
|
||||
unsigned int pp_border_color;
|
||||
|
||||
#ifdef CUBIC_ENABLE
|
||||
unsigned int pp_cubic_faces;
|
||||
unsigned int pp_cubic_offset[5];
|
||||
#endif
|
||||
} drm_radeon_texture_regs_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char next, prev;
|
||||
unsigned char in_use;
|
||||
int age;
|
||||
} drm_radeon_tex_region_t;
|
||||
|
||||
typedef struct {
|
||||
/* The channel for communication of state information to the kernel
|
||||
* on firing a vertex buffer.
|
||||
*/
|
||||
drm_radeon_context_regs_t context_state;
|
||||
drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
|
||||
unsigned int dirty;
|
||||
unsigned int vertsize;
|
||||
unsigned int vc_format;
|
||||
|
||||
/* The current cliprects, or a subset thereof.
|
||||
*/
|
||||
drm_clip_rect_t boxes[RADEON_NR_SAREA_CLIPRECTS];
|
||||
unsigned int nbox;
|
||||
|
||||
/* Counters for client-side throttling of rendering clients.
|
||||
*/
|
||||
unsigned int last_frame;
|
||||
unsigned int last_dispatch;
|
||||
unsigned int last_clear;
|
||||
|
||||
drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
|
||||
int tex_age[RADEON_NR_TEX_HEAPS];
|
||||
int ctx_owner;
|
||||
} drm_radeon_sarea_t;
|
||||
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the Xserver file (xf86drmRadeon.h)
|
||||
*/
|
||||
typedef struct drm_radeon_init {
|
||||
enum {
|
||||
RADEON_INIT_CP = 0x01,
|
||||
RADEON_CLEANUP_CP = 0x02
|
||||
} func;
|
||||
int sarea_priv_offset;
|
||||
int is_pci;
|
||||
int cp_mode;
|
||||
int agp_size;
|
||||
int ring_size;
|
||||
int usec_timeout;
|
||||
|
||||
unsigned int fb_bpp;
|
||||
unsigned int front_offset, front_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int depth_bpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
|
||||
unsigned int fb_offset;
|
||||
unsigned int mmio_offset;
|
||||
unsigned int ring_offset;
|
||||
unsigned int ring_rptr_offset;
|
||||
unsigned int buffers_offset;
|
||||
unsigned int agp_textures_offset;
|
||||
} drm_radeon_init_t;
|
||||
|
||||
typedef struct drm_radeon_cp_stop {
|
||||
int flush;
|
||||
int idle;
|
||||
} drm_radeon_cp_stop_t;
|
||||
|
||||
typedef struct drm_radeon_fullscreen {
|
||||
enum {
|
||||
RADEON_INIT_FULLSCREEN = 0x01,
|
||||
RADEON_CLEANUP_FULLSCREEN = 0x02
|
||||
} func;
|
||||
} drm_radeon_fullscreen_t;
|
||||
|
||||
#define CLEAR_X1 0
|
||||
#define CLEAR_Y1 1
|
||||
#define CLEAR_X2 2
|
||||
#define CLEAR_Y2 3
|
||||
#define CLEAR_DEPTH 4
|
||||
|
||||
typedef struct drm_radeon_clear {
|
||||
unsigned int flags;
|
||||
int x, y, w, h;
|
||||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
union {
|
||||
float f[5];
|
||||
unsigned int ui[5];
|
||||
} rect;
|
||||
} drm_radeon_clear_t;
|
||||
|
||||
typedef struct drm_radeon_vertex {
|
||||
int prim;
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_radeon_vertex_t;
|
||||
|
||||
typedef struct drm_radeon_indices {
|
||||
int prim;
|
||||
int idx;
|
||||
int start;
|
||||
int end;
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_radeon_indices_t;
|
||||
|
||||
typedef struct drm_radeon_blit {
|
||||
int idx;
|
||||
int pitch;
|
||||
int offset;
|
||||
int format;
|
||||
unsigned short x, y;
|
||||
unsigned short width, height;
|
||||
} drm_radeon_blit_t;
|
||||
|
||||
typedef struct drm_radeon_stipple {
|
||||
unsigned int *mask;
|
||||
} drm_radeon_stipple_t;
|
||||
|
||||
typedef struct drm_radeon_indirect {
|
||||
int idx;
|
||||
int start;
|
||||
int end;
|
||||
int discard;
|
||||
} drm_radeon_indirect_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -50,8 +50,6 @@ typedef struct drm_radeon_ring_buffer {
|
|||
u32 tail;
|
||||
u32 tail_mask;
|
||||
int space;
|
||||
|
||||
int high_mark;
|
||||
} drm_radeon_ring_buffer_t;
|
||||
|
||||
typedef struct drm_radeon_depth_clear_t {
|
||||
|
|
@ -93,13 +91,13 @@ typedef struct drm_radeon_private {
|
|||
u32 crtc_offset;
|
||||
u32 crtc_offset_cntl;
|
||||
|
||||
u32 color_fmt;
|
||||
unsigned int color_fmt;
|
||||
unsigned int front_offset;
|
||||
unsigned int front_pitch;
|
||||
unsigned int back_offset;
|
||||
unsigned int back_pitch;
|
||||
|
||||
u32 depth_fmt;
|
||||
unsigned int depth_fmt;
|
||||
unsigned int depth_offset;
|
||||
unsigned int depth_pitch;
|
||||
|
||||
|
|
@ -536,17 +534,15 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
|
|||
#define RADEON_MAX_VB_AGE 0x7fffffff
|
||||
#define RADEON_MAX_VB_VERTS (0xffff)
|
||||
|
||||
#define RADEON_RING_HIGH_MARK 128
|
||||
|
||||
|
||||
#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
|
||||
#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg)
|
||||
|
||||
#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR(reg)
|
||||
#define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg)
|
||||
#define RADEON_READ(reg) RADEON_DEREF(reg)
|
||||
#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0)
|
||||
|
||||
#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR(reg)
|
||||
#define RADEON_DEREF8(reg) *(__volatile__ u8 *)RADEON_ADDR(reg)
|
||||
#define RADEON_READ8(reg) RADEON_DEREF8(reg)
|
||||
#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0)
|
||||
|
||||
|
|
@ -634,25 +630,7 @@ do { \
|
|||
* Misc helper macros
|
||||
*/
|
||||
|
||||
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
|
||||
do { \
|
||||
drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \
|
||||
if ( ring->space < ring->high_mark ) { \
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \
|
||||
ring->space = *ring->head - ring->tail; \
|
||||
if ( ring->space <= 0 ) \
|
||||
ring->space += ring->size; \
|
||||
if ( ring->space >= ring->high_mark ) \
|
||||
goto __ring_space_done; \
|
||||
udelay( 1 ); \
|
||||
} \
|
||||
DRM_ERROR( "ring space check failed!\n" ); \
|
||||
return -EBUSY; \
|
||||
} \
|
||||
__ring_space_done: \
|
||||
} while (0)
|
||||
|
||||
#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
|
||||
#define VB_AGE_CHECK_WITH_RET( dev_priv ) \
|
||||
do { \
|
||||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
|
||||
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
|
||||
|
|
|
|||
1447
linux/radeon_state.c
Normal file
1447
linux/radeon_state.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue