File: /usr/src/linux/drivers/char/drm/r128_state.c

1     /* r128_state.c -- State support for r128 -*- linux-c -*-
2      * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
3      *
4      * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5      * All Rights Reserved.
6      *
7      * Permission is hereby granted, free of charge, to any person obtaining a
8      * copy of this software and associated documentation files (the "Software"),
9      * to deal in the Software without restriction, including without limitation
10      * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11      * and/or sell copies of the Software, and to permit persons to whom the
12      * Software is furnished to do so, subject to the following conditions:
13      *
14      * The above copyright notice and this permission notice (including the next
15      * paragraph) shall be included in all copies or substantial portions of the
16      * Software.
17      *
18      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19      * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20      * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21      * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22      * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23      * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24      * DEALINGS IN THE SOFTWARE.
25      *
26      * Authors:
27      *    Gareth Hughes <gareth@valinux.com>
28      */
29     
30     #define __NO_VERSION__
31     #include "r128.h"
32     #include "drmP.h"
33     #include "r128_drv.h"
34     #include "drm.h"
35     #include <linux/delay.h>
36     
37     
38     /* ================================================================
39      * CCE hardware state programming functions
40      */
41     
42     static void r128_emit_clip_rects( drm_r128_private_t *dev_priv,
43     				  drm_clip_rect_t *boxes, int count )
44     {
45     	u32 aux_sc_cntl = 0x00000000;
46     	RING_LOCALS;
47     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
48     
49     	BEGIN_RING( 17 );
50     
51     	if ( count >= 1 ) {
52     		OUT_RING( CCE_PACKET0( R128_AUX1_SC_LEFT, 3 ) );
53     		OUT_RING( boxes[0].x1 );
54     		OUT_RING( boxes[0].x2 - 1 );
55     		OUT_RING( boxes[0].y1 );
56     		OUT_RING( boxes[0].y2 - 1 );
57     
58     		aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
59     	}
60     	if ( count >= 2 ) {
61     		OUT_RING( CCE_PACKET0( R128_AUX2_SC_LEFT, 3 ) );
62     		OUT_RING( boxes[1].x1 );
63     		OUT_RING( boxes[1].x2 - 1 );
64     		OUT_RING( boxes[1].y1 );
65     		OUT_RING( boxes[1].y2 - 1 );
66     
67     		aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
68     	}
69     	if ( count >= 3 ) {
70     		OUT_RING( CCE_PACKET0( R128_AUX3_SC_LEFT, 3 ) );
71     		OUT_RING( boxes[2].x1 );
72     		OUT_RING( boxes[2].x2 - 1 );
73     		OUT_RING( boxes[2].y1 );
74     		OUT_RING( boxes[2].y2 - 1 );
75     
76     		aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
77     	}
78     
79     	OUT_RING( CCE_PACKET0( R128_AUX_SC_CNTL, 0 ) );
80     	OUT_RING( aux_sc_cntl );
81     
82     	ADVANCE_RING();
83     }
84     
85     static inline void r128_emit_core( drm_r128_private_t *dev_priv )
86     {
87     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
88     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
89     	RING_LOCALS;
90     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
91     
92     	BEGIN_RING( 2 );
93     
94     	OUT_RING( CCE_PACKET0( R128_SCALE_3D_CNTL, 0 ) );
95     	OUT_RING( ctx->scale_3d_cntl );
96     
97     	ADVANCE_RING();
98     }
99     
100     static inline void r128_emit_context( drm_r128_private_t *dev_priv )
101     {
102     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
103     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
104     	RING_LOCALS;
105     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
106     
107     	BEGIN_RING( 13 );
108     
109     	OUT_RING( CCE_PACKET0( R128_DST_PITCH_OFFSET_C, 11 ) );
110     	OUT_RING( ctx->dst_pitch_offset_c );
111     	OUT_RING( ctx->dp_gui_master_cntl_c );
112     	OUT_RING( ctx->sc_top_left_c );
113     	OUT_RING( ctx->sc_bottom_right_c );
114     	OUT_RING( ctx->z_offset_c );
115     	OUT_RING( ctx->z_pitch_c );
116     	OUT_RING( ctx->z_sten_cntl_c );
117     	OUT_RING( ctx->tex_cntl_c );
118     	OUT_RING( ctx->misc_3d_state_cntl_reg );
119     	OUT_RING( ctx->texture_clr_cmp_clr_c );
120     	OUT_RING( ctx->texture_clr_cmp_msk_c );
121     	OUT_RING( ctx->fog_color_c );
122     
123     	ADVANCE_RING();
124     }
125     
126     static inline void r128_emit_setup( drm_r128_private_t *dev_priv )
127     {
128     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
129     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
130     	RING_LOCALS;
131     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
132     
133     	BEGIN_RING( 3 );
134     
135     	OUT_RING( CCE_PACKET1( R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP ) );
136     	OUT_RING( ctx->setup_cntl );
137     	OUT_RING( ctx->pm4_vc_fpu_setup );
138     
139     	ADVANCE_RING();
140     }
141     
142     static inline void r128_emit_masks( drm_r128_private_t *dev_priv )
143     {
144     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
145     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
146     	RING_LOCALS;
147     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
148     
149     	BEGIN_RING( 5 );
150     
151     	OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
152     	OUT_RING( ctx->dp_write_mask );
153     
154     	OUT_RING( CCE_PACKET0( R128_STEN_REF_MASK_C, 1 ) );
155     	OUT_RING( ctx->sten_ref_mask_c );
156     	OUT_RING( ctx->plane_3d_mask_c );
157     
158     	ADVANCE_RING();
159     }
160     
161     static inline void r128_emit_window( drm_r128_private_t *dev_priv )
162     {
163     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
164     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
165     	RING_LOCALS;
166     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
167     
168     	BEGIN_RING( 2 );
169     
170     	OUT_RING( CCE_PACKET0( R128_WINDOW_XY_OFFSET, 0 ) );
171     	OUT_RING( ctx->window_xy_offset );
172     
173     	ADVANCE_RING();
174     }
175     
176     static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
177     {
178     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
179     	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
180     	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
181     	int i;
182     	RING_LOCALS;
183     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
184     
185     	BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
186     
187     	OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
188     			       2 + R128_MAX_TEXTURE_LEVELS ) );
189     	OUT_RING( tex->tex_cntl );
190     	OUT_RING( tex->tex_combine_cntl );
191     	OUT_RING( ctx->tex_size_pitch_c );
192     	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
193     		OUT_RING( tex->tex_offset[i] );
194     	}
195     
196     	OUT_RING( CCE_PACKET0( R128_CONSTANT_COLOR_C, 1 ) );
197     	OUT_RING( ctx->constant_color_c );
198     	OUT_RING( tex->tex_border_color );
199     
200     	ADVANCE_RING();
201     }
202     
203     static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
204     {
205     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
206     	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
207     	int i;
208     	RING_LOCALS;
209     	DRM_DEBUG( "    %s\n", __FUNCTION__ );
210     
211     	BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
212     
213     	OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
214     			       1 + R128_MAX_TEXTURE_LEVELS ) );
215     	OUT_RING( tex->tex_cntl );
216     	OUT_RING( tex->tex_combine_cntl );
217     	for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
218     		OUT_RING( tex->tex_offset[i] );
219     	}
220     
221     	OUT_RING( CCE_PACKET0( R128_SEC_TEXTURE_BORDER_COLOR_C, 0 ) );
222     	OUT_RING( tex->tex_border_color );
223     
224     	ADVANCE_RING();
225     }
226     
227     static inline void r128_emit_state( drm_r128_private_t *dev_priv )
228     {
229     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
230     	unsigned int dirty = sarea_priv->dirty;
231     
232     	DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
233     
234     	if ( dirty & R128_UPLOAD_CORE ) {
235     		r128_emit_core( dev_priv );
236     		sarea_priv->dirty &= ~R128_UPLOAD_CORE;
237     	}
238     
239     	if ( dirty & R128_UPLOAD_CONTEXT ) {
240     		r128_emit_context( dev_priv );
241     		sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
242     	}
243     
244     	if ( dirty & R128_UPLOAD_SETUP ) {
245     		r128_emit_setup( dev_priv );
246     		sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
247     	}
248     
249     	if ( dirty & R128_UPLOAD_MASKS ) {
250     		r128_emit_masks( dev_priv );
251     		sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
252     	}
253     
254     	if ( dirty & R128_UPLOAD_WINDOW ) {
255     		r128_emit_window( dev_priv );
256     		sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
257     	}
258     
259     	if ( dirty & R128_UPLOAD_TEX0 ) {
260     		r128_emit_tex0( dev_priv );
261     		sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
262     	}
263     
264     	if ( dirty & R128_UPLOAD_TEX1 ) {
265     		r128_emit_tex1( dev_priv );
266     		sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
267     	}
268     
269     	/* Turn off the texture cache flushing */
270     	sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
271     
272     	sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
273     }
274     
275     
276     #if R128_PERFORMANCE_BOXES
277     /* ================================================================
278      * Performance monitoring functions
279      */
280     
281     static void r128_clear_box( drm_r128_private_t *dev_priv,
282     			    int x, int y, int w, int h,
283     			    int r, int g, int b )
284     {
285     	u32 pitch, offset;
286     	u32 fb_bpp, color;
287     	RING_LOCALS;
288     
289     	switch ( dev_priv->fb_bpp ) {
290     	case 16:
291     		fb_bpp = R128_GMC_DST_16BPP;
292     		color = (((r & 0xf8) << 8) |
293     			 ((g & 0xfc) << 3) |
294     			 ((b & 0xf8) >> 3));
295     		break;
296     	case 24:
297     		fb_bpp = R128_GMC_DST_24BPP;
298     		color = ((r << 16) | (g << 8) | b);
299     		break;
300     	case 32:
301     		fb_bpp = R128_GMC_DST_32BPP;
302     		color = (((0xff) << 24) | (r << 16) | (g <<  8) | b);
303     		break;
304     	default:
305     		return;
306     	}
307     
308     	offset = dev_priv->back_offset;
309     	pitch = dev_priv->back_pitch >> 3;
310     
311     	BEGIN_RING( 6 );
312     
313     	OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
314     	OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
315     		  R128_GMC_BRUSH_SOLID_COLOR |
316     		  fb_bpp |
317     		  R128_GMC_SRC_DATATYPE_COLOR |
318     		  R128_ROP3_P |
319     		  R128_GMC_CLR_CMP_CNTL_DIS |
320     		  R128_GMC_AUX_CLIP_DIS );
321     
322     	OUT_RING( (pitch << 21) | (offset >> 5) );
323     	OUT_RING( color );
324     
325     	OUT_RING( (x << 16) | y );
326     	OUT_RING( (w << 16) | h );
327     
328     	ADVANCE_RING();
329     }
330     
331     static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
332     {
333     	if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
334     		r128_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
335     	} else {
336     		atomic_set( &dev_priv->idle_count, 0 );
337     	}
338     }
339     
340     #endif
341     
342     
343     /* ================================================================
344      * CCE command dispatch functions
345      */
346     
347     static void r128_print_dirty( const char *msg, unsigned int flags )
348     {
349     	DRM_INFO( "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
350     		  msg,
351     		  flags,
352     		  (flags & R128_UPLOAD_CORE)        ? "core, " : "",
353     		  (flags & R128_UPLOAD_CONTEXT)     ? "context, " : "",
354     		  (flags & R128_UPLOAD_SETUP)       ? "setup, " : "",
355     		  (flags & R128_UPLOAD_TEX0)        ? "tex0, " : "",
356     		  (flags & R128_UPLOAD_TEX1)        ? "tex1, " : "",
357     		  (flags & R128_UPLOAD_MASKS)       ? "masks, " : "",
358     		  (flags & R128_UPLOAD_WINDOW)      ? "window, " : "",
359     		  (flags & R128_UPLOAD_CLIPRECTS)   ? "cliprects, " : "",
360     		  (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
361     }
362     
363     static void r128_cce_dispatch_clear( drm_device_t *dev,
364     				     drm_r128_clear_t *clear )
365     {
366     	drm_r128_private_t *dev_priv = dev->dev_private;
367     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
368     	int nbox = sarea_priv->nbox;
369     	drm_clip_rect_t *pbox = sarea_priv->boxes;
370     	unsigned int flags = clear->flags;
371     	int i;
372     	RING_LOCALS;
373     	DRM_DEBUG( "%s\n", __FUNCTION__ );
374     
375     	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
376     		unsigned int tmp = flags;
377     
378     		flags &= ~(R128_FRONT | R128_BACK);
379     		if ( tmp & R128_FRONT ) flags |= R128_BACK;
380     		if ( tmp & R128_BACK )  flags |= R128_FRONT;
381     	}
382     
383     	for ( i = 0 ; i < nbox ; i++ ) {
384     		int x = pbox[i].x1;
385     		int y = pbox[i].y1;
386     		int w = pbox[i].x2 - x;
387     		int h = pbox[i].y2 - y;
388     
389     		DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
390     			   pbox[i].x1, pbox[i].y1, pbox[i].x2,
391     			   pbox[i].y2, flags );
392     
393     		if ( flags & (R128_FRONT | R128_BACK) ) {
394     			BEGIN_RING( 2 );
395     
396     			OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
397     			OUT_RING( clear->color_mask );
398     
399     			ADVANCE_RING();
400     		}
401     
402     		if ( flags & R128_FRONT ) {
403     			BEGIN_RING( 6 );
404     
405     			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
406     			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
407     				  R128_GMC_BRUSH_SOLID_COLOR |
408     				  (dev_priv->color_fmt << 8) |
409     				  R128_GMC_SRC_DATATYPE_COLOR |
410     				  R128_ROP3_P |
411     				  R128_GMC_CLR_CMP_CNTL_DIS |
412     				  R128_GMC_AUX_CLIP_DIS );
413     
414     			OUT_RING( dev_priv->front_pitch_offset_c );
415     			OUT_RING( clear->clear_color );
416     
417     			OUT_RING( (x << 16) | y );
418     			OUT_RING( (w << 16) | h );
419     
420     			ADVANCE_RING();
421     		}
422     
423     		if ( flags & R128_BACK ) {
424     			BEGIN_RING( 6 );
425     
426     			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
427     			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
428     				  R128_GMC_BRUSH_SOLID_COLOR |
429     				  (dev_priv->color_fmt << 8) |
430     				  R128_GMC_SRC_DATATYPE_COLOR |
431     				  R128_ROP3_P |
432     				  R128_GMC_CLR_CMP_CNTL_DIS |
433     				  R128_GMC_AUX_CLIP_DIS );
434     
435     			OUT_RING( dev_priv->back_pitch_offset_c );
436     			OUT_RING( clear->clear_color );
437     
438     			OUT_RING( (x << 16) | y );
439     			OUT_RING( (w << 16) | h );
440     
441     			ADVANCE_RING();
442     		}
443     
444     		if ( flags & R128_DEPTH ) {
445     			BEGIN_RING( 6 );
446     
447     			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
448     			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
449     				  R128_GMC_BRUSH_SOLID_COLOR |
450     				  (dev_priv->depth_fmt << 8) |
451     				  R128_GMC_SRC_DATATYPE_COLOR |
452     				  R128_ROP3_P |
453     				  R128_GMC_CLR_CMP_CNTL_DIS |
454     				  R128_GMC_AUX_CLIP_DIS |
455     				  R128_GMC_WR_MSK_DIS );
456     
457     			OUT_RING( dev_priv->depth_pitch_offset_c );
458     			OUT_RING( clear->clear_depth );
459     
460     			OUT_RING( (x << 16) | y );
461     			OUT_RING( (w << 16) | h );
462     
463     			ADVANCE_RING();
464     		}
465     	}
466     }
467     
468     static void r128_cce_dispatch_swap( drm_device_t *dev )
469     {
470     	drm_r128_private_t *dev_priv = dev->dev_private;
471     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
472     	int nbox = sarea_priv->nbox;
473     	drm_clip_rect_t *pbox = sarea_priv->boxes;
474     	int i;
475     	RING_LOCALS;
476     	DRM_DEBUG( "%s\n", __FUNCTION__ );
477     
478     #if R128_PERFORMANCE_BOXES
479     	/* Do some trivial performance monitoring...
480     	 */
481     	r128_cce_performance_boxes( dev_priv );
482     #endif
483     
484     	for ( i = 0 ; i < nbox ; i++ ) {
485     		int x = pbox[i].x1;
486     		int y = pbox[i].y1;
487     		int w = pbox[i].x2 - x;
488     		int h = pbox[i].y2 - y;
489     
490     		BEGIN_RING( 7 );
491     
492     		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
493     		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
494     			  R128_GMC_DST_PITCH_OFFSET_CNTL |
495     			  R128_GMC_BRUSH_NONE |
496     			  (dev_priv->color_fmt << 8) |
497     			  R128_GMC_SRC_DATATYPE_COLOR |
498     			  R128_ROP3_S |
499     			  R128_DP_SRC_SOURCE_MEMORY |
500     			  R128_GMC_CLR_CMP_CNTL_DIS |
501     			  R128_GMC_AUX_CLIP_DIS |
502     			  R128_GMC_WR_MSK_DIS );
503     
504     		OUT_RING( dev_priv->back_pitch_offset_c );
505     		OUT_RING( dev_priv->front_pitch_offset_c );
506     
507     		OUT_RING( (x << 16) | y );
508     		OUT_RING( (x << 16) | y );
509     		OUT_RING( (w << 16) | h );
510     
511     		ADVANCE_RING();
512     	}
513     
514     	/* Increment the frame counter.  The client-side 3D driver must
515     	 * throttle the framerate by waiting for this value before
516     	 * performing the swapbuffer ioctl.
517     	 */
518     	dev_priv->sarea_priv->last_frame++;
519     
520     	BEGIN_RING( 2 );
521     
522     	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
523     	OUT_RING( dev_priv->sarea_priv->last_frame );
524     
525     	ADVANCE_RING();
526     }
527     
528     static void r128_cce_dispatch_flip( drm_device_t *dev )
529     {
530     	drm_r128_private_t *dev_priv = dev->dev_private;
531     	RING_LOCALS;
532     	DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
533     
534     #if R128_PERFORMANCE_BOXES
535     	/* Do some trivial performance monitoring...
536     	 */
537     	r128_cce_performance_boxes( dev_priv );
538     #endif
539     
540     	BEGIN_RING( 4 );
541     
542     	R128_WAIT_UNTIL_PAGE_FLIPPED();
543     	OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
544     
545     	if ( dev_priv->current_page == 0 ) {
546     		OUT_RING( dev_priv->back_offset );
547     		dev_priv->current_page = 1;
548     	} else {
549     		OUT_RING( dev_priv->front_offset );
550     		dev_priv->current_page = 0;
551     	}
552     
553     	ADVANCE_RING();
554     
555     	/* Increment the frame counter.  The client-side 3D driver must
556     	 * throttle the framerate by waiting for this value before
557     	 * performing the swapbuffer ioctl.
558     	 */
559     	dev_priv->sarea_priv->last_frame++;
560     
561     	BEGIN_RING( 2 );
562     
563     	OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
564     	OUT_RING( dev_priv->sarea_priv->last_frame );
565     
566     	ADVANCE_RING();
567     }
568     
569     static void r128_cce_dispatch_vertex( drm_device_t *dev,
570     				      drm_buf_t *buf )
571     {
572     	drm_r128_private_t *dev_priv = dev->dev_private;
573     	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
574     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
575     	int format = sarea_priv->vc_format;
576     	int offset = buf->bus_address;
577     	int size = buf->used;
578     	int prim = buf_priv->prim;
579     	int i = 0;
580     	RING_LOCALS;
581     	DRM_DEBUG( "%s: buf=%d nbox=%d\n",
582     		   __FUNCTION__, buf->idx, sarea_priv->nbox );
583     
584     	if ( 0 )
585     		r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
586     
587     	if ( buf->used ) {
588     		buf_priv->dispatched = 1;
589     
590     		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
591     			r128_emit_state( dev_priv );
592     		}
593     
594     		do {
595     			/* Emit the next set of up to three cliprects */
596     			if ( i < sarea_priv->nbox ) {
597     				r128_emit_clip_rects( dev_priv,
598     						      &sarea_priv->boxes[i],
599     						      sarea_priv->nbox - i );
600     			}
601     
602     			/* Emit the vertex buffer rendering commands */
603     			BEGIN_RING( 5 );
604     
605     			OUT_RING( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, 3 ) );
606     			OUT_RING( offset );
607     			OUT_RING( size );
608     			OUT_RING( format );
609     			OUT_RING( prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
610     				  (size << R128_CCE_VC_CNTL_NUM_SHIFT) );
611     
612     			ADVANCE_RING();
613     
614     			i += 3;
615     		} while ( i < sarea_priv->nbox );
616     	}
617     
618     	if ( buf_priv->discard ) {
619     		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
620     
621     		/* Emit the vertex buffer age */
622     		BEGIN_RING( 2 );
623     
624     		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
625     		OUT_RING( buf_priv->age );
626     
627     		ADVANCE_RING();
628     
629     		buf->pending = 1;
630     		buf->used = 0;
631     		/* FIXME: Check dispatched field */
632     		buf_priv->dispatched = 0;
633     	}
634     
635     	dev_priv->sarea_priv->last_dispatch++;
636     
637     	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
638     	sarea_priv->nbox = 0;
639     }
640     
641     static void r128_cce_dispatch_indirect( drm_device_t *dev,
642     					drm_buf_t *buf,
643     					int start, int end )
644     {
645     	drm_r128_private_t *dev_priv = dev->dev_private;
646     	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
647     	RING_LOCALS;
648     	DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
649     		   buf->idx, start, end );
650     
651     	if ( start != end ) {
652     		int offset = buf->bus_address + start;
653     		int dwords = (end - start + 3) / sizeof(u32);
654     
655     		/* Indirect buffer data must be an even number of
656     		 * dwords, so if we've been given an odd number we must
657     		 * pad the data with a Type-2 CCE packet.
658     		 */
659     		if ( dwords & 1 ) {
660     			u32 *data = (u32 *)
661     				((char *)dev_priv->buffers->handle
662     				 + buf->offset + start);
663     			data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
664     		}
665     
666     		buf_priv->dispatched = 1;
667     
668     		/* Fire off the indirect buffer */
669     		BEGIN_RING( 3 );
670     
671     		OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
672     		OUT_RING( offset );
673     		OUT_RING( dwords );
674     
675     		ADVANCE_RING();
676     	}
677     
678     	if ( buf_priv->discard ) {
679     		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
680     
681     		/* Emit the indirect buffer age */
682     		BEGIN_RING( 2 );
683     
684     		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
685     		OUT_RING( buf_priv->age );
686     
687     		ADVANCE_RING();
688     
689     		buf->pending = 1;
690     		buf->used = 0;
691     		/* FIXME: Check dispatched field */
692     		buf_priv->dispatched = 0;
693     	}
694     
695     	dev_priv->sarea_priv->last_dispatch++;
696     }
697     
698     static void r128_cce_dispatch_indices( drm_device_t *dev,
699     				       drm_buf_t *buf,
700     				       int start, int end,
701     				       int count )
702     {
703     	drm_r128_private_t *dev_priv = dev->dev_private;
704     	drm_r128_buf_priv_t *buf_priv = buf->dev_private;
705     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
706     	int format = sarea_priv->vc_format;
707     	int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
708     	int prim = buf_priv->prim;
709     	u32 *data;
710     	int dwords;
711     	int i = 0;
712     	RING_LOCALS;
713     	DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
714     
715     	if ( 0 )
716     		r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
717     
718     	if ( start != end ) {
719     		buf_priv->dispatched = 1;
720     
721     		if ( sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS ) {
722     			r128_emit_state( dev_priv );
723     		}
724     
725     		dwords = (end - start + 3) / sizeof(u32);
726     
727     		data = (u32 *)((char *)dev_priv->buffers->handle
728     			       + buf->offset + start);
729     
730     		data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
731     						    dwords-2 ) );
732     
733     		data[1] = cpu_to_le32( offset );
734     		data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
735     		data[3] = cpu_to_le32( format );
736     		data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
737     					(count << 16)) );
738     
739     		if ( count & 0x1 ) {
740     #ifdef __LITTLE_ENDIAN
741     			data[dwords-1] &= 0x0000ffff;
742     #else
743     			data[dwords-1] &= 0xffff0000;
744     #endif
745     		}
746     
747     		do {
748     			/* Emit the next set of up to three cliprects */
749     			if ( i < sarea_priv->nbox ) {
750     				r128_emit_clip_rects( dev_priv,
751     						      &sarea_priv->boxes[i],
752     						      sarea_priv->nbox - i );
753     			}
754     
755     			r128_cce_dispatch_indirect( dev, buf, start, end );
756     
757     			i += 3;
758     		} while ( i < sarea_priv->nbox );
759     	}
760     
761     	if ( buf_priv->discard ) {
762     		buf_priv->age = dev_priv->sarea_priv->last_dispatch;
763     
764     		/* Emit the vertex buffer age */
765     		BEGIN_RING( 2 );
766     
767     		OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
768     		OUT_RING( buf_priv->age );
769     
770     		ADVANCE_RING();
771     
772     		buf->pending = 1;
773     		/* FIXME: Check dispatched field */
774     		buf_priv->dispatched = 0;
775     	}
776     
777     	dev_priv->sarea_priv->last_dispatch++;
778     
779     	sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
780     	sarea_priv->nbox = 0;
781     }
782     
783     static int r128_cce_dispatch_blit( drm_device_t *dev,
784     				   drm_r128_blit_t *blit )
785     {
786     	drm_r128_private_t *dev_priv = dev->dev_private;
787     	drm_device_dma_t *dma = dev->dma;
788     	drm_buf_t *buf;
789     	drm_r128_buf_priv_t *buf_priv;
790     	u32 *data;
791     	int dword_shift, dwords;
792     	RING_LOCALS;
793     	DRM_DEBUG( "%s\n", __FUNCTION__ );
794     
795     	/* The compiler won't optimize away a division by a variable,
796     	 * even if the only legal values are powers of two.  Thus, we'll
797     	 * use a shift instead.
798     	 */
799     	switch ( blit->format ) {
800     	case R128_DATATYPE_ARGB8888:
801     		dword_shift = 0;
802     		break;
803     	case R128_DATATYPE_ARGB1555:
804     	case R128_DATATYPE_RGB565:
805     	case R128_DATATYPE_ARGB4444:
806     		dword_shift = 1;
807     		break;
808     	case R128_DATATYPE_CI8:
809     	case R128_DATATYPE_RGB8:
810     		dword_shift = 2;
811     		break;
812     	default:
813     		DRM_ERROR( "invalid blit format %d\n", blit->format );
814     		return -EINVAL;
815     	}
816     
817     	/* Flush the pixel cache, and mark the contents as Read Invalid.
818     	 * This ensures no pixel data gets mixed up with the texture
819     	 * data from the host data blit, otherwise part of the texture
820     	 * image may be corrupted.
821     	 */
822     	BEGIN_RING( 2 );
823     
824     	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
825     	OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
826     
827     	ADVANCE_RING();
828     
829     	/* Dispatch the indirect buffer.
830     	 */
831     	buf = dma->buflist[blit->idx];
832     	buf_priv = buf->dev_private;
833     
834     	if ( buf->pid != current->pid ) {
835     		DRM_ERROR( "process %d using buffer owned by %d\n",
836     			   current->pid, buf->pid );
837     		return -EINVAL;
838     	}
839     	if ( buf->pending ) {
840     		DRM_ERROR( "sending pending buffer %d\n", blit->idx );
841     		return -EINVAL;
842     	}
843     
844     	buf_priv->discard = 1;
845     
846     	dwords = (blit->width * blit->height) >> dword_shift;
847     
848     	data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
849     
850     	data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
851     	data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
852     				R128_GMC_BRUSH_NONE |
853     				(blit->format << 8) |
854     				R128_GMC_SRC_DATATYPE_COLOR |
855     				R128_ROP3_S |
856     				R128_DP_SRC_SOURCE_HOST_DATA |
857     				R128_GMC_CLR_CMP_CNTL_DIS |
858     				R128_GMC_AUX_CLIP_DIS |
859     				R128_GMC_WR_MSK_DIS) );
860     
861     	data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
862     	data[3] = cpu_to_le32( 0xffffffff );
863     	data[4] = cpu_to_le32( 0xffffffff );
864     	data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
865     	data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
866     	data[7] = cpu_to_le32( dwords );
867     
868     	buf->used = (dwords + 8) * sizeof(u32);
869     
870     	r128_cce_dispatch_indirect( dev, buf, 0, buf->used );
871     
872     	/* Flush the pixel cache after the blit completes.  This ensures
873     	 * the texture data is written out to memory before rendering
874     	 * continues.
875     	 */
876     	BEGIN_RING( 2 );
877     
878     	OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
879     	OUT_RING( R128_PC_FLUSH_GUI );
880     
881     	ADVANCE_RING();
882     
883     	return 0;
884     }
885     
886     
887     /* ================================================================
888      * Tiled depth buffer management
889      *
890      * FIXME: These should all set the destination write mask for when we
891      * have hardware stencil support.
892      */
893     
894     static int r128_cce_dispatch_write_span( drm_device_t *dev,
895     					 drm_r128_depth_t *depth )
896     {
897     	drm_r128_private_t *dev_priv = dev->dev_private;
898     	int count, x, y;
899     	u32 *buffer;
900     	u8 *mask;
901     	int i;
902     	RING_LOCALS;
903     	DRM_DEBUG( "%s\n", __FUNCTION__ );
904     
905     	count = depth->n;
906     	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
907     		return -EFAULT;
908     	}
909     	if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
910     		return -EFAULT;
911     	}
912     
913     	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
914     	if ( buffer == NULL )
915     		return -ENOMEM;
916     	if ( copy_from_user( buffer, depth->buffer,
917     			     depth->n * sizeof(u32) ) ) {
918     		kfree( buffer );
919     		return -EFAULT;
920     	}
921     
922     	if ( depth->mask ) {
923     		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
924     		if ( mask == NULL ) {
925     			kfree( buffer );
926     			return -ENOMEM;
927     		}
928     		if ( copy_from_user( mask, depth->mask,
929     				     depth->n * sizeof(u8) ) ) {
930     			kfree( buffer );
931     			kfree( mask );
932     			return -EFAULT;
933     		}
934     
935     		for ( i = 0 ; i < count ; i++, x++ ) {
936     			if ( mask[i] ) {
937     				BEGIN_RING( 6 );
938     
939     				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
940     				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
941     					  R128_GMC_BRUSH_SOLID_COLOR |
942     					  (dev_priv->depth_fmt << 8) |
943     					  R128_GMC_SRC_DATATYPE_COLOR |
944     					  R128_ROP3_P |
945     					  R128_GMC_CLR_CMP_CNTL_DIS |
946     					  R128_GMC_WR_MSK_DIS );
947     
948     				OUT_RING( dev_priv->depth_pitch_offset_c );
949     				OUT_RING( buffer[i] );
950     
951     				OUT_RING( (x << 16) | y );
952     				OUT_RING( (1 << 16) | 1 );
953     
954     				ADVANCE_RING();
955     			}
956     		}
957     
958     		kfree( mask );
959     	} else {
960     		for ( i = 0 ; i < count ; i++, x++ ) {
961     			BEGIN_RING( 6 );
962     
963     			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
964     			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
965     				  R128_GMC_BRUSH_SOLID_COLOR |
966     				  (dev_priv->depth_fmt << 8) |
967     				  R128_GMC_SRC_DATATYPE_COLOR |
968     				  R128_ROP3_P |
969     				  R128_GMC_CLR_CMP_CNTL_DIS |
970     				  R128_GMC_WR_MSK_DIS );
971     
972     			OUT_RING( dev_priv->depth_pitch_offset_c );
973     			OUT_RING( buffer[i] );
974     
975     			OUT_RING( (x << 16) | y );
976     			OUT_RING( (1 << 16) | 1 );
977     
978     			ADVANCE_RING();
979     		}
980     	}
981     
982     	kfree( buffer );
983     
984     	return 0;
985     }
986     
987     static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
988     					   drm_r128_depth_t *depth )
989     {
990     	drm_r128_private_t *dev_priv = dev->dev_private;
991     	int count, *x, *y;
992     	u32 *buffer;
993     	u8 *mask;
994     	int i;
995     	RING_LOCALS;
996     	DRM_DEBUG( "%s\n", __FUNCTION__ );
997     
998     	count = depth->n;
999     
1000     	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
1001     	if ( x == NULL ) {
1002     		return -ENOMEM;
1003     	}
1004     	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
1005     	if ( y == NULL ) {
1006     		kfree( x );
1007     		return -ENOMEM;
1008     	}
1009     	if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
1010     		kfree( x );
1011     		kfree( y );
1012     		return -EFAULT;
1013     	}
1014     	if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
1015     		kfree( x );
1016     		kfree( y );
1017     		return -EFAULT;
1018     	}
1019     
1020     	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
1021     	if ( buffer == NULL ) {
1022     		kfree( x );
1023     		kfree( y );
1024     		return -ENOMEM;
1025     	}
1026     	if ( copy_from_user( buffer, depth->buffer,
1027     			     depth->n * sizeof(u32) ) ) {
1028     		kfree( x );
1029     		kfree( y );
1030     		kfree( buffer );
1031     		return -EFAULT;
1032     	}
1033     
1034     	if ( depth->mask ) {
1035     		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
1036     		if ( mask == NULL ) {
1037     			kfree( x );
1038     			kfree( y );
1039     			kfree( buffer );
1040     			return -ENOMEM;
1041     		}
1042     		if ( copy_from_user( mask, depth->mask,
1043     				     depth->n * sizeof(u8) ) ) {
1044     			kfree( x );
1045     			kfree( y );
1046     			kfree( buffer );
1047     			kfree( mask );
1048     			return -EFAULT;
1049     		}
1050     
1051     		for ( i = 0 ; i < count ; i++ ) {
1052     			if ( mask[i] ) {
1053     				BEGIN_RING( 6 );
1054     
1055     				OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
1056     				OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
1057     					  R128_GMC_BRUSH_SOLID_COLOR |
1058     					  (dev_priv->depth_fmt << 8) |
1059     					  R128_GMC_SRC_DATATYPE_COLOR |
1060     					  R128_ROP3_P |
1061     					  R128_GMC_CLR_CMP_CNTL_DIS |
1062     					  R128_GMC_WR_MSK_DIS );
1063     
1064     				OUT_RING( dev_priv->depth_pitch_offset_c );
1065     				OUT_RING( buffer[i] );
1066     
1067     				OUT_RING( (x[i] << 16) | y[i] );
1068     				OUT_RING( (1 << 16) | 1 );
1069     
1070     				ADVANCE_RING();
1071     			}
1072     		}
1073     
1074     		kfree( mask );
1075     	} else {
1076     		for ( i = 0 ; i < count ; i++ ) {
1077     			BEGIN_RING( 6 );
1078     
1079     			OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
1080     			OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
1081     				  R128_GMC_BRUSH_SOLID_COLOR |
1082     				  (dev_priv->depth_fmt << 8) |
1083     				  R128_GMC_SRC_DATATYPE_COLOR |
1084     				  R128_ROP3_P |
1085     				  R128_GMC_CLR_CMP_CNTL_DIS |
1086     				  R128_GMC_WR_MSK_DIS );
1087     
1088     			OUT_RING( dev_priv->depth_pitch_offset_c );
1089     			OUT_RING( buffer[i] );
1090     
1091     			OUT_RING( (x[i] << 16) | y[i] );
1092     			OUT_RING( (1 << 16) | 1 );
1093     
1094     			ADVANCE_RING();
1095     		}
1096     	}
1097     
1098     	kfree( x );
1099     	kfree( y );
1100     	kfree( buffer );
1101     
1102     	return 0;
1103     }
1104     
1105     static int r128_cce_dispatch_read_span( drm_device_t *dev,
1106     					drm_r128_depth_t *depth )
1107     {
1108     	drm_r128_private_t *dev_priv = dev->dev_private;
1109     	int count, x, y;
1110     	RING_LOCALS;
1111     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1112     
1113     	count = depth->n;
1114     	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
1115     		return -EFAULT;
1116     	}
1117     	if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
1118     		return -EFAULT;
1119     	}
1120     
1121     	BEGIN_RING( 7 );
1122     
1123     	OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
1124     	OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
1125     		  R128_GMC_DST_PITCH_OFFSET_CNTL |
1126     		  R128_GMC_BRUSH_NONE |
1127     		  (dev_priv->depth_fmt << 8) |
1128     		  R128_GMC_SRC_DATATYPE_COLOR |
1129     		  R128_ROP3_S |
1130     		  R128_DP_SRC_SOURCE_MEMORY |
1131     		  R128_GMC_CLR_CMP_CNTL_DIS |
1132     		  R128_GMC_WR_MSK_DIS );
1133     
1134     	OUT_RING( dev_priv->depth_pitch_offset_c );
1135     	OUT_RING( dev_priv->span_pitch_offset_c );
1136     
1137     	OUT_RING( (x << 16) | y );
1138     	OUT_RING( (0 << 16) | 0 );
1139     	OUT_RING( (count << 16) | 1 );
1140     
1141     	ADVANCE_RING();
1142     
1143     	return 0;
1144     }
1145     
1146     static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
1147     					  drm_r128_depth_t *depth )
1148     {
1149     	drm_r128_private_t *dev_priv = dev->dev_private;
1150     	int count, *x, *y;
1151     	int i;
1152     	RING_LOCALS;
1153     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1154     
1155     	count = depth->n;
1156     	if ( count > dev_priv->depth_pitch ) {
1157     		count = dev_priv->depth_pitch;
1158     	}
1159     
1160     	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
1161     	if ( x == NULL ) {
1162     		return -ENOMEM;
1163     	}
1164     	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
1165     	if ( y == NULL ) {
1166     		kfree( x );
1167     		return -ENOMEM;
1168     	}
1169     	if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
1170     		kfree( x );
1171     		kfree( y );
1172     		return -EFAULT;
1173     	}
1174     	if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
1175     		kfree( x );
1176     		kfree( y );
1177     		return -EFAULT;
1178     	}
1179     
1180     	for ( i = 0 ; i < count ; i++ ) {
1181     		BEGIN_RING( 7 );
1182     
1183     		OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
1184     		OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
1185     			  R128_GMC_DST_PITCH_OFFSET_CNTL |
1186     			  R128_GMC_BRUSH_NONE |
1187     			  (dev_priv->depth_fmt << 8) |
1188     			  R128_GMC_SRC_DATATYPE_COLOR |
1189     			  R128_ROP3_S |
1190     			  R128_DP_SRC_SOURCE_MEMORY |
1191     			  R128_GMC_CLR_CMP_CNTL_DIS |
1192     			  R128_GMC_WR_MSK_DIS );
1193     
1194     		OUT_RING( dev_priv->depth_pitch_offset_c );
1195     		OUT_RING( dev_priv->span_pitch_offset_c );
1196     
1197     		OUT_RING( (x[i] << 16) | y[i] );
1198     		OUT_RING( (i << 16) | 0 );
1199     		OUT_RING( (1 << 16) | 1 );
1200     
1201     		ADVANCE_RING();
1202     	}
1203     
1204     	kfree( x );
1205     	kfree( y );
1206     
1207     	return 0;
1208     }
1209     
1210     
1211     /* ================================================================
1212      * Polygon stipple
1213      */
1214     
1215     static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
1216     {
1217     	drm_r128_private_t *dev_priv = dev->dev_private;
1218     	int i;
1219     	RING_LOCALS;
1220     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1221     
1222     	BEGIN_RING( 33 );
1223     
1224     	OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
1225     	for ( i = 0 ; i < 32 ; i++ ) {
1226     		OUT_RING( stipple[i] );
1227     	}
1228     
1229     	ADVANCE_RING();
1230     }
1231     
1232     
1233     /* ================================================================
1234      * IOCTL functions
1235      */
1236     
1237     int r128_cce_clear( struct inode *inode, struct file *filp,
1238     		    unsigned int cmd, unsigned long arg )
1239     {
1240     	drm_file_t *priv = filp->private_data;
1241     	drm_device_t *dev = priv->dev;
1242     	drm_r128_private_t *dev_priv = dev->dev_private;
1243     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1244     	drm_r128_clear_t clear;
1245     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1246     
1247     	LOCK_TEST_WITH_RETURN( dev );
1248     
1249     	if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
1250     			     sizeof(clear) ) )
1251     		return -EFAULT;
1252     
1253     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1254     
1255     	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
1256     		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1257     
1258     	r128_cce_dispatch_clear( dev, &clear );
1259     
1260     	/* Make sure we restore the 3D state next time.
1261     	 */
1262     	dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
1263     
1264     	return 0;
1265     }
1266     
1267     int r128_cce_swap( struct inode *inode, struct file *filp,
1268     		   unsigned int cmd, unsigned long arg )
1269     {
1270     	drm_file_t *priv = filp->private_data;
1271     	drm_device_t *dev = priv->dev;
1272     	drm_r128_private_t *dev_priv = dev->dev_private;
1273     	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1274     	DRM_DEBUG( "%s\n", __FUNCTION__ );
1275     
1276     	LOCK_TEST_WITH_RETURN( dev );
1277     
1278     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1279     
1280     	if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
1281     		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1282     
1283     	if ( !dev_priv->page_flipping ) {
1284     		r128_cce_dispatch_swap( dev );
1285     		dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
1286     						R128_UPLOAD_MASKS);
1287     	} else {
1288     		r128_cce_dispatch_flip( dev );
1289     	}
1290     
1291     	return 0;
1292     }
1293     
1294     int r128_cce_vertex( struct inode *inode, struct file *filp,
1295     		     unsigned int cmd, unsigned long arg )
1296     {
1297     	drm_file_t *priv = filp->private_data;
1298     	drm_device_t *dev = priv->dev;
1299     	drm_r128_private_t *dev_priv = dev->dev_private;
1300     	drm_device_dma_t *dma = dev->dma;
1301     	drm_buf_t *buf;
1302     	drm_r128_buf_priv_t *buf_priv;
1303     	drm_r128_vertex_t vertex;
1304     
1305     	LOCK_TEST_WITH_RETURN( dev );
1306     
1307     	if ( !dev_priv ) {
1308     		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
1309     		return -EINVAL;
1310     	}
1311     
1312     	if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg,
1313     			     sizeof(vertex) ) )
1314     		return -EFAULT;
1315     
1316     	DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n",
1317     		   __FUNCTION__, current->pid,
1318     		   vertex.idx, vertex.count, vertex.discard );
1319     
1320     	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
1321     		DRM_ERROR( "buffer index %d (of %d max)\n",
1322     			   vertex.idx, dma->buf_count - 1 );
1323     		return -EINVAL;
1324     	}
1325     	if ( vertex.prim < 0 ||
1326     	     vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
1327     		DRM_ERROR( "buffer prim %d\n", vertex.prim );
1328     		return -EINVAL;
1329     	}
1330     
1331     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1332     	VB_AGE_TEST_WITH_RETURN( dev_priv );
1333     
1334     	buf = dma->buflist[vertex.idx];
1335     	buf_priv = buf->dev_private;
1336     
1337     	if ( buf->pid != current->pid ) {
1338     		DRM_ERROR( "process %d using buffer owned by %d\n",
1339     			   current->pid, buf->pid );
1340     		return -EINVAL;
1341     	}
1342     	if ( buf->pending ) {
1343     		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
1344     		return -EINVAL;
1345     	}
1346     
1347     	buf->used = vertex.count;
1348     	buf_priv->prim = vertex.prim;
1349     	buf_priv->discard = vertex.discard;
1350     
1351     	r128_cce_dispatch_vertex( dev, buf );
1352     
1353     	return 0;
1354     }
1355     
1356     int r128_cce_indices( struct inode *inode, struct file *filp,
1357     		      unsigned int cmd, unsigned long arg )
1358     {
1359     	drm_file_t *priv = filp->private_data;
1360     	drm_device_t *dev = priv->dev;
1361     	drm_r128_private_t *dev_priv = dev->dev_private;
1362     	drm_device_dma_t *dma = dev->dma;
1363     	drm_buf_t *buf;
1364     	drm_r128_buf_priv_t *buf_priv;
1365     	drm_r128_indices_t elts;
1366     	int count;
1367     
1368     	LOCK_TEST_WITH_RETURN( dev );
1369     
1370     	if ( !dev_priv ) {
1371     		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
1372     		return -EINVAL;
1373     	}
1374     
1375     	if ( copy_from_user( &elts, (drm_r128_indices_t *)arg,
1376     			     sizeof(elts) ) )
1377     		return -EFAULT;
1378     
1379     	DRM_DEBUG( "%s: pid=%d buf=%d s=%d e=%d d=%d\n",
1380     		   __FUNCTION__, current->pid,
1381     		   elts.idx, elts.start, elts.end, elts.discard );
1382     
1383     	if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
1384     		DRM_ERROR( "buffer index %d (of %d max)\n",
1385     			   elts.idx, dma->buf_count - 1 );
1386     		return -EINVAL;
1387     	}
1388     	if ( elts.prim < 0 ||
1389     	     elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
1390     		DRM_ERROR( "buffer prim %d\n", elts.prim );
1391     		return -EINVAL;
1392     	}
1393     
1394     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1395     	VB_AGE_TEST_WITH_RETURN( dev_priv );
1396     
1397     	buf = dma->buflist[elts.idx];
1398     	buf_priv = buf->dev_private;
1399     
1400     	if ( buf->pid != current->pid ) {
1401     		DRM_ERROR( "process %d using buffer owned by %d\n",
1402     			   current->pid, buf->pid );
1403     		return -EINVAL;
1404     	}
1405     	if ( buf->pending ) {
1406     		DRM_ERROR( "sending pending buffer %d\n", elts.idx );
1407     		return -EINVAL;
1408     	}
1409     
1410     	count = (elts.end - elts.start) / sizeof(u16);
1411     	elts.start -= R128_INDEX_PRIM_OFFSET;
1412     
1413     	if ( elts.start & 0x7 ) {
1414     		DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
1415     		return -EINVAL;
1416     	}
1417     	if ( elts.start < buf->used ) {
1418     		DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
1419     		return -EINVAL;
1420     	}
1421     
1422     	buf->used = elts.end;
1423     	buf_priv->prim = elts.prim;
1424     	buf_priv->discard = elts.discard;
1425     
1426     	r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count );
1427     
1428     	return 0;
1429     }
1430     
1431     int r128_cce_blit( struct inode *inode, struct file *filp,
1432     		   unsigned int cmd, unsigned long arg )
1433     {
1434     	drm_file_t *priv = filp->private_data;
1435     	drm_device_t *dev = priv->dev;
1436     	drm_device_dma_t *dma = dev->dma;
1437     	drm_r128_private_t *dev_priv = dev->dev_private;
1438     	drm_r128_blit_t blit;
1439     
1440     	LOCK_TEST_WITH_RETURN( dev );
1441     
1442     	if ( copy_from_user( &blit, (drm_r128_blit_t *)arg,
1443     			     sizeof(blit) ) )
1444     		return -EFAULT;
1445     
1446     	DRM_DEBUG( "%s: pid=%d index=%d\n",
1447     		   __FUNCTION__, current->pid, blit.idx );
1448     
1449     	if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
1450     		DRM_ERROR( "buffer index %d (of %d max)\n",
1451     			   blit.idx, dma->buf_count - 1 );
1452     		return -EINVAL;
1453     	}
1454     
1455     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1456     	VB_AGE_TEST_WITH_RETURN( dev_priv );
1457     
1458     	return r128_cce_dispatch_blit( dev, &blit );
1459     }
1460     
1461     int r128_cce_depth( struct inode *inode, struct file *filp,
1462     		    unsigned int cmd, unsigned long arg )
1463     {
1464     	drm_file_t *priv = filp->private_data;
1465     	drm_device_t *dev = priv->dev;
1466     	drm_r128_private_t *dev_priv = dev->dev_private;
1467     	drm_r128_depth_t depth;
1468     
1469     	LOCK_TEST_WITH_RETURN( dev );
1470     
1471     	if ( copy_from_user( &depth, (drm_r128_depth_t *)arg,
1472     			     sizeof(depth) ) )
1473     		return -EFAULT;
1474     
1475     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1476     
1477     	switch ( depth.func ) {
1478     	case R128_WRITE_SPAN:
1479     		return r128_cce_dispatch_write_span( dev, &depth );
1480     	case R128_WRITE_PIXELS:
1481     		return r128_cce_dispatch_write_pixels( dev, &depth );
1482     	case R128_READ_SPAN:
1483     		return r128_cce_dispatch_read_span( dev, &depth );
1484     	case R128_READ_PIXELS:
1485     		return r128_cce_dispatch_read_pixels( dev, &depth );
1486     	}
1487     
1488     	return -EINVAL;
1489     }
1490     
1491     int r128_cce_stipple( struct inode *inode, struct file *filp,
1492     		      unsigned int cmd, unsigned long arg )
1493     {
1494     	drm_file_t *priv = filp->private_data;
1495     	drm_device_t *dev = priv->dev;
1496     	drm_r128_private_t *dev_priv = dev->dev_private;
1497     	drm_r128_stipple_t stipple;
1498     	u32 mask[32];
1499     
1500     	LOCK_TEST_WITH_RETURN( dev );
1501     
1502     	if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg,
1503     			     sizeof(stipple) ) )
1504     		return -EFAULT;
1505     
1506     	if ( copy_from_user( &mask, stipple.mask,
1507     			     32 * sizeof(u32) ) )
1508     		return -EFAULT;
1509     
1510     	RING_SPACE_TEST_WITH_RETURN( dev_priv );
1511     
1512     	r128_cce_dispatch_stipple( dev, mask );
1513     
1514     	return 0;
1515     }
1516     
1517     int r128_cce_indirect( struct inode *inode, struct file *filp,
1518     		       unsigned int cmd, unsigned long arg )
1519     {
1520     	drm_file_t *priv = filp->private_data;
1521     	drm_device_t *dev = priv->dev;
1522     
1523     	LOCK_TEST_WITH_RETURN( dev );
1524     
1525     	/* Indirect buffer firing is not supported at this time.
1526     	 */
1527     	return -EINVAL;
1528     }
1529