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