Michel,
How do these changes for r128 COMMIT_RING look? With these I can run concurrent xine and glx programs in pci and agp mode with XV dma disabled. With XV dma enabled, in both pci and agp mode, I can run xine for some time without any hangs. But startup a glx program and X will hang until I kill the glx program, and then X and xine will recover. I guess sync is the next issue, I have a follow-on question on that below. The patch also includes a change to RING_SPACE_TEST..., based on the radeon version, adding a register read fallback for determining ring space. The current drm r128 does not have any WAIT_UNTIL_*_IDLE macros. I assume I'm going to need at least a general idle wait to address sync issues. The only WAIT_UNTIL mask bit defined in r128_drv.h is for page flip, are there any other bits available for wait functions? Henry
diff -ur kernel.orig/r128_drv.h kernel/r128_drv.h --- kernel.orig/r128_drv.h Fri Jul 5 01:31:11 2002 +++ kernel/r128_drv.h Wed Jul 17 22:02:59 2002 @@ -414,10 +414,23 @@ r128_update_ring_snapshot( ring ); \ if ( ring->space >= ring->high_mark ) \ goto __ring_space_done; \ - DRM_UDELAY(1); \ + DRM_UDELAY(1); \ } \ + DRM_ERROR( "ring space check from memory failed, reading +register...\n" ); \ + /* \ + * If ring space check fails from RAM, try reading the \ + * register directly \ + */ \ + ring->space = ( R128_READ( R128_PM4_BUFFER_DL_RPTR ) \ + - ring->tail ) * sizeof(u32); \ + \ + if ( ring->space <= 0 ) \ + ring->space += ring->size; \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + \ DRM_ERROR( "ring space check failed!\n" ); \ - return DRM_ERR(EBUSY); \ + return DRM_ERR(EBUSY); \ } \ __ring_space_done: \ ; \ @@ -487,11 +500,16 @@ dev_priv->ring.start, \ write * sizeof(u32) ); \ } \ - r128_flush_write_combine(); \ dev_priv->ring.tail = write; \ - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \ } while (0) + +#define COMMIT_RING() do { \ + r128_flush_write_combine(); \ + R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \ +} while (0) + + #define OUT_RING( x ) do { \ if ( R128_VERBOSE ) { \ DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ diff -ur kernel.orig/r128_state.c kernel/r128_state.c --- kernel.orig/r128_state.c Fri Jul 5 01:31:11 2002 +++ kernel/r128_state.c Wed Jul 17 18:02:19 2002 @@ -1256,6 +1256,7 @@ */ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + COMMIT_RING(); return 0; } @@ -1281,6 +1282,7 @@ r128_cce_dispatch_flip( dev ); } + COMMIT_RING(); return 0; } @@ -1340,6 +1342,7 @@ r128_cce_dispatch_vertex( dev, buf ); + COMMIT_RING(); return 0; } @@ -1411,6 +1414,7 @@ r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); + COMMIT_RING(); return 0; } @@ -1420,6 +1424,7 @@ drm_device_dma_t *dma = dev->dma; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_blit_t blit; + int ret; LOCK_TEST_WITH_RETURN( dev ); @@ -1437,7 +1442,9 @@ RING_SPACE_TEST_WITH_RETURN( dev_priv ); VB_AGE_TEST_WITH_RETURN( dev_priv ); - return r128_cce_dispatch_blit( dev, &blit ); + ret = r128_cce_dispatch_blit( dev, &blit ); + COMMIT_RING(); + return ret; } int r128_cce_depth( DRM_IOCTL_ARGS ) @@ -1445,6 +1452,7 @@ DRM_DEVICE; drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_depth_t depth; + int ret; LOCK_TEST_WITH_RETURN( dev ); @@ -1455,16 +1463,19 @@ switch ( depth.func ) { case R128_WRITE_SPAN: - return r128_cce_dispatch_write_span( dev, &depth ); + ret = r128_cce_dispatch_write_span( dev, &depth ); case R128_WRITE_PIXELS: - return r128_cce_dispatch_write_pixels( dev, &depth ); + ret = r128_cce_dispatch_write_pixels( dev, &depth ); case R128_READ_SPAN: - return r128_cce_dispatch_read_span( dev, &depth ); + ret = r128_cce_dispatch_read_span( dev, &depth ); case R128_READ_PIXELS: - return r128_cce_dispatch_read_pixels( dev, &depth ); + ret = r128_cce_dispatch_read_pixels( dev, &depth ); + default: + ret = DRM_ERR(EINVAL); } - return DRM_ERR(EINVAL); + COMMIT_RING(); + return ret; } int r128_cce_stipple( DRM_IOCTL_ARGS ) @@ -1487,6 +1498,7 @@ r128_cce_dispatch_stipple( dev, mask ); + COMMIT_RING(); return 0; } @@ -1562,5 +1574,6 @@ */ r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + COMMIT_RING(); return 0; }