root/drivers/gpu/drm/mga/mga_state.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mga_emit_clip_rect
  2. mga_g200_emit_context
  3. mga_g400_emit_context
  4. mga_g200_emit_tex0
  5. mga_g400_emit_tex0
  6. mga_g400_emit_tex1
  7. mga_g200_emit_pipe
  8. mga_g400_emit_pipe
  9. mga_g200_emit_state
  10. mga_g400_emit_state
  11. mga_verify_context
  12. mga_verify_tex
  13. mga_verify_state
  14. mga_verify_iload
  15. mga_verify_blit
  16. mga_dma_dispatch_clear
  17. mga_dma_dispatch_swap
  18. mga_dma_dispatch_vertex
  19. mga_dma_dispatch_indices
  20. mga_dma_dispatch_iload
  21. mga_dma_dispatch_blit
  22. mga_dma_clear
  23. mga_dma_swap
  24. mga_dma_vertex
  25. mga_dma_indices
  26. mga_dma_iload
  27. mga_dma_blit
  28. mga_getparam
  29. mga_set_fence
  30. mga_wait_fence

   1 /* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*-
   2  * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com
   3  *
   4  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
   5  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
   6  * All Rights Reserved.
   7  *
   8  * Permission is hereby granted, free of charge, to any person obtaining a
   9  * copy of this software and associated documentation files (the "Software"),
  10  * to deal in the Software without restriction, including without limitation
  11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12  * and/or sell copies of the Software, and to permit persons to whom the
  13  * Software is furnished to do so, subject to the following conditions:
  14  *
  15  * The above copyright notice and this permission notice (including the next
  16  * paragraph) shall be included in all copies or substantial portions of the
  17  * Software.
  18  *
  19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25  * OTHER DEALINGS IN THE SOFTWARE.
  26  *
  27  * Authors:
  28  *    Jeff Hartmann <jhartmann@valinux.com>
  29  *    Keith Whitwell <keith@tungstengraphics.com>
  30  *
  31  * Rewritten by:
  32  *    Gareth Hughes <gareth@valinux.com>
  33  */
  34 
  35 #include "mga_drv.h"
  36 
  37 /* ================================================================
  38  * DMA hardware state programming functions
  39  */
  40 
  41 static void mga_emit_clip_rect(drm_mga_private_t *dev_priv,
  42                                struct drm_clip_rect *box)
  43 {
  44         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
  45         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
  46         unsigned int pitch = dev_priv->front_pitch;
  47         DMA_LOCALS;
  48 
  49         BEGIN_DMA(2);
  50 
  51         /* Force reset of DWGCTL on G400 (eliminates clip disable bit).
  52          */
  53         if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
  54                 DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl,
  55                           MGA_LEN + MGA_EXEC, 0x80000000,
  56                           MGA_DWGCTL, ctx->dwgctl,
  57                           MGA_LEN + MGA_EXEC, 0x80000000);
  58         }
  59         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
  60                   MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
  61                   MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
  62 
  63         ADVANCE_DMA();
  64 }
  65 
  66 static __inline__ void mga_g200_emit_context(drm_mga_private_t *dev_priv)
  67 {
  68         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
  69         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
  70         DMA_LOCALS;
  71 
  72         BEGIN_DMA(3);
  73 
  74         DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
  75                   MGA_MACCESS, ctx->maccess,
  76                   MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
  77 
  78         DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
  79                   MGA_FOGCOL, ctx->fogcolor,
  80                   MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
  81 
  82         DMA_BLOCK(MGA_FCOL, ctx->fcol,
  83                   MGA_DMAPAD, 0x00000000,
  84                   MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
  85 
  86         ADVANCE_DMA();
  87 }
  88 
  89 static __inline__ void mga_g400_emit_context(drm_mga_private_t *dev_priv)
  90 {
  91         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
  92         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
  93         DMA_LOCALS;
  94 
  95         BEGIN_DMA(4);
  96 
  97         DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
  98                   MGA_MACCESS, ctx->maccess,
  99                   MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
 100 
 101         DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
 102                   MGA_FOGCOL, ctx->fogcolor,
 103                   MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
 104 
 105         DMA_BLOCK(MGA_WFLAG1, ctx->wflag,
 106                   MGA_TDUALSTAGE0, ctx->tdualstage0,
 107                   MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol);
 108 
 109         DMA_BLOCK(MGA_STENCIL, ctx->stencil,
 110                   MGA_STENCILCTL, ctx->stencilctl,
 111                   MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
 112 
 113         ADVANCE_DMA();
 114 }
 115 
 116 static __inline__ void mga_g200_emit_tex0(drm_mga_private_t *dev_priv)
 117 {
 118         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 119         drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
 120         DMA_LOCALS;
 121 
 122         BEGIN_DMA(4);
 123 
 124         DMA_BLOCK(MGA_TEXCTL2, tex->texctl2,
 125                   MGA_TEXCTL, tex->texctl,
 126                   MGA_TEXFILTER, tex->texfilter,
 127                   MGA_TEXBORDERCOL, tex->texbordercol);
 128 
 129         DMA_BLOCK(MGA_TEXORG, tex->texorg,
 130                   MGA_TEXORG1, tex->texorg1,
 131                   MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
 132 
 133         DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
 134                   MGA_TEXWIDTH, tex->texwidth,
 135                   MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth);
 136 
 137         DMA_BLOCK(MGA_WR34, tex->texheight,
 138                   MGA_TEXTRANS, 0x0000ffff,
 139                   MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000);
 140 
 141         ADVANCE_DMA();
 142 }
 143 
 144 static __inline__ void mga_g400_emit_tex0(drm_mga_private_t *dev_priv)
 145 {
 146         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 147         drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
 148         DMA_LOCALS;
 149 
 150 /*      printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */
 151 /*             tex->texctl, tex->texctl2); */
 152 
 153         BEGIN_DMA(6);
 154 
 155         DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC,
 156                   MGA_TEXCTL, tex->texctl,
 157                   MGA_TEXFILTER, tex->texfilter,
 158                   MGA_TEXBORDERCOL, tex->texbordercol);
 159 
 160         DMA_BLOCK(MGA_TEXORG, tex->texorg,
 161                   MGA_TEXORG1, tex->texorg1,
 162                   MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
 163 
 164         DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
 165                   MGA_TEXWIDTH, tex->texwidth,
 166                   MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
 167 
 168         DMA_BLOCK(MGA_WR57, 0x00000000,
 169                   MGA_WR53, 0x00000000,
 170                   MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC);
 171 
 172         DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC,
 173                   MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC,
 174                   MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC,
 175                   MGA_DMAPAD, 0x00000000);
 176 
 177         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 178                   MGA_DMAPAD, 0x00000000,
 179                   MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff);
 180 
 181         ADVANCE_DMA();
 182 }
 183 
 184 static __inline__ void mga_g400_emit_tex1(drm_mga_private_t *dev_priv)
 185 {
 186         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 187         drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
 188         DMA_LOCALS;
 189 
 190 /*      printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg,  */
 191 /*             tex->texctl, tex->texctl2); */
 192 
 193         BEGIN_DMA(5);
 194 
 195         DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 |
 196                                 MGA_MAP1_ENABLE |
 197                                 MGA_G400_TC2_MAGIC),
 198                   MGA_TEXCTL, tex->texctl,
 199                   MGA_TEXFILTER, tex->texfilter,
 200                   MGA_TEXBORDERCOL, tex->texbordercol);
 201 
 202         DMA_BLOCK(MGA_TEXORG, tex->texorg,
 203                   MGA_TEXORG1, tex->texorg1,
 204                   MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
 205 
 206         DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
 207                   MGA_TEXWIDTH, tex->texwidth,
 208                   MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
 209 
 210         DMA_BLOCK(MGA_WR57, 0x00000000,
 211                   MGA_WR53, 0x00000000,
 212                   MGA_WR61, 0x00000000,
 213                   MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC);
 214 
 215         DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC,
 216                   MGA_TEXTRANS, 0x0000ffff,
 217                   MGA_TEXTRANSHIGH, 0x0000ffff,
 218                   MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC);
 219 
 220         ADVANCE_DMA();
 221 }
 222 
 223 static __inline__ void mga_g200_emit_pipe(drm_mga_private_t *dev_priv)
 224 {
 225         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 226         unsigned int pipe = sarea_priv->warp_pipe;
 227         DMA_LOCALS;
 228 
 229         BEGIN_DMA(3);
 230 
 231         DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND,
 232                   MGA_WVRTXSZ, 0x00000007,
 233                   MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000);
 234 
 235         DMA_BLOCK(MGA_WR25, 0x00000100,
 236                   MGA_WR34, 0x00000000,
 237                   MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff);
 238 
 239         /* Padding required due to hardware bug.
 240          */
 241         DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
 242                   MGA_DMAPAD, 0xffffffff,
 243                   MGA_DMAPAD, 0xffffffff,
 244                   MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] |
 245                                MGA_WMODE_START | dev_priv->wagp_enable));
 246 
 247         ADVANCE_DMA();
 248 }
 249 
 250 static __inline__ void mga_g400_emit_pipe(drm_mga_private_t *dev_priv)
 251 {
 252         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 253         unsigned int pipe = sarea_priv->warp_pipe;
 254         DMA_LOCALS;
 255 
 256 /*      printk("mga_g400_emit_pipe %x\n", pipe); */
 257 
 258         BEGIN_DMA(10);
 259 
 260         DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND,
 261                   MGA_DMAPAD, 0x00000000,
 262                   MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
 263 
 264         if (pipe & MGA_T2) {
 265                 DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09,
 266                           MGA_DMAPAD, 0x00000000,
 267                           MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
 268 
 269                 DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
 270                           MGA_WACCEPTSEQ, 0x00000000,
 271                           MGA_WACCEPTSEQ, 0x00000000,
 272                           MGA_WACCEPTSEQ, 0x1e000000);
 273         } else {
 274                 if (dev_priv->warp_pipe & MGA_T2) {
 275                         /* Flush the WARP pipe */
 276                         DMA_BLOCK(MGA_YDST, 0x00000000,
 277                                   MGA_FXLEFT, 0x00000000,
 278                                   MGA_FXRIGHT, 0x00000001,
 279                                   MGA_DWGCTL, MGA_DWGCTL_FLUSH);
 280 
 281                         DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001,
 282                                   MGA_DWGSYNC, 0x00007000,
 283                                   MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
 284                                   MGA_LEN + MGA_EXEC, 0x00000000);
 285 
 286                         DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX |
 287                                                 MGA_G400_TC2_MAGIC),
 288                                   MGA_LEN + MGA_EXEC, 0x00000000,
 289                                   MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
 290                                   MGA_DMAPAD, 0x00000000);
 291                 }
 292 
 293                 DMA_BLOCK(MGA_WVRTXSZ, 0x00001807,
 294                           MGA_DMAPAD, 0x00000000,
 295                           MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
 296 
 297                 DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
 298                           MGA_WACCEPTSEQ, 0x00000000,
 299                           MGA_WACCEPTSEQ, 0x00000000,
 300                           MGA_WACCEPTSEQ, 0x18000000);
 301         }
 302 
 303         DMA_BLOCK(MGA_WFLAG, 0x00000000,
 304                   MGA_WFLAG1, 0x00000000,
 305                   MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000);
 306 
 307         DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0              */
 308                   MGA_WR57, 0x00000000, /* tex0              */
 309                   MGA_WR53, 0x00000000, /* tex1              */
 310                   MGA_WR61, 0x00000000);        /* tex1              */
 311 
 312         DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC,  /* tex0 width        */
 313                   MGA_WR62, MGA_G400_WR_MAGIC,  /* tex0 height       */
 314                   MGA_WR52, MGA_G400_WR_MAGIC,  /* tex1 width        */
 315                   MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height       */
 316 
 317         /* Padding required due to hardware bug */
 318         DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
 319                   MGA_DMAPAD, 0xffffffff,
 320                   MGA_DMAPAD, 0xffffffff,
 321                   MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] |
 322                                 MGA_WMODE_START | dev_priv->wagp_enable));
 323 
 324         ADVANCE_DMA();
 325 }
 326 
 327 static void mga_g200_emit_state(drm_mga_private_t *dev_priv)
 328 {
 329         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 330         unsigned int dirty = sarea_priv->dirty;
 331 
 332         if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
 333                 mga_g200_emit_pipe(dev_priv);
 334                 dev_priv->warp_pipe = sarea_priv->warp_pipe;
 335         }
 336 
 337         if (dirty & MGA_UPLOAD_CONTEXT) {
 338                 mga_g200_emit_context(dev_priv);
 339                 sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
 340         }
 341 
 342         if (dirty & MGA_UPLOAD_TEX0) {
 343                 mga_g200_emit_tex0(dev_priv);
 344                 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
 345         }
 346 }
 347 
 348 static void mga_g400_emit_state(drm_mga_private_t *dev_priv)
 349 {
 350         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 351         unsigned int dirty = sarea_priv->dirty;
 352         int multitex = sarea_priv->warp_pipe & MGA_T2;
 353 
 354         if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
 355                 mga_g400_emit_pipe(dev_priv);
 356                 dev_priv->warp_pipe = sarea_priv->warp_pipe;
 357         }
 358 
 359         if (dirty & MGA_UPLOAD_CONTEXT) {
 360                 mga_g400_emit_context(dev_priv);
 361                 sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
 362         }
 363 
 364         if (dirty & MGA_UPLOAD_TEX0) {
 365                 mga_g400_emit_tex0(dev_priv);
 366                 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
 367         }
 368 
 369         if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
 370                 mga_g400_emit_tex1(dev_priv);
 371                 sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
 372         }
 373 }
 374 
 375 /* ================================================================
 376  * SAREA state verification
 377  */
 378 
 379 /* Disallow all write destinations except the front and backbuffer.
 380  */
 381 static int mga_verify_context(drm_mga_private_t *dev_priv)
 382 {
 383         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 384         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
 385 
 386         if (ctx->dstorg != dev_priv->front_offset &&
 387             ctx->dstorg != dev_priv->back_offset) {
 388                 DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n",
 389                           ctx->dstorg, dev_priv->front_offset,
 390                           dev_priv->back_offset);
 391                 ctx->dstorg = 0;
 392                 return -EINVAL;
 393         }
 394 
 395         return 0;
 396 }
 397 
 398 /* Disallow texture reads from PCI space.
 399  */
 400 static int mga_verify_tex(drm_mga_private_t *dev_priv, int unit)
 401 {
 402         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 403         drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
 404         unsigned int org;
 405 
 406         org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
 407 
 408         if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) {
 409                 DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit);
 410                 tex->texorg = 0;
 411                 return -EINVAL;
 412         }
 413 
 414         return 0;
 415 }
 416 
 417 static int mga_verify_state(drm_mga_private_t *dev_priv)
 418 {
 419         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 420         unsigned int dirty = sarea_priv->dirty;
 421         int ret = 0;
 422 
 423         if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
 424                 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 425 
 426         if (dirty & MGA_UPLOAD_CONTEXT)
 427                 ret |= mga_verify_context(dev_priv);
 428 
 429         if (dirty & MGA_UPLOAD_TEX0)
 430                 ret |= mga_verify_tex(dev_priv, 0);
 431 
 432         if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
 433                 if (dirty & MGA_UPLOAD_TEX1)
 434                         ret |= mga_verify_tex(dev_priv, 1);
 435 
 436                 if (dirty & MGA_UPLOAD_PIPE)
 437                         ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES);
 438         } else {
 439                 if (dirty & MGA_UPLOAD_PIPE)
 440                         ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES);
 441         }
 442 
 443         return (ret == 0);
 444 }
 445 
 446 static int mga_verify_iload(drm_mga_private_t *dev_priv,
 447                             unsigned int dstorg, unsigned int length)
 448 {
 449         if (dstorg < dev_priv->texture_offset ||
 450             dstorg + length > (dev_priv->texture_offset +
 451                                dev_priv->texture_size)) {
 452                 DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg);
 453                 return -EINVAL;
 454         }
 455 
 456         if (length & MGA_ILOAD_MASK) {
 457                 DRM_ERROR("*** bad iload length: 0x%x\n",
 458                           length & MGA_ILOAD_MASK);
 459                 return -EINVAL;
 460         }
 461 
 462         return 0;
 463 }
 464 
 465 static int mga_verify_blit(drm_mga_private_t *dev_priv,
 466                            unsigned int srcorg, unsigned int dstorg)
 467 {
 468         if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
 469             (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) {
 470                 DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg);
 471                 return -EINVAL;
 472         }
 473         return 0;
 474 }
 475 
 476 /* ================================================================
 477  *
 478  */
 479 
 480 static void mga_dma_dispatch_clear(struct drm_device *dev, drm_mga_clear_t *clear)
 481 {
 482         drm_mga_private_t *dev_priv = dev->dev_private;
 483         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 484         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
 485         struct drm_clip_rect *pbox = sarea_priv->boxes;
 486         int nbox = sarea_priv->nbox;
 487         int i;
 488         DMA_LOCALS;
 489         DRM_DEBUG("\n");
 490 
 491         BEGIN_DMA(1);
 492 
 493         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 494                   MGA_DMAPAD, 0x00000000,
 495                   MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
 496 
 497         ADVANCE_DMA();
 498 
 499         for (i = 0; i < nbox; i++) {
 500                 struct drm_clip_rect *box = &pbox[i];
 501                 u32 height = box->y2 - box->y1;
 502 
 503                 DRM_DEBUG("   from=%d,%d to=%d,%d\n",
 504                           box->x1, box->y1, box->x2, box->y2);
 505 
 506                 if (clear->flags & MGA_FRONT) {
 507                         BEGIN_DMA(2);
 508 
 509                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 510                                   MGA_PLNWT, clear->color_mask,
 511                                   MGA_YDSTLEN, (box->y1 << 16) | height,
 512                                   MGA_FXBNDRY, (box->x2 << 16) | box->x1);
 513 
 514                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 515                                   MGA_FCOL, clear->clear_color,
 516                                   MGA_DSTORG, dev_priv->front_offset,
 517                                   MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
 518 
 519                         ADVANCE_DMA();
 520                 }
 521 
 522                 if (clear->flags & MGA_BACK) {
 523                         BEGIN_DMA(2);
 524 
 525                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 526                                   MGA_PLNWT, clear->color_mask,
 527                                   MGA_YDSTLEN, (box->y1 << 16) | height,
 528                                   MGA_FXBNDRY, (box->x2 << 16) | box->x1);
 529 
 530                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 531                                   MGA_FCOL, clear->clear_color,
 532                                   MGA_DSTORG, dev_priv->back_offset,
 533                                   MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
 534 
 535                         ADVANCE_DMA();
 536                 }
 537 
 538                 if (clear->flags & MGA_DEPTH) {
 539                         BEGIN_DMA(2);
 540 
 541                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 542                                   MGA_PLNWT, clear->depth_mask,
 543                                   MGA_YDSTLEN, (box->y1 << 16) | height,
 544                                   MGA_FXBNDRY, (box->x2 << 16) | box->x1);
 545 
 546                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 547                                   MGA_FCOL, clear->clear_depth,
 548                                   MGA_DSTORG, dev_priv->depth_offset,
 549                                   MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
 550 
 551                         ADVANCE_DMA();
 552                 }
 553 
 554         }
 555 
 556         BEGIN_DMA(1);
 557 
 558         /* Force reset of DWGCTL */
 559         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 560                   MGA_DMAPAD, 0x00000000,
 561                   MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
 562 
 563         ADVANCE_DMA();
 564 
 565         FLUSH_DMA();
 566 }
 567 
 568 static void mga_dma_dispatch_swap(struct drm_device *dev)
 569 {
 570         drm_mga_private_t *dev_priv = dev->dev_private;
 571         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 572         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
 573         struct drm_clip_rect *pbox = sarea_priv->boxes;
 574         int nbox = sarea_priv->nbox;
 575         int i;
 576         DMA_LOCALS;
 577         DRM_DEBUG("\n");
 578 
 579         sarea_priv->last_frame.head = dev_priv->prim.tail;
 580         sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
 581 
 582         BEGIN_DMA(4 + nbox);
 583 
 584         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 585                   MGA_DMAPAD, 0x00000000,
 586                   MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
 587 
 588         DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset,
 589                   MGA_MACCESS, dev_priv->maccess,
 590                   MGA_SRCORG, dev_priv->back_offset,
 591                   MGA_AR5, dev_priv->front_pitch);
 592 
 593         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 594                   MGA_DMAPAD, 0x00000000,
 595                   MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY);
 596 
 597         for (i = 0; i < nbox; i++) {
 598                 struct drm_clip_rect *box = &pbox[i];
 599                 u32 height = box->y2 - box->y1;
 600                 u32 start = box->y1 * dev_priv->front_pitch;
 601 
 602                 DRM_DEBUG("   from=%d,%d to=%d,%d\n",
 603                           box->x1, box->y1, box->x2, box->y2);
 604 
 605                 DMA_BLOCK(MGA_AR0, start + box->x2 - 1,
 606                           MGA_AR3, start + box->x1,
 607                           MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
 608                           MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height);
 609         }
 610 
 611         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 612                   MGA_PLNWT, ctx->plnwt,
 613                   MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl);
 614 
 615         ADVANCE_DMA();
 616 
 617         FLUSH_DMA();
 618 
 619         DRM_DEBUG("... done.\n");
 620 }
 621 
 622 static void mga_dma_dispatch_vertex(struct drm_device *dev, struct drm_buf *buf)
 623 {
 624         drm_mga_private_t *dev_priv = dev->dev_private;
 625         drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 626         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 627         u32 address = (u32) buf->bus_address;
 628         u32 length = (u32) buf->used;
 629         int i = 0;
 630         DMA_LOCALS;
 631         DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
 632 
 633         if (buf->used) {
 634                 buf_priv->dispatched = 1;
 635 
 636                 MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
 637 
 638                 do {
 639                         if (i < sarea_priv->nbox) {
 640                                 mga_emit_clip_rect(dev_priv,
 641                                                    &sarea_priv->boxes[i]);
 642                         }
 643 
 644                         BEGIN_DMA(1);
 645 
 646                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 647                                   MGA_DMAPAD, 0x00000000,
 648                                   MGA_SECADDRESS, (address |
 649                                                    MGA_DMA_VERTEX),
 650                                   MGA_SECEND, ((address + length) |
 651                                                dev_priv->dma_access));
 652 
 653                         ADVANCE_DMA();
 654                 } while (++i < sarea_priv->nbox);
 655         }
 656 
 657         if (buf_priv->discard) {
 658                 AGE_BUFFER(buf_priv);
 659                 buf->pending = 0;
 660                 buf->used = 0;
 661                 buf_priv->dispatched = 0;
 662 
 663                 mga_freelist_put(dev, buf);
 664         }
 665 
 666         FLUSH_DMA();
 667 }
 668 
 669 static void mga_dma_dispatch_indices(struct drm_device *dev, struct drm_buf *buf,
 670                                      unsigned int start, unsigned int end)
 671 {
 672         drm_mga_private_t *dev_priv = dev->dev_private;
 673         drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 674         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 675         u32 address = (u32) buf->bus_address;
 676         int i = 0;
 677         DMA_LOCALS;
 678         DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end);
 679 
 680         if (start != end) {
 681                 buf_priv->dispatched = 1;
 682 
 683                 MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
 684 
 685                 do {
 686                         if (i < sarea_priv->nbox) {
 687                                 mga_emit_clip_rect(dev_priv,
 688                                                    &sarea_priv->boxes[i]);
 689                         }
 690 
 691                         BEGIN_DMA(1);
 692 
 693                         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 694                                   MGA_DMAPAD, 0x00000000,
 695                                   MGA_SETUPADDRESS, address + start,
 696                                   MGA_SETUPEND, ((address + end) |
 697                                                  dev_priv->dma_access));
 698 
 699                         ADVANCE_DMA();
 700                 } while (++i < sarea_priv->nbox);
 701         }
 702 
 703         if (buf_priv->discard) {
 704                 AGE_BUFFER(buf_priv);
 705                 buf->pending = 0;
 706                 buf->used = 0;
 707                 buf_priv->dispatched = 0;
 708 
 709                 mga_freelist_put(dev, buf);
 710         }
 711 
 712         FLUSH_DMA();
 713 }
 714 
 715 /* This copies a 64 byte aligned agp region to the frambuffer with a
 716  * standard blit, the ioctl needs to do checking.
 717  */
 718 static void mga_dma_dispatch_iload(struct drm_device *dev, struct drm_buf *buf,
 719                                    unsigned int dstorg, unsigned int length)
 720 {
 721         drm_mga_private_t *dev_priv = dev->dev_private;
 722         drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 723         drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
 724         u32 srcorg =
 725             buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
 726         u32 y2;
 727         DMA_LOCALS;
 728         DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
 729 
 730         y2 = length / 64;
 731 
 732         BEGIN_DMA(5);
 733 
 734         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 735                   MGA_DMAPAD, 0x00000000,
 736                   MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
 737 
 738         DMA_BLOCK(MGA_DSTORG, dstorg,
 739                   MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64);
 740 
 741         DMA_BLOCK(MGA_PITCH, 64,
 742                   MGA_PLNWT, 0xffffffff,
 743                   MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY);
 744 
 745         DMA_BLOCK(MGA_AR0, 63,
 746                   MGA_AR3, 0,
 747                   MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2);
 748 
 749         DMA_BLOCK(MGA_PLNWT, ctx->plnwt,
 750                   MGA_SRCORG, dev_priv->front_offset,
 751                   MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000);
 752 
 753         ADVANCE_DMA();
 754 
 755         AGE_BUFFER(buf_priv);
 756 
 757         buf->pending = 0;
 758         buf->used = 0;
 759         buf_priv->dispatched = 0;
 760 
 761         mga_freelist_put(dev, buf);
 762 
 763         FLUSH_DMA();
 764 }
 765 
 766 static void mga_dma_dispatch_blit(struct drm_device *dev, drm_mga_blit_t *blit)
 767 {
 768         drm_mga_private_t *dev_priv = dev->dev_private;
 769         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 770         drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
 771         struct drm_clip_rect *pbox = sarea_priv->boxes;
 772         int nbox = sarea_priv->nbox;
 773         u32 scandir = 0, i;
 774         DMA_LOCALS;
 775         DRM_DEBUG("\n");
 776 
 777         BEGIN_DMA(4 + nbox);
 778 
 779         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 780                   MGA_DMAPAD, 0x00000000,
 781                   MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
 782 
 783         DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY,
 784                   MGA_PLNWT, blit->planemask,
 785                   MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg);
 786 
 787         DMA_BLOCK(MGA_SGN, scandir,
 788                   MGA_MACCESS, dev_priv->maccess,
 789                   MGA_AR5, blit->ydir * blit->src_pitch,
 790                   MGA_PITCH, blit->dst_pitch);
 791 
 792         for (i = 0; i < nbox; i++) {
 793                 int srcx = pbox[i].x1 + blit->delta_sx;
 794                 int srcy = pbox[i].y1 + blit->delta_sy;
 795                 int dstx = pbox[i].x1 + blit->delta_dx;
 796                 int dsty = pbox[i].y1 + blit->delta_dy;
 797                 int h = pbox[i].y2 - pbox[i].y1;
 798                 int w = pbox[i].x2 - pbox[i].x1 - 1;
 799                 int start;
 800 
 801                 if (blit->ydir == -1)
 802                         srcy = blit->height - srcy - 1;
 803 
 804                 start = srcy * blit->src_pitch + srcx;
 805 
 806                 DMA_BLOCK(MGA_AR0, start + w,
 807                           MGA_AR3, start,
 808                           MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
 809                           MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h);
 810         }
 811 
 812         /* Do something to flush AGP?
 813          */
 814 
 815         /* Force reset of DWGCTL */
 816         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
 817                   MGA_PLNWT, ctx->plnwt,
 818                   MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl);
 819 
 820         ADVANCE_DMA();
 821 }
 822 
 823 /* ================================================================
 824  *
 825  */
 826 
 827 static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
 828 {
 829         drm_mga_private_t *dev_priv = dev->dev_private;
 830         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 831         drm_mga_clear_t *clear = data;
 832 
 833         LOCK_TEST_WITH_RETURN(dev, file_priv);
 834 
 835         if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
 836                 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 837 
 838         WRAP_TEST_WITH_RETURN(dev_priv);
 839 
 840         mga_dma_dispatch_clear(dev, clear);
 841 
 842         /* Make sure we restore the 3D state next time.
 843          */
 844         dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 845 
 846         return 0;
 847 }
 848 
 849 static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
 850 {
 851         drm_mga_private_t *dev_priv = dev->dev_private;
 852         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 853 
 854         LOCK_TEST_WITH_RETURN(dev, file_priv);
 855 
 856         if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
 857                 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 858 
 859         WRAP_TEST_WITH_RETURN(dev_priv);
 860 
 861         mga_dma_dispatch_swap(dev);
 862 
 863         /* Make sure we restore the 3D state next time.
 864          */
 865         dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 866 
 867         return 0;
 868 }
 869 
 870 static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
 871 {
 872         drm_mga_private_t *dev_priv = dev->dev_private;
 873         struct drm_device_dma *dma = dev->dma;
 874         struct drm_buf *buf;
 875         drm_mga_buf_priv_t *buf_priv;
 876         drm_mga_vertex_t *vertex = data;
 877 
 878         LOCK_TEST_WITH_RETURN(dev, file_priv);
 879 
 880         if (vertex->idx < 0 || vertex->idx > dma->buf_count)
 881                 return -EINVAL;
 882         buf = dma->buflist[vertex->idx];
 883         buf_priv = buf->dev_private;
 884 
 885         buf->used = vertex->used;
 886         buf_priv->discard = vertex->discard;
 887 
 888         if (!mga_verify_state(dev_priv)) {
 889                 if (vertex->discard) {
 890                         if (buf_priv->dispatched == 1)
 891                                 AGE_BUFFER(buf_priv);
 892                         buf_priv->dispatched = 0;
 893                         mga_freelist_put(dev, buf);
 894                 }
 895                 return -EINVAL;
 896         }
 897 
 898         WRAP_TEST_WITH_RETURN(dev_priv);
 899 
 900         mga_dma_dispatch_vertex(dev, buf);
 901 
 902         return 0;
 903 }
 904 
 905 static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
 906 {
 907         drm_mga_private_t *dev_priv = dev->dev_private;
 908         struct drm_device_dma *dma = dev->dma;
 909         struct drm_buf *buf;
 910         drm_mga_buf_priv_t *buf_priv;
 911         drm_mga_indices_t *indices = data;
 912 
 913         LOCK_TEST_WITH_RETURN(dev, file_priv);
 914 
 915         if (indices->idx < 0 || indices->idx > dma->buf_count)
 916                 return -EINVAL;
 917 
 918         buf = dma->buflist[indices->idx];
 919         buf_priv = buf->dev_private;
 920 
 921         buf_priv->discard = indices->discard;
 922 
 923         if (!mga_verify_state(dev_priv)) {
 924                 if (indices->discard) {
 925                         if (buf_priv->dispatched == 1)
 926                                 AGE_BUFFER(buf_priv);
 927                         buf_priv->dispatched = 0;
 928                         mga_freelist_put(dev, buf);
 929                 }
 930                 return -EINVAL;
 931         }
 932 
 933         WRAP_TEST_WITH_RETURN(dev_priv);
 934 
 935         mga_dma_dispatch_indices(dev, buf, indices->start, indices->end);
 936 
 937         return 0;
 938 }
 939 
 940 static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv)
 941 {
 942         struct drm_device_dma *dma = dev->dma;
 943         drm_mga_private_t *dev_priv = dev->dev_private;
 944         struct drm_buf *buf;
 945         drm_mga_buf_priv_t *buf_priv;
 946         drm_mga_iload_t *iload = data;
 947         DRM_DEBUG("\n");
 948 
 949         LOCK_TEST_WITH_RETURN(dev, file_priv);
 950 
 951 #if 0
 952         if (mga_do_wait_for_idle(dev_priv) < 0) {
 953                 if (MGA_DMA_DEBUG)
 954                         DRM_INFO("-EBUSY\n");
 955                 return -EBUSY;
 956         }
 957 #endif
 958         if (iload->idx < 0 || iload->idx > dma->buf_count)
 959                 return -EINVAL;
 960 
 961         buf = dma->buflist[iload->idx];
 962         buf_priv = buf->dev_private;
 963 
 964         if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) {
 965                 mga_freelist_put(dev, buf);
 966                 return -EINVAL;
 967         }
 968 
 969         WRAP_TEST_WITH_RETURN(dev_priv);
 970 
 971         mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length);
 972 
 973         /* Make sure we restore the 3D state next time.
 974          */
 975         dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 976 
 977         return 0;
 978 }
 979 
 980 static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
 981 {
 982         drm_mga_private_t *dev_priv = dev->dev_private;
 983         drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 984         drm_mga_blit_t *blit = data;
 985         DRM_DEBUG("\n");
 986 
 987         LOCK_TEST_WITH_RETURN(dev, file_priv);
 988 
 989         if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
 990                 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 991 
 992         if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg))
 993                 return -EINVAL;
 994 
 995         WRAP_TEST_WITH_RETURN(dev_priv);
 996 
 997         mga_dma_dispatch_blit(dev, blit);
 998 
 999         /* Make sure we restore the 3D state next time.
1000          */
1001         dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
1002 
1003         return 0;
1004 }
1005 
1006 int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
1007 {
1008         drm_mga_private_t *dev_priv = dev->dev_private;
1009         drm_mga_getparam_t *param = data;
1010         int value;
1011 
1012         if (!dev_priv) {
1013                 DRM_ERROR("called with no initialization\n");
1014                 return -EINVAL;
1015         }
1016 
1017         DRM_DEBUG("pid=%d\n", task_pid_nr(current));
1018 
1019         switch (param->param) {
1020         case MGA_PARAM_IRQ_NR:
1021                 value = dev->pdev->irq;
1022                 break;
1023         case MGA_PARAM_CARD_TYPE:
1024                 value = dev_priv->chipset;
1025                 break;
1026         default:
1027                 return -EINVAL;
1028         }
1029 
1030         if (copy_to_user(param->value, &value, sizeof(int))) {
1031                 DRM_ERROR("copy_to_user\n");
1032                 return -EFAULT;
1033         }
1034 
1035         return 0;
1036 }
1037 
1038 static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv)
1039 {
1040         drm_mga_private_t *dev_priv = dev->dev_private;
1041         u32 *fence = data;
1042         DMA_LOCALS;
1043 
1044         if (!dev_priv) {
1045                 DRM_ERROR("called with no initialization\n");
1046                 return -EINVAL;
1047         }
1048 
1049         DRM_DEBUG("pid=%d\n", task_pid_nr(current));
1050 
1051         /* I would normal do this assignment in the declaration of fence,
1052          * but dev_priv may be NULL.
1053          */
1054 
1055         *fence = dev_priv->next_fence_to_post;
1056         dev_priv->next_fence_to_post++;
1057 
1058         BEGIN_DMA(1);
1059         DMA_BLOCK(MGA_DMAPAD, 0x00000000,
1060                   MGA_DMAPAD, 0x00000000,
1061                   MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000);
1062         ADVANCE_DMA();
1063 
1064         return 0;
1065 }
1066 
1067 static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *
1068 file_priv)
1069 {
1070         drm_mga_private_t *dev_priv = dev->dev_private;
1071         u32 *fence = data;
1072 
1073         if (!dev_priv) {
1074                 DRM_ERROR("called with no initialization\n");
1075                 return -EINVAL;
1076         }
1077 
1078         DRM_DEBUG("pid=%d\n", task_pid_nr(current));
1079 
1080         mga_driver_fence_wait(dev, fence);
1081         return 0;
1082 }
1083 
1084 const struct drm_ioctl_desc mga_ioctls[] = {
1085         DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1086         DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH),
1087         DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH),
1088         DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH),
1089         DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH),
1090         DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH),
1091         DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH),
1092         DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH),
1093         DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH),
1094         DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH),
1095         DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH),
1096         DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH),
1097         DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1098 };
1099 
1100 int mga_max_ioctl = ARRAY_SIZE(mga_ioctls);

/* [<][>][^][v][top][bottom][index][help] */