- Fix MGA header info.

- Update date strings.
- Fix MGA hangs (undocumented side effects of DWGSYNC).
- Remove idle before ILOAD??? Seems fine with the above fix.
This commit is contained in:
Gareth Hughes 2001-03-21 13:10:27 +00:00
parent b90028231c
commit 92b0aaa6fe
5 changed files with 85 additions and 21 deletions

View file

@ -38,11 +38,11 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
#define DRIVER_DATE "20010319"
#define DRIVER_DATE "20010321"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 1
#define DRIVER_PATCHLEVEL 2
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \

View file

@ -64,7 +64,10 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
udelay( 1 );
}
DRM_DEBUG( "failed! status=0x%08x\n", status );
#if MGA_DMA_DEBUG
DRM_ERROR( "failed!\n" );
DRM_INFO( " status=0x%08x\n", status );
#endif
return -EBUSY;
}
@ -80,7 +83,9 @@ int mga_do_dma_idle( drm_mga_private_t *dev_priv )
udelay( 1 );
}
DRM_DEBUG( "failed! status=0x%08x\n", status );
#if MGA_DMA_DEBUG
DRM_ERROR( "failed! status=0x%08x\n", status );
#endif
return -EBUSY;
}
@ -209,7 +214,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
MGA_DWGSYNC, 0x12345678 );
MGA_DMAPAD, 0x00000000 );
ADVANCE_DMA();
@ -236,11 +241,13 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
mga_flush_write_combine();
MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
set_bit( 0, &primary->wrapped );
DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
}
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", __FUNCTION__ );
@ -251,6 +258,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
mga_flush_write_combine();
MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
clear_bit( 0, &primary->wrapped );
DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
}
@ -542,6 +550,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
dev_priv->prim.tail = 0;
dev_priv->prim.space = dev_priv->prim.size;
dev_priv->prim.wrapped = 0;
dev_priv->prim.last_flush = 0;
dev_priv->prim.last_wrap = 0;
@ -633,15 +642,21 @@ int mga_dma_flush( struct inode *inode, struct file *filp,
(lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
(lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" );
WRAP_TEST_WITH_RETURN( dev_priv );
WRAP_WAIT_WITH_RETURN( dev_priv );
#if 0
if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) {
mga_do_dma_flush( dev_priv );
}
#endif
if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
#if MGA_DMA_DEBUG
int ret = mga_do_wait_for_idle( dev_priv );
if ( ret < 0 )
DRM_INFO( __FUNCTION__": -EBUSY\n" );
return ret;
#else
return mga_do_wait_for_idle( dev_priv );
#endif
} else {
return 0;
}
@ -693,6 +708,7 @@ int mga_dma_buffers( struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_dma_t d;
int ret = 0;
@ -717,6 +733,8 @@ int mga_dma_buffers( struct inode *inode, struct file *filp,
return -EINVAL;
}
WRAP_TEST_WITH_RETURN( dev_priv );
d.granted_count = 0;
if ( d.request_count ) {

View file

@ -38,11 +38,11 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
#define DRIVER_DATE "20010319"
#define DRIVER_DATE "20010321"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 1
#define DRIVER_PATCHLEVEL 2
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \

View file

@ -38,6 +38,7 @@ typedef struct drm_mga_primary_buffer {
u32 tail;
int space;
volatile int wrapped;
volatile u32 *status;
@ -123,7 +124,6 @@ extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv );
extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
/* mga_state.c */
extern int mga_dma_clear( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@ -193,10 +193,26 @@ do { \
#define WRAP_TEST_WITH_RETURN( dev_priv ) \
do { \
if ( dev_priv->sarea_priv->last_wrap < \
dev_priv->prim.last_wrap ) { \
if ( mga_do_wait_for_idle( dev_priv ) < 0 ) \
if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( mga_is_idle( dev_priv ) ) { \
mga_do_dma_wrap_end( dev_priv ); \
} else if ( dev_priv->prim.space < \
dev_priv->prim.high_mark ) { \
if ( MGA_DMA_DEBUG ) \
DRM_INFO( __FUNCTION__": wrap...\n" ); \
return -EBUSY; \
} \
} \
} while (0)
#define WRAP_WAIT_WITH_RETURN( dev_priv ) \
do { \
if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \
if ( MGA_DMA_DEBUG ) \
DRM_INFO( __FUNCTION__": wrap...\n" ); \
return -EBUSY; \
} \
mga_do_dma_wrap_end( dev_priv ); \
} \
} while (0)
@ -252,10 +268,13 @@ do { \
MGA_READ( MGA_PRIMADDRESS ) - \
dev_priv->primary->offset ); \
} \
if ( dev_priv->prim.space < dev_priv->prim.high_mark ) { \
mga_do_dma_wrap_start( dev_priv ); \
} else { \
mga_do_dma_flush( dev_priv ); \
if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( dev_priv->prim.space < \
dev_priv->prim.high_mark ) { \
mga_do_dma_wrap_start( dev_priv ); \
} else { \
mga_do_dma_flush( dev_priv ); \
} \
} \
} while (0)
@ -317,7 +336,7 @@ do { \
#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \
MGA_ENDPRDMASTS)
#define MGA_DMA_SOFTRAP_SIZE 32 * DMA_BLOCK_SIZE
#define MGA_DMA_DEBUG 0
@ -599,4 +618,12 @@ do { \
MGA_BLTMOD_BFCOL | \
MGA_CLIPDIS)
/* Simple idle test.
*/
static inline int mga_is_idle( drm_mga_private_t *dev_priv )
{
u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
return ( status == MGA_ENDPRDMASTS );
}
#endif

View file

@ -515,6 +515,15 @@ static void mga_dma_dispatch_clear( drm_device_t *dev,
DMA_LOCALS;
DRM_DEBUG( __FUNCTION__ ":\n" );
BEGIN_DMA( 1 );
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
MGA_DWGSYNC, 0x00007100,
MGA_DWGSYNC, 0x00007000 );
ADVANCE_DMA();
for ( i = 0 ; i < nbox ; i++ ) {
drm_clip_rect_t *box = &pbox[i];
u32 height = box->y2 - box->y1;
@ -757,7 +766,12 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
y2 = length / 64;
BEGIN_DMA( 4 );
BEGIN_DMA( 5 );
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
MGA_DMAPAD, 0x00000000,
MGA_DWGSYNC, 0x00007100,
MGA_DWGSYNC, 0x00007000 );
DMA_BLOCK( MGA_DSTORG, dstorg,
MGA_MACCESS, 0x00000000,
@ -1009,8 +1023,13 @@ int mga_dma_iload( struct inode *inode, struct file *filp,
if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) )
return -EFAULT;
if ( mga_do_wait_for_idle( dev_priv ) < 0 )
#if 0
if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
if ( MGA_DMA_DEBUG )
DRM_INFO( __FUNCTION__": -EBUSY\n" );
return -EBUSY;
}
#endif
buf = dma->buflist[iload.idx];
buf_priv = buf->dev_private;