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

Cache object: 2f2cd2ef74dd2409eaf6c2658516855b


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