patch-2.4.8 linux/drivers/char/drm/r128_state.c

Next file: linux/drivers/char/drm/radeon.h
Previous file: linux/drivers/char/drm/r128_drv.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.7/linux/drivers/char/drm/r128_state.c linux/drivers/char/drm/r128_state.c
@@ -25,13 +25,14 @@
  *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
- *
  */
 
 #define __NO_VERSION__
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
 #include "drm.h"
+#include <linux/delay.h>
 
 
 /* ================================================================
@@ -181,14 +182,14 @@
 	RING_LOCALS;
 	DRM_DEBUG( "    %s\n", __FUNCTION__ );
 
-	BEGIN_RING( 7 + R128_TEX_MAXLEVELS );
+	BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
 
 	OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
-			       2 + R128_TEX_MAXLEVELS ) );
+			       2 + R128_MAX_TEXTURE_LEVELS ) );
 	OUT_RING( tex->tex_cntl );
 	OUT_RING( tex->tex_combine_cntl );
 	OUT_RING( ctx->tex_size_pitch_c );
-	for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
+	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
 		OUT_RING( tex->tex_offset[i] );
 	}
 
@@ -207,13 +208,13 @@
 	RING_LOCALS;
 	DRM_DEBUG( "    %s\n", __FUNCTION__ );
 
-	BEGIN_RING( 5 + R128_TEX_MAXLEVELS );
+	BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
 
 	OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
-			       1 + R128_TEX_MAXLEVELS ) );
+			       1 + R128_MAX_TEXTURE_LEVELS ) );
 	OUT_RING( tex->tex_cntl );
 	OUT_RING( tex->tex_combine_cntl );
-	for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
+	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
 		OUT_RING( tex->tex_offset[i] );
 	}
 
@@ -310,13 +311,13 @@
 	BEGIN_RING( 6 );
 
 	OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-	OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-		  | R128_GMC_BRUSH_SOLID_COLOR
-		  | fb_bpp
-		  | R128_GMC_SRC_DATATYPE_COLOR
-		  | R128_ROP3_P
-		  | R128_GMC_CLR_CMP_CNTL_DIS
-		  | R128_GMC_AUX_CLIP_DIS );
+	OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+		  R128_GMC_BRUSH_SOLID_COLOR |
+		  fb_bpp |
+		  R128_GMC_SRC_DATATYPE_COLOR |
+		  R128_ROP3_P |
+		  R128_GMC_CLR_CMP_CNTL_DIS |
+		  R128_GMC_AUX_CLIP_DIS );
 
 	OUT_RING( (pitch << 21) | (offset >> 5) );
 	OUT_RING( color );
@@ -360,42 +361,23 @@
 }
 
 static void r128_cce_dispatch_clear( drm_device_t *dev,
-				     unsigned int flags,
-				     int cx, int cy, int cw, int ch,
-				     unsigned int clear_color,
-				     unsigned int clear_depth )
+				     drm_r128_clear_t *clear )
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	int nbox = sarea_priv->nbox;
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
-	u32 fb_bpp, depth_bpp;
+	unsigned int flags = clear->flags;
 	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
+	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
+		unsigned int tmp = flags;
 
-	switch ( dev_priv->fb_bpp ) {
-	case 16:
-		fb_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 32:
-		fb_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return;
-	}
-	switch ( dev_priv->depth_bpp ) {
-	case 16:
-		depth_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 24:
-	case 32:
-		depth_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return;
+		flags &= ~(R128_FRONT | R128_BACK);
+		if ( tmp & R128_FRONT ) flags |= R128_BACK;
+		if ( tmp & R128_BACK )  flags |= R128_FRONT;
 	}
 
 	for ( i = 0 ; i < nbox ; i++ ) {
@@ -412,7 +394,7 @@
 			BEGIN_RING( 2 );
 
 			OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
-			OUT_RING( sarea_priv->context_state.plane_3d_mask_c );
+			OUT_RING( clear->color_mask );
 
 			ADVANCE_RING();
 		}
@@ -421,16 +403,16 @@
 			BEGIN_RING( 6 );
 
 			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-				  | R128_GMC_BRUSH_SOLID_COLOR
-				  | fb_bpp
-				  | R128_GMC_SRC_DATATYPE_COLOR
-				  | R128_ROP3_P
-				  | R128_GMC_CLR_CMP_CNTL_DIS
-				  | R128_GMC_AUX_CLIP_DIS );
+			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+				  R128_GMC_BRUSH_SOLID_COLOR |
+				  (dev_priv->color_fmt << 8) |
+				  R128_GMC_SRC_DATATYPE_COLOR |
+				  R128_ROP3_P |
+				  R128_GMC_CLR_CMP_CNTL_DIS |
+				  R128_GMC_AUX_CLIP_DIS );
 
 			OUT_RING( dev_priv->front_pitch_offset_c );
-			OUT_RING( clear_color );
+			OUT_RING( clear->clear_color );
 
 			OUT_RING( (x << 16) | y );
 			OUT_RING( (w << 16) | h );
@@ -442,16 +424,16 @@
 			BEGIN_RING( 6 );
 
 			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-				  | R128_GMC_BRUSH_SOLID_COLOR
-				  | fb_bpp
-				  | R128_GMC_SRC_DATATYPE_COLOR
-				  | R128_ROP3_P
-				  | R128_GMC_CLR_CMP_CNTL_DIS
-				  | R128_GMC_AUX_CLIP_DIS );
+			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+				  R128_GMC_BRUSH_SOLID_COLOR |
+				  (dev_priv->color_fmt << 8) |
+				  R128_GMC_SRC_DATATYPE_COLOR |
+				  R128_ROP3_P |
+				  R128_GMC_CLR_CMP_CNTL_DIS |
+				  R128_GMC_AUX_CLIP_DIS );
 
 			OUT_RING( dev_priv->back_pitch_offset_c );
-			OUT_RING( clear_color );
+			OUT_RING( clear->clear_color );
 
 			OUT_RING( (x << 16) | y );
 			OUT_RING( (w << 16) | h );
@@ -463,17 +445,17 @@
 			BEGIN_RING( 6 );
 
 			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-				  | R128_GMC_BRUSH_SOLID_COLOR
-				  | depth_bpp
-				  | R128_GMC_SRC_DATATYPE_COLOR
-				  | R128_ROP3_P
-				  | R128_GMC_CLR_CMP_CNTL_DIS
-				  | R128_GMC_AUX_CLIP_DIS
-				  | R128_GMC_WR_MSK_DIS );
+			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+				  R128_GMC_BRUSH_SOLID_COLOR |
+				  (dev_priv->depth_fmt << 8) |
+				  R128_GMC_SRC_DATATYPE_COLOR |
+				  R128_ROP3_P |
+				  R128_GMC_CLR_CMP_CNTL_DIS |
+				  R128_GMC_AUX_CLIP_DIS |
+				  R128_GMC_WR_MSK_DIS );
 
 			OUT_RING( dev_priv->depth_pitch_offset_c );
-			OUT_RING( clear_depth );
+			OUT_RING( clear->clear_depth );
 
 			OUT_RING( (x << 16) | y );
 			OUT_RING( (w << 16) | h );
@@ -489,29 +471,16 @@
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	int nbox = sarea_priv->nbox;
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
-	u32 fb_bpp;
 	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
 #if R128_PERFORMANCE_BOXES
 	/* Do some trivial performance monitoring...
 	 */
 	r128_cce_performance_boxes( dev_priv );
 #endif
 
-	switch ( dev_priv->fb_bpp ) {
-	case 16:
-		fb_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 32:
-	default:
-		fb_bpp = R128_GMC_DST_32BPP;
-		break;
-	}
-
 	for ( i = 0 ; i < nbox ; i++ ) {
 		int x = pbox[i].x1;
 		int y = pbox[i].y1;
@@ -521,16 +490,16 @@
 		BEGIN_RING( 7 );
 
 		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-			  | R128_GMC_DST_PITCH_OFFSET_CNTL
-			  | R128_GMC_BRUSH_NONE
-			  | fb_bpp
-			  | R128_GMC_SRC_DATATYPE_COLOR
-			  | R128_ROP3_S
-			  | R128_DP_SRC_SOURCE_MEMORY
-			  | R128_GMC_CLR_CMP_CNTL_DIS
-			  | R128_GMC_AUX_CLIP_DIS
-			  | R128_GMC_WR_MSK_DIS );
+		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+			  R128_GMC_DST_PITCH_OFFSET_CNTL |
+			  R128_GMC_BRUSH_NONE |
+			  (dev_priv->color_fmt << 8) |
+			  R128_GMC_SRC_DATATYPE_COLOR |
+			  R128_ROP3_S |
+			  R128_DP_SRC_SOURCE_MEMORY |
+			  R128_GMC_CLR_CMP_CNTL_DIS |
+			  R128_GMC_AUX_CLIP_DIS |
+			  R128_GMC_WR_MSK_DIS );
 
 		OUT_RING( dev_priv->back_pitch_offset_c );
 		OUT_RING( dev_priv->front_pitch_offset_c );
@@ -556,6 +525,47 @@
 	ADVANCE_RING();
 }
 
+static void r128_cce_dispatch_flip( drm_device_t *dev )
+{
+	drm_r128_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+	DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
+
+#if R128_PERFORMANCE_BOXES
+	/* Do some trivial performance monitoring...
+	 */
+	r128_cce_performance_boxes( dev_priv );
+#endif
+
+	BEGIN_RING( 4 );
+
+	R128_WAIT_UNTIL_PAGE_FLIPPED();
+	OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
+
+	if ( dev_priv->current_page == 0 ) {
+		OUT_RING( dev_priv->back_offset );
+		dev_priv->current_page = 1;
+	} else {
+		OUT_RING( dev_priv->front_offset );
+		dev_priv->current_page = 0;
+	}
+
+	ADVANCE_RING();
+
+	/* Increment the frame counter.  The client-side 3D driver must
+	 * throttle the framerate by waiting for this value before
+	 * performing the swapbuffer ioctl.
+	 */
+	dev_priv->sarea_priv->last_frame++;
+
+	BEGIN_RING( 2 );
+
+	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
+	OUT_RING( dev_priv->sarea_priv->last_frame );
+
+	ADVANCE_RING();
+}
+
 static void r128_cce_dispatch_vertex( drm_device_t *dev,
 				      drm_buf_t *buf )
 {
@@ -563,7 +573,7 @@
 	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	int format = sarea_priv->vc_format;
-	int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
+	int offset = buf->bus_address;
 	int size = buf->used;
 	int prim = buf_priv->prim;
 	int i = 0;
@@ -571,8 +581,6 @@
 	DRM_DEBUG( "%s: buf=%d nbox=%d\n",
 		   __FUNCTION__, buf->idx, sarea_priv->nbox );
 
-	r128_update_ring_snapshot( dev_priv );
-
 	if ( 0 )
 		r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
 
@@ -626,22 +634,10 @@
 
 	dev_priv->sarea_priv->last_dispatch++;
 
-#if 0
-	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-		ret = r128_do_cce_idle( dev_priv );
-		if ( ret < 0 ) return ret;
-		dev_priv->submit_age = 0;
-		r128_freelist_reset( dev );
-	}
-#endif
-
 	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
 	sarea_priv->nbox = 0;
 }
 
-
-
-
 static void r128_cce_dispatch_indirect( drm_device_t *dev,
 					drm_buf_t *buf,
 					int start, int end )
@@ -652,11 +648,8 @@
 	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
 		   buf->idx, start, end );
 
-	r128_update_ring_snapshot( dev_priv );
-
 	if ( start != end ) {
-		int offset = (dev_priv->buffers->offset - dev->agp->base
-			      + buf->offset + start);
+		int offset = buf->bus_address + start;
 		int dwords = (end - start + 3) / sizeof(u32);
 
 		/* Indirect buffer data must be an even number of
@@ -667,7 +660,7 @@
 			u32 *data = (u32 *)
 				((char *)dev_priv->buffers->handle
 				 + buf->offset + start);
-			data[dwords++] = R128_CCE_PACKET2;
+			data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
 		}
 
 		buf_priv->dispatched = 1;
@@ -700,15 +693,6 @@
 	}
 
 	dev_priv->sarea_priv->last_dispatch++;
-
-#if 0
-	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-		ret = r128_do_cce_idle( dev_priv );
-		if ( ret < 0 ) return ret;
-		dev_priv->submit_age = 0;
-		r128_freelist_reset( dev );
-	}
-#endif
 }
 
 static void r128_cce_dispatch_indices( drm_device_t *dev,
@@ -720,7 +704,7 @@
 	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	int format = sarea_priv->vc_format;
-	int offset = dev_priv->buffers->offset - dev->agp->base;
+	int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
 	int prim = buf_priv->prim;
 	u32 *data;
 	int dwords;
@@ -728,8 +712,6 @@
 	RING_LOCALS;
 	DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
 
-	r128_update_ring_snapshot( dev_priv );
-
 	if ( 0 )
 		r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
 
@@ -745,16 +727,21 @@
 		data = (u32 *)((char *)dev_priv->buffers->handle
 			       + buf->offset + start);
 
-		data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+		data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
+						    dwords-2 ) );
 
-		data[1] = offset;
-		data[2] = R128_MAX_VB_VERTS;
-		data[3] = format;
-		data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
-			   (count << 16));
+		data[1] = cpu_to_le32( offset );
+		data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
+		data[3] = cpu_to_le32( format );
+		data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
+					(count << 16)) );
 
 		if ( count & 0x1 ) {
+#ifdef __LITTLE_ENDIAN
 			data[dwords-1] &= 0x0000ffff;
+#else
+			data[dwords-1] &= 0xffff0000;
+#endif
 		}
 
 		do {
@@ -789,15 +776,6 @@
 
 	dev_priv->sarea_priv->last_dispatch++;
 
-#if 0
-	if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-		ret = r128_do_cce_idle( dev_priv );
-		if ( ret < 0 ) return ret;
-		dev_priv->submit_age = 0;
-		r128_freelist_reset( dev );
-	}
-#endif
-
 	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
 	sarea_priv->nbox = 0;
 }
@@ -814,20 +792,22 @@
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
 	/* The compiler won't optimize away a division by a variable,
 	 * even if the only legal values are powers of two.  Thus, we'll
 	 * use a shift instead.
 	 */
 	switch ( blit->format ) {
+	case R128_DATATYPE_ARGB8888:
+		dword_shift = 0;
+		break;
 	case R128_DATATYPE_ARGB1555:
 	case R128_DATATYPE_RGB565:
 	case R128_DATATYPE_ARGB4444:
 		dword_shift = 1;
 		break;
-	case R128_DATATYPE_ARGB8888:
-		dword_shift = 0;
+	case R128_DATATYPE_CI8:
+	case R128_DATATYPE_RGB8:
+		dword_shift = 2;
 		break;
 	default:
 		DRM_ERROR( "invalid blit format %d\n", blit->format );
@@ -867,23 +847,23 @@
 
 	data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
 
-	data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
-	data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL
-		    | R128_GMC_BRUSH_NONE
-		    | (blit->format << 8)
-		    | R128_GMC_SRC_DATATYPE_COLOR
-		    | R128_ROP3_S
-		    | R128_DP_SRC_SOURCE_HOST_DATA
-		    | R128_GMC_CLR_CMP_CNTL_DIS
-		    | R128_GMC_AUX_CLIP_DIS
-		    | R128_GMC_WR_MSK_DIS );
-
-	data[2] = (blit->pitch << 21) | (blit->offset >> 5);
-	data[3] = 0xffffffff;
-	data[4] = 0xffffffff;
-	data[5] = (blit->y << 16) | blit->x;
-	data[6] = (blit->height << 16) | blit->width;
-	data[7] = dwords;
+	data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
+	data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
+				R128_GMC_BRUSH_NONE |
+				(blit->format << 8) |
+				R128_GMC_SRC_DATATYPE_COLOR |
+				R128_ROP3_S |
+				R128_DP_SRC_SOURCE_HOST_DATA |
+				R128_GMC_CLR_CMP_CNTL_DIS |
+				R128_GMC_AUX_CLIP_DIS |
+				R128_GMC_WR_MSK_DIS) );
+
+	data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
+	data[3] = cpu_to_le32( 0xffffffff );
+	data[4] = cpu_to_le32( 0xffffffff );
+	data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
+	data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
+	data[7] = cpu_to_le32( dwords );
 
 	buf->used = (dwords + 8) * sizeof(u32);
 
@@ -918,25 +898,10 @@
 	int count, x, y;
 	u32 *buffer;
 	u8 *mask;
-	u32 depth_bpp;
 	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
-	switch ( dev_priv->depth_bpp ) {
-	case 16:
-		depth_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 24:
-	case 32:
-		depth_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	count = depth->n;
 	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
 		return -EFAULT;
@@ -945,7 +910,7 @@
 		return -EFAULT;
 	}
 
-	buffer = kmalloc( depth->n * sizeof(u32), 0 );
+	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
 	if ( buffer == NULL )
 		return -ENOMEM;
 	if ( copy_from_user( buffer, depth->buffer,
@@ -955,7 +920,7 @@
 	}
 
 	if ( depth->mask ) {
-		mask = kmalloc( depth->n * sizeof(u8), 0 );
+		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
 		if ( mask == NULL ) {
 			kfree( buffer );
 			return -ENOMEM;
@@ -971,15 +936,14 @@
 			if ( mask[i] ) {
 				BEGIN_RING( 6 );
 
-				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
-						       4 ) );
-				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-					  | R128_GMC_BRUSH_SOLID_COLOR
-					  | depth_bpp
-					  | R128_GMC_SRC_DATATYPE_COLOR
-					  | R128_ROP3_P
-					  | R128_GMC_CLR_CMP_CNTL_DIS
-					  | R128_GMC_WR_MSK_DIS );
+				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+					  R128_GMC_BRUSH_SOLID_COLOR |
+					  (dev_priv->depth_fmt << 8) |
+					  R128_GMC_SRC_DATATYPE_COLOR |
+					  R128_ROP3_P |
+					  R128_GMC_CLR_CMP_CNTL_DIS |
+					  R128_GMC_WR_MSK_DIS );
 
 				OUT_RING( dev_priv->depth_pitch_offset_c );
 				OUT_RING( buffer[i] );
@@ -997,13 +961,13 @@
 			BEGIN_RING( 6 );
 
 			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-				  | R128_GMC_BRUSH_SOLID_COLOR
-				  | depth_bpp
-				  | R128_GMC_SRC_DATATYPE_COLOR
-				  | R128_ROP3_P
-				  | R128_GMC_CLR_CMP_CNTL_DIS
-				  | R128_GMC_WR_MSK_DIS );
+			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+				  R128_GMC_BRUSH_SOLID_COLOR |
+				  (dev_priv->depth_fmt << 8) |
+				  R128_GMC_SRC_DATATYPE_COLOR |
+				  R128_ROP3_P |
+				  R128_GMC_CLR_CMP_CNTL_DIS |
+				  R128_GMC_WR_MSK_DIS );
 
 			OUT_RING( dev_priv->depth_pitch_offset_c );
 			OUT_RING( buffer[i] );
@@ -1027,32 +991,17 @@
 	int count, *x, *y;
 	u32 *buffer;
 	u8 *mask;
-	u32 depth_bpp;
 	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
-	switch ( dev_priv->depth_bpp ) {
-	case 16:
-		depth_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 24:
-	case 32:
-		depth_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	count = depth->n;
 
-	x = kmalloc( count * sizeof(*x), 0 );
+	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
 	if ( x == NULL ) {
 		return -ENOMEM;
 	}
-	y = kmalloc( count * sizeof(*y), 0 );
+	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
 	if ( y == NULL ) {
 		kfree( x );
 		return -ENOMEM;
@@ -1068,7 +1017,7 @@
 		return -EFAULT;
 	}
 
-	buffer = kmalloc( depth->n * sizeof(u32), 0 );
+	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
 	if ( buffer == NULL ) {
 		kfree( x );
 		kfree( y );
@@ -1083,7 +1032,7 @@
 	}
 
 	if ( depth->mask ) {
-		mask = kmalloc( depth->n * sizeof(u8), 0 );
+		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
 		if ( mask == NULL ) {
 			kfree( x );
 			kfree( y );
@@ -1103,15 +1052,14 @@
 			if ( mask[i] ) {
 				BEGIN_RING( 6 );
 
-				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
-						       4 ) );
-				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-					  | R128_GMC_BRUSH_SOLID_COLOR
-					  | depth_bpp
-					  | R128_GMC_SRC_DATATYPE_COLOR
-					  | R128_ROP3_P
-					  | R128_GMC_CLR_CMP_CNTL_DIS
-					  | R128_GMC_WR_MSK_DIS );
+				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+					  R128_GMC_BRUSH_SOLID_COLOR |
+					  (dev_priv->depth_fmt << 8) |
+					  R128_GMC_SRC_DATATYPE_COLOR |
+					  R128_ROP3_P |
+					  R128_GMC_CLR_CMP_CNTL_DIS |
+					  R128_GMC_WR_MSK_DIS );
 
 				OUT_RING( dev_priv->depth_pitch_offset_c );
 				OUT_RING( buffer[i] );
@@ -1129,13 +1077,13 @@
 			BEGIN_RING( 6 );
 
 			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-				  | R128_GMC_BRUSH_SOLID_COLOR
-				  | depth_bpp
-				  | R128_GMC_SRC_DATATYPE_COLOR
-				  | R128_ROP3_P
-				  | R128_GMC_CLR_CMP_CNTL_DIS
-				  | R128_GMC_WR_MSK_DIS );
+			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+				  R128_GMC_BRUSH_SOLID_COLOR |
+				  (dev_priv->depth_fmt << 8) |
+				  R128_GMC_SRC_DATATYPE_COLOR |
+				  R128_ROP3_P |
+				  R128_GMC_CLR_CMP_CNTL_DIS |
+				  R128_GMC_WR_MSK_DIS );
 
 			OUT_RING( dev_priv->depth_pitch_offset_c );
 			OUT_RING( buffer[i] );
@@ -1159,24 +1107,9 @@
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int count, x, y;
-	u32 depth_bpp;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
-	switch ( dev_priv->depth_bpp ) {
-	case 16:
-		depth_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 24:
-	case 32:
-		depth_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	count = depth->n;
 	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
 		return -EFAULT;
@@ -1188,15 +1121,15 @@
 	BEGIN_RING( 7 );
 
 	OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-	OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-		  | R128_GMC_DST_PITCH_OFFSET_CNTL
-		  | R128_GMC_BRUSH_NONE
-		  | depth_bpp
-		  | R128_GMC_SRC_DATATYPE_COLOR
-		  | R128_ROP3_S
-		  | R128_DP_SRC_SOURCE_MEMORY
-		  | R128_GMC_CLR_CMP_CNTL_DIS
-		  | R128_GMC_WR_MSK_DIS );
+	OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+		  R128_GMC_DST_PITCH_OFFSET_CNTL |
+		  R128_GMC_BRUSH_NONE |
+		  (dev_priv->depth_fmt << 8) |
+		  R128_GMC_SRC_DATATYPE_COLOR |
+		  R128_ROP3_S |
+		  R128_DP_SRC_SOURCE_MEMORY |
+		  R128_GMC_CLR_CMP_CNTL_DIS |
+		  R128_GMC_WR_MSK_DIS );
 
 	OUT_RING( dev_priv->depth_pitch_offset_c );
 	OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1215,35 +1148,20 @@
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int count, *x, *y;
-	u32 depth_bpp;
 	int i;
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
-	switch ( dev_priv->depth_bpp ) {
-	case 16:
-		depth_bpp = R128_GMC_DST_16BPP;
-		break;
-	case 24:
-	case 32:
-		depth_bpp = R128_GMC_DST_32BPP;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	count = depth->n;
 	if ( count > dev_priv->depth_pitch ) {
 		count = dev_priv->depth_pitch;
 	}
 
-	x = kmalloc( count * sizeof(*x), 0 );
+	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
 	if ( x == NULL ) {
 		return -ENOMEM;
 	}
-	y = kmalloc( count * sizeof(*y), 0 );
+	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
 	if ( y == NULL ) {
 		kfree( x );
 		return -ENOMEM;
@@ -1263,15 +1181,15 @@
 		BEGIN_RING( 7 );
 
 		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-			  | R128_GMC_DST_PITCH_OFFSET_CNTL
-			  | R128_GMC_BRUSH_NONE
-			  | depth_bpp
-			  | R128_GMC_SRC_DATATYPE_COLOR
-			  | R128_ROP3_S
-			  | R128_DP_SRC_SOURCE_MEMORY
-			  | R128_GMC_CLR_CMP_CNTL_DIS
-			  | R128_GMC_WR_MSK_DIS );
+		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+			  R128_GMC_DST_PITCH_OFFSET_CNTL |
+			  R128_GMC_BRUSH_NONE |
+			  (dev_priv->depth_fmt << 8) |
+			  R128_GMC_SRC_DATATYPE_COLOR |
+			  R128_ROP3_S |
+			  R128_DP_SRC_SOURCE_MEMORY |
+			  R128_GMC_CLR_CMP_CNTL_DIS |
+			  R128_GMC_WR_MSK_DIS );
 
 		OUT_RING( dev_priv->depth_pitch_offset_c );
 		OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1301,11 +1219,9 @@
 	RING_LOCALS;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	r128_update_ring_snapshot( dev_priv );
-
 	BEGIN_RING( 33 );
 
-	OUT_RING(  CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
+	OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
 	for ( i = 0 ; i < 32 ; i++ ) {
 		OUT_RING( stipple[i] );
 	}
@@ -1328,22 +1244,18 @@
 	drm_r128_clear_t clear;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "r128_cce_clear called without lock held\n" );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
 			     sizeof(clear) ) )
 		return -EFAULT;
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
 	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-	r128_cce_dispatch_clear( dev, clear.flags,
-				 clear.x, clear.y, clear.w, clear.h,
-				 clear.clear_color, clear.clear_depth );
+	r128_cce_dispatch_clear( dev, &clear );
 
 	/* Make sure we restore the 3D state next time.
 	 */
@@ -1361,20 +1273,20 @@
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-	     dev->lock.pid != current->pid ) {
-		DRM_ERROR( "r128_cce_swap called without lock held\n" );
-		return -EINVAL;
-	}
+	LOCK_TEST_WITH_RETURN( dev );
+
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
 	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-	r128_cce_dispatch_swap( dev );
-
-	/* Make sure we restore the 3D state next time.
-	 */
-	dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+	if ( !dev_priv->page_flipping ) {
+		r128_cce_dispatch_swap( dev );
+		dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+						R128_UPLOAD_MASKS);
+	} else {
+		r128_cce_dispatch_flip( dev );
+	}
 
 	return 0;
 }
@@ -1390,13 +1302,10 @@
 	drm_r128_buf_priv_t *buf_priv;
 	drm_r128_vertex_t vertex;
 
-	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;
-	}
-	if ( !dev_priv || dev_priv->is_pci ) {
-		DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+	LOCK_TEST_WITH_RETURN( dev );
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 		return -EINVAL;
 	}
 
@@ -1419,6 +1328,9 @@
 		return -EINVAL;
 	}
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+	VB_AGE_TEST_WITH_RETURN( dev_priv );
+
 	buf = dma->buflist[vertex.idx];
 	buf_priv = buf->dev_private;
 
@@ -1453,13 +1365,10 @@
 	drm_r128_indices_t elts;
 	int count;
 
-	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;
-	}
-	if ( !dev_priv || dev_priv->is_pci ) {
-		DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+	LOCK_TEST_WITH_RETURN( dev );
+
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
 		return -EINVAL;
 	}
 
@@ -1482,6 +1391,9 @@
 		return -EINVAL;
 	}
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+	VB_AGE_TEST_WITH_RETURN( dev_priv );
+
 	buf = dma->buflist[elts.idx];
 	buf_priv = buf->dev_private;
 
@@ -1522,13 +1434,10 @@
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
 	drm_device_dma_t *dma = dev->dma;
+	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_blit_t blit;
 
-	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( &blit, (drm_r128_blit_t *)arg,
 			     sizeof(blit) ) )
@@ -1543,6 +1452,9 @@
 		return -EINVAL;
 	}
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+	VB_AGE_TEST_WITH_RETURN( dev_priv );
+
 	return r128_cce_dispatch_blit( dev, &blit );
 }
 
@@ -1551,18 +1463,17 @@
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
+	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_depth_t depth;
 
-	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( &depth, (drm_r128_depth_t *)arg,
 			     sizeof(depth) ) )
 		return -EFAULT;
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
 	switch ( depth.func ) {
 	case R128_WRITE_SPAN:
 		return r128_cce_dispatch_write_span( dev, &depth );
@@ -1582,14 +1493,11 @@
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
+	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_stipple_t stipple;
 	u32 mask[32];
 
-	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( &stipple, (drm_r128_stipple_t *)arg,
 			     sizeof(stipple) ) )
@@ -1599,7 +1507,22 @@
 			     32 * sizeof(u32) ) )
 		return -EFAULT;
 
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
 	r128_cce_dispatch_stipple( dev, mask );
 
 	return 0;
+}
+
+int r128_cce_indirect( 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;
+
+	LOCK_TEST_WITH_RETURN( dev );
+
+	/* Indirect buffer firing is not supported at this time.
+	 */
+	return -EINVAL;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)