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