Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
r128_state.c
Go to the documentation of this file.
1 /* r128_state.c -- State support for r128 -*- linux-c -*-
2  * Created: Thu Jan 27 02:53:43 2000 by [email protected]
3  */
4 /*
5  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  *
27  * Authors:
28  * Gareth Hughes <[email protected]>
29  */
30 
31 #include <drm/drmP.h>
32 #include <drm/r128_drm.h>
33 #include "r128_drv.h"
34 
35 /* ================================================================
36  * CCE hardware state programming functions
37  */
38 
39 static void r128_emit_clip_rects(drm_r128_private_t *dev_priv,
40  struct drm_clip_rect *boxes, int count)
41 {
42  u32 aux_sc_cntl = 0x00000000;
44  DRM_DEBUG("\n");
45 
46  BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
47 
48  if (count >= 1) {
50  OUT_RING(boxes[0].x1);
51  OUT_RING(boxes[0].x2 - 1);
52  OUT_RING(boxes[0].y1);
53  OUT_RING(boxes[0].y2 - 1);
54 
55  aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
56  }
57  if (count >= 2) {
59  OUT_RING(boxes[1].x1);
60  OUT_RING(boxes[1].x2 - 1);
61  OUT_RING(boxes[1].y1);
62  OUT_RING(boxes[1].y2 - 1);
63 
64  aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
65  }
66  if (count >= 3) {
68  OUT_RING(boxes[2].x1);
69  OUT_RING(boxes[2].x2 - 1);
70  OUT_RING(boxes[2].y1);
71  OUT_RING(boxes[2].y2 - 1);
72 
73  aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
74  }
75 
77  OUT_RING(aux_sc_cntl);
78 
79  ADVANCE_RING();
80 }
81 
82 static __inline__ void r128_emit_core(drm_r128_private_t *dev_priv)
83 {
84  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
87  DRM_DEBUG("\n");
88 
89  BEGIN_RING(2);
90 
92  OUT_RING(ctx->scale_3d_cntl);
93 
94  ADVANCE_RING();
95 }
96 
97 static __inline__ void r128_emit_context(drm_r128_private_t *dev_priv)
98 {
99  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
100  drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
101  RING_LOCALS;
102  DRM_DEBUG("\n");
103 
104  BEGIN_RING(13);
105 
109  OUT_RING(ctx->sc_top_left_c);
111  OUT_RING(ctx->z_offset_c);
112  OUT_RING(ctx->z_pitch_c);
113  OUT_RING(ctx->z_sten_cntl_c);
114  OUT_RING(ctx->tex_cntl_c);
118  OUT_RING(ctx->fog_color_c);
119 
120  ADVANCE_RING();
121 }
122 
123 static __inline__ void r128_emit_setup(drm_r128_private_t *dev_priv)
124 {
125  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
126  drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
127  RING_LOCALS;
128  DRM_DEBUG("\n");
129 
130  BEGIN_RING(3);
131 
133  OUT_RING(ctx->setup_cntl);
135 
136  ADVANCE_RING();
137 }
138 
139 static __inline__ void r128_emit_masks(drm_r128_private_t *dev_priv)
140 {
141  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
142  drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
143  RING_LOCALS;
144  DRM_DEBUG("\n");
145 
146  BEGIN_RING(5);
147 
149  OUT_RING(ctx->dp_write_mask);
150 
154 
155  ADVANCE_RING();
156 }
157 
158 static __inline__ void r128_emit_window(drm_r128_private_t *dev_priv)
159 {
160  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
161  drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
162  RING_LOCALS;
163  DRM_DEBUG("\n");
164 
165  BEGIN_RING(2);
166 
169 
170  ADVANCE_RING();
171 }
172 
173 static __inline__ void r128_emit_tex0(drm_r128_private_t *dev_priv)
174 {
175  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
176  drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
177  drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
178  int i;
179  RING_LOCALS;
180  DRM_DEBUG("\n");
181 
183 
186  OUT_RING(tex->tex_cntl);
189  for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
190  OUT_RING(tex->tex_offset[i]);
191 
195 
196  ADVANCE_RING();
197 }
198 
199 static __inline__ void r128_emit_tex1(drm_r128_private_t *dev_priv)
200 {
201  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
202  drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
203  int i;
204  RING_LOCALS;
205  DRM_DEBUG("\n");
206 
207  BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
208 
209  OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
210  OUT_RING(tex->tex_cntl);
212  for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++)
213  OUT_RING(tex->tex_offset[i]);
214 
217 
218  ADVANCE_RING();
219 }
220 
221 static void r128_emit_state(drm_r128_private_t *dev_priv)
222 {
223  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
224  unsigned int dirty = sarea_priv->dirty;
225 
226  DRM_DEBUG("dirty=0x%08x\n", dirty);
227 
228  if (dirty & R128_UPLOAD_CORE) {
229  r128_emit_core(dev_priv);
230  sarea_priv->dirty &= ~R128_UPLOAD_CORE;
231  }
232 
233  if (dirty & R128_UPLOAD_CONTEXT) {
234  r128_emit_context(dev_priv);
235  sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
236  }
237 
238  if (dirty & R128_UPLOAD_SETUP) {
239  r128_emit_setup(dev_priv);
240  sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
241  }
242 
243  if (dirty & R128_UPLOAD_MASKS) {
244  r128_emit_masks(dev_priv);
245  sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
246  }
247 
248  if (dirty & R128_UPLOAD_WINDOW) {
249  r128_emit_window(dev_priv);
250  sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
251  }
252 
253  if (dirty & R128_UPLOAD_TEX0) {
254  r128_emit_tex0(dev_priv);
255  sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
256  }
257 
258  if (dirty & R128_UPLOAD_TEX1) {
259  r128_emit_tex1(dev_priv);
260  sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
261  }
262 
263  /* Turn off the texture cache flushing */
265 
266  sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
267 }
268 
269 #if R128_PERFORMANCE_BOXES
270 /* ================================================================
271  * Performance monitoring functions
272  */
273 
274 static void r128_clear_box(drm_r128_private_t *dev_priv,
275  int x, int y, int w, int h, int r, int g, int b)
276 {
277  u32 pitch, offset;
278  u32 fb_bpp, color;
279  RING_LOCALS;
280 
281  switch (dev_priv->fb_bpp) {
282  case 16:
283  fb_bpp = R128_GMC_DST_16BPP;
284  color = (((r & 0xf8) << 8) |
285  ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
286  break;
287  case 24:
288  fb_bpp = R128_GMC_DST_24BPP;
289  color = ((r << 16) | (g << 8) | b);
290  break;
291  case 32:
292  fb_bpp = R128_GMC_DST_32BPP;
293  color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
294  break;
295  default:
296  return;
297  }
298 
299  offset = dev_priv->back_offset;
300  pitch = dev_priv->back_pitch >> 3;
301 
302  BEGIN_RING(6);
303 
307  fb_bpp |
309  R128_ROP3_P |
311 
312  OUT_RING((pitch << 21) | (offset >> 5));
313  OUT_RING(color);
314 
315  OUT_RING((x << 16) | y);
316  OUT_RING((w << 16) | h);
317 
318  ADVANCE_RING();
319 }
320 
321 static void r128_cce_performance_boxes(drm_r128_private_t *dev_priv)
322 {
323  if (atomic_read(&dev_priv->idle_count) == 0)
324  r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
325  else
326  atomic_set(&dev_priv->idle_count, 0);
327 }
328 
329 #endif
330 
331 /* ================================================================
332  * CCE command dispatch functions
333  */
334 
335 static void r128_print_dirty(const char *msg, unsigned int flags)
336 {
337  DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
338  msg,
339  flags,
340  (flags & R128_UPLOAD_CORE) ? "core, " : "",
341  (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
342  (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
343  (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
344  (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
345  (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
346  (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
347  (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
348  (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
349 }
350 
351 static void r128_cce_dispatch_clear(struct drm_device *dev,
353 {
354  drm_r128_private_t *dev_priv = dev->dev_private;
355  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
356  int nbox = sarea_priv->nbox;
357  struct drm_clip_rect *pbox = sarea_priv->boxes;
358  unsigned int flags = clear->flags;
359  int i;
360  RING_LOCALS;
361  DRM_DEBUG("\n");
362 
363  if (dev_priv->page_flipping && dev_priv->current_page == 1) {
364  unsigned int tmp = flags;
365 
366  flags &= ~(R128_FRONT | R128_BACK);
367  if (tmp & R128_FRONT)
368  flags |= R128_BACK;
369  if (tmp & R128_BACK)
370  flags |= R128_FRONT;
371  }
372 
373  for (i = 0; i < nbox; i++) {
374  int x = pbox[i].x1;
375  int y = pbox[i].y1;
376  int w = pbox[i].x2 - x;
377  int h = pbox[i].y2 - y;
378 
379  DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
380  pbox[i].x1, pbox[i].y1, pbox[i].x2,
381  pbox[i].y2, flags);
382 
383  if (flags & (R128_FRONT | R128_BACK)) {
384  BEGIN_RING(2);
385 
387  OUT_RING(clear->color_mask);
388 
389  ADVANCE_RING();
390  }
391 
392  if (flags & R128_FRONT) {
393  BEGIN_RING(6);
394 
398  (dev_priv->color_fmt << 8) |
400  R128_ROP3_P |
403 
404  OUT_RING(dev_priv->front_pitch_offset_c);
405  OUT_RING(clear->clear_color);
406 
407  OUT_RING((x << 16) | y);
408  OUT_RING((w << 16) | h);
409 
410  ADVANCE_RING();
411  }
412 
413  if (flags & R128_BACK) {
414  BEGIN_RING(6);
415 
419  (dev_priv->color_fmt << 8) |
421  R128_ROP3_P |
424 
425  OUT_RING(dev_priv->back_pitch_offset_c);
426  OUT_RING(clear->clear_color);
427 
428  OUT_RING((x << 16) | y);
429  OUT_RING((w << 16) | h);
430 
431  ADVANCE_RING();
432  }
433 
434  if (flags & R128_DEPTH) {
435  BEGIN_RING(6);
436 
440  (dev_priv->depth_fmt << 8) |
442  R128_ROP3_P |
445 
446  OUT_RING(dev_priv->depth_pitch_offset_c);
447  OUT_RING(clear->clear_depth);
448 
449  OUT_RING((x << 16) | y);
450  OUT_RING((w << 16) | h);
451 
452  ADVANCE_RING();
453  }
454  }
455 }
456 
457 static void r128_cce_dispatch_swap(struct drm_device *dev)
458 {
459  drm_r128_private_t *dev_priv = dev->dev_private;
460  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
461  int nbox = sarea_priv->nbox;
462  struct drm_clip_rect *pbox = sarea_priv->boxes;
463  int i;
464  RING_LOCALS;
465  DRM_DEBUG("\n");
466 
467 #if R128_PERFORMANCE_BOXES
468  /* Do some trivial performance monitoring...
469  */
470  r128_cce_performance_boxes(dev_priv);
471 #endif
472 
473  for (i = 0; i < nbox; i++) {
474  int x = pbox[i].x1;
475  int y = pbox[i].y1;
476  int w = pbox[i].x2 - x;
477  int h = pbox[i].y2 - y;
478 
479  BEGIN_RING(7);
480 
485  (dev_priv->color_fmt << 8) |
487  R128_ROP3_S |
491 
492  /* Make this work even if front & back are flipped:
493  */
494  if (dev_priv->current_page == 0) {
495  OUT_RING(dev_priv->back_pitch_offset_c);
496  OUT_RING(dev_priv->front_pitch_offset_c);
497  } else {
498  OUT_RING(dev_priv->front_pitch_offset_c);
499  OUT_RING(dev_priv->back_pitch_offset_c);
500  }
501 
502  OUT_RING((x << 16) | y);
503  OUT_RING((x << 16) | y);
504  OUT_RING((w << 16) | h);
505 
506  ADVANCE_RING();
507  }
508 
509  /* Increment the frame counter. The client-side 3D driver must
510  * throttle the framerate by waiting for this value before
511  * performing the swapbuffer ioctl.
512  */
513  dev_priv->sarea_priv->last_frame++;
514 
515  BEGIN_RING(2);
516 
518  OUT_RING(dev_priv->sarea_priv->last_frame);
519 
520  ADVANCE_RING();
521 }
522 
523 static void r128_cce_dispatch_flip(struct drm_device *dev)
524 {
525  drm_r128_private_t *dev_priv = dev->dev_private;
526  RING_LOCALS;
527  DRM_DEBUG("page=%d pfCurrentPage=%d\n",
528  dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
529 
530 #if R128_PERFORMANCE_BOXES
531  /* Do some trivial performance monitoring...
532  */
533  r128_cce_performance_boxes(dev_priv);
534 #endif
535 
536  BEGIN_RING(4);
537 
540 
541  if (dev_priv->current_page == 0)
542  OUT_RING(dev_priv->back_offset);
543  else
544  OUT_RING(dev_priv->front_offset);
545 
546  ADVANCE_RING();
547 
548  /* Increment the frame counter. The client-side 3D driver must
549  * throttle the framerate by waiting for this value before
550  * performing the swapbuffer ioctl.
551  */
552  dev_priv->sarea_priv->last_frame++;
553  dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
554  1 - dev_priv->current_page;
555 
556  BEGIN_RING(2);
557 
559  OUT_RING(dev_priv->sarea_priv->last_frame);
560 
561  ADVANCE_RING();
562 }
563 
564 static void r128_cce_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf)
565 {
566  drm_r128_private_t *dev_priv = dev->dev_private;
567  drm_r128_buf_priv_t *buf_priv = buf->dev_private;
568  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
569  int format = sarea_priv->vc_format;
570  int offset = buf->bus_address;
571  int size = buf->used;
572  int prim = buf_priv->prim;
573  int i = 0;
574  RING_LOCALS;
575  DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);
576 
577  if (0)
578  r128_print_dirty("dispatch_vertex", sarea_priv->dirty);
579 
580  if (buf->used) {
581  buf_priv->dispatched = 1;
582 
583  if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
584  r128_emit_state(dev_priv);
585 
586  do {
587  /* Emit the next set of up to three cliprects */
588  if (i < sarea_priv->nbox) {
589  r128_emit_clip_rects(dev_priv,
590  &sarea_priv->boxes[i],
591  sarea_priv->nbox - i);
592  }
593 
594  /* Emit the vertex buffer rendering commands */
595  BEGIN_RING(5);
596 
598  OUT_RING(offset);
599  OUT_RING(size);
600  OUT_RING(format);
602  (size << R128_CCE_VC_CNTL_NUM_SHIFT));
603 
604  ADVANCE_RING();
605 
606  i += 3;
607  } while (i < sarea_priv->nbox);
608  }
609 
610  if (buf_priv->discard) {
611  buf_priv->age = dev_priv->sarea_priv->last_dispatch;
612 
613  /* Emit the vertex buffer age */
614  BEGIN_RING(2);
615 
617  OUT_RING(buf_priv->age);
618 
619  ADVANCE_RING();
620 
621  buf->pending = 1;
622  buf->used = 0;
623  /* FIXME: Check dispatched field */
624  buf_priv->dispatched = 0;
625  }
626 
627  dev_priv->sarea_priv->last_dispatch++;
628 
629  sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
630  sarea_priv->nbox = 0;
631 }
632 
633 static void r128_cce_dispatch_indirect(struct drm_device *dev,
634  struct drm_buf *buf, int start, int end)
635 {
636  drm_r128_private_t *dev_priv = dev->dev_private;
637  drm_r128_buf_priv_t *buf_priv = buf->dev_private;
638  RING_LOCALS;
639  DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
640 
641  if (start != end) {
642  int offset = buf->bus_address + start;
643  int dwords = (end - start + 3) / sizeof(u32);
644 
645  /* Indirect buffer data must be an even number of
646  * dwords, so if we've been given an odd number we must
647  * pad the data with a Type-2 CCE packet.
648  */
649  if (dwords & 1) {
650  u32 *data = (u32 *)
651  ((char *)dev->agp_buffer_map->handle
652  + buf->offset + start);
653  data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
654  }
655 
656  buf_priv->dispatched = 1;
657 
658  /* Fire off the indirect buffer */
659  BEGIN_RING(3);
660 
662  OUT_RING(offset);
663  OUT_RING(dwords);
664 
665  ADVANCE_RING();
666  }
667 
668  if (buf_priv->discard) {
669  buf_priv->age = dev_priv->sarea_priv->last_dispatch;
670 
671  /* Emit the indirect buffer age */
672  BEGIN_RING(2);
673 
675  OUT_RING(buf_priv->age);
676 
677  ADVANCE_RING();
678 
679  buf->pending = 1;
680  buf->used = 0;
681  /* FIXME: Check dispatched field */
682  buf_priv->dispatched = 0;
683  }
684 
685  dev_priv->sarea_priv->last_dispatch++;
686 }
687 
688 static void r128_cce_dispatch_indices(struct drm_device *dev,
689  struct drm_buf *buf,
690  int start, int end, int count)
691 {
692  drm_r128_private_t *dev_priv = dev->dev_private;
693  drm_r128_buf_priv_t *buf_priv = buf->dev_private;
694  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
695  int format = sarea_priv->vc_format;
696  int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset;
697  int prim = buf_priv->prim;
698  u32 *data;
699  int dwords;
700  int i = 0;
701  RING_LOCALS;
702  DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);
703 
704  if (0)
705  r128_print_dirty("dispatch_indices", sarea_priv->dirty);
706 
707  if (start != end) {
708  buf_priv->dispatched = 1;
709 
710  if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS)
711  r128_emit_state(dev_priv);
712 
713  dwords = (end - start + 3) / sizeof(u32);
714 
715  data = (u32 *) ((char *)dev->agp_buffer_map->handle
716  + buf->offset + start);
717 
719  dwords - 2));
720 
721  data[1] = cpu_to_le32(offset);
722  data[2] = cpu_to_le32(R128_MAX_VB_VERTS);
723  data[3] = cpu_to_le32(format);
724  data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
725  (count << 16)));
726 
727  if (count & 0x1) {
728 #ifdef __LITTLE_ENDIAN
729  data[dwords - 1] &= 0x0000ffff;
730 #else
731  data[dwords - 1] &= 0xffff0000;
732 #endif
733  }
734 
735  do {
736  /* Emit the next set of up to three cliprects */
737  if (i < sarea_priv->nbox) {
738  r128_emit_clip_rects(dev_priv,
739  &sarea_priv->boxes[i],
740  sarea_priv->nbox - i);
741  }
742 
743  r128_cce_dispatch_indirect(dev, buf, start, end);
744 
745  i += 3;
746  } while (i < sarea_priv->nbox);
747  }
748 
749  if (buf_priv->discard) {
750  buf_priv->age = dev_priv->sarea_priv->last_dispatch;
751 
752  /* Emit the vertex buffer age */
753  BEGIN_RING(2);
754 
756  OUT_RING(buf_priv->age);
757 
758  ADVANCE_RING();
759 
760  buf->pending = 1;
761  /* FIXME: Check dispatched field */
762  buf_priv->dispatched = 0;
763  }
764 
765  dev_priv->sarea_priv->last_dispatch++;
766 
767  sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
768  sarea_priv->nbox = 0;
769 }
770 
771 static int r128_cce_dispatch_blit(struct drm_device *dev,
772  struct drm_file *file_priv,
773  drm_r128_blit_t *blit)
774 {
775  drm_r128_private_t *dev_priv = dev->dev_private;
776  struct drm_device_dma *dma = dev->dma;
777  struct drm_buf *buf;
778  drm_r128_buf_priv_t *buf_priv;
779  u32 *data;
780  int dword_shift, dwords;
781  RING_LOCALS;
782  DRM_DEBUG("\n");
783 
784  /* The compiler won't optimize away a division by a variable,
785  * even if the only legal values are powers of two. Thus, we'll
786  * use a shift instead.
787  */
788  switch (blit->format) {
790  dword_shift = 0;
791  break;
797  dword_shift = 1;
798  break;
799  case R128_DATATYPE_CI8:
800  case R128_DATATYPE_RGB8:
801  dword_shift = 2;
802  break;
803  default:
804  DRM_ERROR("invalid blit format %d\n", blit->format);
805  return -EINVAL;
806  }
807 
808  /* Flush the pixel cache, and mark the contents as Read Invalid.
809  * This ensures no pixel data gets mixed up with the texture
810  * data from the host data blit, otherwise part of the texture
811  * image may be corrupted.
812  */
813  BEGIN_RING(2);
814 
817 
818  ADVANCE_RING();
819 
820  /* Dispatch the indirect buffer.
821  */
822  buf = dma->buflist[blit->idx];
823  buf_priv = buf->dev_private;
824 
825  if (buf->file_priv != file_priv) {
826  DRM_ERROR("process %d using buffer owned by %p\n",
827  DRM_CURRENTPID, buf->file_priv);
828  return -EINVAL;
829  }
830  if (buf->pending) {
831  DRM_ERROR("sending pending buffer %d\n", blit->idx);
832  return -EINVAL;
833  }
834 
835  buf_priv->discard = 1;
836 
837  dwords = (blit->width * blit->height) >> dword_shift;
838 
839  data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
840 
841  data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));
844  (blit->format << 8) |
846  R128_ROP3_S |
850 
851  data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));
852  data[3] = cpu_to_le32(0xffffffff);
853  data[4] = cpu_to_le32(0xffffffff);
854  data[5] = cpu_to_le32((blit->y << 16) | blit->x);
855  data[6] = cpu_to_le32((blit->height << 16) | blit->width);
856  data[7] = cpu_to_le32(dwords);
857 
858  buf->used = (dwords + 8) * sizeof(u32);
859 
860  r128_cce_dispatch_indirect(dev, buf, 0, buf->used);
861 
862  /* Flush the pixel cache after the blit completes. This ensures
863  * the texture data is written out to memory before rendering
864  * continues.
865  */
866  BEGIN_RING(2);
867 
870 
871  ADVANCE_RING();
872 
873  return 0;
874 }
875 
876 /* ================================================================
877  * Tiled depth buffer management
878  *
879  * FIXME: These should all set the destination write mask for when we
880  * have hardware stencil support.
881  */
882 
883 static int r128_cce_dispatch_write_span(struct drm_device *dev,
885 {
886  drm_r128_private_t *dev_priv = dev->dev_private;
887  int count, x, y;
888  u32 *buffer;
889  u8 *mask;
890  int i, buffer_size, mask_size;
891  RING_LOCALS;
892  DRM_DEBUG("\n");
893 
894  count = depth->n;
895  if (count > 4096 || count <= 0)
896  return -EMSGSIZE;
897 
898  if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x)))
899  return -EFAULT;
900  if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y)))
901  return -EFAULT;
902 
903  buffer_size = depth->n * sizeof(u32);
904  buffer = kmalloc(buffer_size, GFP_KERNEL);
905  if (buffer == NULL)
906  return -ENOMEM;
907  if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
908  kfree(buffer);
909  return -EFAULT;
910  }
911 
912  mask_size = depth->n * sizeof(u8);
913  if (depth->mask) {
914  mask = kmalloc(mask_size, GFP_KERNEL);
915  if (mask == NULL) {
916  kfree(buffer);
917  return -ENOMEM;
918  }
919  if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
920  kfree(buffer);
921  kfree(mask);
922  return -EFAULT;
923  }
924 
925  for (i = 0; i < count; i++, x++) {
926  if (mask[i]) {
927  BEGIN_RING(6);
928 
932  (dev_priv->depth_fmt << 8) |
934  R128_ROP3_P |
937 
938  OUT_RING(dev_priv->depth_pitch_offset_c);
939  OUT_RING(buffer[i]);
940 
941  OUT_RING((x << 16) | y);
942  OUT_RING((1 << 16) | 1);
943 
944  ADVANCE_RING();
945  }
946  }
947 
948  kfree(mask);
949  } else {
950  for (i = 0; i < count; i++, x++) {
951  BEGIN_RING(6);
952 
956  (dev_priv->depth_fmt << 8) |
958  R128_ROP3_P |
961 
962  OUT_RING(dev_priv->depth_pitch_offset_c);
963  OUT_RING(buffer[i]);
964 
965  OUT_RING((x << 16) | y);
966  OUT_RING((1 << 16) | 1);
967 
968  ADVANCE_RING();
969  }
970  }
971 
972  kfree(buffer);
973 
974  return 0;
975 }
976 
977 static int r128_cce_dispatch_write_pixels(struct drm_device *dev,
978  drm_r128_depth_t *depth)
979 {
980  drm_r128_private_t *dev_priv = dev->dev_private;
981  int count, *x, *y;
982  u32 *buffer;
983  u8 *mask;
984  int i, xbuf_size, ybuf_size, buffer_size, mask_size;
985  RING_LOCALS;
986  DRM_DEBUG("\n");
987 
988  count = depth->n;
989  if (count > 4096 || count <= 0)
990  return -EMSGSIZE;
991 
992  xbuf_size = count * sizeof(*x);
993  ybuf_size = count * sizeof(*y);
994  x = kmalloc(xbuf_size, GFP_KERNEL);
995  if (x == NULL)
996  return -ENOMEM;
997  y = kmalloc(ybuf_size, GFP_KERNEL);
998  if (y == NULL) {
999  kfree(x);
1000  return -ENOMEM;
1001  }
1002  if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
1003  kfree(x);
1004  kfree(y);
1005  return -EFAULT;
1006  }
1007  if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) {
1008  kfree(x);
1009  kfree(y);
1010  return -EFAULT;
1011  }
1012 
1013  buffer_size = depth->n * sizeof(u32);
1014  buffer = kmalloc(buffer_size, GFP_KERNEL);
1015  if (buffer == NULL) {
1016  kfree(x);
1017  kfree(y);
1018  return -ENOMEM;
1019  }
1020  if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
1021  kfree(x);
1022  kfree(y);
1023  kfree(buffer);
1024  return -EFAULT;
1025  }
1026 
1027  if (depth->mask) {
1028  mask_size = depth->n * sizeof(u8);
1029  mask = kmalloc(mask_size, GFP_KERNEL);
1030  if (mask == NULL) {
1031  kfree(x);
1032  kfree(y);
1033  kfree(buffer);
1034  return -ENOMEM;
1035  }
1036  if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
1037  kfree(x);
1038  kfree(y);
1039  kfree(buffer);
1040  kfree(mask);
1041  return -EFAULT;
1042  }
1043 
1044  for (i = 0; i < count; i++) {
1045  if (mask[i]) {
1046  BEGIN_RING(6);
1047 
1051  (dev_priv->depth_fmt << 8) |
1053  R128_ROP3_P |
1056 
1057  OUT_RING(dev_priv->depth_pitch_offset_c);
1058  OUT_RING(buffer[i]);
1059 
1060  OUT_RING((x[i] << 16) | y[i]);
1061  OUT_RING((1 << 16) | 1);
1062 
1063  ADVANCE_RING();
1064  }
1065  }
1066 
1067  kfree(mask);
1068  } else {
1069  for (i = 0; i < count; i++) {
1070  BEGIN_RING(6);
1071 
1075  (dev_priv->depth_fmt << 8) |
1077  R128_ROP3_P |
1080 
1081  OUT_RING(dev_priv->depth_pitch_offset_c);
1082  OUT_RING(buffer[i]);
1083 
1084  OUT_RING((x[i] << 16) | y[i]);
1085  OUT_RING((1 << 16) | 1);
1086 
1087  ADVANCE_RING();
1088  }
1089  }
1090 
1091  kfree(x);
1092  kfree(y);
1093  kfree(buffer);
1094 
1095  return 0;
1096 }
1097 
1098 static int r128_cce_dispatch_read_span(struct drm_device *dev,
1099  drm_r128_depth_t *depth)
1100 {
1101  drm_r128_private_t *dev_priv = dev->dev_private;
1102  int count, x, y;
1103  RING_LOCALS;
1104  DRM_DEBUG("\n");
1105 
1106  count = depth->n;
1107  if (count > 4096 || count <= 0)
1108  return -EMSGSIZE;
1109 
1110  if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x)))
1111  return -EFAULT;
1112  if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y)))
1113  return -EFAULT;
1114 
1115  BEGIN_RING(7);
1116 
1121  (dev_priv->depth_fmt << 8) |
1123  R128_ROP3_S |
1126 
1127  OUT_RING(dev_priv->depth_pitch_offset_c);
1128  OUT_RING(dev_priv->span_pitch_offset_c);
1129 
1130  OUT_RING((x << 16) | y);
1131  OUT_RING((0 << 16) | 0);
1132  OUT_RING((count << 16) | 1);
1133 
1134  ADVANCE_RING();
1135 
1136  return 0;
1137 }
1138 
1139 static int r128_cce_dispatch_read_pixels(struct drm_device *dev,
1140  drm_r128_depth_t *depth)
1141 {
1142  drm_r128_private_t *dev_priv = dev->dev_private;
1143  int count, *x, *y;
1144  int i, xbuf_size, ybuf_size;
1145  RING_LOCALS;
1146  DRM_DEBUG("\n");
1147 
1148  count = depth->n;
1149  if (count > 4096 || count <= 0)
1150  return -EMSGSIZE;
1151 
1152  if (count > dev_priv->depth_pitch)
1153  count = dev_priv->depth_pitch;
1154 
1155  xbuf_size = count * sizeof(*x);
1156  ybuf_size = count * sizeof(*y);
1157  x = kmalloc(xbuf_size, GFP_KERNEL);
1158  if (x == NULL)
1159  return -ENOMEM;
1160  y = kmalloc(ybuf_size, GFP_KERNEL);
1161  if (y == NULL) {
1162  kfree(x);
1163  return -ENOMEM;
1164  }
1165  if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
1166  kfree(x);
1167  kfree(y);
1168  return -EFAULT;
1169  }
1170  if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) {
1171  kfree(x);
1172  kfree(y);
1173  return -EFAULT;
1174  }
1175 
1176  for (i = 0; i < count; i++) {
1177  BEGIN_RING(7);
1178 
1183  (dev_priv->depth_fmt << 8) |
1185  R128_ROP3_S |
1188 
1189  OUT_RING(dev_priv->depth_pitch_offset_c);
1190  OUT_RING(dev_priv->span_pitch_offset_c);
1191 
1192  OUT_RING((x[i] << 16) | y[i]);
1193  OUT_RING((i << 16) | 0);
1194  OUT_RING((1 << 16) | 1);
1195 
1196  ADVANCE_RING();
1197  }
1198 
1199  kfree(x);
1200  kfree(y);
1201 
1202  return 0;
1203 }
1204 
1205 /* ================================================================
1206  * Polygon stipple
1207  */
1208 
1209 static void r128_cce_dispatch_stipple(struct drm_device *dev, u32 *stipple)
1210 {
1211  drm_r128_private_t *dev_priv = dev->dev_private;
1212  int i;
1213  RING_LOCALS;
1214  DRM_DEBUG("\n");
1215 
1216  BEGIN_RING(33);
1217 
1219  for (i = 0; i < 32; i++)
1220  OUT_RING(stipple[i]);
1221 
1222  ADVANCE_RING();
1223 }
1224 
1225 /* ================================================================
1226  * IOCTL functions
1227  */
1228 
1229 static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
1230 {
1231  drm_r128_private_t *dev_priv = dev->dev_private;
1232  drm_r128_sarea_t *sarea_priv;
1233  drm_r128_clear_t *clear = data;
1234  DRM_DEBUG("\n");
1235 
1236  LOCK_TEST_WITH_RETURN(dev, file_priv);
1237 
1238  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1239 
1240  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1241 
1242  sarea_priv = dev_priv->sarea_priv;
1243 
1244  if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1245  sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1246 
1247  r128_cce_dispatch_clear(dev, clear);
1248  COMMIT_RING();
1249 
1250  /* Make sure we restore the 3D state next time.
1251  */
1252  dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
1253 
1254  return 0;
1255 }
1256 
1257 static int r128_do_init_pageflip(struct drm_device *dev)
1258 {
1259  drm_r128_private_t *dev_priv = dev->dev_private;
1260  DRM_DEBUG("\n");
1261 
1262  dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET);
1264 
1268 
1269  dev_priv->page_flipping = 1;
1270  dev_priv->current_page = 0;
1271  dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
1272 
1273  return 0;
1274 }
1275 
1276 static int r128_do_cleanup_pageflip(struct drm_device *dev)
1277 {
1278  drm_r128_private_t *dev_priv = dev->dev_private;
1279  DRM_DEBUG("\n");
1280 
1283 
1284  if (dev_priv->current_page != 0) {
1285  r128_cce_dispatch_flip(dev);
1286  COMMIT_RING();
1287  }
1288 
1289  dev_priv->page_flipping = 0;
1290  return 0;
1291 }
1292 
1293 /* Swapping and flipping are different operations, need different ioctls.
1294  * They can & should be intermixed to support multiple 3d windows.
1295  */
1296 
1297 static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
1298 {
1299  drm_r128_private_t *dev_priv = dev->dev_private;
1300  DRM_DEBUG("\n");
1301 
1302  LOCK_TEST_WITH_RETURN(dev, file_priv);
1303 
1304  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1305 
1306  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1307 
1308  if (!dev_priv->page_flipping)
1309  r128_do_init_pageflip(dev);
1310 
1311  r128_cce_dispatch_flip(dev);
1312 
1313  COMMIT_RING();
1314  return 0;
1315 }
1316 
1317 static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
1318 {
1319  drm_r128_private_t *dev_priv = dev->dev_private;
1320  drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1321  DRM_DEBUG("\n");
1322 
1323  LOCK_TEST_WITH_RETURN(dev, file_priv);
1324 
1325  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1326 
1327  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1328 
1329  if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1330  sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1331 
1332  r128_cce_dispatch_swap(dev);
1333  dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
1335 
1336  COMMIT_RING();
1337  return 0;
1338 }
1339 
1340 static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
1341 {
1342  drm_r128_private_t *dev_priv = dev->dev_private;
1343  struct drm_device_dma *dma = dev->dma;
1344  struct drm_buf *buf;
1345  drm_r128_buf_priv_t *buf_priv;
1346  drm_r128_vertex_t *vertex = data;
1347 
1348  LOCK_TEST_WITH_RETURN(dev, file_priv);
1349 
1350  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1351 
1352  DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
1353  DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
1354 
1355  if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
1356  DRM_ERROR("buffer index %d (of %d max)\n",
1357  vertex->idx, dma->buf_count - 1);
1358  return -EINVAL;
1359  }
1360  if (vertex->prim < 0 ||
1362  DRM_ERROR("buffer prim %d\n", vertex->prim);
1363  return -EINVAL;
1364  }
1365 
1366  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1367  VB_AGE_TEST_WITH_RETURN(dev_priv);
1368 
1369  buf = dma->buflist[vertex->idx];
1370  buf_priv = buf->dev_private;
1371 
1372  if (buf->file_priv != file_priv) {
1373  DRM_ERROR("process %d using buffer owned by %p\n",
1374  DRM_CURRENTPID, buf->file_priv);
1375  return -EINVAL;
1376  }
1377  if (buf->pending) {
1378  DRM_ERROR("sending pending buffer %d\n", vertex->idx);
1379  return -EINVAL;
1380  }
1381 
1382  buf->used = vertex->count;
1383  buf_priv->prim = vertex->prim;
1384  buf_priv->discard = vertex->discard;
1385 
1386  r128_cce_dispatch_vertex(dev, buf);
1387 
1388  COMMIT_RING();
1389  return 0;
1390 }
1391 
1392 static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
1393 {
1394  drm_r128_private_t *dev_priv = dev->dev_private;
1395  struct drm_device_dma *dma = dev->dma;
1396  struct drm_buf *buf;
1397  drm_r128_buf_priv_t *buf_priv;
1398  drm_r128_indices_t *elts = data;
1399  int count;
1400 
1401  LOCK_TEST_WITH_RETURN(dev, file_priv);
1402 
1403  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1404 
1405  DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
1406  elts->idx, elts->start, elts->end, elts->discard);
1407 
1408  if (elts->idx < 0 || elts->idx >= dma->buf_count) {
1409  DRM_ERROR("buffer index %d (of %d max)\n",
1410  elts->idx, dma->buf_count - 1);
1411  return -EINVAL;
1412  }
1413  if (elts->prim < 0 ||
1415  DRM_ERROR("buffer prim %d\n", elts->prim);
1416  return -EINVAL;
1417  }
1418 
1419  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1420  VB_AGE_TEST_WITH_RETURN(dev_priv);
1421 
1422  buf = dma->buflist[elts->idx];
1423  buf_priv = buf->dev_private;
1424 
1425  if (buf->file_priv != file_priv) {
1426  DRM_ERROR("process %d using buffer owned by %p\n",
1427  DRM_CURRENTPID, buf->file_priv);
1428  return -EINVAL;
1429  }
1430  if (buf->pending) {
1431  DRM_ERROR("sending pending buffer %d\n", elts->idx);
1432  return -EINVAL;
1433  }
1434 
1435  count = (elts->end - elts->start) / sizeof(u16);
1436  elts->start -= R128_INDEX_PRIM_OFFSET;
1437 
1438  if (elts->start & 0x7) {
1439  DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
1440  return -EINVAL;
1441  }
1442  if (elts->start < buf->used) {
1443  DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
1444  return -EINVAL;
1445  }
1446 
1447  buf->used = elts->end;
1448  buf_priv->prim = elts->prim;
1449  buf_priv->discard = elts->discard;
1450 
1451  r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count);
1452 
1453  COMMIT_RING();
1454  return 0;
1455 }
1456 
1457 static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
1458 {
1459  struct drm_device_dma *dma = dev->dma;
1460  drm_r128_private_t *dev_priv = dev->dev_private;
1461  drm_r128_blit_t *blit = data;
1462  int ret;
1463 
1464  LOCK_TEST_WITH_RETURN(dev, file_priv);
1465 
1466  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1467 
1468  DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
1469 
1470  if (blit->idx < 0 || blit->idx >= dma->buf_count) {
1471  DRM_ERROR("buffer index %d (of %d max)\n",
1472  blit->idx, dma->buf_count - 1);
1473  return -EINVAL;
1474  }
1475 
1476  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1477  VB_AGE_TEST_WITH_RETURN(dev_priv);
1478 
1479  ret = r128_cce_dispatch_blit(dev, file_priv, blit);
1480 
1481  COMMIT_RING();
1482  return ret;
1483 }
1484 
1485 static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv)
1486 {
1487  drm_r128_private_t *dev_priv = dev->dev_private;
1488  drm_r128_depth_t *depth = data;
1489  int ret;
1490 
1491  LOCK_TEST_WITH_RETURN(dev, file_priv);
1492 
1493  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1494 
1495  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1496 
1497  ret = -EINVAL;
1498  switch (depth->func) {
1499  case R128_WRITE_SPAN:
1500  ret = r128_cce_dispatch_write_span(dev, depth);
1501  break;
1502  case R128_WRITE_PIXELS:
1503  ret = r128_cce_dispatch_write_pixels(dev, depth);
1504  break;
1505  case R128_READ_SPAN:
1506  ret = r128_cce_dispatch_read_span(dev, depth);
1507  break;
1508  case R128_READ_PIXELS:
1509  ret = r128_cce_dispatch_read_pixels(dev, depth);
1510  break;
1511  }
1512 
1513  COMMIT_RING();
1514  return ret;
1515 }
1516 
1517 static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
1518 {
1519  drm_r128_private_t *dev_priv = dev->dev_private;
1520  drm_r128_stipple_t *stipple = data;
1521  u32 mask[32];
1522 
1523  LOCK_TEST_WITH_RETURN(dev, file_priv);
1524 
1525  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1526 
1527  if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
1528  return -EFAULT;
1529 
1530  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1531 
1532  r128_cce_dispatch_stipple(dev, mask);
1533 
1534  COMMIT_RING();
1535  return 0;
1536 }
1537 
1538 static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
1539 {
1540  drm_r128_private_t *dev_priv = dev->dev_private;
1541  struct drm_device_dma *dma = dev->dma;
1542  struct drm_buf *buf;
1543  drm_r128_buf_priv_t *buf_priv;
1544  drm_r128_indirect_t *indirect = data;
1545 #if 0
1546  RING_LOCALS;
1547 #endif
1548 
1549  LOCK_TEST_WITH_RETURN(dev, file_priv);
1550 
1551  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1552 
1553  DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
1554  indirect->idx, indirect->start, indirect->end,
1555  indirect->discard);
1556 
1557  if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
1558  DRM_ERROR("buffer index %d (of %d max)\n",
1559  indirect->idx, dma->buf_count - 1);
1560  return -EINVAL;
1561  }
1562 
1563  buf = dma->buflist[indirect->idx];
1564  buf_priv = buf->dev_private;
1565 
1566  if (buf->file_priv != file_priv) {
1567  DRM_ERROR("process %d using buffer owned by %p\n",
1568  DRM_CURRENTPID, buf->file_priv);
1569  return -EINVAL;
1570  }
1571  if (buf->pending) {
1572  DRM_ERROR("sending pending buffer %d\n", indirect->idx);
1573  return -EINVAL;
1574  }
1575 
1576  if (indirect->start < buf->used) {
1577  DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
1578  indirect->start, buf->used);
1579  return -EINVAL;
1580  }
1581 
1582  RING_SPACE_TEST_WITH_RETURN(dev_priv);
1583  VB_AGE_TEST_WITH_RETURN(dev_priv);
1584 
1585  buf->used = indirect->end;
1586  buf_priv->discard = indirect->discard;
1587 
1588 #if 0
1589  /* Wait for the 3D stream to idle before the indirect buffer
1590  * containing 2D acceleration commands is processed.
1591  */
1592  BEGIN_RING(2);
1594  ADVANCE_RING();
1595 #endif
1596 
1597  /* Dispatch the indirect buffer full of commands from the
1598  * X server. This is insecure and is thus only available to
1599  * privileged clients.
1600  */
1601  r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end);
1602 
1603  COMMIT_RING();
1604  return 0;
1605 }
1606 
1607 static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
1608 {
1609  drm_r128_private_t *dev_priv = dev->dev_private;
1611  int value;
1612 
1613  DEV_INIT_TEST_WITH_RETURN(dev_priv);
1614 
1615  DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1616 
1617  switch (param->param) {
1618  case R128_PARAM_IRQ_NR:
1619  value = drm_dev_to_irq(dev);
1620  break;
1621  default:
1622  return -EINVAL;
1623  }
1624 
1625  if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
1626  DRM_ERROR("copy_to_user\n");
1627  return -EFAULT;
1628  }
1629 
1630  return 0;
1631 }
1632 
1633 void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
1634 {
1635  if (dev->dev_private) {
1636  drm_r128_private_t *dev_priv = dev->dev_private;
1637  if (dev_priv->page_flipping)
1638  r128_do_cleanup_pageflip(dev);
1639  }
1640 }
1642 {
1643  r128_do_cleanup_cce(dev);
1644 }
1645 
1646 struct drm_ioctl_desc r128_ioctls[] = {
1647  DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1648  DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1649  DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1650  DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1651  DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH),
1652  DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH),
1653  DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH),
1654  DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH),
1655  DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH),
1656  DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH),
1657  DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH),
1658  DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH),
1659  DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH),
1660  DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH),
1661  DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH),
1662  DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1663  DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH),
1664 };
1665 
1666 int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);