diff options
-rw-r--r-- | linux/mga_dma.c | 40 | ||||
-rw-r--r-- | linux/mga_drm.h | 2 | ||||
-rw-r--r-- | linux/mga_drv.h | 10 | ||||
-rw-r--r-- | linux/mga_state.c | 21 | ||||
-rw-r--r-- | linux/radeon_state.c | 13 |
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; } |