1/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
2/*
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 *    Gareth Hughes <gareth@valinux.com>
27 *    Kevin E. Martin <martin@valinux.com>
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <dev/drm2/drmP.h>
34#include <dev/drm2/drm_buffer.h>
35#include <dev/drm2/radeon/radeon_drm.h>
36#include "radeon_drv.h"
37
38/* ================================================================
39 * Helper functions for client state checking and fixup
40 */
41
42static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
43						    dev_priv,
44						    struct drm_file * file_priv,
45						    u32 *offset)
46{
47	u64 off = *offset;
48	u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
49	struct drm_radeon_driver_file_fields *radeon_priv;
50
51	/* Hrm ... the story of the offset ... So this function converts
52	 * the various ideas of what userland clients might have for an
53	 * offset in the card address space into an offset into the card
54	 * address space :) So with a sane client, it should just keep
55	 * the value intact and just do some boundary checking. However,
56	 * not all clients are sane. Some older clients pass us 0 based
57	 * offsets relative to the start of the framebuffer and some may
58	 * assume the AGP aperture it appended to the framebuffer, so we
59	 * try to detect those cases and fix them up.
60	 *
61	 * Note: It might be a good idea here to make sure the offset lands
62	 * in some "allowed" area to protect things like the PCIE GART...
63	 */
64
65	/* First, the best case, the offset already lands in either the
66	 * framebuffer or the GART mapped space
67	 */
68	if (radeon_check_offset(dev_priv, off))
69		return 0;
70
71	/* Ok, that didn't happen... now check if we have a zero based
72	 * offset that fits in the framebuffer + gart space, apply the
73	 * magic offset we get from SETPARAM or calculated from fb_location
74	 */
75	if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
76		radeon_priv = file_priv->driver_priv;
77		off += radeon_priv->radeon_fb_delta;
78	}
79
80	/* Finally, assume we aimed at a GART offset if beyond the fb */
81	if (off > fb_end)
82		off = off - fb_end - 1 + dev_priv->gart_vm_start;
83
84	/* Now recheck and fail if out of bounds */
85	if (radeon_check_offset(dev_priv, off)) {
86		DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
87		*offset = off;
88		return 0;
89	}
90	return -EINVAL;
91}
92
93static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
94						     dev_priv,
95						     struct drm_file *file_priv,
96						     int id, struct drm_buffer *buf)
97{
98	u32 *data;
99	switch (id) {
100
101	case RADEON_EMIT_PP_MISC:
102		data = drm_buffer_pointer_to_dword(buf,
103			(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4);
104
105		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
106			DRM_ERROR("Invalid depth buffer offset\n");
107			return -EINVAL;
108		}
109		dev_priv->have_z_offset = 1;
110		break;
111
112	case RADEON_EMIT_PP_CNTL:
113		data = drm_buffer_pointer_to_dword(buf,
114			(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4);
115
116		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
117			DRM_ERROR("Invalid colour buffer offset\n");
118			return -EINVAL;
119		}
120		break;
121
122	case R200_EMIT_PP_TXOFFSET_0:
123	case R200_EMIT_PP_TXOFFSET_1:
124	case R200_EMIT_PP_TXOFFSET_2:
125	case R200_EMIT_PP_TXOFFSET_3:
126	case R200_EMIT_PP_TXOFFSET_4:
127	case R200_EMIT_PP_TXOFFSET_5:
128		data = drm_buffer_pointer_to_dword(buf, 0);
129		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
130			DRM_ERROR("Invalid R200 texture offset\n");
131			return -EINVAL;
132		}
133		break;
134
135	case RADEON_EMIT_PP_TXFILTER_0:
136	case RADEON_EMIT_PP_TXFILTER_1:
137	case RADEON_EMIT_PP_TXFILTER_2:
138		data = drm_buffer_pointer_to_dword(buf,
139			(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4);
140		if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
141			DRM_ERROR("Invalid R100 texture offset\n");
142			return -EINVAL;
143		}
144		break;
145
146	case R200_EMIT_PP_CUBIC_OFFSETS_0:
147	case R200_EMIT_PP_CUBIC_OFFSETS_1:
148	case R200_EMIT_PP_CUBIC_OFFSETS_2:
149	case R200_EMIT_PP_CUBIC_OFFSETS_3:
150	case R200_EMIT_PP_CUBIC_OFFSETS_4:
151	case R200_EMIT_PP_CUBIC_OFFSETS_5:{
152			int i;
153			for (i = 0; i < 5; i++) {
154				data = drm_buffer_pointer_to_dword(buf, i);
155				if (radeon_check_and_fixup_offset(dev_priv,
156								  file_priv,
157								  data)) {
158					DRM_ERROR
159					    ("Invalid R200 cubic texture offset\n");
160					return -EINVAL;
161				}
162			}
163			break;
164		}
165
166	case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
167	case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
168	case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
169			int i;
170			for (i = 0; i < 5; i++) {
171				data = drm_buffer_pointer_to_dword(buf, i);
172				if (radeon_check_and_fixup_offset(dev_priv,
173								  file_priv,
174								  data)) {
175					DRM_ERROR
176					    ("Invalid R100 cubic texture offset\n");
177					return -EINVAL;
178				}
179			}
180		}
181		break;
182
183	case R200_EMIT_VAP_CTL:{
184			RING_LOCALS;
185			BEGIN_RING(2);
186			OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
187			ADVANCE_RING();
188		}
189		break;
190
191	case RADEON_EMIT_RB3D_COLORPITCH:
192	case RADEON_EMIT_RE_LINE_PATTERN:
193	case RADEON_EMIT_SE_LINE_WIDTH:
194	case RADEON_EMIT_PP_LUM_MATRIX:
195	case RADEON_EMIT_PP_ROT_MATRIX_0:
196	case RADEON_EMIT_RB3D_STENCILREFMASK:
197	case RADEON_EMIT_SE_VPORT_XSCALE:
198	case RADEON_EMIT_SE_CNTL:
199	case RADEON_EMIT_SE_CNTL_STATUS:
200	case RADEON_EMIT_RE_MISC:
201	case RADEON_EMIT_PP_BORDER_COLOR_0:
202	case RADEON_EMIT_PP_BORDER_COLOR_1:
203	case RADEON_EMIT_PP_BORDER_COLOR_2:
204	case RADEON_EMIT_SE_ZBIAS_FACTOR:
205	case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:
206	case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:
207	case R200_EMIT_PP_TXCBLEND_0:
208	case R200_EMIT_PP_TXCBLEND_1:
209	case R200_EMIT_PP_TXCBLEND_2:
210	case R200_EMIT_PP_TXCBLEND_3:
211	case R200_EMIT_PP_TXCBLEND_4:
212	case R200_EMIT_PP_TXCBLEND_5:
213	case R200_EMIT_PP_TXCBLEND_6:
214	case R200_EMIT_PP_TXCBLEND_7:
215	case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
216	case R200_EMIT_TFACTOR_0:
217	case R200_EMIT_VTX_FMT_0:
218	case R200_EMIT_MATRIX_SELECT_0:
219	case R200_EMIT_TEX_PROC_CTL_2:
220	case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
221	case R200_EMIT_PP_TXFILTER_0:
222	case R200_EMIT_PP_TXFILTER_1:
223	case R200_EMIT_PP_TXFILTER_2:
224	case R200_EMIT_PP_TXFILTER_3:
225	case R200_EMIT_PP_TXFILTER_4:
226	case R200_EMIT_PP_TXFILTER_5:
227	case R200_EMIT_VTE_CNTL:
228	case R200_EMIT_OUTPUT_VTX_COMP_SEL:
229	case R200_EMIT_PP_TAM_DEBUG3:
230	case R200_EMIT_PP_CNTL_X:
231	case R200_EMIT_RB3D_DEPTHXY_OFFSET:
232	case R200_EMIT_RE_AUX_SCISSOR_CNTL:
233	case R200_EMIT_RE_SCISSOR_TL_0:
234	case R200_EMIT_RE_SCISSOR_TL_1:
235	case R200_EMIT_RE_SCISSOR_TL_2:
236	case R200_EMIT_SE_VAP_CNTL_STATUS:
237	case R200_EMIT_SE_VTX_STATE_CNTL:
238	case R200_EMIT_RE_POINTSIZE:
239	case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0:
240	case R200_EMIT_PP_CUBIC_FACES_0:
241	case R200_EMIT_PP_CUBIC_FACES_1:
242	case R200_EMIT_PP_CUBIC_FACES_2:
243	case R200_EMIT_PP_CUBIC_FACES_3:
244	case R200_EMIT_PP_CUBIC_FACES_4:
245	case R200_EMIT_PP_CUBIC_FACES_5:
246	case RADEON_EMIT_PP_TEX_SIZE_0:
247	case RADEON_EMIT_PP_TEX_SIZE_1:
248	case RADEON_EMIT_PP_TEX_SIZE_2:
249	case R200_EMIT_RB3D_BLENDCOLOR:
250	case R200_EMIT_TCL_POINT_SPRITE_CNTL:
251	case RADEON_EMIT_PP_CUBIC_FACES_0:
252	case RADEON_EMIT_PP_CUBIC_FACES_1:
253	case RADEON_EMIT_PP_CUBIC_FACES_2:
254	case R200_EMIT_PP_TRI_PERF_CNTL:
255	case R200_EMIT_PP_AFS_0:
256	case R200_EMIT_PP_AFS_1:
257	case R200_EMIT_ATF_TFACTOR:
258	case R200_EMIT_PP_TXCTLALL_0:
259	case R200_EMIT_PP_TXCTLALL_1:
260	case R200_EMIT_PP_TXCTLALL_2:
261	case R200_EMIT_PP_TXCTLALL_3:
262	case R200_EMIT_PP_TXCTLALL_4:
263	case R200_EMIT_PP_TXCTLALL_5:
264	case R200_EMIT_VAP_PVS_CNTL:
265		/* These packets don't contain memory offsets */
266		break;
267
268	default:
269		DRM_ERROR("Unknown state packet ID %d\n", id);
270		return -EINVAL;
271	}
272
273	return 0;
274}
275
276static int radeon_check_and_fixup_packet3(drm_radeon_private_t *
277					  dev_priv,
278					  struct drm_file *file_priv,
279					  drm_radeon_kcmd_buffer_t *
280					  cmdbuf,
281					  unsigned int *cmdsz)
282{
283	u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
284	u32 offset, narrays;
285	int count, i, k;
286
287	count = ((*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16);
288	*cmdsz = 2 + count;
289
290	if ((*cmd & 0xc0000000) != RADEON_CP_PACKET3) {
291		DRM_ERROR("Not a type 3 packet\n");
292		return -EINVAL;
293	}
294
295	if (4 * *cmdsz > drm_buffer_unprocessed(cmdbuf->buffer)) {
296		DRM_ERROR("Packet size larger than size of data provided\n");
297		return -EINVAL;
298	}
299
300	switch (*cmd & 0xff00) {
301	/* XXX Are there old drivers needing other packets? */
302
303	case RADEON_3D_DRAW_IMMD:
304	case RADEON_3D_DRAW_VBUF:
305	case RADEON_3D_DRAW_INDX:
306	case RADEON_WAIT_FOR_IDLE:
307	case RADEON_CP_NOP:
308	case RADEON_3D_CLEAR_ZMASK:
309/*	case RADEON_CP_NEXT_CHAR:
310	case RADEON_CP_PLY_NEXTSCAN:
311	case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
312		/* these packets are safe */
313		break;
314
315	case RADEON_CP_3D_DRAW_IMMD_2:
316	case RADEON_CP_3D_DRAW_VBUF_2:
317	case RADEON_CP_3D_DRAW_INDX_2:
318	case RADEON_3D_CLEAR_HIZ:
319		/* safe but r200 only */
320		if (dev_priv->microcode_version != UCODE_R200) {
321			DRM_ERROR("Invalid 3d packet for r100-class chip\n");
322			return -EINVAL;
323		}
324		break;
325
326	case RADEON_3D_LOAD_VBPNTR:
327
328		if (count > 18) { /* 12 arrays max */
329			DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
330				  count);
331			return -EINVAL;
332		}
333
334		/* carefully check packet contents */
335		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
336
337		narrays = *cmd & ~0xc000;
338		k = 0;
339		i = 2;
340		while ((k < narrays) && (i < (count + 2))) {
341			i++;		/* skip attribute field */
342			cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
343			if (radeon_check_and_fixup_offset(dev_priv, file_priv,
344							  cmd)) {
345				DRM_ERROR
346				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
347				     k, i);
348				return -EINVAL;
349			}
350			k++;
351			i++;
352			if (k == narrays)
353				break;
354			/* have one more to process, they come in pairs */
355			cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
356
357			if (radeon_check_and_fixup_offset(dev_priv,
358							  file_priv, cmd))
359			{
360				DRM_ERROR
361				    ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
362				     k, i);
363				return -EINVAL;
364			}
365			k++;
366			i++;
367		}
368		/* do the counts match what we expect ? */
369		if ((k != narrays) || (i != (count + 2))) {
370			DRM_ERROR
371			    ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
372			      k, i, narrays, count + 1);
373			return -EINVAL;
374		}
375		break;
376
377	case RADEON_3D_RNDR_GEN_INDX_PRIM:
378		if (dev_priv->microcode_version != UCODE_R100) {
379			DRM_ERROR("Invalid 3d packet for r200-class chip\n");
380			return -EINVAL;
381		}
382
383		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
384		if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
385				DRM_ERROR("Invalid rndr_gen_indx offset\n");
386				return -EINVAL;
387		}
388		break;
389
390	case RADEON_CP_INDX_BUFFER:
391		if (dev_priv->microcode_version != UCODE_R200) {
392			DRM_ERROR("Invalid 3d packet for r100-class chip\n");
393			return -EINVAL;
394		}
395
396		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
397		if ((*cmd & 0x8000ffff) != 0x80000810) {
398			DRM_ERROR("Invalid indx_buffer reg address %08X\n", *cmd);
399			return -EINVAL;
400		}
401		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
402		if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
403			DRM_ERROR("Invalid indx_buffer offset is %08X\n", *cmd);
404			return -EINVAL;
405		}
406		break;
407
408	case RADEON_CNTL_HOSTDATA_BLT:
409	case RADEON_CNTL_PAINT_MULTI:
410	case RADEON_CNTL_BITBLT_MULTI:
411		/* MSB of opcode: next DWORD GUI_CNTL */
412		cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
413		if (*cmd & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
414			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
415			u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
416			offset = *cmd2 << 10;
417			if (radeon_check_and_fixup_offset
418			    (dev_priv, file_priv, &offset)) {
419				DRM_ERROR("Invalid first packet offset\n");
420				return -EINVAL;
421			}
422			*cmd2 = (*cmd2 & 0xffc00000) | offset >> 10;
423		}
424
425		if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
426		    (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
427			u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
428			offset = *cmd3 << 10;
429			if (radeon_check_and_fixup_offset
430			    (dev_priv, file_priv, &offset)) {
431				DRM_ERROR("Invalid second packet offset\n");
432				return -EINVAL;
433			}
434			*cmd3 = (*cmd3 & 0xffc00000) | offset >> 10;
435		}
436		break;
437
438	default:
439		DRM_ERROR("Invalid packet type %x\n", *cmd & 0xff00);
440		return -EINVAL;
441	}
442
443	return 0;
444}
445
446/* ================================================================
447 * CP hardware state programming functions
448 */
449
450static void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
451				  struct drm_clip_rect * box)
452{
453	RING_LOCALS;
454
455	DRM_DEBUG("   box:  x1=%d y1=%d  x2=%d y2=%d\n",
456		  box->x1, box->y1, box->x2, box->y2);
457
458	BEGIN_RING(4);
459	OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
460	OUT_RING((box->y1 << 16) | box->x1);
461	OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
462	OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
463	ADVANCE_RING();
464}
465
466/* Emit 1.1 state
467 */
468static int radeon_emit_state(drm_radeon_private_t * dev_priv,
469			     struct drm_file *file_priv,
470			     drm_radeon_context_regs_t * ctx,
471			     drm_radeon_texture_regs_t * tex,
472			     unsigned int dirty)
473{
474	RING_LOCALS;
475	DRM_DEBUG("dirty=0x%08x\n", dirty);
476
477	if (dirty & RADEON_UPLOAD_CONTEXT) {
478		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
479						  &ctx->rb3d_depthoffset)) {
480			DRM_ERROR("Invalid depth buffer offset\n");
481			return -EINVAL;
482		}
483
484		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
485						  &ctx->rb3d_coloroffset)) {
486			DRM_ERROR("Invalid depth buffer offset\n");
487			return -EINVAL;
488		}
489
490		BEGIN_RING(14);
491		OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
492		OUT_RING(ctx->pp_misc);
493		OUT_RING(ctx->pp_fog_color);
494		OUT_RING(ctx->re_solid_color);
495		OUT_RING(ctx->rb3d_blendcntl);
496		OUT_RING(ctx->rb3d_depthoffset);
497		OUT_RING(ctx->rb3d_depthpitch);
498		OUT_RING(ctx->rb3d_zstencilcntl);
499		OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
500		OUT_RING(ctx->pp_cntl);
501		OUT_RING(ctx->rb3d_cntl);
502		OUT_RING(ctx->rb3d_coloroffset);
503		OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
504		OUT_RING(ctx->rb3d_colorpitch);
505		ADVANCE_RING();
506	}
507
508	if (dirty & RADEON_UPLOAD_VERTFMT) {
509		BEGIN_RING(2);
510		OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
511		OUT_RING(ctx->se_coord_fmt);
512		ADVANCE_RING();
513	}
514
515	if (dirty & RADEON_UPLOAD_LINE) {
516		BEGIN_RING(5);
517		OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
518		OUT_RING(ctx->re_line_pattern);
519		OUT_RING(ctx->re_line_state);
520		OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
521		OUT_RING(ctx->se_line_width);
522		ADVANCE_RING();
523	}
524
525	if (dirty & RADEON_UPLOAD_BUMPMAP) {
526		BEGIN_RING(5);
527		OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
528		OUT_RING(ctx->pp_lum_matrix);
529		OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
530		OUT_RING(ctx->pp_rot_matrix_0);
531		OUT_RING(ctx->pp_rot_matrix_1);
532		ADVANCE_RING();
533	}
534
535	if (dirty & RADEON_UPLOAD_MASKS) {
536		BEGIN_RING(4);
537		OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
538		OUT_RING(ctx->rb3d_stencilrefmask);
539		OUT_RING(ctx->rb3d_ropcntl);
540		OUT_RING(ctx->rb3d_planemask);
541		ADVANCE_RING();
542	}
543
544	if (dirty & RADEON_UPLOAD_VIEWPORT) {
545		BEGIN_RING(7);
546		OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
547		OUT_RING(ctx->se_vport_xscale);
548		OUT_RING(ctx->se_vport_xoffset);
549		OUT_RING(ctx->se_vport_yscale);
550		OUT_RING(ctx->se_vport_yoffset);
551		OUT_RING(ctx->se_vport_zscale);
552		OUT_RING(ctx->se_vport_zoffset);
553		ADVANCE_RING();
554	}
555
556	if (dirty & RADEON_UPLOAD_SETUP) {
557		BEGIN_RING(4);
558		OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
559		OUT_RING(ctx->se_cntl);
560		OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
561		OUT_RING(ctx->se_cntl_status);
562		ADVANCE_RING();
563	}
564
565	if (dirty & RADEON_UPLOAD_MISC) {
566		BEGIN_RING(2);
567		OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
568		OUT_RING(ctx->re_misc);
569		ADVANCE_RING();
570	}
571
572	if (dirty & RADEON_UPLOAD_TEX0) {
573		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
574						  &tex[0].pp_txoffset)) {
575			DRM_ERROR("Invalid texture offset for unit 0\n");
576			return -EINVAL;
577		}
578
579		BEGIN_RING(9);
580		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
581		OUT_RING(tex[0].pp_txfilter);
582		OUT_RING(tex[0].pp_txformat);
583		OUT_RING(tex[0].pp_txoffset);
584		OUT_RING(tex[0].pp_txcblend);
585		OUT_RING(tex[0].pp_txablend);
586		OUT_RING(tex[0].pp_tfactor);
587		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
588		OUT_RING(tex[0].pp_border_color);
589		ADVANCE_RING();
590	}
591
592	if (dirty & RADEON_UPLOAD_TEX1) {
593		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
594						  &tex[1].pp_txoffset)) {
595			DRM_ERROR("Invalid texture offset for unit 1\n");
596			return -EINVAL;
597		}
598
599		BEGIN_RING(9);
600		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
601		OUT_RING(tex[1].pp_txfilter);
602		OUT_RING(tex[1].pp_txformat);
603		OUT_RING(tex[1].pp_txoffset);
604		OUT_RING(tex[1].pp_txcblend);
605		OUT_RING(tex[1].pp_txablend);
606		OUT_RING(tex[1].pp_tfactor);
607		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
608		OUT_RING(tex[1].pp_border_color);
609		ADVANCE_RING();
610	}
611
612	if (dirty & RADEON_UPLOAD_TEX2) {
613		if (radeon_check_and_fixup_offset(dev_priv, file_priv,
614						  &tex[2].pp_txoffset)) {
615			DRM_ERROR("Invalid texture offset for unit 2\n");
616			return -EINVAL;
617		}
618
619		BEGIN_RING(9);
620		OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
621		OUT_RING(tex[2].pp_txfilter);
622		OUT_RING(tex[2].pp_txformat);
623		OUT_RING(tex[2].pp_txoffset);
624		OUT_RING(tex[2].pp_txcblend);
625		OUT_RING(tex[2].pp_txablend);
626		OUT_RING(tex[2].pp_tfactor);
627		OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
628		OUT_RING(tex[2].pp_border_color);
629		ADVANCE_RING();
630	}
631
632	return 0;
633}
634
635/* Emit 1.2 state
636 */
637static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
638			      struct drm_file *file_priv,
639			      drm_radeon_state_t * state)
640{
641	RING_LOCALS;
642
643	if (state->dirty & RADEON_UPLOAD_ZBIAS) {
644		BEGIN_RING(3);
645		OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
646		OUT_RING(state->context2.se_zbias_factor);
647		OUT_RING(state->context2.se_zbias_constant);
648		ADVANCE_RING();
649	}
650
651	return radeon_emit_state(dev_priv, file_priv, &state->context,
652				 state->tex, state->dirty);
653}
654
655/* New (1.3) state mechanism.  3 commands (packet, scalar, vector) in
656 * 1.3 cmdbuffers allow all previous state to be updated as well as
657 * the tcl scalar and vector areas.
658 */
659static struct {
660	int start;
661	int len;
662	const char *name;
663} packet[RADEON_MAX_STATE_PACKETS] = {
664	{RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
665	{RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
666	{RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
667	{RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
668	{RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
669	{RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
670	{RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
671	{RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
672	{RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
673	{RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
674	{RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
675	{RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
676	{RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
677	{RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
678	{RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
679	{RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
680	{RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
681	{RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
682	{RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
683	{RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
684	{RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
685		    "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
686	{R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
687	{R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
688	{R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
689	{R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
690	{R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
691	{R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
692	{R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
693	{R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
694	{R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
695	{R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
696	{R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
697	{R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
698	{R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
699	{R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
700	{R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
701	{R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
702	{R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
703	{R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
704	{R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
705	{R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
706	{R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
707	{R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
708	{R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
709	{R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
710	{R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
711	{R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
712	{R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
713	{R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
714	{R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
715	 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
716	{R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
717	{R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
718	{R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
719	{R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
720	{R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
721	{R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
722	{R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
723	{R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
724	{R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
725	{R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
726	{R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
727		    "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
728	{R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"},	/* 61 */
729	{R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
730	{R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
731	{R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
732	{R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
733	{R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
734	{R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
735	{R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
736	{R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
737	{R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
738	{R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
739	{R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
740	{RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
741	{RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
742	{RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
743	{R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
744	{R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
745	{RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
746	{RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
747	{RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
748	{RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
749	{RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
750	{RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
751	{R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
752	{R200_PP_AFS_0, 32, "R200_PP_AFS_0"},     /* 85 */
753	{R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
754	{R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
755	{R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
756	{R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
757	{R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
758	{R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
759	{R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
760	{R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
761	{R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
762};
763
764/* ================================================================
765 * Performance monitoring functions
766 */
767
768static void radeon_clear_box(drm_radeon_private_t * dev_priv,
769			     struct drm_radeon_master_private *master_priv,
770			     int x, int y, int w, int h, int r, int g, int b)
771{
772	u32 color;
773	RING_LOCALS;
774
775	x += master_priv->sarea_priv->boxes[0].x1;
776	y += master_priv->sarea_priv->boxes[0].y1;
777
778	switch (dev_priv->color_fmt) {
779	case RADEON_COLOR_FORMAT_RGB565:
780		color = (((r & 0xf8) << 8) |
781			 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
782		break;
783	case RADEON_COLOR_FORMAT_ARGB8888:
784	default:
785		color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
786		break;
787	}
788
789	BEGIN_RING(4);
790	RADEON_WAIT_UNTIL_3D_IDLE();
791	OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
792	OUT_RING(0xffffffff);
793	ADVANCE_RING();
794
795	BEGIN_RING(6);
796
797	OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
798	OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
799		 RADEON_GMC_BRUSH_SOLID_COLOR |
800		 (dev_priv->color_fmt << 8) |
801		 RADEON_GMC_SRC_DATATYPE_COLOR |
802		 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
803
804	if (master_priv->sarea_priv->pfCurrentPage == 1) {
805		OUT_RING(dev_priv->front_pitch_offset);
806	} else {
807		OUT_RING(dev_priv->back_pitch_offset);
808	}
809
810	OUT_RING(color);
811
812	OUT_RING((x << 16) | y);
813	OUT_RING((w << 16) | h);
814
815	ADVANCE_RING();
816}
817
818static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv, struct drm_radeon_master_private *master_priv)
819{
820	/* Collapse various things into a wait flag -- trying to
821	 * guess if userspase slept -- better just to have them tell us.
822	 */
823	if (dev_priv->stats.last_frame_reads > 1 ||
824	    dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {
825		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
826	}
827
828	if (dev_priv->stats.freelist_loops) {
829		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
830	}
831
832	/* Purple box for page flipping
833	 */
834	if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
835		radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255);
836
837	/* Red box if we have to wait for idle at any point
838	 */
839	if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
840		radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0);
841
842	/* Blue box: lost context?
843	 */
844
845	/* Yellow box for texture swaps
846	 */
847	if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
848		radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0);
849
850	/* Green box if hardware never idles (as far as we can tell)
851	 */
852	if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
853		radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0);
854
855	/* Draw bars indicating number of buffers allocated
856	 * (not a great measure, easily confused)
857	 */
858	if (dev_priv->stats.requested_bufs) {
859		if (dev_priv->stats.requested_bufs > 100)
860			dev_priv->stats.requested_bufs = 100;
861
862		radeon_clear_box(dev_priv, master_priv, 4, 16,
863				 dev_priv->stats.requested_bufs, 4,
864				 196, 128, 128);
865	}
866
867	memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
868
869}
870
871/* ================================================================
872 * CP command dispatch functions
873 */
874
875static void radeon_cp_dispatch_clear(struct drm_device * dev,
876				     struct drm_master *master,
877				     drm_radeon_clear_t * clear,
878				     drm_radeon_clear_rect_t * depth_boxes)
879{
880	drm_radeon_private_t *dev_priv = dev->dev_private;
881	struct drm_radeon_master_private *master_priv = master->driver_priv;
882	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
883	drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
884	int nbox = sarea_priv->nbox;
885	struct drm_clip_rect *pbox = sarea_priv->boxes;
886	unsigned int flags = clear->flags;
887	u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
888	int i;
889	RING_LOCALS;
890	DRM_DEBUG("flags = 0x%x\n", flags);
891
892	dev_priv->stats.clears++;
893
894	if (sarea_priv->pfCurrentPage == 1) {
895		unsigned int tmp = flags;
896
897		flags &= ~(RADEON_FRONT | RADEON_BACK);
898		if (tmp & RADEON_FRONT)
899			flags |= RADEON_BACK;
900		if (tmp & RADEON_BACK)
901			flags |= RADEON_FRONT;
902	}
903	if (flags & (RADEON_DEPTH|RADEON_STENCIL)) {
904		if (!dev_priv->have_z_offset) {
905			DRM_ERROR("radeon: illegal depth clear request. Buggy mesa detected - please update.\n");
906			flags &= ~(RADEON_DEPTH | RADEON_STENCIL);
907		}
908	}
909
910	if (flags & (RADEON_FRONT | RADEON_BACK)) {
911
912		BEGIN_RING(4);
913
914		/* Ensure the 3D stream is idle before doing a
915		 * 2D fill to clear the front or back buffer.
916		 */
917		RADEON_WAIT_UNTIL_3D_IDLE();
918
919		OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
920		OUT_RING(clear->color_mask);
921
922		ADVANCE_RING();
923
924		/* Make sure we restore the 3D state next time.
925		 */
926		sarea_priv->ctx_owner = 0;
927
928		for (i = 0; i < nbox; i++) {
929			int x = pbox[i].x1;
930			int y = pbox[i].y1;
931			int w = pbox[i].x2 - x;
932			int h = pbox[i].y2 - y;
933
934			DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
935				  x, y, w, h, flags);
936
937			if (flags & RADEON_FRONT) {
938				BEGIN_RING(6);
939
940				OUT_RING(CP_PACKET3
941					 (RADEON_CNTL_PAINT_MULTI, 4));
942				OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
943					 RADEON_GMC_BRUSH_SOLID_COLOR |
944					 (dev_priv->
945					  color_fmt << 8) |
946					 RADEON_GMC_SRC_DATATYPE_COLOR |
947					 RADEON_ROP3_P |
948					 RADEON_GMC_CLR_CMP_CNTL_DIS);
949
950				OUT_RING(dev_priv->front_pitch_offset);
951				OUT_RING(clear->clear_color);
952
953				OUT_RING((x << 16) | y);
954				OUT_RING((w << 16) | h);
955
956				ADVANCE_RING();
957			}
958
959			if (flags & RADEON_BACK) {
960				BEGIN_RING(6);
961
962				OUT_RING(CP_PACKET3
963					 (RADEON_CNTL_PAINT_MULTI, 4));
964				OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
965					 RADEON_GMC_BRUSH_SOLID_COLOR |
966					 (dev_priv->
967					  color_fmt << 8) |
968					 RADEON_GMC_SRC_DATATYPE_COLOR |
969					 RADEON_ROP3_P |
970					 RADEON_GMC_CLR_CMP_CNTL_DIS);
971
972				OUT_RING(dev_priv->back_pitch_offset);
973				OUT_RING(clear->clear_color);
974
975				OUT_RING((x << 16) | y);
976				OUT_RING((w << 16) | h);
977
978				ADVANCE_RING();
979			}
980		}
981	}
982
983	/* hyper z clear */
984	/* no docs available, based on reverse engineering by Stephane Marchesin */
985	if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
986	    && (flags & RADEON_CLEAR_FASTZ)) {
987
988		int i;
989		int depthpixperline =
990		    dev_priv->depth_fmt ==
991		    RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
992						       2) : (dev_priv->
993							     depth_pitch / 4);
994
995		u32 clearmask;
996
997		u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
998		    ((clear->depth_mask & 0xff) << 24);
999
1000		/* Make sure we restore the 3D state next time.
1001		 * we haven't touched any "normal" state - still need this?
1002		 */
1003		sarea_priv->ctx_owner = 0;
1004
1005		if ((dev_priv->flags & RADEON_HAS_HIERZ)
1006		    && (flags & RADEON_USE_HIERZ)) {
1007			/* FIXME : reverse engineer that for Rx00 cards */
1008			/* FIXME : the mask supposedly contains low-res z values. So can't set
1009			   just to the max (0xff? or actually 0x3fff?), need to take z clear
1010			   value into account? */
1011			/* pattern seems to work for r100, though get slight
1012			   rendering errors with glxgears. If hierz is not enabled for r100,
1013			   only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
1014			   other ones are ignored, and the same clear mask can be used. That's
1015			   very different behaviour than R200 which needs different clear mask
1016			   and different number of tiles to clear if hierz is enabled or not !?!
1017			 */
1018			clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
1019		} else {
1020			/* clear mask : chooses the clearing pattern.
1021			   rv250: could be used to clear only parts of macrotiles
1022			   (but that would get really complicated...)?
1023			   bit 0 and 1 (either or both of them ?!?!) are used to
1024			   not clear tile (or maybe one of the bits indicates if the tile is
1025			   compressed or not), bit 2 and 3 to not clear tile 1,...,.
1026			   Pattern is as follows:
1027			   | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
1028			   bits -------------------------------------------------
1029			   | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
1030			   rv100: clearmask covers 2x8 4x1 tiles, but one clear still
1031			   covers 256 pixels ?!?
1032			 */
1033			clearmask = 0x0;
1034		}
1035
1036		BEGIN_RING(8);
1037		RADEON_WAIT_UNTIL_2D_IDLE();
1038		OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
1039			     tempRB3D_DEPTHCLEARVALUE);
1040		/* what offset is this exactly ? */
1041		OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
1042		/* need ctlstat, otherwise get some strange black flickering */
1043		OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
1044			     RADEON_RB3D_ZC_FLUSH_ALL);
1045		ADVANCE_RING();
1046
1047		for (i = 0; i < nbox; i++) {
1048			int tileoffset, nrtilesx, nrtilesy, j;
1049			/* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
1050			if ((dev_priv->flags & RADEON_HAS_HIERZ)
1051			    && !(dev_priv->microcode_version == UCODE_R200)) {
1052				/* FIXME : figure this out for r200 (when hierz is enabled). Or
1053				   maybe r200 actually doesn't need to put the low-res z value into
1054				   the tile cache like r100, but just needs to clear the hi-level z-buffer?
1055				   Works for R100, both with hierz and without.
1056				   R100 seems to operate on 2x1 8x8 tiles, but...
1057				   odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
1058				   problematic with resolutions which are not 64 pix aligned? */
1059				tileoffset =
1060				    ((pbox[i].y1 >> 3) * depthpixperline +
1061				     pbox[i].x1) >> 6;
1062				nrtilesx =
1063				    ((pbox[i].x2 & ~63) -
1064				     (pbox[i].x1 & ~63)) >> 4;
1065				nrtilesy =
1066				    (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1067				for (j = 0; j <= nrtilesy; j++) {
1068					BEGIN_RING(4);
1069					OUT_RING(CP_PACKET3
1070						 (RADEON_3D_CLEAR_ZMASK, 2));
1071					/* first tile */
1072					OUT_RING(tileoffset * 8);
1073					/* the number of tiles to clear */
1074					OUT_RING(nrtilesx + 4);
1075					/* clear mask : chooses the clearing pattern. */
1076					OUT_RING(clearmask);
1077					ADVANCE_RING();
1078					tileoffset += depthpixperline >> 6;
1079				}
1080			} else if (dev_priv->microcode_version == UCODE_R200) {
1081				/* works for rv250. */
1082				/* find first macro tile (8x2 4x4 z-pixels on rv250) */
1083				tileoffset =
1084				    ((pbox[i].y1 >> 3) * depthpixperline +
1085				     pbox[i].x1) >> 5;
1086				nrtilesx =
1087				    (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
1088				nrtilesy =
1089				    (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1090				for (j = 0; j <= nrtilesy; j++) {
1091					BEGIN_RING(4);
1092					OUT_RING(CP_PACKET3
1093						 (RADEON_3D_CLEAR_ZMASK, 2));
1094					/* first tile */
1095					/* judging by the first tile offset needed, could possibly
1096					   directly address/clear 4x4 tiles instead of 8x2 * 4x4
1097					   macro tiles, though would still need clear mask for
1098					   right/bottom if truly 4x4 granularity is desired ? */
1099					OUT_RING(tileoffset * 16);
1100					/* the number of tiles to clear */
1101					OUT_RING(nrtilesx + 1);
1102					/* clear mask : chooses the clearing pattern. */
1103					OUT_RING(clearmask);
1104					ADVANCE_RING();
1105					tileoffset += depthpixperline >> 5;
1106				}
1107			} else {	/* rv 100 */
1108				/* rv100 might not need 64 pix alignment, who knows */
1109				/* offsets are, hmm, weird */
1110				tileoffset =
1111				    ((pbox[i].y1 >> 4) * depthpixperline +
1112				     pbox[i].x1) >> 6;
1113				nrtilesx =
1114				    ((pbox[i].x2 & ~63) -
1115				     (pbox[i].x1 & ~63)) >> 4;
1116				nrtilesy =
1117				    (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
1118				for (j = 0; j <= nrtilesy; j++) {
1119					BEGIN_RING(4);
1120					OUT_RING(CP_PACKET3
1121						 (RADEON_3D_CLEAR_ZMASK, 2));
1122					OUT_RING(tileoffset * 128);
1123					/* the number of tiles to clear */
1124					OUT_RING(nrtilesx + 4);
1125					/* clear mask : chooses the clearing pattern. */
1126					OUT_RING(clearmask);
1127					ADVANCE_RING();
1128					tileoffset += depthpixperline >> 6;
1129				}
1130			}
1131		}
1132
1133		/* TODO don't always clear all hi-level z tiles */
1134		if ((dev_priv->flags & RADEON_HAS_HIERZ)
1135		    && (dev_priv->microcode_version == UCODE_R200)
1136		    && (flags & RADEON_USE_HIERZ))
1137			/* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
1138			/* FIXME : the mask supposedly contains low-res z values. So can't set
1139			   just to the max (0xff? or actually 0x3fff?), need to take z clear
1140			   value into account? */
1141		{
1142			BEGIN_RING(4);
1143			OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
1144			OUT_RING(0x0);	/* First tile */
1145			OUT_RING(0x3cc0);
1146			OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1147			ADVANCE_RING();
1148		}
1149	}
1150
1151	/* We have to clear the depth and/or stencil buffers by
1152	 * rendering a quad into just those buffers.  Thus, we have to
1153	 * make sure the 3D engine is configured correctly.
1154	 */
1155	else if ((dev_priv->microcode_version == UCODE_R200) &&
1156		(flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1157
1158		int tempPP_CNTL;
1159		int tempRE_CNTL;
1160		int tempRB3D_CNTL;
1161		int tempRB3D_ZSTENCILCNTL;
1162		int tempRB3D_STENCILREFMASK;
1163		int tempRB3D_PLANEMASK;
1164		int tempSE_CNTL;
1165		int tempSE_VTE_CNTL;
1166		int tempSE_VTX_FMT_0;
1167		int tempSE_VTX_FMT_1;
1168		int tempSE_VAP_CNTL;
1169		int tempRE_AUX_SCISSOR_CNTL;
1170
1171		tempPP_CNTL = 0;
1172		tempRE_CNTL = 0;
1173
1174		tempRB3D_CNTL = depth_clear->rb3d_cntl;
1175
1176		tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1177		tempRB3D_STENCILREFMASK = 0x0;
1178
1179		tempSE_CNTL = depth_clear->se_cntl;
1180
1181		/* Disable TCL */
1182
1183		tempSE_VAP_CNTL = (	/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK |  */
1184					  (0x9 <<
1185					   SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
1186
1187		tempRB3D_PLANEMASK = 0x0;
1188
1189		tempRE_AUX_SCISSOR_CNTL = 0x0;
1190
1191		tempSE_VTE_CNTL =
1192		    SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
1193
1194		/* Vertex format (X, Y, Z, W) */
1195		tempSE_VTX_FMT_0 =
1196		    SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
1197		    SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
1198		tempSE_VTX_FMT_1 = 0x0;
1199
1200		/*
1201		 * Depth buffer specific enables
1202		 */
1203		if (flags & RADEON_DEPTH) {
1204			/* Enable depth buffer */
1205			tempRB3D_CNTL |= RADEON_Z_ENABLE;
1206		} else {
1207			/* Disable depth buffer */
1208			tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
1209		}
1210
1211		/*
1212		 * Stencil buffer specific enables
1213		 */
1214		if (flags & RADEON_STENCIL) {
1215			tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
1216			tempRB3D_STENCILREFMASK = clear->depth_mask;
1217		} else {
1218			tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
1219			tempRB3D_STENCILREFMASK = 0x00000000;
1220		}
1221
1222		if (flags & RADEON_USE_COMP_ZBUF) {
1223			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1224			    RADEON_Z_DECOMPRESSION_ENABLE;
1225		}
1226		if (flags & RADEON_USE_HIERZ) {
1227			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1228		}
1229
1230		BEGIN_RING(26);
1231		RADEON_WAIT_UNTIL_2D_IDLE();
1232
1233		OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
1234		OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
1235		OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
1236		OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1237		OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
1238			     tempRB3D_STENCILREFMASK);
1239		OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
1240		OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
1241		OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
1242		OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
1243		OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
1244		OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
1245		OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
1246		ADVANCE_RING();
1247
1248		/* Make sure we restore the 3D state next time.
1249		 */
1250		sarea_priv->ctx_owner = 0;
1251
1252		for (i = 0; i < nbox; i++) {
1253
1254			/* Funny that this should be required --
1255			 *  sets top-left?
1256			 */
1257			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1258
1259			BEGIN_RING(14);
1260			OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
1261			OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1262				  RADEON_PRIM_WALK_RING |
1263				  (3 << RADEON_NUM_VERTICES_SHIFT)));
1264			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1265			OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1266			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1267			OUT_RING(0x3f800000);
1268			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1269			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1270			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1271			OUT_RING(0x3f800000);
1272			OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1273			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1274			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1275			OUT_RING(0x3f800000);
1276			ADVANCE_RING();
1277		}
1278	} else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1279
1280		int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1281
1282		rb3d_cntl = depth_clear->rb3d_cntl;
1283
1284		if (flags & RADEON_DEPTH) {
1285			rb3d_cntl |= RADEON_Z_ENABLE;
1286		} else {
1287			rb3d_cntl &= ~RADEON_Z_ENABLE;
1288		}
1289
1290		if (flags & RADEON_STENCIL) {
1291			rb3d_cntl |= RADEON_STENCIL_ENABLE;
1292			rb3d_stencilrefmask = clear->depth_mask;	/* misnamed field */
1293		} else {
1294			rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
1295			rb3d_stencilrefmask = 0x00000000;
1296		}
1297
1298		if (flags & RADEON_USE_COMP_ZBUF) {
1299			tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1300			    RADEON_Z_DECOMPRESSION_ENABLE;
1301		}
1302		if (flags & RADEON_USE_HIERZ) {
1303			tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1304		}
1305
1306		BEGIN_RING(13);
1307		RADEON_WAIT_UNTIL_2D_IDLE();
1308
1309		OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
1310		OUT_RING(0x00000000);
1311		OUT_RING(rb3d_cntl);
1312
1313		OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1314		OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
1315		OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
1316		OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
1317		ADVANCE_RING();
1318
1319		/* Make sure we restore the 3D state next time.
1320		 */
1321		sarea_priv->ctx_owner = 0;
1322
1323		for (i = 0; i < nbox; i++) {
1324
1325			/* Funny that this should be required --
1326			 *  sets top-left?
1327			 */
1328			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1329
1330			BEGIN_RING(15);
1331
1332			OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
1333			OUT_RING(RADEON_VTX_Z_PRESENT |
1334				 RADEON_VTX_PKCOLOR_PRESENT);
1335			OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1336				  RADEON_PRIM_WALK_RING |
1337				  RADEON_MAOS_ENABLE |
1338				  RADEON_VTX_FMT_RADEON_MODE |
1339				  (3 << RADEON_NUM_VERTICES_SHIFT)));
1340
1341			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1342			OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1343			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1344			OUT_RING(0x0);
1345
1346			OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1347			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1348			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1349			OUT_RING(0x0);
1350
1351			OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1352			OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1353			OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1354			OUT_RING(0x0);
1355
1356			ADVANCE_RING();
1357		}
1358	}
1359
1360	/* Increment the clear counter.  The client-side 3D driver must
1361	 * wait on this value before performing the clear ioctl.  We
1362	 * need this because the card's so damned fast...
1363	 */
1364	sarea_priv->last_clear++;
1365
1366	BEGIN_RING(4);
1367
1368	RADEON_CLEAR_AGE(sarea_priv->last_clear);
1369	RADEON_WAIT_UNTIL_IDLE();
1370
1371	ADVANCE_RING();
1372}
1373
1374static void radeon_cp_dispatch_swap(struct drm_device *dev, struct drm_master *master)
1375{
1376	drm_radeon_private_t *dev_priv = dev->dev_private;
1377	struct drm_radeon_master_private *master_priv = master->driver_priv;
1378	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1379	int nbox = sarea_priv->nbox;
1380	struct drm_clip_rect *pbox = sarea_priv->boxes;
1381	int i;
1382	RING_LOCALS;
1383	DRM_DEBUG("\n");
1384
1385	/* Do some trivial performance monitoring...
1386	 */
1387	if (dev_priv->do_boxes)
1388		radeon_cp_performance_boxes(dev_priv, master_priv);
1389
1390	/* Wait for the 3D stream to idle before dispatching the bitblt.
1391	 * This will prevent data corruption between the two streams.
1392	 */
1393	BEGIN_RING(2);
1394
1395	RADEON_WAIT_UNTIL_3D_IDLE();
1396
1397	ADVANCE_RING();
1398
1399	for (i = 0; i < nbox; i++) {
1400		int x = pbox[i].x1;
1401		int y = pbox[i].y1;
1402		int w = pbox[i].x2 - x;
1403		int h = pbox[i].y2 - y;
1404
1405		DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
1406
1407		BEGIN_RING(9);
1408
1409		OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
1410		OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1411			 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1412			 RADEON_GMC_BRUSH_NONE |
1413			 (dev_priv->color_fmt << 8) |
1414			 RADEON_GMC_SRC_DATATYPE_COLOR |
1415			 RADEON_ROP3_S |
1416			 RADEON_DP_SRC_SOURCE_MEMORY |
1417			 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1418
1419		/* Make this work even if front & back are flipped:
1420		 */
1421		OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
1422		if (sarea_priv->pfCurrentPage == 0) {
1423			OUT_RING(dev_priv->back_pitch_offset);
1424			OUT_RING(dev_priv->front_pitch_offset);
1425		} else {
1426			OUT_RING(dev_priv->front_pitch_offset);
1427			OUT_RING(dev_priv->back_pitch_offset);
1428		}
1429
1430		OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
1431		OUT_RING((x << 16) | y);
1432		OUT_RING((x << 16) | y);
1433		OUT_RING((w << 16) | h);
1434
1435		ADVANCE_RING();
1436	}
1437
1438	/* Increment the frame counter.  The client-side 3D driver must
1439	 * throttle the framerate by waiting for this value before
1440	 * performing the swapbuffer ioctl.
1441	 */
1442	sarea_priv->last_frame++;
1443
1444	BEGIN_RING(4);
1445
1446	RADEON_FRAME_AGE(sarea_priv->last_frame);
1447	RADEON_WAIT_UNTIL_2D_IDLE();
1448
1449	ADVANCE_RING();
1450}
1451
1452void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master)
1453{
1454	drm_radeon_private_t *dev_priv = dev->dev_private;
1455	struct drm_radeon_master_private *master_priv = master->driver_priv;
1456	struct drm_sarea *sarea = (struct drm_sarea *)master_priv->sarea->handle;
1457	int offset = (master_priv->sarea_priv->pfCurrentPage == 1)
1458	    ? dev_priv->front_offset : dev_priv->back_offset;
1459	RING_LOCALS;
1460	DRM_DEBUG("pfCurrentPage=%d\n",
1461		  master_priv->sarea_priv->pfCurrentPage);
1462
1463	/* Do some trivial performance monitoring...
1464	 */
1465	if (dev_priv->do_boxes) {
1466		dev_priv->stats.boxes |= RADEON_BOX_FLIP;
1467		radeon_cp_performance_boxes(dev_priv, master_priv);
1468	}
1469
1470	/* Update the frame offsets for both CRTCs
1471	 */
1472	BEGIN_RING(6);
1473
1474	RADEON_WAIT_UNTIL_3D_IDLE();
1475	OUT_RING_REG(RADEON_CRTC_OFFSET,
1476		     ((sarea->frame.y * dev_priv->front_pitch +
1477		       sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
1478		     + offset);
1479	OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base
1480		     + offset);
1481
1482	ADVANCE_RING();
1483
1484	/* Increment the frame counter.  The client-side 3D driver must
1485	 * throttle the framerate by waiting for this value before
1486	 * performing the swapbuffer ioctl.
1487	 */
1488	master_priv->sarea_priv->last_frame++;
1489	master_priv->sarea_priv->pfCurrentPage =
1490		1 - master_priv->sarea_priv->pfCurrentPage;
1491
1492	BEGIN_RING(2);
1493
1494	RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame);
1495
1496	ADVANCE_RING();
1497}
1498
1499static int bad_prim_vertex_nr(int primitive, int nr)
1500{
1501	switch (primitive & RADEON_PRIM_TYPE_MASK) {
1502	case RADEON_PRIM_TYPE_NONE:
1503	case RADEON_PRIM_TYPE_POINT:
1504		return nr < 1;
1505	case RADEON_PRIM_TYPE_LINE:
1506		return (nr & 1) || nr == 0;
1507	case RADEON_PRIM_TYPE_LINE_STRIP:
1508		return nr < 2;
1509	case RADEON_PRIM_TYPE_TRI_LIST:
1510	case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
1511	case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
1512	case RADEON_PRIM_TYPE_RECT_LIST:
1513		return nr % 3 || nr == 0;
1514	case RADEON_PRIM_TYPE_TRI_FAN:
1515	case RADEON_PRIM_TYPE_TRI_STRIP:
1516		return nr < 3;
1517	default:
1518		return 1;
1519	}
1520}
1521
1522typedef struct {
1523	unsigned int start;
1524	unsigned int finish;
1525	unsigned int prim;
1526	unsigned int numverts;
1527	unsigned int offset;
1528	unsigned int vc_format;
1529} drm_radeon_tcl_prim_t;
1530
1531static void radeon_cp_dispatch_vertex(struct drm_device * dev,
1532				      struct drm_file *file_priv,
1533				      struct drm_buf * buf,
1534				      drm_radeon_tcl_prim_t * prim)
1535{
1536	drm_radeon_private_t *dev_priv = dev->dev_private;
1537	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
1538	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1539	int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
1540	int numverts = (int)prim->numverts;
1541	int nbox = sarea_priv->nbox;
1542	int i = 0;
1543	RING_LOCALS;
1544
1545	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1546		  prim->prim,
1547		  prim->vc_format, prim->start, prim->finish, prim->numverts);
1548
1549	if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
1550		DRM_ERROR("bad prim %x numverts %d\n",
1551			  prim->prim, prim->numverts);
1552		return;
1553	}
1554
1555	do {
1556		/* Emit the next cliprect */
1557		if (i < nbox) {
1558			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1559		}
1560
1561		/* Emit the vertex buffer rendering commands */
1562		BEGIN_RING(5);
1563
1564		OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
1565		OUT_RING(offset);
1566		OUT_RING(numverts);
1567		OUT_RING(prim->vc_format);
1568		OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
1569			 RADEON_COLOR_ORDER_RGBA |
1570			 RADEON_VTX_FMT_RADEON_MODE |
1571			 (numverts << RADEON_NUM_VERTICES_SHIFT));
1572
1573		ADVANCE_RING();
1574
1575		i++;
1576	} while (i < nbox);
1577}
1578
1579void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
1580{
1581	drm_radeon_private_t *dev_priv = dev->dev_private;
1582	struct drm_radeon_master_private *master_priv = master->driver_priv;
1583	drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1584	RING_LOCALS;
1585
1586	buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
1587
1588	/* Emit the vertex buffer age */
1589	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
1590		BEGIN_RING(3);
1591		R600_DISPATCH_AGE(buf_priv->age);
1592		ADVANCE_RING();
1593	} else {
1594		BEGIN_RING(2);
1595		RADEON_DISPATCH_AGE(buf_priv->age);
1596		ADVANCE_RING();
1597	}
1598
1599	buf->pending = 1;
1600	buf->used = 0;
1601}
1602
1603static void radeon_cp_dispatch_indirect(struct drm_device * dev,
1604					struct drm_buf * buf, int start, int end)
1605{
1606	drm_radeon_private_t *dev_priv = dev->dev_private;
1607	RING_LOCALS;
1608	DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
1609
1610	if (start != end) {
1611		int offset = (dev_priv->gart_buffers_offset
1612			      + buf->offset + start);
1613		int dwords = (end - start + 3) / sizeof(u32);
1614
1615		/* Indirect buffer data must be an even number of
1616		 * dwords, so if we've been given an odd number we must
1617		 * pad the data with a Type-2 CP packet.
1618		 */
1619		if (dwords & 1) {
1620			u32 *data = (u32 *)
1621			    ((char *)dev->agp_buffer_map->handle
1622			     + buf->offset + start);
1623			data[dwords++] = RADEON_CP_PACKET2;
1624		}
1625
1626		/* Fire off the indirect buffer */
1627		BEGIN_RING(3);
1628
1629		OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
1630		OUT_RING(offset);
1631		OUT_RING(dwords);
1632
1633		ADVANCE_RING();
1634	}
1635}
1636
1637static void radeon_cp_dispatch_indices(struct drm_device *dev,
1638				       struct drm_master *master,
1639				       struct drm_buf * elt_buf,
1640				       drm_radeon_tcl_prim_t * prim)
1641{
1642	drm_radeon_private_t *dev_priv = dev->dev_private;
1643	struct drm_radeon_master_private *master_priv = master->driver_priv;
1644	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1645	int offset = dev_priv->gart_buffers_offset + prim->offset;
1646	u32 *data;
1647	int dwords;
1648	int i = 0;
1649	int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
1650	int count = (prim->finish - start) / sizeof(u16);
1651	int nbox = sarea_priv->nbox;
1652
1653	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1654		  prim->prim,
1655		  prim->vc_format,
1656		  prim->start, prim->finish, prim->offset, prim->numverts);
1657
1658	if (bad_prim_vertex_nr(prim->prim, count)) {
1659		DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
1660		return;
1661	}
1662
1663	if (start >= prim->finish || (prim->start & 0x7)) {
1664		DRM_ERROR("buffer prim %d\n", prim->prim);
1665		return;
1666	}
1667
1668	dwords = (prim->finish - prim->start + 3) / sizeof(u32);
1669
1670	data = (u32 *) ((char *)dev->agp_buffer_map->handle +
1671			elt_buf->offset + prim->start);
1672
1673	data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
1674	data[1] = offset;
1675	data[2] = prim->numverts;
1676	data[3] = prim->vc_format;
1677	data[4] = (prim->prim |
1678		   RADEON_PRIM_WALK_IND |
1679		   RADEON_COLOR_ORDER_RGBA |
1680		   RADEON_VTX_FMT_RADEON_MODE |
1681		   (count << RADEON_NUM_VERTICES_SHIFT));
1682
1683	do {
1684		if (i < nbox)
1685			radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1686
1687		radeon_cp_dispatch_indirect(dev, elt_buf,
1688					    prim->start, prim->finish);
1689
1690		i++;
1691	} while (i < nbox);
1692
1693}
1694
1695#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1696
1697static int radeon_cp_dispatch_texture(struct drm_device * dev,
1698				      struct drm_file *file_priv,
1699				      drm_radeon_texture_t * tex,
1700				      drm_radeon_tex_image_t * image)
1701{
1702	drm_radeon_private_t *dev_priv = dev->dev_private;
1703	struct drm_buf *buf;
1704	u32 format;
1705	u32 *buffer;
1706	const u8 __user *data;
1707	int size, dwords, tex_width, blit_width, spitch;
1708	u32 height;
1709	int i;
1710	u32 texpitch, microtile;
1711	u32 offset, byte_offset;
1712	RING_LOCALS;
1713
1714	if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
1715		DRM_ERROR("Invalid destination offset\n");
1716		return -EINVAL;
1717	}
1718
1719	dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
1720
1721	/* Flush the pixel cache.  This ensures no pixel data gets mixed
1722	 * up with the texture data from the host data blit, otherwise
1723	 * part of the texture image may be corrupted.
1724	 */
1725	BEGIN_RING(4);
1726	RADEON_FLUSH_CACHE();
1727	RADEON_WAIT_UNTIL_IDLE();
1728	ADVANCE_RING();
1729
1730	/* The compiler won't optimize away a division by a variable,
1731	 * even if the only legal values are powers of two.  Thus, we'll
1732	 * use a shift instead.
1733	 */
1734	switch (tex->format) {
1735	case RADEON_TXFORMAT_ARGB8888:
1736	case RADEON_TXFORMAT_RGBA8888:
1737		format = RADEON_COLOR_FORMAT_ARGB8888;
1738		tex_width = tex->width * 4;
1739		blit_width = image->width * 4;
1740		break;
1741	case RADEON_TXFORMAT_AI88:
1742	case RADEON_TXFORMAT_ARGB1555:
1743	case RADEON_TXFORMAT_RGB565:
1744	case RADEON_TXFORMAT_ARGB4444:
1745	case RADEON_TXFORMAT_VYUY422:
1746	case RADEON_TXFORMAT_YVYU422:
1747		format = RADEON_COLOR_FORMAT_RGB565;
1748		tex_width = tex->width * 2;
1749		blit_width = image->width * 2;
1750		break;
1751	case RADEON_TXFORMAT_I8:
1752	case RADEON_TXFORMAT_RGB332:
1753		format = RADEON_COLOR_FORMAT_CI8;
1754		tex_width = tex->width * 1;
1755		blit_width = image->width * 1;
1756		break;
1757	default:
1758		DRM_ERROR("invalid texture format %d\n", tex->format);
1759		return -EINVAL;
1760	}
1761	spitch = blit_width >> 6;
1762	if (spitch == 0 && image->height > 1)
1763		return -EINVAL;
1764
1765	texpitch = tex->pitch;
1766	if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
1767		microtile = 1;
1768		if (tex_width < 64) {
1769			texpitch &= ~(RADEON_DST_TILE_MICRO >> 22);
1770			/* we got tiled coordinates, untile them */
1771			image->x *= 2;
1772		}
1773	} else
1774		microtile = 0;
1775
1776	/* this might fail for zero-sized uploads - are those illegal? */
1777	if (!radeon_check_offset(dev_priv, tex->offset + image->height *
1778				blit_width - 1)) {
1779		DRM_ERROR("Invalid final destination offset\n");
1780		return -EINVAL;
1781	}
1782
1783	DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
1784
1785	do {
1786		DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%u y=%u w=%u h=%u\n",
1787			  tex->offset >> 10, tex->pitch, tex->format,
1788			  image->x, image->y, image->width, image->height);
1789
1790		/* Make a copy of some parameters in case we have to
1791		 * update them for a multi-pass texture blit.
1792		 */
1793		height = image->height;
1794		data = (const u8 __user *)image->data;
1795
1796		size = height * blit_width;
1797
1798		if (size > RADEON_MAX_TEXTURE_SIZE) {
1799			height = RADEON_MAX_TEXTURE_SIZE / blit_width;
1800			size = height * blit_width;
1801		} else if (size < 4 && size > 0) {
1802			size = 4;
1803		} else if (size == 0) {
1804			return 0;
1805		}
1806
1807		buf = radeon_freelist_get(dev);
1808		if (0 && !buf) {
1809			radeon_do_cp_idle(dev_priv);
1810			buf = radeon_freelist_get(dev);
1811		}
1812		if (!buf) {
1813			DRM_DEBUG("EAGAIN\n");
1814			if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
1815				return -EFAULT;
1816			return -EAGAIN;
1817		}
1818
1819		/* Dispatch the indirect buffer.
1820		 */
1821		buffer =
1822		    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
1823		dwords = size / 4;
1824
1825#define RADEON_COPY_MT(_buf, _data, _width) \
1826	do { \
1827		if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1828			DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1829			return -EFAULT; \
1830		} \
1831	} while(0)
1832
1833		if (microtile) {
1834			/* texture micro tiling in use, minimum texture width is thus 16 bytes.
1835			   however, we cannot use blitter directly for texture width < 64 bytes,
1836			   since minimum tex pitch is 64 bytes and we need this to match
1837			   the texture width, otherwise the blitter will tile it wrong.
1838			   Thus, tiling manually in this case. Additionally, need to special
1839			   case tex height = 1, since our actual image will have height 2
1840			   and we need to ensure we don't read beyond the texture size
1841			   from user space. */
1842			if (tex->height == 1) {
1843				if (tex_width >= 64 || tex_width <= 16) {
1844					RADEON_COPY_MT(buffer, data,
1845						(int)(tex_width * sizeof(u32)));
1846				} else if (tex_width == 32) {
1847					RADEON_COPY_MT(buffer, data, 16);
1848					RADEON_COPY_MT(buffer + 8,
1849						       data + 16, 16);
1850				}
1851			} else if (tex_width >= 64 || tex_width == 16) {
1852				RADEON_COPY_MT(buffer, data,
1853					       (int)(dwords * sizeof(u32)));
1854			} else if (tex_width < 16) {
1855				for (i = 0; i < tex->height; i++) {
1856					RADEON_COPY_MT(buffer, data, tex_width);
1857					buffer += 4;
1858					data += tex_width;
1859				}
1860			} else if (tex_width == 32) {
1861				/* TODO: make sure this works when not fitting in one buffer
1862				   (i.e. 32bytes x 2048...) */
1863				for (i = 0; i < tex->height; i += 2) {
1864					RADEON_COPY_MT(buffer, data, 16);
1865					data += 16;
1866					RADEON_COPY_MT(buffer + 8, data, 16);
1867					data += 16;
1868					RADEON_COPY_MT(buffer + 4, data, 16);
1869					data += 16;
1870					RADEON_COPY_MT(buffer + 12, data, 16);
1871					data += 16;
1872					buffer += 16;
1873				}
1874			}
1875		} else {
1876			if (tex_width >= 32) {
1877				/* Texture image width is larger than the minimum, so we
1878				 * can upload it directly.
1879				 */
1880				RADEON_COPY_MT(buffer, data,
1881					       (int)(dwords * sizeof(u32)));
1882			} else {
1883				/* Texture image width is less than the minimum, so we
1884				 * need to pad out each image scanline to the minimum
1885				 * width.
1886				 */
1887				for (i = 0; i < tex->height; i++) {
1888					RADEON_COPY_MT(buffer, data, tex_width);
1889					buffer += 8;
1890					data += tex_width;
1891				}
1892			}
1893		}
1894
1895#undef RADEON_COPY_MT
1896		byte_offset = (image->y & ~2047) * blit_width;
1897		buf->file_priv = file_priv;
1898		buf->used = size;
1899		offset = dev_priv->gart_buffers_offset + buf->offset;
1900		BEGIN_RING(9);
1901		OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
1902		OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1903			 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1904			 RADEON_GMC_BRUSH_NONE |
1905			 (format << 8) |
1906			 RADEON_GMC_SRC_DATATYPE_COLOR |
1907			 RADEON_ROP3_S |
1908			 RADEON_DP_SRC_SOURCE_MEMORY |
1909			 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1910		OUT_RING((spitch << 22) | (offset >> 10));
1911		OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
1912		OUT_RING(0);
1913		OUT_RING((image->x << 16) | (image->y % 2048));
1914		OUT_RING((image->width << 16) | height);
1915		RADEON_WAIT_UNTIL_2D_IDLE();
1916		ADVANCE_RING();
1917		COMMIT_RING();
1918
1919		radeon_cp_discard_buffer(dev, file_priv->master, buf);
1920
1921		/* Update the input parameters for next time */
1922		image->y += height;
1923		image->height -= height;
1924		image->data = (const u8 __user *)image->data + size;
1925	} while (image->height > 0);
1926
1927	/* Flush the pixel cache after the blit completes.  This ensures
1928	 * the texture data is written out to memory before rendering
1929	 * continues.
1930	 */
1931	BEGIN_RING(4);
1932	RADEON_FLUSH_CACHE();
1933	RADEON_WAIT_UNTIL_2D_IDLE();
1934	ADVANCE_RING();
1935	COMMIT_RING();
1936
1937	return 0;
1938}
1939
1940static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1941{
1942	drm_radeon_private_t *dev_priv = dev->dev_private;
1943	int i;
1944	RING_LOCALS;
1945	DRM_DEBUG("\n");
1946
1947	BEGIN_RING(35);
1948
1949	OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
1950	OUT_RING(0x00000000);
1951
1952	OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
1953	for (i = 0; i < 32; i++) {
1954		OUT_RING(stipple[i]);
1955	}
1956
1957	ADVANCE_RING();
1958}
1959
1960static void radeon_apply_surface_regs(int surf_index,
1961				      drm_radeon_private_t *dev_priv)
1962{
1963	if (!dev_priv->mmio)
1964		return;
1965
1966	radeon_do_cp_idle(dev_priv);
1967
1968	RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
1969		     dev_priv->surfaces[surf_index].flags);
1970	RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
1971		     dev_priv->surfaces[surf_index].lower);
1972	RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
1973		     dev_priv->surfaces[surf_index].upper);
1974}
1975
1976/* Allocates a virtual surface
1977 * doesn't always allocate a real surface, will stretch an existing
1978 * surface when possible.
1979 *
1980 * Note that refcount can be at most 2, since during a free refcount=3
1981 * might mean we have to allocate a new surface which might not always
1982 * be available.
1983 * For example : we allocate three contiguous surfaces ABC. If B is
1984 * freed, we suddenly need two surfaces to store A and C, which might
1985 * not always be available.
1986 */
1987static int alloc_surface(drm_radeon_surface_alloc_t *new,
1988			 drm_radeon_private_t *dev_priv,
1989			 struct drm_file *file_priv)
1990{
1991	struct radeon_virt_surface *s;
1992	int i;
1993	int virt_surface_index;
1994	uint32_t new_upper, new_lower;
1995
1996	new_lower = new->address;
1997	new_upper = new_lower + new->size - 1;
1998
1999	/* sanity check */
2000	if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
2001	    ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
2002	     RADEON_SURF_ADDRESS_FIXED_MASK)
2003	    || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
2004		return -1;
2005
2006	/* make sure there is no overlap with existing surfaces */
2007	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2008		if ((dev_priv->surfaces[i].refcount != 0) &&
2009		    (((new_lower >= dev_priv->surfaces[i].lower) &&
2010		      (new_lower < dev_priv->surfaces[i].upper)) ||
2011		     ((new_lower < dev_priv->surfaces[i].lower) &&
2012		      (new_upper > dev_priv->surfaces[i].lower)))) {
2013			return -1;
2014		}
2015	}
2016
2017	/* find a virtual surface */
2018	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
2019		if (dev_priv->virt_surfaces[i].file_priv == NULL)
2020			break;
2021	if (i == 2 * RADEON_MAX_SURFACES) {
2022		return -1;
2023	}
2024	virt_surface_index = i;
2025
2026	/* try to reuse an existing surface */
2027	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2028		/* extend before */
2029		if ((dev_priv->surfaces[i].refcount == 1) &&
2030		    (new->flags == dev_priv->surfaces[i].flags) &&
2031		    (new_upper + 1 == dev_priv->surfaces[i].lower)) {
2032			s = &(dev_priv->virt_surfaces[virt_surface_index]);
2033			s->surface_index = i;
2034			s->lower = new_lower;
2035			s->upper = new_upper;
2036			s->flags = new->flags;
2037			s->file_priv = file_priv;
2038			dev_priv->surfaces[i].refcount++;
2039			dev_priv->surfaces[i].lower = s->lower;
2040			radeon_apply_surface_regs(s->surface_index, dev_priv);
2041			return virt_surface_index;
2042		}
2043
2044		/* extend after */
2045		if ((dev_priv->surfaces[i].refcount == 1) &&
2046		    (new->flags == dev_priv->surfaces[i].flags) &&
2047		    (new_lower == dev_priv->surfaces[i].upper + 1)) {
2048			s = &(dev_priv->virt_surfaces[virt_surface_index]);
2049			s->surface_index = i;
2050			s->lower = new_lower;
2051			s->upper = new_upper;
2052			s->flags = new->flags;
2053			s->file_priv = file_priv;
2054			dev_priv->surfaces[i].refcount++;
2055			dev_priv->surfaces[i].upper = s->upper;
2056			radeon_apply_surface_regs(s->surface_index, dev_priv);
2057			return virt_surface_index;
2058		}
2059	}
2060
2061	/* okay, we need a new one */
2062	for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2063		if (dev_priv->surfaces[i].refcount == 0) {
2064			s = &(dev_priv->virt_surfaces[virt_surface_index]);
2065			s->surface_index = i;
2066			s->lower = new_lower;
2067			s->upper = new_upper;
2068			s->flags = new->flags;
2069			s->file_priv = file_priv;
2070			dev_priv->surfaces[i].refcount = 1;
2071			dev_priv->surfaces[i].lower = s->lower;
2072			dev_priv->surfaces[i].upper = s->upper;
2073			dev_priv->surfaces[i].flags = s->flags;
2074			radeon_apply_surface_regs(s->surface_index, dev_priv);
2075			return virt_surface_index;
2076		}
2077	}
2078
2079	/* we didn't find anything */
2080	return -1;
2081}
2082
2083static int free_surface(struct drm_file *file_priv,
2084			drm_radeon_private_t * dev_priv,
2085			int lower)
2086{
2087	struct radeon_virt_surface *s;
2088	int i;
2089	/* find the virtual surface */
2090	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2091		s = &(dev_priv->virt_surfaces[i]);
2092		if (s->file_priv) {
2093			if ((lower == s->lower) && (file_priv == s->file_priv))
2094			{
2095				if (dev_priv->surfaces[s->surface_index].
2096				    lower == s->lower)
2097					dev_priv->surfaces[s->surface_index].
2098					    lower = s->upper;
2099
2100				if (dev_priv->surfaces[s->surface_index].
2101				    upper == s->upper)
2102					dev_priv->surfaces[s->surface_index].
2103					    upper = s->lower;
2104
2105				dev_priv->surfaces[s->surface_index].refcount--;
2106				if (dev_priv->surfaces[s->surface_index].
2107				    refcount == 0)
2108					dev_priv->surfaces[s->surface_index].
2109					    flags = 0;
2110				s->file_priv = NULL;
2111				radeon_apply_surface_regs(s->surface_index,
2112							  dev_priv);
2113				return 0;
2114			}
2115		}
2116	}
2117	return 1;
2118}
2119
2120static void radeon_surfaces_release(struct drm_file *file_priv,
2121				    drm_radeon_private_t * dev_priv)
2122{
2123	int i;
2124	for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2125		if (dev_priv->virt_surfaces[i].file_priv == file_priv)
2126			free_surface(file_priv, dev_priv,
2127				     dev_priv->virt_surfaces[i].lower);
2128	}
2129}
2130
2131/* ================================================================
2132 * IOCTL functions
2133 */
2134static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
2135{
2136	drm_radeon_private_t *dev_priv = dev->dev_private;
2137	drm_radeon_surface_alloc_t *alloc = data;
2138
2139	if (alloc_surface(alloc, dev_priv, file_priv) == -1)
2140		return -EINVAL;
2141	else
2142		return 0;
2143}
2144
2145static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2146{
2147	drm_radeon_private_t *dev_priv = dev->dev_private;
2148	drm_radeon_surface_free_t *memfree = data;
2149
2150	if (free_surface(file_priv, dev_priv, memfree->address))
2151		return -EINVAL;
2152	else
2153		return 0;
2154}
2155
2156static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
2157{
2158	drm_radeon_private_t *dev_priv = dev->dev_private;
2159	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2160	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
2161	drm_radeon_clear_t *clear = data;
2162	drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
2163	DRM_DEBUG("\n");
2164
2165	LOCK_TEST_WITH_RETURN(dev, file_priv);
2166
2167	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2168
2169	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2170		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2171
2172	if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
2173			       sarea_priv->nbox * sizeof(depth_boxes[0])))
2174		return -EFAULT;
2175
2176	radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes);
2177
2178	COMMIT_RING();
2179	return 0;
2180}
2181
2182/* Not sure why this isn't set all the time:
2183 */
2184static int radeon_do_init_pageflip(struct drm_device *dev, struct drm_master *master)
2185{
2186	drm_radeon_private_t *dev_priv = dev->dev_private;
2187	struct drm_radeon_master_private *master_priv = master->driver_priv;
2188	RING_LOCALS;
2189
2190	DRM_DEBUG("\n");
2191
2192	BEGIN_RING(6);
2193	RADEON_WAIT_UNTIL_3D_IDLE();
2194	OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
2195	OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
2196		 RADEON_CRTC_OFFSET_FLIP_CNTL);
2197	OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
2198	OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
2199		 RADEON_CRTC_OFFSET_FLIP_CNTL);
2200	ADVANCE_RING();
2201
2202	dev_priv->page_flipping = 1;
2203
2204	if (master_priv->sarea_priv->pfCurrentPage != 1)
2205		master_priv->sarea_priv->pfCurrentPage = 0;
2206
2207	return 0;
2208}
2209
2210/* Swapping and flipping are different operations, need different ioctls.
2211 * They can & should be intermixed to support multiple 3d windows.
2212 */
2213static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
2214{
2215	drm_radeon_private_t *dev_priv = dev->dev_private;
2216	DRM_DEBUG("\n");
2217
2218	LOCK_TEST_WITH_RETURN(dev, file_priv);
2219
2220	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2221
2222	if (!dev_priv->page_flipping)
2223		radeon_do_init_pageflip(dev, file_priv->master);
2224
2225	radeon_cp_dispatch_flip(dev, file_priv->master);
2226
2227	COMMIT_RING();
2228	return 0;
2229}
2230
2231static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
2232{
2233	drm_radeon_private_t *dev_priv = dev->dev_private;
2234	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2235	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
2236
2237	DRM_DEBUG("\n");
2238
2239	LOCK_TEST_WITH_RETURN(dev, file_priv);
2240
2241	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2242
2243	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2244		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2245
2246	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2247		r600_cp_dispatch_swap(dev, file_priv);
2248	else
2249		radeon_cp_dispatch_swap(dev, file_priv->master);
2250	sarea_priv->ctx_owner = 0;
2251
2252	COMMIT_RING();
2253	return 0;
2254}
2255
2256static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
2257{
2258	drm_radeon_private_t *dev_priv = dev->dev_private;
2259	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2260	drm_radeon_sarea_t *sarea_priv;
2261	struct drm_device_dma *dma = dev->dma;
2262	struct drm_buf *buf;
2263	drm_radeon_vertex_t *vertex = data;
2264	drm_radeon_tcl_prim_t prim;
2265
2266	LOCK_TEST_WITH_RETURN(dev, file_priv);
2267
2268	sarea_priv = master_priv->sarea_priv;
2269
2270	DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2271		  DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
2272
2273	if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2274		DRM_ERROR("buffer index %d (of %d max)\n",
2275			  vertex->idx, dma->buf_count - 1);
2276		return -EINVAL;
2277	}
2278	if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2279		DRM_ERROR("buffer prim %d\n", vertex->prim);
2280		return -EINVAL;
2281	}
2282
2283	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2284	VB_AGE_TEST_WITH_RETURN(dev_priv);
2285
2286	buf = dma->buflist[vertex->idx];
2287
2288	if (buf->file_priv != file_priv) {
2289		DRM_ERROR("process %d using buffer owned by %p\n",
2290			  DRM_CURRENTPID, buf->file_priv);
2291		return -EINVAL;
2292	}
2293	if (buf->pending) {
2294		DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2295		return -EINVAL;
2296	}
2297
2298	/* Build up a prim_t record:
2299	 */
2300	if (vertex->count) {
2301		buf->used = vertex->count;	/* not used? */
2302
2303		if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2304			if (radeon_emit_state(dev_priv, file_priv,
2305					      &sarea_priv->context_state,
2306					      sarea_priv->tex_state,
2307					      sarea_priv->dirty)) {
2308				DRM_ERROR("radeon_emit_state failed\n");
2309				return -EINVAL;
2310			}
2311
2312			sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2313					       RADEON_UPLOAD_TEX1IMAGES |
2314					       RADEON_UPLOAD_TEX2IMAGES |
2315					       RADEON_REQUIRE_QUIESCENCE);
2316		}
2317
2318		prim.start = 0;
2319		prim.finish = vertex->count;	/* unused */
2320		prim.prim = vertex->prim;
2321		prim.numverts = vertex->count;
2322		prim.vc_format = sarea_priv->vc_format;
2323
2324		radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim);
2325	}
2326
2327	if (vertex->discard) {
2328		radeon_cp_discard_buffer(dev, file_priv->master, buf);
2329	}
2330
2331	COMMIT_RING();
2332	return 0;
2333}
2334
2335static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
2336{
2337	drm_radeon_private_t *dev_priv = dev->dev_private;
2338	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2339	drm_radeon_sarea_t *sarea_priv;
2340	struct drm_device_dma *dma = dev->dma;
2341	struct drm_buf *buf;
2342	drm_radeon_indices_t *elts = data;
2343	drm_radeon_tcl_prim_t prim;
2344	int count;
2345
2346	LOCK_TEST_WITH_RETURN(dev, file_priv);
2347
2348	sarea_priv = master_priv->sarea_priv;
2349
2350	DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2351		  DRM_CURRENTPID, elts->idx, elts->start, elts->end,
2352		  elts->discard);
2353
2354	if (elts->idx < 0 || elts->idx >= dma->buf_count) {
2355		DRM_ERROR("buffer index %d (of %d max)\n",
2356			  elts->idx, dma->buf_count - 1);
2357		return -EINVAL;
2358	}
2359	if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2360		DRM_ERROR("buffer prim %d\n", elts->prim);
2361		return -EINVAL;
2362	}
2363
2364	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2365	VB_AGE_TEST_WITH_RETURN(dev_priv);
2366
2367	buf = dma->buflist[elts->idx];
2368
2369	if (buf->file_priv != file_priv) {
2370		DRM_ERROR("process %d using buffer owned by %p\n",
2371			  DRM_CURRENTPID, buf->file_priv);
2372		return -EINVAL;
2373	}
2374	if (buf->pending) {
2375		DRM_ERROR("sending pending buffer %d\n", elts->idx);
2376		return -EINVAL;
2377	}
2378
2379	count = (elts->end - elts->start) / sizeof(u16);
2380	elts->start -= RADEON_INDEX_PRIM_OFFSET;
2381
2382	if (elts->start & 0x7) {
2383		DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
2384		return -EINVAL;
2385	}
2386	if (elts->start < buf->used) {
2387		DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
2388		return -EINVAL;
2389	}
2390
2391	buf->used = elts->end;
2392
2393	if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2394		if (radeon_emit_state(dev_priv, file_priv,
2395				      &sarea_priv->context_state,
2396				      sarea_priv->tex_state,
2397				      sarea_priv->dirty)) {
2398			DRM_ERROR("radeon_emit_state failed\n");
2399			return -EINVAL;
2400		}
2401
2402		sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2403				       RADEON_UPLOAD_TEX1IMAGES |
2404				       RADEON_UPLOAD_TEX2IMAGES |
2405				       RADEON_REQUIRE_QUIESCENCE);
2406	}
2407
2408	/* Build up a prim_t record:
2409	 */
2410	prim.start = elts->start;
2411	prim.finish = elts->end;
2412	prim.prim = elts->prim;
2413	prim.offset = 0;	/* offset from start of dma buffers */
2414	prim.numverts = RADEON_MAX_VB_VERTS;	/* duh */
2415	prim.vc_format = sarea_priv->vc_format;
2416
2417	radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim);
2418	if (elts->discard) {
2419		radeon_cp_discard_buffer(dev, file_priv->master, buf);
2420	}
2421
2422	COMMIT_RING();
2423	return 0;
2424}
2425
2426static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv)
2427{
2428	drm_radeon_private_t *dev_priv = dev->dev_private;
2429	drm_radeon_texture_t *tex = data;
2430	drm_radeon_tex_image_t image;
2431	int ret;
2432
2433	LOCK_TEST_WITH_RETURN(dev, file_priv);
2434
2435	if (tex->image == NULL) {
2436		DRM_ERROR("null texture image!\n");
2437		return -EINVAL;
2438	}
2439
2440	if (DRM_COPY_FROM_USER(&image,
2441			       (drm_radeon_tex_image_t __user *) tex->image,
2442			       sizeof(image)))
2443		return -EFAULT;
2444
2445	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2446	VB_AGE_TEST_WITH_RETURN(dev_priv);
2447
2448	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2449		ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
2450	else
2451		ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
2452
2453	return ret;
2454}
2455
2456static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
2457{
2458	drm_radeon_private_t *dev_priv = dev->dev_private;
2459	drm_radeon_stipple_t *stipple = data;
2460	u32 mask[32];
2461
2462	LOCK_TEST_WITH_RETURN(dev, file_priv);
2463
2464	if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
2465		return -EFAULT;
2466
2467	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2468
2469	radeon_cp_dispatch_stipple(dev, mask);
2470
2471	COMMIT_RING();
2472	return 0;
2473}
2474
2475static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
2476{
2477	drm_radeon_private_t *dev_priv = dev->dev_private;
2478	struct drm_device_dma *dma = dev->dma;
2479	struct drm_buf *buf;
2480	drm_radeon_indirect_t *indirect = data;
2481	RING_LOCALS;
2482
2483	LOCK_TEST_WITH_RETURN(dev, file_priv);
2484
2485	DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
2486		  indirect->idx, indirect->start, indirect->end,
2487		  indirect->discard);
2488
2489	if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
2490		DRM_ERROR("buffer index %d (of %d max)\n",
2491			  indirect->idx, dma->buf_count - 1);
2492		return -EINVAL;
2493	}
2494
2495	buf = dma->buflist[indirect->idx];
2496
2497	if (buf->file_priv != file_priv) {
2498		DRM_ERROR("process %d using buffer owned by %p\n",
2499			  DRM_CURRENTPID, buf->file_priv);
2500		return -EINVAL;
2501	}
2502	if (buf->pending) {
2503		DRM_ERROR("sending pending buffer %d\n", indirect->idx);
2504		return -EINVAL;
2505	}
2506
2507	if (indirect->start < buf->used) {
2508		DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2509			  indirect->start, buf->used);
2510		return -EINVAL;
2511	}
2512
2513	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2514	VB_AGE_TEST_WITH_RETURN(dev_priv);
2515
2516	buf->used = indirect->end;
2517
2518	/* Dispatch the indirect buffer full of commands from the
2519	 * X server.  This is insecure and is thus only available to
2520	 * privileged clients.
2521	 */
2522	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2523		r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2524	else {
2525		/* Wait for the 3D stream to idle before the indirect buffer
2526		 * containing 2D acceleration commands is processed.
2527		 */
2528		BEGIN_RING(2);
2529		RADEON_WAIT_UNTIL_3D_IDLE();
2530		ADVANCE_RING();
2531		radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2532	}
2533
2534	if (indirect->discard) {
2535		radeon_cp_discard_buffer(dev, file_priv->master, buf);
2536	}
2537
2538	COMMIT_RING();
2539	return 0;
2540}
2541
2542static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
2543{
2544	drm_radeon_private_t *dev_priv = dev->dev_private;
2545	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2546	drm_radeon_sarea_t *sarea_priv;
2547	struct drm_device_dma *dma = dev->dma;
2548	struct drm_buf *buf;
2549	drm_radeon_vertex2_t *vertex = data;
2550	int i;
2551	unsigned char laststate;
2552
2553	LOCK_TEST_WITH_RETURN(dev, file_priv);
2554
2555	sarea_priv = master_priv->sarea_priv;
2556
2557	DRM_DEBUG("pid=%d index=%d discard=%d\n",
2558		  DRM_CURRENTPID, vertex->idx, vertex->discard);
2559
2560	if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2561		DRM_ERROR("buffer index %d (of %d max)\n",
2562			  vertex->idx, dma->buf_count - 1);
2563		return -EINVAL;
2564	}
2565
2566	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2567	VB_AGE_TEST_WITH_RETURN(dev_priv);
2568
2569	buf = dma->buflist[vertex->idx];
2570
2571	if (buf->file_priv != file_priv) {
2572		DRM_ERROR("process %d using buffer owned by %p\n",
2573			  DRM_CURRENTPID, buf->file_priv);
2574		return -EINVAL;
2575	}
2576
2577	if (buf->pending) {
2578		DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2579		return -EINVAL;
2580	}
2581
2582	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2583		return -EINVAL;
2584
2585	for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) {
2586		drm_radeon_prim_t prim;
2587		drm_radeon_tcl_prim_t tclprim;
2588
2589		if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim)))
2590			return -EFAULT;
2591
2592		if (prim.stateidx != laststate) {
2593			drm_radeon_state_t state;
2594
2595			if (DRM_COPY_FROM_USER(&state,
2596					       &vertex->state[prim.stateidx],
2597					       sizeof(state)))
2598				return -EFAULT;
2599
2600			if (radeon_emit_state2(dev_priv, file_priv, &state)) {
2601				DRM_ERROR("radeon_emit_state2 failed\n");
2602				return -EINVAL;
2603			}
2604
2605			laststate = prim.stateidx;
2606		}
2607
2608		tclprim.start = prim.start;
2609		tclprim.finish = prim.finish;
2610		tclprim.prim = prim.prim;
2611		tclprim.vc_format = prim.vc_format;
2612
2613		if (prim.prim & RADEON_PRIM_WALK_IND) {
2614			tclprim.offset = prim.numverts * 64;
2615			tclprim.numverts = RADEON_MAX_VB_VERTS;	/* duh */
2616
2617			radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim);
2618		} else {
2619			tclprim.numverts = prim.numverts;
2620			tclprim.offset = 0;	/* not used */
2621
2622			radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim);
2623		}
2624
2625		if (sarea_priv->nbox == 1)
2626			sarea_priv->nbox = 0;
2627	}
2628
2629	if (vertex->discard) {
2630		radeon_cp_discard_buffer(dev, file_priv->master, buf);
2631	}
2632
2633	COMMIT_RING();
2634	return 0;
2635}
2636
2637static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
2638			       struct drm_file *file_priv,
2639			       drm_radeon_cmd_header_t header,
2640			       drm_radeon_kcmd_buffer_t *cmdbuf)
2641{
2642	int id = (int)header.packet.packet_id;
2643	int sz, reg;
2644	RING_LOCALS;
2645
2646	if (id >= RADEON_MAX_STATE_PACKETS)
2647		return -EINVAL;
2648
2649	sz = packet[id].len;
2650	reg = packet[id].start;
2651
2652	if (sz * sizeof(u32) > drm_buffer_unprocessed(cmdbuf->buffer)) {
2653		DRM_ERROR("Packet size provided larger than data provided\n");
2654		return -EINVAL;
2655	}
2656
2657	if (radeon_check_and_fixup_packets(dev_priv, file_priv, id,
2658				cmdbuf->buffer)) {
2659		DRM_ERROR("Packet verification failed\n");
2660		return -EINVAL;
2661	}
2662
2663	BEGIN_RING(sz + 1);
2664	OUT_RING(CP_PACKET0(reg, (sz - 1)));
2665	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2666	ADVANCE_RING();
2667
2668	return 0;
2669}
2670
2671static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
2672					  drm_radeon_cmd_header_t header,
2673					  drm_radeon_kcmd_buffer_t *cmdbuf)
2674{
2675	int sz = header.scalars.count;
2676	int start = header.scalars.offset;
2677	int stride = header.scalars.stride;
2678	RING_LOCALS;
2679
2680	BEGIN_RING(3 + sz);
2681	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2682	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2683	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2684	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2685	ADVANCE_RING();
2686	return 0;
2687}
2688
2689/* God this is ugly
2690 */
2691static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
2692					   drm_radeon_cmd_header_t header,
2693					   drm_radeon_kcmd_buffer_t *cmdbuf)
2694{
2695	int sz = header.scalars.count;
2696	int start = ((unsigned int)header.scalars.offset) + 0x100;
2697	int stride = header.scalars.stride;
2698	RING_LOCALS;
2699
2700	BEGIN_RING(3 + sz);
2701	OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2702	OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2703	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2704	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2705	ADVANCE_RING();
2706	return 0;
2707}
2708
2709static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2710					  drm_radeon_cmd_header_t header,
2711					  drm_radeon_kcmd_buffer_t *cmdbuf)
2712{
2713	int sz = header.vectors.count;
2714	int start = header.vectors.offset;
2715	int stride = header.vectors.stride;
2716	RING_LOCALS;
2717
2718	BEGIN_RING(5 + sz);
2719	OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2720	OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2721	OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2722	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2723	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2724	ADVANCE_RING();
2725
2726	return 0;
2727}
2728
2729static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
2730					  drm_radeon_cmd_header_t header,
2731					  drm_radeon_kcmd_buffer_t *cmdbuf)
2732{
2733	int sz = header.veclinear.count * 4;
2734	int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
2735	RING_LOCALS;
2736
2737        if (!sz)
2738                return 0;
2739	if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
2740                return -EINVAL;
2741
2742	BEGIN_RING(5 + sz);
2743	OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2744	OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2745	OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2746	OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2747	OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2748	ADVANCE_RING();
2749
2750	return 0;
2751}
2752
2753static int radeon_emit_packet3(struct drm_device * dev,
2754			       struct drm_file *file_priv,
2755			       drm_radeon_kcmd_buffer_t *cmdbuf)
2756{
2757	drm_radeon_private_t *dev_priv = dev->dev_private;
2758	unsigned int cmdsz;
2759	int ret;
2760	RING_LOCALS;
2761
2762	DRM_DEBUG("\n");
2763
2764	if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2765						  cmdbuf, &cmdsz))) {
2766		DRM_ERROR("Packet verification failed\n");
2767		return ret;
2768	}
2769
2770	BEGIN_RING(cmdsz);
2771	OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
2772	ADVANCE_RING();
2773
2774	return 0;
2775}
2776
2777static int radeon_emit_packet3_cliprect(struct drm_device *dev,
2778					struct drm_file *file_priv,
2779					drm_radeon_kcmd_buffer_t *cmdbuf,
2780					int orig_nbox)
2781{
2782	drm_radeon_private_t *dev_priv = dev->dev_private;
2783	struct drm_clip_rect box;
2784	unsigned int cmdsz;
2785	int ret;
2786	struct drm_clip_rect __user *boxes = cmdbuf->boxes;
2787	int i = 0;
2788	RING_LOCALS;
2789
2790	DRM_DEBUG("\n");
2791
2792	if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2793						  cmdbuf, &cmdsz))) {
2794		DRM_ERROR("Packet verification failed\n");
2795		return ret;
2796	}
2797
2798	if (!orig_nbox)
2799		goto out;
2800
2801	do {
2802		if (i < cmdbuf->nbox) {
2803			if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
2804				return -EFAULT;
2805			/* FIXME The second and subsequent times round
2806			 * this loop, send a WAIT_UNTIL_3D_IDLE before
2807			 * calling emit_clip_rect(). This fixes a
2808			 * lockup on fast machines when sending
2809			 * several cliprects with a cmdbuf, as when
2810			 * waving a 2D window over a 3D
2811			 * window. Something in the commands from user
2812			 * space seems to hang the card when they're
2813			 * sent several times in a row. That would be
2814			 * the correct place to fix it but this works
2815			 * around it until I can figure that out - Tim
2816			 * Smith */
2817			if (i) {
2818				BEGIN_RING(2);
2819				RADEON_WAIT_UNTIL_3D_IDLE();
2820				ADVANCE_RING();
2821			}
2822			radeon_emit_clip_rect(dev_priv, &box);
2823		}
2824
2825		BEGIN_RING(cmdsz);
2826		OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
2827		ADVANCE_RING();
2828
2829	} while (++i < cmdbuf->nbox);
2830	if (cmdbuf->nbox == 1)
2831		cmdbuf->nbox = 0;
2832
2833	return 0;
2834      out:
2835	drm_buffer_advance(cmdbuf->buffer, cmdsz * 4);
2836	return 0;
2837}
2838
2839static int radeon_emit_wait(struct drm_device * dev, int flags)
2840{
2841	drm_radeon_private_t *dev_priv = dev->dev_private;
2842	RING_LOCALS;
2843
2844	DRM_DEBUG("%x\n", flags);
2845	switch (flags) {
2846	case RADEON_WAIT_2D:
2847		BEGIN_RING(2);
2848		RADEON_WAIT_UNTIL_2D_IDLE();
2849		ADVANCE_RING();
2850		break;
2851	case RADEON_WAIT_3D:
2852		BEGIN_RING(2);
2853		RADEON_WAIT_UNTIL_3D_IDLE();
2854		ADVANCE_RING();
2855		break;
2856	case RADEON_WAIT_2D | RADEON_WAIT_3D:
2857		BEGIN_RING(2);
2858		RADEON_WAIT_UNTIL_IDLE();
2859		ADVANCE_RING();
2860		break;
2861	default:
2862		return -EINVAL;
2863	}
2864
2865	return 0;
2866}
2867
2868static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
2869		struct drm_file *file_priv)
2870{
2871	drm_radeon_private_t *dev_priv = dev->dev_private;
2872	struct drm_device_dma *dma = dev->dma;
2873	struct drm_buf *buf = NULL;
2874	drm_radeon_cmd_header_t stack_header;
2875	int idx;
2876	drm_radeon_kcmd_buffer_t *cmdbuf = data;
2877	int orig_nbox;
2878
2879	LOCK_TEST_WITH_RETURN(dev, file_priv);
2880
2881	RING_SPACE_TEST_WITH_RETURN(dev_priv);
2882	VB_AGE_TEST_WITH_RETURN(dev_priv);
2883
2884	if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) {
2885		return -EINVAL;
2886	}
2887
2888	/* Allocate an in-kernel area and copy in the cmdbuf.  Do this to avoid
2889	 * races between checking values and using those values in other code,
2890	 * and simply to avoid a lot of function calls to copy in data.
2891	 */
2892	if (cmdbuf->bufsz != 0) {
2893		int rv;
2894		void __user *buffer = cmdbuf->buffer;
2895		rv = drm_buffer_alloc(&cmdbuf->buffer, cmdbuf->bufsz);
2896		if (rv)
2897			return rv;
2898		rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
2899						cmdbuf->bufsz);
2900		if (rv) {
2901			drm_buffer_free(cmdbuf->buffer);
2902			return rv;
2903		}
2904	} else
2905		goto done;
2906
2907	orig_nbox = cmdbuf->nbox;
2908
2909	if (dev_priv->microcode_version == UCODE_R300) {
2910		int temp;
2911		temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
2912
2913		drm_buffer_free(cmdbuf->buffer);
2914
2915		return temp;
2916	}
2917
2918	/* microcode_version != r300 */
2919	while (drm_buffer_unprocessed(cmdbuf->buffer) >= sizeof(stack_header)) {
2920
2921		drm_radeon_cmd_header_t *header;
2922		header = drm_buffer_read_object(cmdbuf->buffer,
2923				sizeof(stack_header), &stack_header);
2924
2925		switch (header->header.cmd_type) {
2926		case RADEON_CMD_PACKET:
2927			DRM_DEBUG("RADEON_CMD_PACKET\n");
2928			if (radeon_emit_packets
2929			    (dev_priv, file_priv, *header, cmdbuf)) {
2930				DRM_ERROR("radeon_emit_packets failed\n");
2931				goto err;
2932			}
2933			break;
2934
2935		case RADEON_CMD_SCALARS:
2936			DRM_DEBUG("RADEON_CMD_SCALARS\n");
2937			if (radeon_emit_scalars(dev_priv, *header, cmdbuf)) {
2938				DRM_ERROR("radeon_emit_scalars failed\n");
2939				goto err;
2940			}
2941			break;
2942
2943		case RADEON_CMD_VECTORS:
2944			DRM_DEBUG("RADEON_CMD_VECTORS\n");
2945			if (radeon_emit_vectors(dev_priv, *header, cmdbuf)) {
2946				DRM_ERROR("radeon_emit_vectors failed\n");
2947				goto err;
2948			}
2949			break;
2950
2951		case RADEON_CMD_DMA_DISCARD:
2952			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2953			idx = header->dma.buf_idx;
2954			if (idx < 0 || idx >= dma->buf_count) {
2955				DRM_ERROR("buffer index %d (of %d max)\n",
2956					  idx, dma->buf_count - 1);
2957				goto err;
2958			}
2959
2960			buf = dma->buflist[idx];
2961			if (buf->file_priv != file_priv || buf->pending) {
2962				DRM_ERROR("bad buffer %p %p %d\n",
2963					  buf->file_priv, file_priv,
2964					  buf->pending);
2965				goto err;
2966			}
2967
2968			radeon_cp_discard_buffer(dev, file_priv->master, buf);
2969			break;
2970
2971		case RADEON_CMD_PACKET3:
2972			DRM_DEBUG("RADEON_CMD_PACKET3\n");
2973			if (radeon_emit_packet3(dev, file_priv, cmdbuf)) {
2974				DRM_ERROR("radeon_emit_packet3 failed\n");
2975				goto err;
2976			}
2977			break;
2978
2979		case RADEON_CMD_PACKET3_CLIP:
2980			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2981			if (radeon_emit_packet3_cliprect
2982			    (dev, file_priv, cmdbuf, orig_nbox)) {
2983				DRM_ERROR("radeon_emit_packet3_clip failed\n");
2984				goto err;
2985			}
2986			break;
2987
2988		case RADEON_CMD_SCALARS2:
2989			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2990			if (radeon_emit_scalars2(dev_priv, *header, cmdbuf)) {
2991				DRM_ERROR("radeon_emit_scalars2 failed\n");
2992				goto err;
2993			}
2994			break;
2995
2996		case RADEON_CMD_WAIT:
2997			DRM_DEBUG("RADEON_CMD_WAIT\n");
2998			if (radeon_emit_wait(dev, header->wait.flags)) {
2999				DRM_ERROR("radeon_emit_wait failed\n");
3000				goto err;
3001			}
3002			break;
3003		case RADEON_CMD_VECLINEAR:
3004			DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
3005			if (radeon_emit_veclinear(dev_priv, *header, cmdbuf)) {
3006				DRM_ERROR("radeon_emit_veclinear failed\n");
3007				goto err;
3008			}
3009			break;
3010
3011		default:
3012			DRM_ERROR("bad cmd_type %d at byte %d\n",
3013				  header->header.cmd_type,
3014				  cmdbuf->buffer->iterator);
3015			goto err;
3016		}
3017	}
3018
3019	drm_buffer_free(cmdbuf->buffer);
3020
3021      done:
3022	DRM_DEBUG("DONE\n");
3023	COMMIT_RING();
3024	return 0;
3025
3026      err:
3027	drm_buffer_free(cmdbuf->buffer);
3028	return -EINVAL;
3029}
3030
3031static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3032{
3033	drm_radeon_private_t *dev_priv = dev->dev_private;
3034	drm_radeon_getparam_t *param = data;
3035	int value;
3036
3037	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
3038
3039	switch (param->param) {
3040	case RADEON_PARAM_GART_BUFFER_OFFSET:
3041		value = dev_priv->gart_buffers_offset;
3042		break;
3043	case RADEON_PARAM_LAST_FRAME:
3044		dev_priv->stats.last_frame_reads++;
3045		value = GET_SCRATCH(dev_priv, 0);
3046		break;
3047	case RADEON_PARAM_LAST_DISPATCH:
3048		value = GET_SCRATCH(dev_priv, 1);
3049		break;
3050	case RADEON_PARAM_LAST_CLEAR:
3051		dev_priv->stats.last_clear_reads++;
3052		value = GET_SCRATCH(dev_priv, 2);
3053		break;
3054	case RADEON_PARAM_IRQ_NR:
3055		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
3056			value = 0;
3057		else
3058			value = dev->irq;
3059		break;
3060	case RADEON_PARAM_GART_BASE:
3061		value = dev_priv->gart_vm_start;
3062		break;
3063	case RADEON_PARAM_REGISTER_HANDLE:
3064		value = dev_priv->mmio->offset;
3065		break;
3066	case RADEON_PARAM_STATUS_HANDLE:
3067		value = dev_priv->ring_rptr_offset;
3068		break;
3069#if BITS_PER_LONG == 32
3070		/*
3071		 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
3072		 * pointer which can't fit into an int-sized variable.  According to
3073		 * Michel D��nzer, the ioctl() is only used on embedded platforms, so
3074		 * not supporting it shouldn't be a problem.  If the same functionality
3075		 * is needed on 64-bit platforms, a new ioctl() would have to be added,
3076		 * so backwards-compatibility for the embedded platforms can be
3077		 * maintained.  --davidm 4-Feb-2004.
3078		 */
3079	case RADEON_PARAM_SAREA_HANDLE:
3080		/* The lock is the first dword in the sarea. */
3081		/* no users of this parameter */
3082		break;
3083#endif
3084	case RADEON_PARAM_GART_TEX_HANDLE:
3085		value = dev_priv->gart_textures_offset;
3086		break;
3087	case RADEON_PARAM_SCRATCH_OFFSET:
3088		if (!dev_priv->writeback_works)
3089			return -EINVAL;
3090		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
3091			value = R600_SCRATCH_REG_OFFSET;
3092		else
3093			value = RADEON_SCRATCH_REG_OFFSET;
3094		break;
3095	case RADEON_PARAM_CARD_TYPE:
3096		if (dev_priv->flags & RADEON_IS_PCIE)
3097			value = RADEON_CARD_PCIE;
3098		else if (dev_priv->flags & RADEON_IS_AGP)
3099			value = RADEON_CARD_AGP;
3100		else
3101			value = RADEON_CARD_PCI;
3102		break;
3103	case RADEON_PARAM_VBLANK_CRTC:
3104		value = radeon_vblank_crtc_get(dev);
3105		break;
3106	case RADEON_PARAM_FB_LOCATION:
3107		value = radeon_read_fb_location(dev_priv);
3108		break;
3109	case RADEON_PARAM_NUM_GB_PIPES:
3110		value = dev_priv->num_gb_pipes;
3111		break;
3112	case RADEON_PARAM_NUM_Z_PIPES:
3113		value = dev_priv->num_z_pipes;
3114		break;
3115	default:
3116		DRM_DEBUG("Invalid parameter %d\n", param->param);
3117		return -EINVAL;
3118	}
3119
3120	if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
3121		DRM_ERROR("copy_to_user\n");
3122		return -EFAULT;
3123	}
3124
3125	return 0;
3126}
3127
3128static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3129{
3130	drm_radeon_private_t *dev_priv = dev->dev_private;
3131	struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
3132	drm_radeon_setparam_t *sp = data;
3133	struct drm_radeon_driver_file_fields *radeon_priv;
3134
3135	switch (sp->param) {
3136	case RADEON_SETPARAM_FB_LOCATION:
3137		radeon_priv = file_priv->driver_priv;
3138		radeon_priv->radeon_fb_delta = dev_priv->fb_location -
3139		    sp->value;
3140		break;
3141	case RADEON_SETPARAM_SWITCH_TILING:
3142		if (sp->value == 0) {
3143			DRM_DEBUG("color tiling disabled\n");
3144			dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3145			dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3146			if (master_priv->sarea_priv)
3147				master_priv->sarea_priv->tiling_enabled = 0;
3148		} else if (sp->value == 1) {
3149			DRM_DEBUG("color tiling enabled\n");
3150			dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
3151			dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
3152			if (master_priv->sarea_priv)
3153				master_priv->sarea_priv->tiling_enabled = 1;
3154		}
3155		break;
3156	case RADEON_SETPARAM_PCIGART_LOCATION:
3157		dev_priv->pcigart_offset = sp->value;
3158		dev_priv->pcigart_offset_set = 1;
3159		break;
3160	case RADEON_SETPARAM_NEW_MEMMAP:
3161		dev_priv->new_memmap = sp->value;
3162		break;
3163	case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
3164		dev_priv->gart_info.table_size = sp->value;
3165		if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
3166			dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
3167		break;
3168	case RADEON_SETPARAM_VBLANK_CRTC:
3169		return radeon_vblank_crtc_set(dev, sp->value);
3170		break;
3171	default:
3172		DRM_DEBUG("Invalid parameter %d\n", sp->param);
3173		return -EINVAL;
3174	}
3175
3176	return 0;
3177}
3178
3179/* When a client dies:
3180 *    - Check for and clean up flipped page state
3181 *    - Free any alloced GART memory.
3182 *    - Free any alloced radeon surfaces.
3183 *
3184 * DRM infrastructure takes care of reclaiming dma buffers.
3185 */
3186void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
3187{
3188	if (dev->dev_private) {
3189		drm_radeon_private_t *dev_priv = dev->dev_private;
3190		dev_priv->page_flipping = 0;
3191		radeon_mem_release(file_priv, dev_priv->gart_heap);
3192		radeon_mem_release(file_priv, dev_priv->fb_heap);
3193		radeon_surfaces_release(file_priv, dev_priv);
3194	}
3195}
3196
3197void radeon_driver_lastclose(struct drm_device *dev)
3198{
3199	radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
3200	radeon_do_release(dev);
3201}
3202
3203int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv)
3204{
3205	drm_radeon_private_t *dev_priv = dev->dev_private;
3206	struct drm_radeon_driver_file_fields *radeon_priv;
3207
3208	DRM_DEBUG("\n");
3209	radeon_priv = malloc(sizeof(*radeon_priv), DRM_MEM_DRIVER, M_NOWAIT);
3210
3211	if (!radeon_priv)
3212		return -ENOMEM;
3213
3214	file_priv->driver_priv = radeon_priv;
3215
3216	if (dev_priv)
3217		radeon_priv->radeon_fb_delta = dev_priv->fb_location;
3218	else
3219		radeon_priv->radeon_fb_delta = 0;
3220	return 0;
3221}
3222
3223void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
3224{
3225	struct drm_radeon_driver_file_fields *radeon_priv =
3226	    file_priv->driver_priv;
3227
3228	free(radeon_priv, DRM_MEM_DRIVER);
3229}
3230
3231struct drm_ioctl_desc radeon_ioctls[] = {
3232	DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3233	DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3234	DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3235	DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3236	DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
3237	DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
3238	DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH),
3239	DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
3240	DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
3241	DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
3242	DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
3243	DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
3244	DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
3245	DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
3246	DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3247	DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
3248	DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
3249	DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
3250	DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
3251	DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
3252	DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH),
3253	DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3254	DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
3255	DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
3256	DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
3257	DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
3258	DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
3259	DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
3260};
3261
3262int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls);
3263