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

Cache object: adef122a9203588b083cba4b62ea0bd7


[ 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.