GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / gpu / drm / radeon / radeon_state.c
blobcd1e1e564706d799d3a50647b60c1c64bdce9d8e
1 /* radeon_state.c -- State support for Radeon -*- linux-c -*- */
2 /*
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4 * All Rights Reserved.
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:
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.
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.
25 * Authors:
26 * Gareth Hughes <gareth@valinux.com>
27 * Kevin E. Martin <martin@valinux.com>
30 #include "drmP.h"
31 #include "drm.h"
32 #include "drm_buffer.h"
33 #include "drm_sarea.h"
34 #include "radeon_drm.h"
35 #include "radeon_drv.h"
37 /* ================================================================
38 * Helper functions for client state checking and fixup
41 static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
42 dev_priv,
43 struct drm_file * file_priv,
44 u32 *offset)
46 u64 off = *offset;
47 u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
48 struct drm_radeon_driver_file_fields *radeon_priv;
50 /* Hrm ... the story of the offset ... So this function converts
51 * the various ideas of what userland clients might have for an
52 * offset in the card address space into an offset into the card
53 * address space :) So with a sane client, it should just keep
54 * the value intact and just do some boundary checking. However,
55 * not all clients are sane. Some older clients pass us 0 based
56 * offsets relative to the start of the framebuffer and some may
57 * assume the AGP aperture it appended to the framebuffer, so we
58 * try to detect those cases and fix them up.
60 * Note: It might be a good idea here to make sure the offset lands
61 * in some "allowed" area to protect things like the PCIE GART...
64 /* First, the best case, the offset already lands in either the
65 * framebuffer or the GART mapped space
67 if (radeon_check_offset(dev_priv, off))
68 return 0;
70 /* Ok, that didn't happen... now check if we have a zero based
71 * offset that fits in the framebuffer + gart space, apply the
72 * magic offset we get from SETPARAM or calculated from fb_location
74 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
75 radeon_priv = file_priv->driver_priv;
76 off += radeon_priv->radeon_fb_delta;
79 /* Finally, assume we aimed at a GART offset if beyond the fb */
80 if (off > fb_end)
81 off = off - fb_end - 1 + dev_priv->gart_vm_start;
83 /* Now recheck and fail if out of bounds */
84 if (radeon_check_offset(dev_priv, off)) {
85 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
86 *offset = off;
87 return 0;
89 return -EINVAL;
92 static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
93 dev_priv,
94 struct drm_file *file_priv,
95 int id, struct drm_buffer *buf)
97 u32 *data;
98 switch (id) {
100 case RADEON_EMIT_PP_MISC:
101 data = drm_buffer_pointer_to_dword(buf,
102 (RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4);
104 if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
105 DRM_ERROR("Invalid depth buffer offset\n");
106 return -EINVAL;
108 dev_priv->have_z_offset = 1;
109 break;
111 case RADEON_EMIT_PP_CNTL:
112 data = drm_buffer_pointer_to_dword(buf,
113 (RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4);
115 if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
116 DRM_ERROR("Invalid colour buffer offset\n");
117 return -EINVAL;
119 break;
121 case R200_EMIT_PP_TXOFFSET_0:
122 case R200_EMIT_PP_TXOFFSET_1:
123 case R200_EMIT_PP_TXOFFSET_2:
124 case R200_EMIT_PP_TXOFFSET_3:
125 case R200_EMIT_PP_TXOFFSET_4:
126 case R200_EMIT_PP_TXOFFSET_5:
127 data = drm_buffer_pointer_to_dword(buf, 0);
128 if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
129 DRM_ERROR("Invalid R200 texture offset\n");
130 return -EINVAL;
132 break;
134 case RADEON_EMIT_PP_TXFILTER_0:
135 case RADEON_EMIT_PP_TXFILTER_1:
136 case RADEON_EMIT_PP_TXFILTER_2:
137 data = drm_buffer_pointer_to_dword(buf,
138 (RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4);
139 if (radeon_check_and_fixup_offset(dev_priv, file_priv, data)) {
140 DRM_ERROR("Invalid R100 texture offset\n");
141 return -EINVAL;
143 break;
145 case R200_EMIT_PP_CUBIC_OFFSETS_0:
146 case R200_EMIT_PP_CUBIC_OFFSETS_1:
147 case R200_EMIT_PP_CUBIC_OFFSETS_2:
148 case R200_EMIT_PP_CUBIC_OFFSETS_3:
149 case R200_EMIT_PP_CUBIC_OFFSETS_4:
150 case R200_EMIT_PP_CUBIC_OFFSETS_5:{
151 int i;
152 for (i = 0; i < 5; i++) {
153 data = drm_buffer_pointer_to_dword(buf, i);
154 if (radeon_check_and_fixup_offset(dev_priv,
155 file_priv,
156 data)) {
157 DRM_ERROR
158 ("Invalid R200 cubic texture offset\n");
159 return -EINVAL;
162 break;
165 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
166 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
167 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
168 int i;
169 for (i = 0; i < 5; i++) {
170 data = drm_buffer_pointer_to_dword(buf, i);
171 if (radeon_check_and_fixup_offset(dev_priv,
172 file_priv,
173 data)) {
174 DRM_ERROR
175 ("Invalid R100 cubic texture offset\n");
176 return -EINVAL;
180 break;
182 case R200_EMIT_VAP_CTL:{
183 RING_LOCALS;
184 BEGIN_RING(2);
185 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
186 ADVANCE_RING();
188 break;
190 case RADEON_EMIT_RB3D_COLORPITCH:
191 case RADEON_EMIT_RE_LINE_PATTERN:
192 case RADEON_EMIT_SE_LINE_WIDTH:
193 case RADEON_EMIT_PP_LUM_MATRIX:
194 case RADEON_EMIT_PP_ROT_MATRIX_0:
195 case RADEON_EMIT_RB3D_STENCILREFMASK:
196 case RADEON_EMIT_SE_VPORT_XSCALE:
197 case RADEON_EMIT_SE_CNTL:
198 case RADEON_EMIT_SE_CNTL_STATUS:
199 case RADEON_EMIT_RE_MISC:
200 case RADEON_EMIT_PP_BORDER_COLOR_0:
201 case RADEON_EMIT_PP_BORDER_COLOR_1:
202 case RADEON_EMIT_PP_BORDER_COLOR_2:
203 case RADEON_EMIT_SE_ZBIAS_FACTOR:
204 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:
205 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:
206 case R200_EMIT_PP_TXCBLEND_0:
207 case R200_EMIT_PP_TXCBLEND_1:
208 case R200_EMIT_PP_TXCBLEND_2:
209 case R200_EMIT_PP_TXCBLEND_3:
210 case R200_EMIT_PP_TXCBLEND_4:
211 case R200_EMIT_PP_TXCBLEND_5:
212 case R200_EMIT_PP_TXCBLEND_6:
213 case R200_EMIT_PP_TXCBLEND_7:
214 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
215 case R200_EMIT_TFACTOR_0:
216 case R200_EMIT_VTX_FMT_0:
217 case R200_EMIT_MATRIX_SELECT_0:
218 case R200_EMIT_TEX_PROC_CTL_2:
219 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
220 case R200_EMIT_PP_TXFILTER_0:
221 case R200_EMIT_PP_TXFILTER_1:
222 case R200_EMIT_PP_TXFILTER_2:
223 case R200_EMIT_PP_TXFILTER_3:
224 case R200_EMIT_PP_TXFILTER_4:
225 case R200_EMIT_PP_TXFILTER_5:
226 case R200_EMIT_VTE_CNTL:
227 case R200_EMIT_OUTPUT_VTX_COMP_SEL:
228 case R200_EMIT_PP_TAM_DEBUG3:
229 case R200_EMIT_PP_CNTL_X:
230 case R200_EMIT_RB3D_DEPTHXY_OFFSET:
231 case R200_EMIT_RE_AUX_SCISSOR_CNTL:
232 case R200_EMIT_RE_SCISSOR_TL_0:
233 case R200_EMIT_RE_SCISSOR_TL_1:
234 case R200_EMIT_RE_SCISSOR_TL_2:
235 case R200_EMIT_SE_VAP_CNTL_STATUS:
236 case R200_EMIT_SE_VTX_STATE_CNTL:
237 case R200_EMIT_RE_POINTSIZE:
238 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0:
239 case R200_EMIT_PP_CUBIC_FACES_0:
240 case R200_EMIT_PP_CUBIC_FACES_1:
241 case R200_EMIT_PP_CUBIC_FACES_2:
242 case R200_EMIT_PP_CUBIC_FACES_3:
243 case R200_EMIT_PP_CUBIC_FACES_4:
244 case R200_EMIT_PP_CUBIC_FACES_5:
245 case RADEON_EMIT_PP_TEX_SIZE_0:
246 case RADEON_EMIT_PP_TEX_SIZE_1:
247 case RADEON_EMIT_PP_TEX_SIZE_2:
248 case R200_EMIT_RB3D_BLENDCOLOR:
249 case R200_EMIT_TCL_POINT_SPRITE_CNTL:
250 case RADEON_EMIT_PP_CUBIC_FACES_0:
251 case RADEON_EMIT_PP_CUBIC_FACES_1:
252 case RADEON_EMIT_PP_CUBIC_FACES_2:
253 case R200_EMIT_PP_TRI_PERF_CNTL:
254 case R200_EMIT_PP_AFS_0:
255 case R200_EMIT_PP_AFS_1:
256 case R200_EMIT_ATF_TFACTOR:
257 case R200_EMIT_PP_TXCTLALL_0:
258 case R200_EMIT_PP_TXCTLALL_1:
259 case R200_EMIT_PP_TXCTLALL_2:
260 case R200_EMIT_PP_TXCTLALL_3:
261 case R200_EMIT_PP_TXCTLALL_4:
262 case R200_EMIT_PP_TXCTLALL_5:
263 case R200_EMIT_VAP_PVS_CNTL:
264 /* These packets don't contain memory offsets */
265 break;
267 default:
268 DRM_ERROR("Unknown state packet ID %d\n", id);
269 return -EINVAL;
272 return 0;
275 static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
276 dev_priv,
277 struct drm_file *file_priv,
278 drm_radeon_kcmd_buffer_t *
279 cmdbuf,
280 unsigned int *cmdsz)
282 u32 *cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
283 u32 offset, narrays;
284 int count, i, k;
286 count = ((*cmd & RADEON_CP_PACKET_COUNT_MASK) >> 16);
287 *cmdsz = 2 + count;
289 if ((*cmd & 0xc0000000) != RADEON_CP_PACKET3) {
290 DRM_ERROR("Not a type 3 packet\n");
291 return -EINVAL;
294 if (4 * *cmdsz > drm_buffer_unprocessed(cmdbuf->buffer)) {
295 DRM_ERROR("Packet size larger than size of data provided\n");
296 return -EINVAL;
299 switch (*cmd & 0xff00) {
301 case RADEON_3D_DRAW_IMMD:
302 case RADEON_3D_DRAW_VBUF:
303 case RADEON_3D_DRAW_INDX:
304 case RADEON_WAIT_FOR_IDLE:
305 case RADEON_CP_NOP:
306 case RADEON_3D_CLEAR_ZMASK:
307 /* case RADEON_CP_NEXT_CHAR:
308 case RADEON_CP_PLY_NEXTSCAN:
309 case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
310 /* these packets are safe */
311 break;
313 case RADEON_CP_3D_DRAW_IMMD_2:
314 case RADEON_CP_3D_DRAW_VBUF_2:
315 case RADEON_CP_3D_DRAW_INDX_2:
316 case RADEON_3D_CLEAR_HIZ:
317 /* safe but r200 only */
318 if (dev_priv->microcode_version != UCODE_R200) {
319 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
320 return -EINVAL;
322 break;
324 case RADEON_3D_LOAD_VBPNTR:
326 if (count > 18) { /* 12 arrays max */
327 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
328 count);
329 return -EINVAL;
332 /* carefully check packet contents */
333 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
335 narrays = *cmd & ~0xc000;
336 k = 0;
337 i = 2;
338 while ((k < narrays) && (i < (count + 2))) {
339 i++; /* skip attribute field */
340 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
341 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
342 cmd)) {
343 DRM_ERROR
344 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
345 k, i);
346 return -EINVAL;
348 k++;
349 i++;
350 if (k == narrays)
351 break;
352 /* have one more to process, they come in pairs */
353 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, i);
355 if (radeon_check_and_fixup_offset(dev_priv,
356 file_priv, cmd))
358 DRM_ERROR
359 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
360 k, i);
361 return -EINVAL;
363 k++;
364 i++;
366 /* do the counts match what we expect ? */
367 if ((k != narrays) || (i != (count + 2))) {
368 DRM_ERROR
369 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
370 k, i, narrays, count + 1);
371 return -EINVAL;
373 break;
375 case RADEON_3D_RNDR_GEN_INDX_PRIM:
376 if (dev_priv->microcode_version != UCODE_R100) {
377 DRM_ERROR("Invalid 3d packet for r200-class chip\n");
378 return -EINVAL;
381 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
382 if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
383 DRM_ERROR("Invalid rndr_gen_indx offset\n");
384 return -EINVAL;
386 break;
388 case RADEON_CP_INDX_BUFFER:
389 if (dev_priv->microcode_version != UCODE_R200) {
390 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
391 return -EINVAL;
394 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
395 if ((*cmd & 0x8000ffff) != 0x80000810) {
396 DRM_ERROR("Invalid indx_buffer reg address %08X\n", *cmd);
397 return -EINVAL;
399 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
400 if (radeon_check_and_fixup_offset(dev_priv, file_priv, cmd)) {
401 DRM_ERROR("Invalid indx_buffer offset is %08X\n", *cmd);
402 return -EINVAL;
404 break;
406 case RADEON_CNTL_HOSTDATA_BLT:
407 case RADEON_CNTL_PAINT_MULTI:
408 case RADEON_CNTL_BITBLT_MULTI:
409 /* MSB of opcode: next DWORD GUI_CNTL */
410 cmd = drm_buffer_pointer_to_dword(cmdbuf->buffer, 1);
411 if (*cmd & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
412 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
413 u32 *cmd2 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 2);
414 offset = *cmd2 << 10;
415 if (radeon_check_and_fixup_offset
416 (dev_priv, file_priv, &offset)) {
417 DRM_ERROR("Invalid first packet offset\n");
418 return -EINVAL;
420 *cmd2 = (*cmd2 & 0xffc00000) | offset >> 10;
423 if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
424 (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
425 u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
426 offset = *cmd3 << 10;
427 if (radeon_check_and_fixup_offset
428 (dev_priv, file_priv, &offset)) {
429 DRM_ERROR("Invalid second packet offset\n");
430 return -EINVAL;
432 *cmd3 = (*cmd3 & 0xffc00000) | offset >> 10;
434 break;
436 default:
437 DRM_ERROR("Invalid packet type %x\n", *cmd & 0xff00);
438 return -EINVAL;
441 return 0;
444 /* ================================================================
445 * CP hardware state programming functions
448 static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
449 struct drm_clip_rect * box)
451 RING_LOCALS;
453 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
454 box->x1, box->y1, box->x2, box->y2);
456 BEGIN_RING(4);
457 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
458 OUT_RING((box->y1 << 16) | box->x1);
459 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
460 OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
461 ADVANCE_RING();
464 /* Emit 1.1 state
466 static int radeon_emit_state(drm_radeon_private_t * dev_priv,
467 struct drm_file *file_priv,
468 drm_radeon_context_regs_t * ctx,
469 drm_radeon_texture_regs_t * tex,
470 unsigned int dirty)
472 RING_LOCALS;
473 DRM_DEBUG("dirty=0x%08x\n", dirty);
475 if (dirty & RADEON_UPLOAD_CONTEXT) {
476 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
477 &ctx->rb3d_depthoffset)) {
478 DRM_ERROR("Invalid depth buffer offset\n");
479 return -EINVAL;
482 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
483 &ctx->rb3d_coloroffset)) {
484 DRM_ERROR("Invalid depth buffer offset\n");
485 return -EINVAL;
488 BEGIN_RING(14);
489 OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
490 OUT_RING(ctx->pp_misc);
491 OUT_RING(ctx->pp_fog_color);
492 OUT_RING(ctx->re_solid_color);
493 OUT_RING(ctx->rb3d_blendcntl);
494 OUT_RING(ctx->rb3d_depthoffset);
495 OUT_RING(ctx->rb3d_depthpitch);
496 OUT_RING(ctx->rb3d_zstencilcntl);
497 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
498 OUT_RING(ctx->pp_cntl);
499 OUT_RING(ctx->rb3d_cntl);
500 OUT_RING(ctx->rb3d_coloroffset);
501 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
502 OUT_RING(ctx->rb3d_colorpitch);
503 ADVANCE_RING();
506 if (dirty & RADEON_UPLOAD_VERTFMT) {
507 BEGIN_RING(2);
508 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
509 OUT_RING(ctx->se_coord_fmt);
510 ADVANCE_RING();
513 if (dirty & RADEON_UPLOAD_LINE) {
514 BEGIN_RING(5);
515 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
516 OUT_RING(ctx->re_line_pattern);
517 OUT_RING(ctx->re_line_state);
518 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
519 OUT_RING(ctx->se_line_width);
520 ADVANCE_RING();
523 if (dirty & RADEON_UPLOAD_BUMPMAP) {
524 BEGIN_RING(5);
525 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
526 OUT_RING(ctx->pp_lum_matrix);
527 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
528 OUT_RING(ctx->pp_rot_matrix_0);
529 OUT_RING(ctx->pp_rot_matrix_1);
530 ADVANCE_RING();
533 if (dirty & RADEON_UPLOAD_MASKS) {
534 BEGIN_RING(4);
535 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
536 OUT_RING(ctx->rb3d_stencilrefmask);
537 OUT_RING(ctx->rb3d_ropcntl);
538 OUT_RING(ctx->rb3d_planemask);
539 ADVANCE_RING();
542 if (dirty & RADEON_UPLOAD_VIEWPORT) {
543 BEGIN_RING(7);
544 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
545 OUT_RING(ctx->se_vport_xscale);
546 OUT_RING(ctx->se_vport_xoffset);
547 OUT_RING(ctx->se_vport_yscale);
548 OUT_RING(ctx->se_vport_yoffset);
549 OUT_RING(ctx->se_vport_zscale);
550 OUT_RING(ctx->se_vport_zoffset);
551 ADVANCE_RING();
554 if (dirty & RADEON_UPLOAD_SETUP) {
555 BEGIN_RING(4);
556 OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
557 OUT_RING(ctx->se_cntl);
558 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
559 OUT_RING(ctx->se_cntl_status);
560 ADVANCE_RING();
563 if (dirty & RADEON_UPLOAD_MISC) {
564 BEGIN_RING(2);
565 OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
566 OUT_RING(ctx->re_misc);
567 ADVANCE_RING();
570 if (dirty & RADEON_UPLOAD_TEX0) {
571 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
572 &tex[0].pp_txoffset)) {
573 DRM_ERROR("Invalid texture offset for unit 0\n");
574 return -EINVAL;
577 BEGIN_RING(9);
578 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
579 OUT_RING(tex[0].pp_txfilter);
580 OUT_RING(tex[0].pp_txformat);
581 OUT_RING(tex[0].pp_txoffset);
582 OUT_RING(tex[0].pp_txcblend);
583 OUT_RING(tex[0].pp_txablend);
584 OUT_RING(tex[0].pp_tfactor);
585 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
586 OUT_RING(tex[0].pp_border_color);
587 ADVANCE_RING();
590 if (dirty & RADEON_UPLOAD_TEX1) {
591 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
592 &tex[1].pp_txoffset)) {
593 DRM_ERROR("Invalid texture offset for unit 1\n");
594 return -EINVAL;
597 BEGIN_RING(9);
598 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
599 OUT_RING(tex[1].pp_txfilter);
600 OUT_RING(tex[1].pp_txformat);
601 OUT_RING(tex[1].pp_txoffset);
602 OUT_RING(tex[1].pp_txcblend);
603 OUT_RING(tex[1].pp_txablend);
604 OUT_RING(tex[1].pp_tfactor);
605 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
606 OUT_RING(tex[1].pp_border_color);
607 ADVANCE_RING();
610 if (dirty & RADEON_UPLOAD_TEX2) {
611 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
612 &tex[2].pp_txoffset)) {
613 DRM_ERROR("Invalid texture offset for unit 2\n");
614 return -EINVAL;
617 BEGIN_RING(9);
618 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
619 OUT_RING(tex[2].pp_txfilter);
620 OUT_RING(tex[2].pp_txformat);
621 OUT_RING(tex[2].pp_txoffset);
622 OUT_RING(tex[2].pp_txcblend);
623 OUT_RING(tex[2].pp_txablend);
624 OUT_RING(tex[2].pp_tfactor);
625 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
626 OUT_RING(tex[2].pp_border_color);
627 ADVANCE_RING();
630 return 0;
633 /* Emit 1.2 state
635 static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
636 struct drm_file *file_priv,
637 drm_radeon_state_t * state)
639 RING_LOCALS;
641 if (state->dirty & RADEON_UPLOAD_ZBIAS) {
642 BEGIN_RING(3);
643 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
644 OUT_RING(state->context2.se_zbias_factor);
645 OUT_RING(state->context2.se_zbias_constant);
646 ADVANCE_RING();
649 return radeon_emit_state(dev_priv, file_priv, &state->context,
650 state->tex, state->dirty);
653 /* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
654 * 1.3 cmdbuffers allow all previous state to be updated as well as
655 * the tcl scalar and vector areas.
657 static struct {
658 int start;
659 int len;
660 const char *name;
661 } packet[RADEON_MAX_STATE_PACKETS] = {
662 {RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
663 {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
664 {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
665 {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
666 {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
667 {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
668 {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
669 {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
670 {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
671 {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
672 {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
673 {RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
674 {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
675 {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
676 {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
677 {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
678 {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
679 {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
680 {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
681 {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
682 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
683 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
684 {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
685 {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
686 {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
687 {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
688 {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
689 {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
690 {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
691 {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
692 {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
693 {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
694 {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
695 {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
696 {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
697 {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
698 {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
699 {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
700 {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
701 {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
702 {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
703 {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
704 {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
705 {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
706 {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
707 {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
708 {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
709 {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
710 {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
711 {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
712 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
713 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
714 {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
715 {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
716 {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
717 {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
718 {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
719 {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
720 {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
721 {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
722 {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
723 {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
724 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
725 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
726 {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
727 {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
728 {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
729 {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
730 {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
731 {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
732 {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
733 {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
734 {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
735 {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
736 {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
737 {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
738 {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
739 {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
740 {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
741 {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
742 {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
743 {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
744 {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
745 {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
746 {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
747 {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
748 {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
749 {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
750 {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
751 {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
752 {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
753 {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
754 {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
755 {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
756 {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
757 {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
758 {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
759 {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
762 /* ================================================================
763 * Performance monitoring functions
766 static void radeon_clear_box(drm_radeon_private_t * dev_priv,
767 struct drm_radeon_master_private *master_priv,
768 int x, int y, int w, int h, int r, int g, int b)
770 u32 color;
771 RING_LOCALS;
773 x += master_priv->sarea_priv->boxes[0].x1;
774 y += master_priv->sarea_priv->boxes[0].y1;
776 switch (dev_priv->color_fmt) {
777 case RADEON_COLOR_FORMAT_RGB565:
778 color = (((r & 0xf8) << 8) |
779 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
780 break;
781 case RADEON_COLOR_FORMAT_ARGB8888:
782 default:
783 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
784 break;
787 BEGIN_RING(4);
788 RADEON_WAIT_UNTIL_3D_IDLE();
789 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
790 OUT_RING(0xffffffff);
791 ADVANCE_RING();
793 BEGIN_RING(6);
795 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
796 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
797 RADEON_GMC_BRUSH_SOLID_COLOR |
798 (dev_priv->color_fmt << 8) |
799 RADEON_GMC_SRC_DATATYPE_COLOR |
800 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
802 if (master_priv->sarea_priv->pfCurrentPage == 1) {
803 OUT_RING(dev_priv->front_pitch_offset);
804 } else {
805 OUT_RING(dev_priv->back_pitch_offset);
808 OUT_RING(color);
810 OUT_RING((x << 16) | y);
811 OUT_RING((w << 16) | h);
813 ADVANCE_RING();
816 static void radeon_cp_performance_boxes(drm_radeon_private_t *dev_priv, struct drm_radeon_master_private *master_priv)
818 /* Collapse various things into a wait flag -- trying to
819 * guess if userspase slept -- better just to have them tell us.
821 if (dev_priv->stats.last_frame_reads > 1 ||
822 dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {
823 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
826 if (dev_priv->stats.freelist_loops) {
827 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
830 /* Purple box for page flipping
832 if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
833 radeon_clear_box(dev_priv, master_priv, 4, 4, 8, 8, 255, 0, 255);
835 /* Red box if we have to wait for idle at any point
837 if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
838 radeon_clear_box(dev_priv, master_priv, 16, 4, 8, 8, 255, 0, 0);
840 /* Blue box: lost context?
843 /* Yellow box for texture swaps
845 if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
846 radeon_clear_box(dev_priv, master_priv, 40, 4, 8, 8, 255, 255, 0);
848 /* Green box if hardware never idles (as far as we can tell)
850 if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
851 radeon_clear_box(dev_priv, master_priv, 64, 4, 8, 8, 0, 255, 0);
853 /* Draw bars indicating number of buffers allocated
854 * (not a great measure, easily confused)
856 if (dev_priv->stats.requested_bufs) {
857 if (dev_priv->stats.requested_bufs > 100)
858 dev_priv->stats.requested_bufs = 100;
860 radeon_clear_box(dev_priv, master_priv, 4, 16,
861 dev_priv->stats.requested_bufs, 4,
862 196, 128, 128);
865 memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
869 /* ================================================================
870 * CP command dispatch functions
873 static void radeon_cp_dispatch_clear(struct drm_device * dev,
874 struct drm_master *master,
875 drm_radeon_clear_t * clear,
876 drm_radeon_clear_rect_t * depth_boxes)
878 drm_radeon_private_t *dev_priv = dev->dev_private;
879 struct drm_radeon_master_private *master_priv = master->driver_priv;
880 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
881 drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
882 int nbox = sarea_priv->nbox;
883 struct drm_clip_rect *pbox = sarea_priv->boxes;
884 unsigned int flags = clear->flags;
885 u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
886 int i;
887 RING_LOCALS;
888 DRM_DEBUG("flags = 0x%x\n", flags);
890 dev_priv->stats.clears++;
892 if (sarea_priv->pfCurrentPage == 1) {
893 unsigned int tmp = flags;
895 flags &= ~(RADEON_FRONT | RADEON_BACK);
896 if (tmp & RADEON_FRONT)
897 flags |= RADEON_BACK;
898 if (tmp & RADEON_BACK)
899 flags |= RADEON_FRONT;
901 if (flags & (RADEON_DEPTH|RADEON_STENCIL)) {
902 if (!dev_priv->have_z_offset) {
903 printk_once(KERN_ERR "radeon: illegal depth clear request. Buggy mesa detected - please update.\n");
904 flags &= ~(RADEON_DEPTH | RADEON_STENCIL);
908 if (flags & (RADEON_FRONT | RADEON_BACK)) {
910 BEGIN_RING(4);
912 /* Ensure the 3D stream is idle before doing a
913 * 2D fill to clear the front or back buffer.
915 RADEON_WAIT_UNTIL_3D_IDLE();
917 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
918 OUT_RING(clear->color_mask);
920 ADVANCE_RING();
922 /* Make sure we restore the 3D state next time.
924 sarea_priv->ctx_owner = 0;
926 for (i = 0; i < nbox; i++) {
927 int x = pbox[i].x1;
928 int y = pbox[i].y1;
929 int w = pbox[i].x2 - x;
930 int h = pbox[i].y2 - y;
932 DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
933 x, y, w, h, flags);
935 if (flags & RADEON_FRONT) {
936 BEGIN_RING(6);
938 OUT_RING(CP_PACKET3
939 (RADEON_CNTL_PAINT_MULTI, 4));
940 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
941 RADEON_GMC_BRUSH_SOLID_COLOR |
942 (dev_priv->
943 color_fmt << 8) |
944 RADEON_GMC_SRC_DATATYPE_COLOR |
945 RADEON_ROP3_P |
946 RADEON_GMC_CLR_CMP_CNTL_DIS);
948 OUT_RING(dev_priv->front_pitch_offset);
949 OUT_RING(clear->clear_color);
951 OUT_RING((x << 16) | y);
952 OUT_RING((w << 16) | h);
954 ADVANCE_RING();
957 if (flags & RADEON_BACK) {
958 BEGIN_RING(6);
960 OUT_RING(CP_PACKET3
961 (RADEON_CNTL_PAINT_MULTI, 4));
962 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
963 RADEON_GMC_BRUSH_SOLID_COLOR |
964 (dev_priv->
965 color_fmt << 8) |
966 RADEON_GMC_SRC_DATATYPE_COLOR |
967 RADEON_ROP3_P |
968 RADEON_GMC_CLR_CMP_CNTL_DIS);
970 OUT_RING(dev_priv->back_pitch_offset);
971 OUT_RING(clear->clear_color);
973 OUT_RING((x << 16) | y);
974 OUT_RING((w << 16) | h);
976 ADVANCE_RING();
981 /* hyper z clear */
982 /* no docs available, based on reverse engeneering by Stephane Marchesin */
983 if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
984 && (flags & RADEON_CLEAR_FASTZ)) {
986 int i;
987 int depthpixperline =
988 dev_priv->depth_fmt ==
989 RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
990 2) : (dev_priv->
991 depth_pitch / 4);
993 u32 clearmask;
995 u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
996 ((clear->depth_mask & 0xff) << 24);
998 /* Make sure we restore the 3D state next time.
999 * we haven't touched any "normal" state - still need this?
1001 sarea_priv->ctx_owner = 0;
1003 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1004 && (flags & RADEON_USE_HIERZ)) {
1005 /* pattern seems to work for r100, though get slight
1006 rendering errors with glxgears. If hierz is not enabled for r100,
1007 only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
1008 other ones are ignored, and the same clear mask can be used. That's
1009 very different behaviour than R200 which needs different clear mask
1010 and different number of tiles to clear if hierz is enabled or not !?!
1012 clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
1013 } else {
1014 /* clear mask : chooses the clearing pattern.
1015 rv250: could be used to clear only parts of macrotiles
1016 (but that would get really complicated...)?
1017 bit 0 and 1 (either or both of them ?!?!) are used to
1018 not clear tile (or maybe one of the bits indicates if the tile is
1019 compressed or not), bit 2 and 3 to not clear tile 1,...,.
1020 Pattern is as follows:
1021 | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
1022 bits -------------------------------------------------
1023 | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
1024 rv100: clearmask covers 2x8 4x1 tiles, but one clear still
1025 covers 256 pixels ?!?
1027 clearmask = 0x0;
1030 BEGIN_RING(8);
1031 RADEON_WAIT_UNTIL_2D_IDLE();
1032 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
1033 tempRB3D_DEPTHCLEARVALUE);
1034 /* what offset is this exactly ? */
1035 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
1036 /* need ctlstat, otherwise get some strange black flickering */
1037 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
1038 RADEON_RB3D_ZC_FLUSH_ALL);
1039 ADVANCE_RING();
1041 for (i = 0; i < nbox; i++) {
1042 int tileoffset, nrtilesx, nrtilesy, j;
1043 /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
1044 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1045 && !(dev_priv->microcode_version == UCODE_R200)) {
1046 tileoffset =
1047 ((pbox[i].y1 >> 3) * depthpixperline +
1048 pbox[i].x1) >> 6;
1049 nrtilesx =
1050 ((pbox[i].x2 & ~63) -
1051 (pbox[i].x1 & ~63)) >> 4;
1052 nrtilesy =
1053 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1054 for (j = 0; j <= nrtilesy; j++) {
1055 BEGIN_RING(4);
1056 OUT_RING(CP_PACKET3
1057 (RADEON_3D_CLEAR_ZMASK, 2));
1058 /* first tile */
1059 OUT_RING(tileoffset * 8);
1060 /* the number of tiles to clear */
1061 OUT_RING(nrtilesx + 4);
1062 /* clear mask : chooses the clearing pattern. */
1063 OUT_RING(clearmask);
1064 ADVANCE_RING();
1065 tileoffset += depthpixperline >> 6;
1067 } else if (dev_priv->microcode_version == UCODE_R200) {
1068 /* works for rv250. */
1069 /* find first macro tile (8x2 4x4 z-pixels on rv250) */
1070 tileoffset =
1071 ((pbox[i].y1 >> 3) * depthpixperline +
1072 pbox[i].x1) >> 5;
1073 nrtilesx =
1074 (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
1075 nrtilesy =
1076 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1077 for (j = 0; j <= nrtilesy; j++) {
1078 BEGIN_RING(4);
1079 OUT_RING(CP_PACKET3
1080 (RADEON_3D_CLEAR_ZMASK, 2));
1081 /* first tile */
1082 /* judging by the first tile offset needed, could possibly
1083 directly address/clear 4x4 tiles instead of 8x2 * 4x4
1084 macro tiles, though would still need clear mask for
1085 right/bottom if truly 4x4 granularity is desired ? */
1086 OUT_RING(tileoffset * 16);
1087 /* the number of tiles to clear */
1088 OUT_RING(nrtilesx + 1);
1089 /* clear mask : chooses the clearing pattern. */
1090 OUT_RING(clearmask);
1091 ADVANCE_RING();
1092 tileoffset += depthpixperline >> 5;
1094 } else { /* rv 100 */
1095 /* rv100 might not need 64 pix alignment, who knows */
1096 /* offsets are, hmm, weird */
1097 tileoffset =
1098 ((pbox[i].y1 >> 4) * depthpixperline +
1099 pbox[i].x1) >> 6;
1100 nrtilesx =
1101 ((pbox[i].x2 & ~63) -
1102 (pbox[i].x1 & ~63)) >> 4;
1103 nrtilesy =
1104 (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
1105 for (j = 0; j <= nrtilesy; j++) {
1106 BEGIN_RING(4);
1107 OUT_RING(CP_PACKET3
1108 (RADEON_3D_CLEAR_ZMASK, 2));
1109 OUT_RING(tileoffset * 128);
1110 /* the number of tiles to clear */
1111 OUT_RING(nrtilesx + 4);
1112 /* clear mask : chooses the clearing pattern. */
1113 OUT_RING(clearmask);
1114 ADVANCE_RING();
1115 tileoffset += depthpixperline >> 6;
1120 /* TODO don't always clear all hi-level z tiles */
1121 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1122 && (dev_priv->microcode_version == UCODE_R200)
1123 && (flags & RADEON_USE_HIERZ))
1124 /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
1126 BEGIN_RING(4);
1127 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
1128 OUT_RING(0x0); /* First tile */
1129 OUT_RING(0x3cc0);
1130 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1131 ADVANCE_RING();
1135 /* We have to clear the depth and/or stencil buffers by
1136 * rendering a quad into just those buffers. Thus, we have to
1137 * make sure the 3D engine is configured correctly.
1139 else if ((dev_priv->microcode_version == UCODE_R200) &&
1140 (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1142 int tempPP_CNTL;
1143 int tempRE_CNTL;
1144 int tempRB3D_CNTL;
1145 int tempRB3D_ZSTENCILCNTL;
1146 int tempRB3D_STENCILREFMASK;
1147 int tempRB3D_PLANEMASK;
1148 int tempSE_CNTL;
1149 int tempSE_VTE_CNTL;
1150 int tempSE_VTX_FMT_0;
1151 int tempSE_VTX_FMT_1;
1152 int tempSE_VAP_CNTL;
1153 int tempRE_AUX_SCISSOR_CNTL;
1155 tempPP_CNTL = 0;
1156 tempRE_CNTL = 0;
1158 tempRB3D_CNTL = depth_clear->rb3d_cntl;
1160 tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1161 tempRB3D_STENCILREFMASK = 0x0;
1163 tempSE_CNTL = depth_clear->se_cntl;
1165 /* Disable TCL */
1167 tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1168 (0x9 <<
1169 SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
1171 tempRB3D_PLANEMASK = 0x0;
1173 tempRE_AUX_SCISSOR_CNTL = 0x0;
1175 tempSE_VTE_CNTL =
1176 SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
1178 /* Vertex format (X, Y, Z, W) */
1179 tempSE_VTX_FMT_0 =
1180 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
1181 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
1182 tempSE_VTX_FMT_1 = 0x0;
1185 * Depth buffer specific enables
1187 if (flags & RADEON_DEPTH) {
1188 /* Enable depth buffer */
1189 tempRB3D_CNTL |= RADEON_Z_ENABLE;
1190 } else {
1191 /* Disable depth buffer */
1192 tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
1196 * Stencil buffer specific enables
1198 if (flags & RADEON_STENCIL) {
1199 tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
1200 tempRB3D_STENCILREFMASK = clear->depth_mask;
1201 } else {
1202 tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
1203 tempRB3D_STENCILREFMASK = 0x00000000;
1206 if (flags & RADEON_USE_COMP_ZBUF) {
1207 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1208 RADEON_Z_DECOMPRESSION_ENABLE;
1210 if (flags & RADEON_USE_HIERZ) {
1211 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1214 BEGIN_RING(26);
1215 RADEON_WAIT_UNTIL_2D_IDLE();
1217 OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
1218 OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
1219 OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
1220 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1221 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
1222 tempRB3D_STENCILREFMASK);
1223 OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
1224 OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
1225 OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
1226 OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
1227 OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
1228 OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
1229 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
1230 ADVANCE_RING();
1232 /* Make sure we restore the 3D state next time.
1234 sarea_priv->ctx_owner = 0;
1236 for (i = 0; i < nbox; i++) {
1238 /* Funny that this should be required --
1239 * sets top-left?
1241 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1243 BEGIN_RING(14);
1244 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
1245 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1246 RADEON_PRIM_WALK_RING |
1247 (3 << RADEON_NUM_VERTICES_SHIFT)));
1248 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1249 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1250 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1251 OUT_RING(0x3f800000);
1252 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1253 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1254 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1255 OUT_RING(0x3f800000);
1256 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1257 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1258 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1259 OUT_RING(0x3f800000);
1260 ADVANCE_RING();
1262 } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1264 int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1266 rb3d_cntl = depth_clear->rb3d_cntl;
1268 if (flags & RADEON_DEPTH) {
1269 rb3d_cntl |= RADEON_Z_ENABLE;
1270 } else {
1271 rb3d_cntl &= ~RADEON_Z_ENABLE;
1274 if (flags & RADEON_STENCIL) {
1275 rb3d_cntl |= RADEON_STENCIL_ENABLE;
1276 rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
1277 } else {
1278 rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
1279 rb3d_stencilrefmask = 0x00000000;
1282 if (flags & RADEON_USE_COMP_ZBUF) {
1283 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1284 RADEON_Z_DECOMPRESSION_ENABLE;
1286 if (flags & RADEON_USE_HIERZ) {
1287 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1290 BEGIN_RING(13);
1291 RADEON_WAIT_UNTIL_2D_IDLE();
1293 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
1294 OUT_RING(0x00000000);
1295 OUT_RING(rb3d_cntl);
1297 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1298 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
1299 OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
1300 OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
1301 ADVANCE_RING();
1303 /* Make sure we restore the 3D state next time.
1305 sarea_priv->ctx_owner = 0;
1307 for (i = 0; i < nbox; i++) {
1309 /* Funny that this should be required --
1310 * sets top-left?
1312 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1314 BEGIN_RING(15);
1316 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
1317 OUT_RING(RADEON_VTX_Z_PRESENT |
1318 RADEON_VTX_PKCOLOR_PRESENT);
1319 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1320 RADEON_PRIM_WALK_RING |
1321 RADEON_MAOS_ENABLE |
1322 RADEON_VTX_FMT_RADEON_MODE |
1323 (3 << RADEON_NUM_VERTICES_SHIFT)));
1325 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1326 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1327 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1328 OUT_RING(0x0);
1330 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1331 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1332 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1333 OUT_RING(0x0);
1335 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1336 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1337 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1338 OUT_RING(0x0);
1340 ADVANCE_RING();
1344 /* Increment the clear counter. The client-side 3D driver must
1345 * wait on this value before performing the clear ioctl. We
1346 * need this because the card's so damned fast...
1348 sarea_priv->last_clear++;
1350 BEGIN_RING(4);
1352 RADEON_CLEAR_AGE(sarea_priv->last_clear);
1353 RADEON_WAIT_UNTIL_IDLE();
1355 ADVANCE_RING();
1358 static void radeon_cp_dispatch_swap(struct drm_device *dev, struct drm_master *master)
1360 drm_radeon_private_t *dev_priv = dev->dev_private;
1361 struct drm_radeon_master_private *master_priv = master->driver_priv;
1362 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1363 int nbox = sarea_priv->nbox;
1364 struct drm_clip_rect *pbox = sarea_priv->boxes;
1365 int i;
1366 RING_LOCALS;
1367 DRM_DEBUG("\n");
1369 /* Do some trivial performance monitoring...
1371 if (dev_priv->do_boxes)
1372 radeon_cp_performance_boxes(dev_priv, master_priv);
1374 /* Wait for the 3D stream to idle before dispatching the bitblt.
1375 * This will prevent data corruption between the two streams.
1377 BEGIN_RING(2);
1379 RADEON_WAIT_UNTIL_3D_IDLE();
1381 ADVANCE_RING();
1383 for (i = 0; i < nbox; i++) {
1384 int x = pbox[i].x1;
1385 int y = pbox[i].y1;
1386 int w = pbox[i].x2 - x;
1387 int h = pbox[i].y2 - y;
1389 DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
1391 BEGIN_RING(9);
1393 OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
1394 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1395 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1396 RADEON_GMC_BRUSH_NONE |
1397 (dev_priv->color_fmt << 8) |
1398 RADEON_GMC_SRC_DATATYPE_COLOR |
1399 RADEON_ROP3_S |
1400 RADEON_DP_SRC_SOURCE_MEMORY |
1401 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1403 /* Make this work even if front & back are flipped:
1405 OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
1406 if (sarea_priv->pfCurrentPage == 0) {
1407 OUT_RING(dev_priv->back_pitch_offset);
1408 OUT_RING(dev_priv->front_pitch_offset);
1409 } else {
1410 OUT_RING(dev_priv->front_pitch_offset);
1411 OUT_RING(dev_priv->back_pitch_offset);
1414 OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
1415 OUT_RING((x << 16) | y);
1416 OUT_RING((x << 16) | y);
1417 OUT_RING((w << 16) | h);
1419 ADVANCE_RING();
1422 /* Increment the frame counter. The client-side 3D driver must
1423 * throttle the framerate by waiting for this value before
1424 * performing the swapbuffer ioctl.
1426 sarea_priv->last_frame++;
1428 BEGIN_RING(4);
1430 RADEON_FRAME_AGE(sarea_priv->last_frame);
1431 RADEON_WAIT_UNTIL_2D_IDLE();
1433 ADVANCE_RING();
1436 void radeon_cp_dispatch_flip(struct drm_device *dev, struct drm_master *master)
1438 drm_radeon_private_t *dev_priv = dev->dev_private;
1439 struct drm_radeon_master_private *master_priv = master->driver_priv;
1440 struct drm_sarea *sarea = (struct drm_sarea *)master_priv->sarea->handle;
1441 int offset = (master_priv->sarea_priv->pfCurrentPage == 1)
1442 ? dev_priv->front_offset : dev_priv->back_offset;
1443 RING_LOCALS;
1444 DRM_DEBUG("pfCurrentPage=%d\n",
1445 master_priv->sarea_priv->pfCurrentPage);
1447 /* Do some trivial performance monitoring...
1449 if (dev_priv->do_boxes) {
1450 dev_priv->stats.boxes |= RADEON_BOX_FLIP;
1451 radeon_cp_performance_boxes(dev_priv, master_priv);
1454 /* Update the frame offsets for both CRTCs
1456 BEGIN_RING(6);
1458 RADEON_WAIT_UNTIL_3D_IDLE();
1459 OUT_RING_REG(RADEON_CRTC_OFFSET,
1460 ((sarea->frame.y * dev_priv->front_pitch +
1461 sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
1462 + offset);
1463 OUT_RING_REG(RADEON_CRTC2_OFFSET, master_priv->sarea_priv->crtc2_base
1464 + offset);
1466 ADVANCE_RING();
1468 /* Increment the frame counter. The client-side 3D driver must
1469 * throttle the framerate by waiting for this value before
1470 * performing the swapbuffer ioctl.
1472 master_priv->sarea_priv->last_frame++;
1473 master_priv->sarea_priv->pfCurrentPage =
1474 1 - master_priv->sarea_priv->pfCurrentPage;
1476 BEGIN_RING(2);
1478 RADEON_FRAME_AGE(master_priv->sarea_priv->last_frame);
1480 ADVANCE_RING();
1483 static int bad_prim_vertex_nr(int primitive, int nr)
1485 switch (primitive & RADEON_PRIM_TYPE_MASK) {
1486 case RADEON_PRIM_TYPE_NONE:
1487 case RADEON_PRIM_TYPE_POINT:
1488 return nr < 1;
1489 case RADEON_PRIM_TYPE_LINE:
1490 return (nr & 1) || nr == 0;
1491 case RADEON_PRIM_TYPE_LINE_STRIP:
1492 return nr < 2;
1493 case RADEON_PRIM_TYPE_TRI_LIST:
1494 case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
1495 case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
1496 case RADEON_PRIM_TYPE_RECT_LIST:
1497 return nr % 3 || nr == 0;
1498 case RADEON_PRIM_TYPE_TRI_FAN:
1499 case RADEON_PRIM_TYPE_TRI_STRIP:
1500 return nr < 3;
1501 default:
1502 return 1;
1506 typedef struct {
1507 unsigned int start;
1508 unsigned int finish;
1509 unsigned int prim;
1510 unsigned int numverts;
1511 unsigned int offset;
1512 unsigned int vc_format;
1513 } drm_radeon_tcl_prim_t;
1515 static void radeon_cp_dispatch_vertex(struct drm_device * dev,
1516 struct drm_file *file_priv,
1517 struct drm_buf * buf,
1518 drm_radeon_tcl_prim_t * prim)
1520 drm_radeon_private_t *dev_priv = dev->dev_private;
1521 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
1522 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1523 int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
1524 int numverts = (int)prim->numverts;
1525 int nbox = sarea_priv->nbox;
1526 int i = 0;
1527 RING_LOCALS;
1529 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1530 prim->prim,
1531 prim->vc_format, prim->start, prim->finish, prim->numverts);
1533 if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
1534 DRM_ERROR("bad prim %x numverts %d\n",
1535 prim->prim, prim->numverts);
1536 return;
1539 do {
1540 /* Emit the next cliprect */
1541 if (i < nbox) {
1542 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1545 /* Emit the vertex buffer rendering commands */
1546 BEGIN_RING(5);
1548 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
1549 OUT_RING(offset);
1550 OUT_RING(numverts);
1551 OUT_RING(prim->vc_format);
1552 OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
1553 RADEON_COLOR_ORDER_RGBA |
1554 RADEON_VTX_FMT_RADEON_MODE |
1555 (numverts << RADEON_NUM_VERTICES_SHIFT));
1557 ADVANCE_RING();
1559 i++;
1560 } while (i < nbox);
1563 void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
1565 drm_radeon_private_t *dev_priv = dev->dev_private;
1566 struct drm_radeon_master_private *master_priv = master->driver_priv;
1567 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1568 RING_LOCALS;
1570 buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
1572 /* Emit the vertex buffer age */
1573 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
1574 BEGIN_RING(3);
1575 R600_DISPATCH_AGE(buf_priv->age);
1576 ADVANCE_RING();
1577 } else {
1578 BEGIN_RING(2);
1579 RADEON_DISPATCH_AGE(buf_priv->age);
1580 ADVANCE_RING();
1583 buf->pending = 1;
1584 buf->used = 0;
1587 static void radeon_cp_dispatch_indirect(struct drm_device * dev,
1588 struct drm_buf * buf, int start, int end)
1590 drm_radeon_private_t *dev_priv = dev->dev_private;
1591 RING_LOCALS;
1592 DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
1594 if (start != end) {
1595 int offset = (dev_priv->gart_buffers_offset
1596 + buf->offset + start);
1597 int dwords = (end - start + 3) / sizeof(u32);
1599 /* Indirect buffer data must be an even number of
1600 * dwords, so if we've been given an odd number we must
1601 * pad the data with a Type-2 CP packet.
1603 if (dwords & 1) {
1604 u32 *data = (u32 *)
1605 ((char *)dev->agp_buffer_map->handle
1606 + buf->offset + start);
1607 data[dwords++] = RADEON_CP_PACKET2;
1610 /* Fire off the indirect buffer */
1611 BEGIN_RING(3);
1613 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
1614 OUT_RING(offset);
1615 OUT_RING(dwords);
1617 ADVANCE_RING();
1621 static void radeon_cp_dispatch_indices(struct drm_device *dev,
1622 struct drm_master *master,
1623 struct drm_buf * elt_buf,
1624 drm_radeon_tcl_prim_t * prim)
1626 drm_radeon_private_t *dev_priv = dev->dev_private;
1627 struct drm_radeon_master_private *master_priv = master->driver_priv;
1628 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
1629 int offset = dev_priv->gart_buffers_offset + prim->offset;
1630 u32 *data;
1631 int dwords;
1632 int i = 0;
1633 int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
1634 int count = (prim->finish - start) / sizeof(u16);
1635 int nbox = sarea_priv->nbox;
1637 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1638 prim->prim,
1639 prim->vc_format,
1640 prim->start, prim->finish, prim->offset, prim->numverts);
1642 if (bad_prim_vertex_nr(prim->prim, count)) {
1643 DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
1644 return;
1647 if (start >= prim->finish || (prim->start & 0x7)) {
1648 DRM_ERROR("buffer prim %d\n", prim->prim);
1649 return;
1652 dwords = (prim->finish - prim->start + 3) / sizeof(u32);
1654 data = (u32 *) ((char *)dev->agp_buffer_map->handle +
1655 elt_buf->offset + prim->start);
1657 data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
1658 data[1] = offset;
1659 data[2] = prim->numverts;
1660 data[3] = prim->vc_format;
1661 data[4] = (prim->prim |
1662 RADEON_PRIM_WALK_IND |
1663 RADEON_COLOR_ORDER_RGBA |
1664 RADEON_VTX_FMT_RADEON_MODE |
1665 (count << RADEON_NUM_VERTICES_SHIFT));
1667 do {
1668 if (i < nbox)
1669 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1671 radeon_cp_dispatch_indirect(dev, elt_buf,
1672 prim->start, prim->finish);
1674 i++;
1675 } while (i < nbox);
1679 #define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1681 static int radeon_cp_dispatch_texture(struct drm_device * dev,
1682 struct drm_file *file_priv,
1683 drm_radeon_texture_t * tex,
1684 drm_radeon_tex_image_t * image)
1686 drm_radeon_private_t *dev_priv = dev->dev_private;
1687 struct drm_buf *buf;
1688 u32 format;
1689 u32 *buffer;
1690 const u8 __user *data;
1691 int size, dwords, tex_width, blit_width, spitch;
1692 u32 height;
1693 int i;
1694 u32 texpitch, microtile;
1695 u32 offset, byte_offset;
1696 RING_LOCALS;
1698 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
1699 DRM_ERROR("Invalid destination offset\n");
1700 return -EINVAL;
1703 dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
1705 /* Flush the pixel cache. This ensures no pixel data gets mixed
1706 * up with the texture data from the host data blit, otherwise
1707 * part of the texture image may be corrupted.
1709 BEGIN_RING(4);
1710 RADEON_FLUSH_CACHE();
1711 RADEON_WAIT_UNTIL_IDLE();
1712 ADVANCE_RING();
1714 /* The compiler won't optimize away a division by a variable,
1715 * even if the only legal values are powers of two. Thus, we'll
1716 * use a shift instead.
1718 switch (tex->format) {
1719 case RADEON_TXFORMAT_ARGB8888:
1720 case RADEON_TXFORMAT_RGBA8888:
1721 format = RADEON_COLOR_FORMAT_ARGB8888;
1722 tex_width = tex->width * 4;
1723 blit_width = image->width * 4;
1724 break;
1725 case RADEON_TXFORMAT_AI88:
1726 case RADEON_TXFORMAT_ARGB1555:
1727 case RADEON_TXFORMAT_RGB565:
1728 case RADEON_TXFORMAT_ARGB4444:
1729 case RADEON_TXFORMAT_VYUY422:
1730 case RADEON_TXFORMAT_YVYU422:
1731 format = RADEON_COLOR_FORMAT_RGB565;
1732 tex_width = tex->width * 2;
1733 blit_width = image->width * 2;
1734 break;
1735 case RADEON_TXFORMAT_I8:
1736 case RADEON_TXFORMAT_RGB332:
1737 format = RADEON_COLOR_FORMAT_CI8;
1738 tex_width = tex->width * 1;
1739 blit_width = image->width * 1;
1740 break;
1741 default:
1742 DRM_ERROR("invalid texture format %d\n", tex->format);
1743 return -EINVAL;
1745 spitch = blit_width >> 6;
1746 if (spitch == 0 && image->height > 1)
1747 return -EINVAL;
1749 texpitch = tex->pitch;
1750 if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
1751 microtile = 1;
1752 if (tex_width < 64) {
1753 texpitch &= ~(RADEON_DST_TILE_MICRO >> 22);
1754 /* we got tiled coordinates, untile them */
1755 image->x *= 2;
1757 } else
1758 microtile = 0;
1760 /* this might fail for zero-sized uploads - are those illegal? */
1761 if (!radeon_check_offset(dev_priv, tex->offset + image->height *
1762 blit_width - 1)) {
1763 DRM_ERROR("Invalid final destination offset\n");
1764 return -EINVAL;
1767 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
1769 do {
1770 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1771 tex->offset >> 10, tex->pitch, tex->format,
1772 image->x, image->y, image->width, image->height);
1774 /* Make a copy of some parameters in case we have to
1775 * update them for a multi-pass texture blit.
1777 height = image->height;
1778 data = (const u8 __user *)image->data;
1780 size = height * blit_width;
1782 if (size > RADEON_MAX_TEXTURE_SIZE) {
1783 height = RADEON_MAX_TEXTURE_SIZE / blit_width;
1784 size = height * blit_width;
1785 } else if (size < 4 && size > 0) {
1786 size = 4;
1787 } else if (size == 0) {
1788 return 0;
1791 buf = radeon_freelist_get(dev);
1792 if (0 && !buf) {
1793 radeon_do_cp_idle(dev_priv);
1794 buf = radeon_freelist_get(dev);
1796 if (!buf) {
1797 DRM_DEBUG("EAGAIN\n");
1798 if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
1799 return -EFAULT;
1800 return -EAGAIN;
1803 /* Dispatch the indirect buffer.
1805 buffer =
1806 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
1807 dwords = size / 4;
1809 #define RADEON_COPY_MT(_buf, _data, _width) \
1810 do { \
1811 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1812 DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1813 return -EFAULT; \
1815 } while(0)
1817 if (microtile) {
1818 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1819 however, we cannot use blitter directly for texture width < 64 bytes,
1820 since minimum tex pitch is 64 bytes and we need this to match
1821 the texture width, otherwise the blitter will tile it wrong.
1822 Thus, tiling manually in this case. Additionally, need to special
1823 case tex height = 1, since our actual image will have height 2
1824 and we need to ensure we don't read beyond the texture size
1825 from user space. */
1826 if (tex->height == 1) {
1827 if (tex_width >= 64 || tex_width <= 16) {
1828 RADEON_COPY_MT(buffer, data,
1829 (int)(tex_width * sizeof(u32)));
1830 } else if (tex_width == 32) {
1831 RADEON_COPY_MT(buffer, data, 16);
1832 RADEON_COPY_MT(buffer + 8,
1833 data + 16, 16);
1835 } else if (tex_width >= 64 || tex_width == 16) {
1836 RADEON_COPY_MT(buffer, data,
1837 (int)(dwords * sizeof(u32)));
1838 } else if (tex_width < 16) {
1839 for (i = 0; i < tex->height; i++) {
1840 RADEON_COPY_MT(buffer, data, tex_width);
1841 buffer += 4;
1842 data += tex_width;
1844 } else if (tex_width == 32) {
1845 /* TODO: make sure this works when not fitting in one buffer
1846 (i.e. 32bytes x 2048...) */
1847 for (i = 0; i < tex->height; i += 2) {
1848 RADEON_COPY_MT(buffer, data, 16);
1849 data += 16;
1850 RADEON_COPY_MT(buffer + 8, data, 16);
1851 data += 16;
1852 RADEON_COPY_MT(buffer + 4, data, 16);
1853 data += 16;
1854 RADEON_COPY_MT(buffer + 12, data, 16);
1855 data += 16;
1856 buffer += 16;
1859 } else {
1860 if (tex_width >= 32) {
1861 /* Texture image width is larger than the minimum, so we
1862 * can upload it directly.
1864 RADEON_COPY_MT(buffer, data,
1865 (int)(dwords * sizeof(u32)));
1866 } else {
1867 /* Texture image width is less than the minimum, so we
1868 * need to pad out each image scanline to the minimum
1869 * width.
1871 for (i = 0; i < tex->height; i++) {
1872 RADEON_COPY_MT(buffer, data, tex_width);
1873 buffer += 8;
1874 data += tex_width;
1879 #undef RADEON_COPY_MT
1880 byte_offset = (image->y & ~2047) * blit_width;
1881 buf->file_priv = file_priv;
1882 buf->used = size;
1883 offset = dev_priv->gart_buffers_offset + buf->offset;
1884 BEGIN_RING(9);
1885 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
1886 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1887 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1888 RADEON_GMC_BRUSH_NONE |
1889 (format << 8) |
1890 RADEON_GMC_SRC_DATATYPE_COLOR |
1891 RADEON_ROP3_S |
1892 RADEON_DP_SRC_SOURCE_MEMORY |
1893 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1894 OUT_RING((spitch << 22) | (offset >> 10));
1895 OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
1896 OUT_RING(0);
1897 OUT_RING((image->x << 16) | (image->y % 2048));
1898 OUT_RING((image->width << 16) | height);
1899 RADEON_WAIT_UNTIL_2D_IDLE();
1900 ADVANCE_RING();
1901 COMMIT_RING();
1903 radeon_cp_discard_buffer(dev, file_priv->master, buf);
1905 /* Update the input parameters for next time */
1906 image->y += height;
1907 image->height -= height;
1908 image->data = (const u8 __user *)image->data + size;
1909 } while (image->height > 0);
1911 /* Flush the pixel cache after the blit completes. This ensures
1912 * the texture data is written out to memory before rendering
1913 * continues.
1915 BEGIN_RING(4);
1916 RADEON_FLUSH_CACHE();
1917 RADEON_WAIT_UNTIL_2D_IDLE();
1918 ADVANCE_RING();
1919 COMMIT_RING();
1921 return 0;
1924 static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1926 drm_radeon_private_t *dev_priv = dev->dev_private;
1927 int i;
1928 RING_LOCALS;
1929 DRM_DEBUG("\n");
1931 BEGIN_RING(35);
1933 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
1934 OUT_RING(0x00000000);
1936 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
1937 for (i = 0; i < 32; i++) {
1938 OUT_RING(stipple[i]);
1941 ADVANCE_RING();
1944 static void radeon_apply_surface_regs(int surf_index,
1945 drm_radeon_private_t *dev_priv)
1947 if (!dev_priv->mmio)
1948 return;
1950 radeon_do_cp_idle(dev_priv);
1952 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
1953 dev_priv->surfaces[surf_index].flags);
1954 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
1955 dev_priv->surfaces[surf_index].lower);
1956 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
1957 dev_priv->surfaces[surf_index].upper);
1960 /* Allocates a virtual surface
1961 * doesn't always allocate a real surface, will stretch an existing
1962 * surface when possible.
1964 * Note that refcount can be at most 2, since during a free refcount=3
1965 * might mean we have to allocate a new surface which might not always
1966 * be available.
1967 * For example : we allocate three contiguous surfaces ABC. If B is
1968 * freed, we suddenly need two surfaces to store A and C, which might
1969 * not always be available.
1971 static int alloc_surface(drm_radeon_surface_alloc_t *new,
1972 drm_radeon_private_t *dev_priv,
1973 struct drm_file *file_priv)
1975 struct radeon_virt_surface *s;
1976 int i;
1977 int virt_surface_index;
1978 uint32_t new_upper, new_lower;
1980 new_lower = new->address;
1981 new_upper = new_lower + new->size - 1;
1983 /* sanity check */
1984 if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
1985 ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
1986 RADEON_SURF_ADDRESS_FIXED_MASK)
1987 || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
1988 return -1;
1990 /* make sure there is no overlap with existing surfaces */
1991 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1992 if ((dev_priv->surfaces[i].refcount != 0) &&
1993 (((new_lower >= dev_priv->surfaces[i].lower) &&
1994 (new_lower < dev_priv->surfaces[i].upper)) ||
1995 ((new_lower < dev_priv->surfaces[i].lower) &&
1996 (new_upper > dev_priv->surfaces[i].lower)))) {
1997 return -1;
2001 /* find a virtual surface */
2002 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
2003 if (dev_priv->virt_surfaces[i].file_priv == NULL)
2004 break;
2005 if (i == 2 * RADEON_MAX_SURFACES) {
2006 return -1;
2008 virt_surface_index = i;
2010 /* try to reuse an existing surface */
2011 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2012 /* extend before */
2013 if ((dev_priv->surfaces[i].refcount == 1) &&
2014 (new->flags == dev_priv->surfaces[i].flags) &&
2015 (new_upper + 1 == dev_priv->surfaces[i].lower)) {
2016 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2017 s->surface_index = i;
2018 s->lower = new_lower;
2019 s->upper = new_upper;
2020 s->flags = new->flags;
2021 s->file_priv = file_priv;
2022 dev_priv->surfaces[i].refcount++;
2023 dev_priv->surfaces[i].lower = s->lower;
2024 radeon_apply_surface_regs(s->surface_index, dev_priv);
2025 return virt_surface_index;
2028 /* extend after */
2029 if ((dev_priv->surfaces[i].refcount == 1) &&
2030 (new->flags == dev_priv->surfaces[i].flags) &&
2031 (new_lower == dev_priv->surfaces[i].upper + 1)) {
2032 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2033 s->surface_index = i;
2034 s->lower = new_lower;
2035 s->upper = new_upper;
2036 s->flags = new->flags;
2037 s->file_priv = file_priv;
2038 dev_priv->surfaces[i].refcount++;
2039 dev_priv->surfaces[i].upper = s->upper;
2040 radeon_apply_surface_regs(s->surface_index, dev_priv);
2041 return virt_surface_index;
2045 /* okay, we need a new one */
2046 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2047 if (dev_priv->surfaces[i].refcount == 0) {
2048 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2049 s->surface_index = i;
2050 s->lower = new_lower;
2051 s->upper = new_upper;
2052 s->flags = new->flags;
2053 s->file_priv = file_priv;
2054 dev_priv->surfaces[i].refcount = 1;
2055 dev_priv->surfaces[i].lower = s->lower;
2056 dev_priv->surfaces[i].upper = s->upper;
2057 dev_priv->surfaces[i].flags = s->flags;
2058 radeon_apply_surface_regs(s->surface_index, dev_priv);
2059 return virt_surface_index;
2063 /* we didn't find anything */
2064 return -1;
2067 static int free_surface(struct drm_file *file_priv,
2068 drm_radeon_private_t * dev_priv,
2069 int lower)
2071 struct radeon_virt_surface *s;
2072 int i;
2073 /* find the virtual surface */
2074 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2075 s = &(dev_priv->virt_surfaces[i]);
2076 if (s->file_priv) {
2077 if ((lower == s->lower) && (file_priv == s->file_priv))
2079 if (dev_priv->surfaces[s->surface_index].
2080 lower == s->lower)
2081 dev_priv->surfaces[s->surface_index].
2082 lower = s->upper;
2084 if (dev_priv->surfaces[s->surface_index].
2085 upper == s->upper)
2086 dev_priv->surfaces[s->surface_index].
2087 upper = s->lower;
2089 dev_priv->surfaces[s->surface_index].refcount--;
2090 if (dev_priv->surfaces[s->surface_index].
2091 refcount == 0)
2092 dev_priv->surfaces[s->surface_index].
2093 flags = 0;
2094 s->file_priv = NULL;
2095 radeon_apply_surface_regs(s->surface_index,
2096 dev_priv);
2097 return 0;
2101 return 1;
2104 static void radeon_surfaces_release(struct drm_file *file_priv,
2105 drm_radeon_private_t * dev_priv)
2107 int i;
2108 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2109 if (dev_priv->virt_surfaces[i].file_priv == file_priv)
2110 free_surface(file_priv, dev_priv,
2111 dev_priv->virt_surfaces[i].lower);
2115 /* ================================================================
2116 * IOCTL functions
2118 static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
2120 drm_radeon_private_t *dev_priv = dev->dev_private;
2121 drm_radeon_surface_alloc_t *alloc = data;
2123 if (alloc_surface(alloc, dev_priv, file_priv) == -1)
2124 return -EINVAL;
2125 else
2126 return 0;
2129 static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2131 drm_radeon_private_t *dev_priv = dev->dev_private;
2132 drm_radeon_surface_free_t *memfree = data;
2134 if (free_surface(file_priv, dev_priv, memfree->address))
2135 return -EINVAL;
2136 else
2137 return 0;
2140 static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
2142 drm_radeon_private_t *dev_priv = dev->dev_private;
2143 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2144 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
2145 drm_radeon_clear_t *clear = data;
2146 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
2147 DRM_DEBUG("\n");
2149 LOCK_TEST_WITH_RETURN(dev, file_priv);
2151 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2153 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2154 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2156 if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
2157 sarea_priv->nbox * sizeof(depth_boxes[0])))
2158 return -EFAULT;
2160 radeon_cp_dispatch_clear(dev, file_priv->master, clear, depth_boxes);
2162 COMMIT_RING();
2163 return 0;
2166 /* Not sure why this isn't set all the time:
2168 static int radeon_do_init_pageflip(struct drm_device *dev, struct drm_master *master)
2170 drm_radeon_private_t *dev_priv = dev->dev_private;
2171 struct drm_radeon_master_private *master_priv = master->driver_priv;
2172 RING_LOCALS;
2174 DRM_DEBUG("\n");
2176 BEGIN_RING(6);
2177 RADEON_WAIT_UNTIL_3D_IDLE();
2178 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
2179 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
2180 RADEON_CRTC_OFFSET_FLIP_CNTL);
2181 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
2182 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
2183 RADEON_CRTC_OFFSET_FLIP_CNTL);
2184 ADVANCE_RING();
2186 dev_priv->page_flipping = 1;
2188 if (master_priv->sarea_priv->pfCurrentPage != 1)
2189 master_priv->sarea_priv->pfCurrentPage = 0;
2191 return 0;
2194 /* Swapping and flipping are different operations, need different ioctls.
2195 * They can & should be intermixed to support multiple 3d windows.
2197 static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
2199 drm_radeon_private_t *dev_priv = dev->dev_private;
2200 DRM_DEBUG("\n");
2202 LOCK_TEST_WITH_RETURN(dev, file_priv);
2204 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2206 if (!dev_priv->page_flipping)
2207 radeon_do_init_pageflip(dev, file_priv->master);
2209 radeon_cp_dispatch_flip(dev, file_priv->master);
2211 COMMIT_RING();
2212 return 0;
2215 static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
2217 drm_radeon_private_t *dev_priv = dev->dev_private;
2218 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2219 drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
2221 DRM_DEBUG("\n");
2223 LOCK_TEST_WITH_RETURN(dev, file_priv);
2225 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2227 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2228 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2230 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2231 r600_cp_dispatch_swap(dev, file_priv);
2232 else
2233 radeon_cp_dispatch_swap(dev, file_priv->master);
2234 sarea_priv->ctx_owner = 0;
2236 COMMIT_RING();
2237 return 0;
2240 static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
2242 drm_radeon_private_t *dev_priv = dev->dev_private;
2243 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2244 drm_radeon_sarea_t *sarea_priv;
2245 struct drm_device_dma *dma = dev->dma;
2246 struct drm_buf *buf;
2247 drm_radeon_vertex_t *vertex = data;
2248 drm_radeon_tcl_prim_t prim;
2250 LOCK_TEST_WITH_RETURN(dev, file_priv);
2252 sarea_priv = master_priv->sarea_priv;
2254 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2255 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
2257 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2258 DRM_ERROR("buffer index %d (of %d max)\n",
2259 vertex->idx, dma->buf_count - 1);
2260 return -EINVAL;
2262 if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2263 DRM_ERROR("buffer prim %d\n", vertex->prim);
2264 return -EINVAL;
2267 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2268 VB_AGE_TEST_WITH_RETURN(dev_priv);
2270 buf = dma->buflist[vertex->idx];
2272 if (buf->file_priv != file_priv) {
2273 DRM_ERROR("process %d using buffer owned by %p\n",
2274 DRM_CURRENTPID, buf->file_priv);
2275 return -EINVAL;
2277 if (buf->pending) {
2278 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2279 return -EINVAL;
2282 /* Build up a prim_t record:
2284 if (vertex->count) {
2285 buf->used = vertex->count; /* not used? */
2287 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2288 if (radeon_emit_state(dev_priv, file_priv,
2289 &sarea_priv->context_state,
2290 sarea_priv->tex_state,
2291 sarea_priv->dirty)) {
2292 DRM_ERROR("radeon_emit_state failed\n");
2293 return -EINVAL;
2296 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2297 RADEON_UPLOAD_TEX1IMAGES |
2298 RADEON_UPLOAD_TEX2IMAGES |
2299 RADEON_REQUIRE_QUIESCENCE);
2302 prim.start = 0;
2303 prim.finish = vertex->count; /* unused */
2304 prim.prim = vertex->prim;
2305 prim.numverts = vertex->count;
2306 prim.vc_format = sarea_priv->vc_format;
2308 radeon_cp_dispatch_vertex(dev, file_priv, buf, &prim);
2311 if (vertex->discard) {
2312 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2315 COMMIT_RING();
2316 return 0;
2319 static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
2321 drm_radeon_private_t *dev_priv = dev->dev_private;
2322 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2323 drm_radeon_sarea_t *sarea_priv;
2324 struct drm_device_dma *dma = dev->dma;
2325 struct drm_buf *buf;
2326 drm_radeon_indices_t *elts = data;
2327 drm_radeon_tcl_prim_t prim;
2328 int count;
2330 LOCK_TEST_WITH_RETURN(dev, file_priv);
2332 sarea_priv = master_priv->sarea_priv;
2334 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2335 DRM_CURRENTPID, elts->idx, elts->start, elts->end,
2336 elts->discard);
2338 if (elts->idx < 0 || elts->idx >= dma->buf_count) {
2339 DRM_ERROR("buffer index %d (of %d max)\n",
2340 elts->idx, dma->buf_count - 1);
2341 return -EINVAL;
2343 if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2344 DRM_ERROR("buffer prim %d\n", elts->prim);
2345 return -EINVAL;
2348 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2349 VB_AGE_TEST_WITH_RETURN(dev_priv);
2351 buf = dma->buflist[elts->idx];
2353 if (buf->file_priv != file_priv) {
2354 DRM_ERROR("process %d using buffer owned by %p\n",
2355 DRM_CURRENTPID, buf->file_priv);
2356 return -EINVAL;
2358 if (buf->pending) {
2359 DRM_ERROR("sending pending buffer %d\n", elts->idx);
2360 return -EINVAL;
2363 count = (elts->end - elts->start) / sizeof(u16);
2364 elts->start -= RADEON_INDEX_PRIM_OFFSET;
2366 if (elts->start & 0x7) {
2367 DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
2368 return -EINVAL;
2370 if (elts->start < buf->used) {
2371 DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
2372 return -EINVAL;
2375 buf->used = elts->end;
2377 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2378 if (radeon_emit_state(dev_priv, file_priv,
2379 &sarea_priv->context_state,
2380 sarea_priv->tex_state,
2381 sarea_priv->dirty)) {
2382 DRM_ERROR("radeon_emit_state failed\n");
2383 return -EINVAL;
2386 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2387 RADEON_UPLOAD_TEX1IMAGES |
2388 RADEON_UPLOAD_TEX2IMAGES |
2389 RADEON_REQUIRE_QUIESCENCE);
2392 /* Build up a prim_t record:
2394 prim.start = elts->start;
2395 prim.finish = elts->end;
2396 prim.prim = elts->prim;
2397 prim.offset = 0; /* offset from start of dma buffers */
2398 prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2399 prim.vc_format = sarea_priv->vc_format;
2401 radeon_cp_dispatch_indices(dev, file_priv->master, buf, &prim);
2402 if (elts->discard) {
2403 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2406 COMMIT_RING();
2407 return 0;
2410 static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv)
2412 drm_radeon_private_t *dev_priv = dev->dev_private;
2413 drm_radeon_texture_t *tex = data;
2414 drm_radeon_tex_image_t image;
2415 int ret;
2417 LOCK_TEST_WITH_RETURN(dev, file_priv);
2419 if (tex->image == NULL) {
2420 DRM_ERROR("null texture image!\n");
2421 return -EINVAL;
2424 if (DRM_COPY_FROM_USER(&image,
2425 (drm_radeon_tex_image_t __user *) tex->image,
2426 sizeof(image)))
2427 return -EFAULT;
2429 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2430 VB_AGE_TEST_WITH_RETURN(dev_priv);
2432 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2433 ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
2434 else
2435 ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
2437 return ret;
2440 static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
2442 drm_radeon_private_t *dev_priv = dev->dev_private;
2443 drm_radeon_stipple_t *stipple = data;
2444 u32 mask[32];
2446 LOCK_TEST_WITH_RETURN(dev, file_priv);
2448 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
2449 return -EFAULT;
2451 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2453 radeon_cp_dispatch_stipple(dev, mask);
2455 COMMIT_RING();
2456 return 0;
2459 static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
2461 drm_radeon_private_t *dev_priv = dev->dev_private;
2462 struct drm_device_dma *dma = dev->dma;
2463 struct drm_buf *buf;
2464 drm_radeon_indirect_t *indirect = data;
2465 RING_LOCALS;
2467 LOCK_TEST_WITH_RETURN(dev, file_priv);
2469 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
2470 indirect->idx, indirect->start, indirect->end,
2471 indirect->discard);
2473 if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
2474 DRM_ERROR("buffer index %d (of %d max)\n",
2475 indirect->idx, dma->buf_count - 1);
2476 return -EINVAL;
2479 buf = dma->buflist[indirect->idx];
2481 if (buf->file_priv != file_priv) {
2482 DRM_ERROR("process %d using buffer owned by %p\n",
2483 DRM_CURRENTPID, buf->file_priv);
2484 return -EINVAL;
2486 if (buf->pending) {
2487 DRM_ERROR("sending pending buffer %d\n", indirect->idx);
2488 return -EINVAL;
2491 if (indirect->start < buf->used) {
2492 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2493 indirect->start, buf->used);
2494 return -EINVAL;
2497 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2498 VB_AGE_TEST_WITH_RETURN(dev_priv);
2500 buf->used = indirect->end;
2502 /* Dispatch the indirect buffer full of commands from the
2503 * X server. This is insecure and is thus only available to
2504 * privileged clients.
2506 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
2507 r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2508 else {
2509 /* Wait for the 3D stream to idle before the indirect buffer
2510 * containing 2D acceleration commands is processed.
2512 BEGIN_RING(2);
2513 RADEON_WAIT_UNTIL_3D_IDLE();
2514 ADVANCE_RING();
2515 radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2518 if (indirect->discard) {
2519 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2522 COMMIT_RING();
2523 return 0;
2526 static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
2528 drm_radeon_private_t *dev_priv = dev->dev_private;
2529 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
2530 drm_radeon_sarea_t *sarea_priv;
2531 struct drm_device_dma *dma = dev->dma;
2532 struct drm_buf *buf;
2533 drm_radeon_vertex2_t *vertex = data;
2534 int i;
2535 unsigned char laststate;
2537 LOCK_TEST_WITH_RETURN(dev, file_priv);
2539 sarea_priv = master_priv->sarea_priv;
2541 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2542 DRM_CURRENTPID, vertex->idx, vertex->discard);
2544 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2545 DRM_ERROR("buffer index %d (of %d max)\n",
2546 vertex->idx, dma->buf_count - 1);
2547 return -EINVAL;
2550 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2551 VB_AGE_TEST_WITH_RETURN(dev_priv);
2553 buf = dma->buflist[vertex->idx];
2555 if (buf->file_priv != file_priv) {
2556 DRM_ERROR("process %d using buffer owned by %p\n",
2557 DRM_CURRENTPID, buf->file_priv);
2558 return -EINVAL;
2561 if (buf->pending) {
2562 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2563 return -EINVAL;
2566 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2567 return -EINVAL;
2569 for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) {
2570 drm_radeon_prim_t prim;
2571 drm_radeon_tcl_prim_t tclprim;
2573 if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim)))
2574 return -EFAULT;
2576 if (prim.stateidx != laststate) {
2577 drm_radeon_state_t state;
2579 if (DRM_COPY_FROM_USER(&state,
2580 &vertex->state[prim.stateidx],
2581 sizeof(state)))
2582 return -EFAULT;
2584 if (radeon_emit_state2(dev_priv, file_priv, &state)) {
2585 DRM_ERROR("radeon_emit_state2 failed\n");
2586 return -EINVAL;
2589 laststate = prim.stateidx;
2592 tclprim.start = prim.start;
2593 tclprim.finish = prim.finish;
2594 tclprim.prim = prim.prim;
2595 tclprim.vc_format = prim.vc_format;
2597 if (prim.prim & RADEON_PRIM_WALK_IND) {
2598 tclprim.offset = prim.numverts * 64;
2599 tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2601 radeon_cp_dispatch_indices(dev, file_priv->master, buf, &tclprim);
2602 } else {
2603 tclprim.numverts = prim.numverts;
2604 tclprim.offset = 0; /* not used */
2606 radeon_cp_dispatch_vertex(dev, file_priv, buf, &tclprim);
2609 if (sarea_priv->nbox == 1)
2610 sarea_priv->nbox = 0;
2613 if (vertex->discard) {
2614 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2617 COMMIT_RING();
2618 return 0;
2621 static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
2622 struct drm_file *file_priv,
2623 drm_radeon_cmd_header_t header,
2624 drm_radeon_kcmd_buffer_t *cmdbuf)
2626 int id = (int)header.packet.packet_id;
2627 int sz, reg;
2628 RING_LOCALS;
2630 if (id >= RADEON_MAX_STATE_PACKETS)
2631 return -EINVAL;
2633 sz = packet[id].len;
2634 reg = packet[id].start;
2636 if (sz * sizeof(u32) > drm_buffer_unprocessed(cmdbuf->buffer)) {
2637 DRM_ERROR("Packet size provided larger than data provided\n");
2638 return -EINVAL;
2641 if (radeon_check_and_fixup_packets(dev_priv, file_priv, id,
2642 cmdbuf->buffer)) {
2643 DRM_ERROR("Packet verification failed\n");
2644 return -EINVAL;
2647 BEGIN_RING(sz + 1);
2648 OUT_RING(CP_PACKET0(reg, (sz - 1)));
2649 OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2650 ADVANCE_RING();
2652 return 0;
2655 static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
2656 drm_radeon_cmd_header_t header,
2657 drm_radeon_kcmd_buffer_t *cmdbuf)
2659 int sz = header.scalars.count;
2660 int start = header.scalars.offset;
2661 int stride = header.scalars.stride;
2662 RING_LOCALS;
2664 BEGIN_RING(3 + sz);
2665 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2666 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2667 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2668 OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2669 ADVANCE_RING();
2670 return 0;
2673 /* God this is ugly
2675 static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
2676 drm_radeon_cmd_header_t header,
2677 drm_radeon_kcmd_buffer_t *cmdbuf)
2679 int sz = header.scalars.count;
2680 int start = ((unsigned int)header.scalars.offset) + 0x100;
2681 int stride = header.scalars.stride;
2682 RING_LOCALS;
2684 BEGIN_RING(3 + sz);
2685 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2686 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2687 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2688 OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2689 ADVANCE_RING();
2690 return 0;
2693 static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2694 drm_radeon_cmd_header_t header,
2695 drm_radeon_kcmd_buffer_t *cmdbuf)
2697 int sz = header.vectors.count;
2698 int start = header.vectors.offset;
2699 int stride = header.vectors.stride;
2700 RING_LOCALS;
2702 BEGIN_RING(5 + sz);
2703 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2704 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2705 OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2706 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2707 OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2708 ADVANCE_RING();
2710 return 0;
2713 static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
2714 drm_radeon_cmd_header_t header,
2715 drm_radeon_kcmd_buffer_t *cmdbuf)
2717 int sz = header.veclinear.count * 4;
2718 int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
2719 RING_LOCALS;
2721 if (!sz)
2722 return 0;
2723 if (sz * 4 > drm_buffer_unprocessed(cmdbuf->buffer))
2724 return -EINVAL;
2726 BEGIN_RING(5 + sz);
2727 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2728 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2729 OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2730 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2731 OUT_RING_DRM_BUFFER(cmdbuf->buffer, sz);
2732 ADVANCE_RING();
2734 return 0;
2737 static int radeon_emit_packet3(struct drm_device * dev,
2738 struct drm_file *file_priv,
2739 drm_radeon_kcmd_buffer_t *cmdbuf)
2741 drm_radeon_private_t *dev_priv = dev->dev_private;
2742 unsigned int cmdsz;
2743 int ret;
2744 RING_LOCALS;
2746 DRM_DEBUG("\n");
2748 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2749 cmdbuf, &cmdsz))) {
2750 DRM_ERROR("Packet verification failed\n");
2751 return ret;
2754 BEGIN_RING(cmdsz);
2755 OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
2756 ADVANCE_RING();
2758 return 0;
2761 static int radeon_emit_packet3_cliprect(struct drm_device *dev,
2762 struct drm_file *file_priv,
2763 drm_radeon_kcmd_buffer_t *cmdbuf,
2764 int orig_nbox)
2766 drm_radeon_private_t *dev_priv = dev->dev_private;
2767 struct drm_clip_rect box;
2768 unsigned int cmdsz;
2769 int ret;
2770 struct drm_clip_rect __user *boxes = cmdbuf->boxes;
2771 int i = 0;
2772 RING_LOCALS;
2774 DRM_DEBUG("\n");
2776 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2777 cmdbuf, &cmdsz))) {
2778 DRM_ERROR("Packet verification failed\n");
2779 return ret;
2782 if (!orig_nbox)
2783 goto out;
2785 do {
2786 if (i < cmdbuf->nbox) {
2787 if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
2788 return -EFAULT;
2789 if (i) {
2790 BEGIN_RING(2);
2791 RADEON_WAIT_UNTIL_3D_IDLE();
2792 ADVANCE_RING();
2794 radeon_emit_clip_rect(dev_priv, &box);
2797 BEGIN_RING(cmdsz);
2798 OUT_RING_DRM_BUFFER(cmdbuf->buffer, cmdsz);
2799 ADVANCE_RING();
2801 } while (++i < cmdbuf->nbox);
2802 if (cmdbuf->nbox == 1)
2803 cmdbuf->nbox = 0;
2805 return 0;
2806 out:
2807 drm_buffer_advance(cmdbuf->buffer, cmdsz * 4);
2808 return 0;
2811 static int radeon_emit_wait(struct drm_device * dev, int flags)
2813 drm_radeon_private_t *dev_priv = dev->dev_private;
2814 RING_LOCALS;
2816 DRM_DEBUG("%x\n", flags);
2817 switch (flags) {
2818 case RADEON_WAIT_2D:
2819 BEGIN_RING(2);
2820 RADEON_WAIT_UNTIL_2D_IDLE();
2821 ADVANCE_RING();
2822 break;
2823 case RADEON_WAIT_3D:
2824 BEGIN_RING(2);
2825 RADEON_WAIT_UNTIL_3D_IDLE();
2826 ADVANCE_RING();
2827 break;
2828 case RADEON_WAIT_2D | RADEON_WAIT_3D:
2829 BEGIN_RING(2);
2830 RADEON_WAIT_UNTIL_IDLE();
2831 ADVANCE_RING();
2832 break;
2833 default:
2834 return -EINVAL;
2837 return 0;
2840 static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
2841 struct drm_file *file_priv)
2843 drm_radeon_private_t *dev_priv = dev->dev_private;
2844 struct drm_device_dma *dma = dev->dma;
2845 struct drm_buf *buf = NULL;
2846 drm_radeon_cmd_header_t stack_header;
2847 int idx;
2848 drm_radeon_kcmd_buffer_t *cmdbuf = data;
2849 int orig_nbox;
2851 LOCK_TEST_WITH_RETURN(dev, file_priv);
2853 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2854 VB_AGE_TEST_WITH_RETURN(dev_priv);
2856 if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) {
2857 return -EINVAL;
2860 /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid
2861 * races between checking values and using those values in other code,
2862 * and simply to avoid a lot of function calls to copy in data.
2864 if (cmdbuf->bufsz != 0) {
2865 int rv;
2866 void __user *buffer = cmdbuf->buffer;
2867 rv = drm_buffer_alloc(&cmdbuf->buffer, cmdbuf->bufsz);
2868 if (rv)
2869 return rv;
2870 rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
2871 cmdbuf->bufsz);
2872 if (rv) {
2873 drm_buffer_free(cmdbuf->buffer);
2874 return rv;
2876 } else
2877 goto done;
2879 orig_nbox = cmdbuf->nbox;
2881 if (dev_priv->microcode_version == UCODE_R300) {
2882 int temp;
2883 temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
2885 drm_buffer_free(cmdbuf->buffer);
2887 return temp;
2890 /* microcode_version != r300 */
2891 while (drm_buffer_unprocessed(cmdbuf->buffer) >= sizeof(stack_header)) {
2893 drm_radeon_cmd_header_t *header;
2894 header = drm_buffer_read_object(cmdbuf->buffer,
2895 sizeof(stack_header), &stack_header);
2897 switch (header->header.cmd_type) {
2898 case RADEON_CMD_PACKET:
2899 DRM_DEBUG("RADEON_CMD_PACKET\n");
2900 if (radeon_emit_packets
2901 (dev_priv, file_priv, *header, cmdbuf)) {
2902 DRM_ERROR("radeon_emit_packets failed\n");
2903 goto err;
2905 break;
2907 case RADEON_CMD_SCALARS:
2908 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2909 if (radeon_emit_scalars(dev_priv, *header, cmdbuf)) {
2910 DRM_ERROR("radeon_emit_scalars failed\n");
2911 goto err;
2913 break;
2915 case RADEON_CMD_VECTORS:
2916 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2917 if (radeon_emit_vectors(dev_priv, *header, cmdbuf)) {
2918 DRM_ERROR("radeon_emit_vectors failed\n");
2919 goto err;
2921 break;
2923 case RADEON_CMD_DMA_DISCARD:
2924 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2925 idx = header->dma.buf_idx;
2926 if (idx < 0 || idx >= dma->buf_count) {
2927 DRM_ERROR("buffer index %d (of %d max)\n",
2928 idx, dma->buf_count - 1);
2929 goto err;
2932 buf = dma->buflist[idx];
2933 if (buf->file_priv != file_priv || buf->pending) {
2934 DRM_ERROR("bad buffer %p %p %d\n",
2935 buf->file_priv, file_priv,
2936 buf->pending);
2937 goto err;
2940 radeon_cp_discard_buffer(dev, file_priv->master, buf);
2941 break;
2943 case RADEON_CMD_PACKET3:
2944 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2945 if (radeon_emit_packet3(dev, file_priv, cmdbuf)) {
2946 DRM_ERROR("radeon_emit_packet3 failed\n");
2947 goto err;
2949 break;
2951 case RADEON_CMD_PACKET3_CLIP:
2952 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2953 if (radeon_emit_packet3_cliprect
2954 (dev, file_priv, cmdbuf, orig_nbox)) {
2955 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2956 goto err;
2958 break;
2960 case RADEON_CMD_SCALARS2:
2961 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2962 if (radeon_emit_scalars2(dev_priv, *header, cmdbuf)) {
2963 DRM_ERROR("radeon_emit_scalars2 failed\n");
2964 goto err;
2966 break;
2968 case RADEON_CMD_WAIT:
2969 DRM_DEBUG("RADEON_CMD_WAIT\n");
2970 if (radeon_emit_wait(dev, header->wait.flags)) {
2971 DRM_ERROR("radeon_emit_wait failed\n");
2972 goto err;
2974 break;
2975 case RADEON_CMD_VECLINEAR:
2976 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
2977 if (radeon_emit_veclinear(dev_priv, *header, cmdbuf)) {
2978 DRM_ERROR("radeon_emit_veclinear failed\n");
2979 goto err;
2981 break;
2983 default:
2984 DRM_ERROR("bad cmd_type %d at byte %d\n",
2985 header->header.cmd_type,
2986 cmdbuf->buffer->iterator);
2987 goto err;
2991 drm_buffer_free(cmdbuf->buffer);
2993 done:
2994 DRM_DEBUG("DONE\n");
2995 COMMIT_RING();
2996 return 0;
2998 err:
2999 drm_buffer_free(cmdbuf->buffer);
3000 return -EINVAL;
3003 static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3005 drm_radeon_private_t *dev_priv = dev->dev_private;
3006 drm_radeon_getparam_t *param = data;
3007 int value;
3009 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
3011 switch (param->param) {
3012 case RADEON_PARAM_GART_BUFFER_OFFSET:
3013 value = dev_priv->gart_buffers_offset;
3014 break;
3015 case RADEON_PARAM_LAST_FRAME:
3016 dev_priv->stats.last_frame_reads++;
3017 value = GET_SCRATCH(dev_priv, 0);
3018 break;
3019 case RADEON_PARAM_LAST_DISPATCH:
3020 value = GET_SCRATCH(dev_priv, 1);
3021 break;
3022 case RADEON_PARAM_LAST_CLEAR:
3023 dev_priv->stats.last_clear_reads++;
3024 value = GET_SCRATCH(dev_priv, 2);
3025 break;
3026 case RADEON_PARAM_IRQ_NR:
3027 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
3028 value = 0;
3029 else
3030 value = drm_dev_to_irq(dev);
3031 break;
3032 case RADEON_PARAM_GART_BASE:
3033 value = dev_priv->gart_vm_start;
3034 break;
3035 case RADEON_PARAM_REGISTER_HANDLE:
3036 value = dev_priv->mmio->offset;
3037 break;
3038 case RADEON_PARAM_STATUS_HANDLE:
3039 value = dev_priv->ring_rptr_offset;
3040 break;
3041 #if BITS_PER_LONG == 32
3043 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
3044 * pointer which can't fit into an int-sized variable. According to
3045 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
3046 * not supporting it shouldn't be a problem. If the same functionality
3047 * is needed on 64-bit platforms, a new ioctl() would have to be added,
3048 * so backwards-compatibility for the embedded platforms can be
3049 * maintained. --davidm 4-Feb-2004.
3051 case RADEON_PARAM_SAREA_HANDLE:
3052 /* The lock is the first dword in the sarea. */
3053 /* no users of this parameter */
3054 break;
3055 #endif
3056 case RADEON_PARAM_GART_TEX_HANDLE:
3057 value = dev_priv->gart_textures_offset;
3058 break;
3059 case RADEON_PARAM_SCRATCH_OFFSET:
3060 if (!dev_priv->writeback_works)
3061 return -EINVAL;
3062 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
3063 value = R600_SCRATCH_REG_OFFSET;
3064 else
3065 value = RADEON_SCRATCH_REG_OFFSET;
3066 break;
3067 case RADEON_PARAM_CARD_TYPE:
3068 if (dev_priv->flags & RADEON_IS_PCIE)
3069 value = RADEON_CARD_PCIE;
3070 else if (dev_priv->flags & RADEON_IS_AGP)
3071 value = RADEON_CARD_AGP;
3072 else
3073 value = RADEON_CARD_PCI;
3074 break;
3075 case RADEON_PARAM_VBLANK_CRTC:
3076 value = radeon_vblank_crtc_get(dev);
3077 break;
3078 case RADEON_PARAM_FB_LOCATION:
3079 value = radeon_read_fb_location(dev_priv);
3080 break;
3081 case RADEON_PARAM_NUM_GB_PIPES:
3082 value = dev_priv->num_gb_pipes;
3083 break;
3084 case RADEON_PARAM_NUM_Z_PIPES:
3085 value = dev_priv->num_z_pipes;
3086 break;
3087 default:
3088 DRM_DEBUG("Invalid parameter %d\n", param->param);
3089 return -EINVAL;
3092 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
3093 DRM_ERROR("copy_to_user\n");
3094 return -EFAULT;
3097 return 0;
3100 static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3102 drm_radeon_private_t *dev_priv = dev->dev_private;
3103 struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
3104 drm_radeon_setparam_t *sp = data;
3105 struct drm_radeon_driver_file_fields *radeon_priv;
3107 switch (sp->param) {
3108 case RADEON_SETPARAM_FB_LOCATION:
3109 radeon_priv = file_priv->driver_priv;
3110 radeon_priv->radeon_fb_delta = dev_priv->fb_location -
3111 sp->value;
3112 break;
3113 case RADEON_SETPARAM_SWITCH_TILING:
3114 if (sp->value == 0) {
3115 DRM_DEBUG("color tiling disabled\n");
3116 dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3117 dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3118 if (master_priv->sarea_priv)
3119 master_priv->sarea_priv->tiling_enabled = 0;
3120 } else if (sp->value == 1) {
3121 DRM_DEBUG("color tiling enabled\n");
3122 dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
3123 dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
3124 if (master_priv->sarea_priv)
3125 master_priv->sarea_priv->tiling_enabled = 1;
3127 break;
3128 case RADEON_SETPARAM_PCIGART_LOCATION:
3129 dev_priv->pcigart_offset = sp->value;
3130 dev_priv->pcigart_offset_set = 1;
3131 break;
3132 case RADEON_SETPARAM_NEW_MEMMAP:
3133 dev_priv->new_memmap = sp->value;
3134 break;
3135 case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
3136 dev_priv->gart_info.table_size = sp->value;
3137 if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
3138 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
3139 break;
3140 case RADEON_SETPARAM_VBLANK_CRTC:
3141 return radeon_vblank_crtc_set(dev, sp->value);
3142 break;
3143 default:
3144 DRM_DEBUG("Invalid parameter %d\n", sp->param);
3145 return -EINVAL;
3148 return 0;
3151 /* When a client dies:
3152 * - Check for and clean up flipped page state
3153 * - Free any alloced GART memory.
3154 * - Free any alloced radeon surfaces.
3156 * DRM infrastructure takes care of reclaiming dma buffers.
3158 void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
3160 if (dev->dev_private) {
3161 drm_radeon_private_t *dev_priv = dev->dev_private;
3162 dev_priv->page_flipping = 0;
3163 radeon_mem_release(file_priv, dev_priv->gart_heap);
3164 radeon_mem_release(file_priv, dev_priv->fb_heap);
3165 radeon_surfaces_release(file_priv, dev_priv);
3169 void radeon_driver_lastclose(struct drm_device *dev)
3171 radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
3172 radeon_do_release(dev);
3175 int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv)
3177 drm_radeon_private_t *dev_priv = dev->dev_private;
3178 struct drm_radeon_driver_file_fields *radeon_priv;
3180 DRM_DEBUG("\n");
3181 radeon_priv = kmalloc(sizeof(*radeon_priv), GFP_KERNEL);
3183 if (!radeon_priv)
3184 return -ENOMEM;
3186 file_priv->driver_priv = radeon_priv;
3188 if (dev_priv)
3189 radeon_priv->radeon_fb_delta = dev_priv->fb_location;
3190 else
3191 radeon_priv->radeon_fb_delta = 0;
3192 return 0;
3195 void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
3197 struct drm_radeon_driver_file_fields *radeon_priv =
3198 file_priv->driver_priv;
3200 kfree(radeon_priv);
3203 struct drm_ioctl_desc radeon_ioctls[] = {
3204 DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3205 DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3206 DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3207 DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3208 DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
3209 DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
3210 DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH),
3211 DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
3212 DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
3213 DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
3214 DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
3215 DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
3216 DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
3217 DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
3218 DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3219 DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
3220 DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
3221 DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
3222 DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
3223 DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
3224 DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH),
3225 DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3226 DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
3227 DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
3228 DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
3229 DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
3230 DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
3231 DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
3234 int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);