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