summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/mga_dma.c40
-rw-r--r--linux/mga_drm.h2
-rw-r--r--linux/mga_drv.h10
-rw-r--r--linux/mga_state.c21
-rw-r--r--linux/radeon_state.c13
5 files changed, 46 insertions, 40 deletions
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index 952617c6..c76e54eb 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -178,7 +178,7 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
primary->last_flush = primary->tail;
- head = *primary->head;
+ head = MGA_READ( MGA_PRIMADDRESS );
if ( head <= tail ) {
primary->space = primary->size - primary->tail;
@@ -218,7 +218,7 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
primary->last_flush = 0;
primary->last_wrap++;
- head = *primary->head;
+ head = MGA_READ( MGA_PRIMADDRESS );
if ( head == dev_priv->primary->offset ) {
primary->space = primary->size;
@@ -240,7 +240,6 @@ void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
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__ );
@@ -248,8 +247,6 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
sarea_priv->last_wrap++;
DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap );
- *primary->head = head;
-
mga_flush_write_combine();
MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
@@ -272,7 +269,7 @@ static void mga_freelist_print( drm_device_t *dev )
DRM_INFO( "\n" );
DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
dev_priv->sarea_priv->last_dispatch,
- (unsigned int)(*dev_priv->prim.head -
+ (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) -
dev_priv->primary->offset) );
DRM_INFO( "current freelist:\n" );
@@ -375,7 +372,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev )
u32 head, wrap;
DRM_DEBUG( "%s:\n", __FUNCTION__ );
- head = *dev_priv->prim.head;
+ head = MGA_READ( MGA_PRIMADDRESS );
wrap = dev_priv->sarea_priv->last_wrap;
DRM_DEBUG( " tail=0x%06lx %d\n",
@@ -403,7 +400,7 @@ 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, *next, *prev;
+ drm_mga_freelist_t *head, *entry, *prev;
DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n",
__FUNCTION__,
@@ -411,22 +408,23 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
dev_priv->primary->offset,
buf_priv->list_entry->age.wrap );
- /* Put buffer on the head + 1, as the head is a sentinal.
- */
-
- next = buf_priv->list_entry;
+ entry = buf_priv->list_entry;
head = dev_priv->head;
- prev = head->next;
if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
- SET_AGE( &next->age, MGA_BUFFER_FREE, 0 );
+ SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
+ prev = dev_priv->tail;
+ prev->next = entry;
+ entry->prev = prev;
+ entry->next = NULL;
+ } else {
+ prev = head->next;
+ head->next = entry;
+ prev->prev = entry;
+ entry->prev = head;
+ entry->next = prev;
}
- head->next = next;
- prev->prev = next;
- next->prev = head;
- next->next = prev;
-
return 0;
}
@@ -520,7 +518,6 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
+ dev_priv->primary->size);
dev_priv->prim.size = dev_priv->primary->size;
- dev_priv->prim.head = &dev_priv->prim.status[0];
dev_priv->prim.tail = 0;
dev_priv->prim.space = dev_priv->prim.size;
@@ -616,10 +613,11 @@ int mga_dma_flush( struct inode *inode, struct file *filp,
WRAP_TEST_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 ) {
return mga_do_wait_for_idle( dev_priv );
} else {
diff --git a/linux/mga_drm.h b/linux/mga_drm.h
index c2fe4a18..5cf86318 100644
--- a/linux/mga_drm.h
+++ b/linux/mga_drm.h
@@ -97,7 +97,7 @@
/* 32 buffers of 64k each, total 2 meg.
*/
#define MGA_BUFFER_SIZE (1 << 16)
-#define MGA_NUM_BUFFERS 32
+#define MGA_NUM_BUFFERS 128
/* Keep these small for testing.
*/
diff --git a/linux/mga_drv.h b/linux/mga_drv.h
index f56186e1..bd33d9d1 100644
--- a/linux/mga_drv.h
+++ b/linux/mga_drv.h
@@ -36,7 +36,6 @@ typedef struct drm_mga_primary_buffer {
u8 *end;
int size;
- volatile u32 *head;
u32 tail;
int space;
@@ -246,6 +245,13 @@ do { \
#define FLUSH_DMA() \
do { \
+ if ( 0 ) { \
+ DRM_INFO( __FUNCTION__ ":\n" ); \
+ DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
+ dev_priv->prim.tail, \
+ 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 { \
@@ -278,7 +284,7 @@ do { \
} while (0)
-/* Buffer ageing via primary DMA stream head pointer.
+/* Buffer aging via primary DMA stream head pointer.
*/
#define SET_AGE( age, h, w ) \
diff --git a/linux/mga_state.c b/linux/mga_state.c
index dc2c8c30..1e1c2827 100644
--- a/linux/mga_state.c
+++ b/linux/mga_state.c
@@ -591,20 +591,9 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
int i;
DMA_LOCALS;
DRM_DEBUG( __FUNCTION__ ":\n" );
- DRM_DEBUG( " head = 0x%06x\n", *dev_priv->prim.head );
+ DRM_DEBUG( " head = 0x%06x\n", MGA_READ( MGA_PRIMADDRESS ) );
- sarea_priv->last_frame.head = dev_priv->prim.tail;
- sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
-
- DRM_DEBUG( " tail = 0x%06x\n", dev_priv->prim.tail );
- DRM_DEBUG( " wrap = 0x%06x\n", dev_priv->prim.last_wrap );
-
- BEGIN_DMA( 4 + nbox );
-
- DMA_BLOCK( MGA_DMAPAD, 0x00000000,
- MGA_DMAPAD, 0x00000000,
- MGA_DWGSYNC, 0x00007100,
- MGA_DWGSYNC, 0x00007000 );
+ BEGIN_DMA( 3 + nbox );
DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset,
MGA_MACCESS, dev_priv->maccess,
@@ -635,6 +624,12 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
ADVANCE_DMA();
+ DRM_DEBUG( " tail = 0x%06x\n", dev_priv->prim.tail );
+ DRM_DEBUG( " wrap = 0x%06x\n", dev_priv->prim.last_wrap );
+
+ sarea_priv->last_frame.head = dev_priv->prim.tail;
+ sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
+
FLUSH_DMA();
DRM_DEBUG( "%s... done.\n", __FUNCTION__ );
diff --git a/linux/radeon_state.c b/linux/radeon_state.c
index 816e63bd..9360c43b 100644
--- a/linux/radeon_state.c
+++ b/linux/radeon_state.c
@@ -1054,8 +1054,10 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
image->height -= height;
image->data = (char *)image->data + size;
- if ( copy_to_user( tex->image, image, sizeof(*image) ) )
+ if ( copy_to_user( tex->image, image, sizeof(*image) ) ) {
+ DRM_ERROR( "EFAULT on tex->image\n" );
return -EFAULT;
+ }
} else if ( size < 4 ) {
size = 4;
}
@@ -1089,16 +1091,21 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
/* Texture image width is larger than the minimum, so we
* can upload it directly.
*/
- if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) )
+ if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) {
+ DRM_ERROR( "EFAULT on data, %d dwords\n", dwords );
return -EFAULT;
+ }
} else {
/* Texture image width is less than the minimum, so we
* need to pad out each image scanline to the minimum
* width.
*/
for ( i = 0 ; i < tex->height ; i++ ) {
- if ( copy_from_user( buffer, data, tex_width ) )
+ if ( copy_from_user( buffer, data, tex_width ) ) {
+ DRM_ERROR( "EFAULT on pad, %d bytes\n",
+ tex_width );
return -EFAULT;
+ }
buffer += 8;
data += tex_width;
}