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