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:
Gareth Hughes 2001-01-28 12:54:52 +00:00
parent 4840ecda0b
commit 0bdc7bf06f
14 changed files with 3416 additions and 271 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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
};

View file

@ -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

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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
};

View file

@ -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.
*/

View file

@ -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

File diff suppressed because it is too large Load diff

325
linux/radeon_drm.h Normal file
View 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

View file

@ -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

File diff suppressed because it is too large Load diff