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


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

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

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

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

Cache object: 4b3dc686027481856cbdb8d26ae1408e


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


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