The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/r128_state.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 98cb4d13495b5db895fdabb552edc4a7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.