From 360475376c5a597caf4a981c934a6b0d783fa94d Mon Sep 17 00:00:00 2001 From: Gareth Hughes Date: Thu, 15 Feb 2001 08:12:14 +0000 Subject: Merge mga-1-0-0-branch into trunk. --- linux/mga_state.c | 1542 +++++++++++++++++++++++++---------------------------- 1 file changed, 730 insertions(+), 812 deletions(-) (limited to 'linux/mga_state.c') diff --git a/linux/mga_state.c b/linux/mga_state.c index bba8fa35..dc2c8c30 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -1,4 +1,4 @@ -/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*- +/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*- * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -19,404 +19,400 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. * - * Authors: Jeff Hartmann - * Keith Whitwell + * Authors: + * Jeff Hartmann + * Keith Whitwell * + * Rewritten by: + * Gareth Hughes */ #define __NO_VERSION__ +#include "mga.h" #include "drmP.h" #include "mga_drv.h" #include "drm.h" -/* If you change the functions to set state, PLEASE - * change these values - */ - -#define MGAEMITCLIP_SIZE 10 -#define MGAEMITCTX_SIZE 20 -#define MGAG200EMITTEX_SIZE 20 -#define MGAG400EMITTEX0_SIZE 30 -#define MGAG400EMITTEX1_SIZE 25 -#define MGAG400EMITPIPE_SIZE 50 -#define MGAG200EMITPIPE_SIZE 15 -#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \ - MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \ - MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE) +/* ================================================================ + * DMA hardware state programming functions + */ -static void mgaEmitClipRect(drm_mga_private_t * dev_priv, - drm_clip_rect_t * box) +static void mga_emit_clip_rect( drm_mga_private_t *dev_priv, + drm_clip_rect_t *box ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - PRIMLOCALS; - - /* This takes 10 dwords */ - PRIMGETPTR(dev_priv); - - /* Force reset of dwgctl on G400 (eliminates clip disable bit) */ - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { -#if 0 - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); -#else - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000); -#endif - } - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1)); - PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp); - PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp); + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + unsigned int pitch = dev_priv->front_pitch; + DMA_LOCALS; - PRIMADVANCE(dev_priv); -} + BEGIN_DMA( 2 ); -static void mgaEmitContext(drm_mga_private_t * dev_priv) -{ - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - PRIMLOCALS; - - /* This takes a max of 20 dwords */ - PRIMGETPTR(dev_priv); - - PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]); - PRIMOUTREG(MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS]); - PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - - PRIMOUTREG(MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL]); - PRIMOUTREG(MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR]); - PRIMOUTREG(MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG]); - PRIMOUTREG(MGAREG_ZORG, dev_priv->depthOffset); /* invarient */ - - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - PRIMOUTREG(MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG]); - PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]); - PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]); - PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]); - - PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]); - PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - } else { - PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + /* Force reset of DWGCTL on G400 (eliminates clip disable bit). + */ + if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { + DMA_BLOCK( MGA_DWGCTL, ctx->dwgctl, + MGA_LEN + MGA_EXEC, 0x80000000, + MGA_DWGCTL, ctx->dwgctl, + MGA_LEN + MGA_EXEC, 0x80000000 ); } + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_CXBNDRY, (box->x2 << 16) | box->x1, + MGA_YTOP, box->y1 * pitch, + MGA_YBOT, box->y2 * pitch ); - PRIMADVANCE(dev_priv); + ADVANCE_DMA(); } -static void mgaG200EmitTex(drm_mga_private_t * dev_priv) +static inline void mga_g200_emit_context( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->TexState[0]; - PRIMLOCALS; - - PRIMGETPTR(dev_priv); + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + DMA_LOCALS; - /* This takes 20 dwords */ + BEGIN_DMA( 3 ); - PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2]); - PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]); - PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]); - PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]); + DMA_BLOCK( MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); - PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]); - PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]); - PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]); - PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]); + DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, + MGA_ZORG, dev_priv->depth_offset ); - PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]); - PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]); - PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]); + DMA_BLOCK( MGA_FCOL, ctx->fcol, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); - PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]); - PRIMOUTREG(MGAREG_TEXTRANS, 0xffff); - PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff); - PRIMOUTREG(MGAREG_DMAPAD, 0); - - PRIMADVANCE(dev_priv); + ADVANCE_DMA(); } -#define TMC_dualtex_enable 0x80 - -static void mgaG400EmitTex0(drm_mga_private_t * dev_priv) +static inline void mga_g400_emit_context( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->TexState[0]; - PRIMLOCALS; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + DMA_LOCALS; - PRIMGETPTR(dev_priv); + BEGIN_DMA( 4 ); - /* This takes 30 dwords */ + DMA_BLOCK( MGA_DSTORG, ctx->dstorg, + MGA_MACCESS, ctx->maccess, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); - PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000); - PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]); - PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]); - PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]); + DMA_BLOCK( MGA_ALPHACTRL, ctx->alphactrl, + MGA_FOGCOL, ctx->fogcolor, + MGA_WFLAG, ctx->wflag, + MGA_ZORG, dev_priv->depth_offset ); - PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]); - PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]); - PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]); - PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]); + DMA_BLOCK( MGA_WFLAG1, ctx->wflag, + MGA_TDUALSTAGE0, ctx->tdualstage0, + MGA_TDUALSTAGE1, ctx->tdualstage1, + MGA_FCOL, ctx->fcol ); - PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]); - PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]); - PRIMOUTREG(MGAREG_WR49, 0); + DMA_BLOCK( MGA_STENCIL, ctx->stencil, + MGA_STENCILCTL, ctx->stencilctl, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); - PRIMOUTREG(MGAREG_WR57, 0); - PRIMOUTREG(MGAREG_WR53, 0); - PRIMOUTREG(MGAREG_WR61, 0); - PRIMOUTREG(MGAREG_WR52, 0x40); - - PRIMOUTREG(MGAREG_WR60, 0x40); - PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40); - PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40); - PRIMOUTREG(MGAREG_DMAPAD, 0); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_TEXTRANS, 0xffff); - PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff); - - PRIMADVANCE(dev_priv); + ADVANCE_DMA(); } -#define TMC_map1_enable 0x80000000 - -static void mgaG400EmitTex1(drm_mga_private_t * dev_priv) +static inline void mga_g200_emit_tex0( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->TexState[1]; - PRIMLOCALS; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; + DMA_LOCALS; - PRIMGETPTR(dev_priv); + BEGIN_DMA( 4 ); - /* This takes 25 dwords */ + DMA_BLOCK( MGA_TEXCTL2, tex->texctl2, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); - PRIMOUTREG(MGAREG_TEXCTL2, - regs[MGA_TEXREG_CTL2] | TMC_map1_enable | 0x00008000); - PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]); - PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]); - PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]); + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); - PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]); - PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]); - PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]); - PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]); + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR24, tex->texwidth ); - PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]); - PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]); - PRIMOUTREG(MGAREG_WR49, 0); + DMA_BLOCK( MGA_WR34, tex->texheight, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, + MGA_DMAPAD, 0x00000000 ); - PRIMOUTREG(MGAREG_WR57, 0); - PRIMOUTREG(MGAREG_WR53, 0); - PRIMOUTREG(MGAREG_WR61, 0); - PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40); - - PRIMOUTREG(MGAREG_WR60, regs[MGA_TEXREG_HEIGHT] | 0x40); - PRIMOUTREG(MGAREG_TEXTRANS, 0xffff); - PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff); - PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000); + ADVANCE_DMA(); +} - PRIMADVANCE(dev_priv); +static inline void mga_g400_emit_tex0( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0]; + DMA_LOCALS; + + BEGIN_DMA( 6 ); + + DMA_BLOCK( MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC, + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); + + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); + + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR49, 0x00000000 ); + + DMA_BLOCK( MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, + MGA_WR52, MGA_G400_WR_MAGIC ); + + DMA_BLOCK( MGA_WR60, MGA_G400_WR_MAGIC, + MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC, + MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff ); + + ADVANCE_DMA(); } -#define MAGIC_FPARAM_HEX_VALUE 0x46480000 -/* This is the hex value of 12800.0f which is a magic value we must - * set in wr56. - */ +static inline void mga_g400_emit_tex1( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1]; + DMA_LOCALS; + + BEGIN_DMA( 5 ); + + DMA_BLOCK( MGA_TEXCTL2, (tex->texctl2 | + MGA_MAP1_ENABLE | + MGA_G400_TC2_MAGIC), + MGA_TEXCTL, tex->texctl, + MGA_TEXFILTER, tex->texfilter, + MGA_TEXBORDERCOL, tex->texbordercol ); + + DMA_BLOCK( MGA_TEXORG, tex->texorg, + MGA_TEXORG1, tex->texorg1, + MGA_TEXORG2, tex->texorg2, + MGA_TEXORG3, tex->texorg3 ); + + DMA_BLOCK( MGA_TEXORG4, tex->texorg4, + MGA_TEXWIDTH, tex->texwidth, + MGA_TEXHEIGHT, tex->texheight, + MGA_WR49, 0x00000000 ); + + DMA_BLOCK( MGA_WR57, 0x00000000, + MGA_WR53, 0x00000000, + MGA_WR61, 0x00000000, + MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC ); + + DMA_BLOCK( MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC, + MGA_TEXTRANS, 0x0000ffff, + MGA_TEXTRANSHIGH, 0x0000ffff, + MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC ); + + ADVANCE_DMA(); +} -static void mgaG400EmitPipe(drm_mga_private_t * dev_priv) +static inline void mga_g200_emit_pipe( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->WarpPipe; - PRIMLOCALS; + unsigned int pipe = sarea_priv->warp_pipe; + DMA_LOCALS; - PRIMGETPTR(dev_priv); + BEGIN_DMA( 3 ); - /* This takes 50 dwords */ + DMA_BLOCK( MGA_WIADDR, MGA_WMODE_SUSPEND, + MGA_WVRTXSZ, 0x00000007, + MGA_WFLAG, 0x00000000, + MGA_WR24, 0x00000000 ); - /* Establish vertex size. + DMA_BLOCK( MGA_WR25, 0x00000100, + MGA_WR34, 0x00000000, + MGA_WR42, 0x0000ffff, + MGA_WR60, 0x0000ffff ); + + /* Padding required to to hardware bug. */ - PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - - if (pipe & MGA_T2) { - PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000); + DMA_BLOCK( MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] | + MGA_WMODE_START | + MGA_WAGP_ENABLE) ); + + ADVANCE_DMA(); +} + +static inline void mga_g400_emit_pipe( drm_mga_private_t *dev_priv ) +{ + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int pipe = sarea_priv->warp_pipe; + DMA_LOCALS; + + BEGIN_DMA( 10 ); + + DMA_BLOCK( MGA_WIADDR2, MGA_WMODE_SUSPEND, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + if ( pipe & MGA_T2 ) { + DMA_BLOCK( MGA_WVRTXSZ, 0x00001e09, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x1e000000 ); } else { - if (dev_priv->WarpPipe & MGA_T2) { + if ( dev_priv->warp_pipe & MGA_T2 ) { /* Flush the WARP pipe */ - PRIMOUTREG(MGAREG_YDST, 0); - PRIMOUTREG(MGAREG_FXLEFT, 0); - PRIMOUTREG(MGAREG_FXRIGHT, 1); - PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD); - - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); - PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); - - PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000); - PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0); - PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000); - PRIMOUTREG(MGAREG_DMAPAD, 0); + DMA_BLOCK( MGA_YDST, 0x00000000, + MGA_FXLEFT, 0x00000000, + MGA_FXRIGHT, 0x00000001, + MGA_DWGCTL, MGA_DWGCTL_FLUSH ); + + DMA_BLOCK( MGA_LEN + MGA_EXEC, 0x00000001, + MGA_DWGSYNC, 0x00007000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_LEN + MGA_EXEC, 0x00000000 ); + + DMA_BLOCK( MGA_TEXCTL2, (MGA_DUALTEX | + MGA_G400_TC2_MAGIC), + MGA_LEN + MGA_EXEC, 0x00000000, + MGA_TEXCTL2, MGA_G400_TC2_MAGIC, + MGA_DMAPAD, 0x00000000 ); } - PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); + DMA_BLOCK( MGA_WVRTXSZ, 0x00001807, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000 ); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0); - PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000); + DMA_BLOCK( MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x00000000, + MGA_WACCEPTSEQ, 0x18000000 ); } - PRIMOUTREG(MGAREG_WFLAG, 0); - PRIMOUTREG(MGAREG_WFLAG1, 0); - PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE); - PRIMOUTREG(MGAREG_DMAPAD, 0); - - PRIMOUTREG(MGAREG_WR49, 0); /* Tex stage 0 */ - PRIMOUTREG(MGAREG_WR57, 0); /* Tex stage 0 */ - PRIMOUTREG(MGAREG_WR53, 0); /* Tex stage 1 */ - PRIMOUTREG(MGAREG_WR61, 0); /* Tex stage 1 */ - - PRIMOUTREG(MGAREG_WR54, 0x40); /* Tex stage 0 : w */ - PRIMOUTREG(MGAREG_WR62, 0x40); /* Tex stage 0 : h */ - PRIMOUTREG(MGAREG_WR52, 0x40); /* Tex stage 1 : w */ - PRIMOUTREG(MGAREG_WR60, 0x40); /* Tex stage 1 : h */ - - /* Dma pading required due to hw bug */ - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR2, - (u32) (dev_priv->WarpIndex[pipe]. - phys_addr | WIA_wmode_start | WIA_wagp_agp)); - PRIMADVANCE(dev_priv); + DMA_BLOCK( MGA_WFLAG, 0x00000000, + MGA_WFLAG1, 0x00000000, + MGA_WR56, MGA_G400_WR56_MAGIC, + MGA_DMAPAD, 0x00000000 ); + + DMA_BLOCK( MGA_WR49, 0x00000000, /* tex0 */ + MGA_WR57, 0x00000000, /* tex0 */ + MGA_WR53, 0x00000000, /* tex1 */ + MGA_WR61, 0x00000000 ); /* tex1 */ + + DMA_BLOCK( MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */ + MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */ + MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */ + MGA_WR60, MGA_G400_WR_MAGIC ); /* tex1 height */ + + /* Padding required to to hardware bug */ + DMA_BLOCK( MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_DMAPAD, 0xffffffff, + MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] | + MGA_WMODE_START | + MGA_WAGP_ENABLE) ); + + ADVANCE_DMA(); } -static void mgaG200EmitPipe(drm_mga_private_t * dev_priv) +static void mga_g200_emit_state( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int pipe = sarea_priv->WarpPipe; - PRIMLOCALS; - - PRIMGETPTR(dev_priv); - - /* This takes 15 dwords */ - - PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend); - PRIMOUTREG(MGAREG_WVRTXSZ, 7); - PRIMOUTREG(MGAREG_WFLAG, 0); - PRIMOUTREG(MGAREG_WR24, 0); /* tex w/h */ + unsigned int dirty = sarea_priv->dirty; - PRIMOUTREG(MGAREG_WR25, 0x100); - PRIMOUTREG(MGAREG_WR34, 0); /* tex w/h */ - PRIMOUTREG(MGAREG_WR42, 0xFFFF); - PRIMOUTREG(MGAREG_WR60, 0xFFFF); + if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { + mga_g200_emit_pipe( dev_priv ); + dev_priv->warp_pipe = sarea_priv->warp_pipe; + } - /* Dma pading required due to hw bug */ - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR, - (u32) (dev_priv->WarpIndex[pipe]. - phys_addr | WIA_wmode_start | WIA_wagp_agp)); + if ( dirty & MGA_UPLOAD_CONTEXT ) { + mga_g200_emit_context( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; + } - PRIMADVANCE( dev_priv ); + if ( dirty & MGA_UPLOAD_TEX0 ) { + mga_g200_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } } -static void mgaEmitState(drm_mga_private_t * dev_priv) +static void mga_g400_emit_state( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; + int multitex = sarea_priv->warp_pipe & MGA_T2; - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - int multitex = sarea_priv->WarpPipe & MGA_T2; - - if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { - mgaG400EmitPipe(dev_priv); - dev_priv->WarpPipe = sarea_priv->WarpPipe; - } - - if (dirty & MGA_UPLOAD_CTX) { - mgaEmitContext(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CTX; - } - - if (dirty & MGA_UPLOAD_TEX0) { - mgaG400EmitTex0(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } + if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) { + mga_g400_emit_pipe( dev_priv ); + dev_priv->warp_pipe = sarea_priv->warp_pipe; + } - if ((dirty & MGA_UPLOAD_TEX1) && multitex) { - mgaG400EmitTex1(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; - } - } else { - if (sarea_priv->WarpPipe != dev_priv->WarpPipe) { - mgaG200EmitPipe(dev_priv); - dev_priv->WarpPipe = sarea_priv->WarpPipe; - } + if ( dirty & MGA_UPLOAD_CONTEXT ) { + mga_g400_emit_context( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT; + } - if (dirty & MGA_UPLOAD_CTX) { - mgaEmitContext(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_CTX; - } + if ( dirty & MGA_UPLOAD_TEX0 ) { + mga_g400_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; + } - if (dirty & MGA_UPLOAD_TEX0) { - mgaG200EmitTex(dev_priv); - sarea_priv->dirty &= ~MGA_UPLOAD_TEX0; - } + if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) { + mga_g400_emit_tex1( dev_priv ); + sarea_priv->dirty &= ~MGA_UPLOAD_TEX1; } } + +/* ================================================================ + * SAREA state verification + */ + /* Disallow all write destinations except the front and backbuffer. */ -static int mgaVerifyContext(drm_mga_private_t * dev_priv) +static int mga_verify_context( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - - if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset && - regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) { - DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n", - regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset, - dev_priv->backOffset); - regs[MGA_CTXREG_DSTORG] = 0; - return -1; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + + if ( ctx->dstorg != dev_priv->front_offset && + ctx->dstorg != dev_priv->back_offset ) { + DRM_DEBUG( "*** bad DSTORG: %x (front %x, back %x)\n\n", + ctx->dstorg, dev_priv->front_offset, + dev_priv->back_offset ); + ctx->dstorg = 0; + return -EINVAL; } return 0; @@ -424,720 +420,642 @@ static int mgaVerifyContext(drm_mga_private_t * dev_priv) /* Disallow texture reads from PCI space. */ -static int mgaVerifyTex(drm_mga_private_t * dev_priv, int unit) +static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit]; + unsigned int org; - if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) { - DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n", - sarea_priv->TexState[unit][MGA_TEXREG_ORG], - unit); - sarea_priv->TexState[unit][MGA_TEXREG_ORG] = 0; - return -1; + org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK); + + if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) { + DRM_DEBUG( "*** bad TEXORG: 0x%x, unit %d\n", + tex->texorg, unit ); + tex->texorg = 0; + return -EINVAL; } return 0; } -static int mgaVerifyState(drm_mga_private_t * dev_priv) +static int mga_verify_state( drm_mga_private_t *dev_priv ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; - int rv = 0; + int ret = 0; - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - if (dirty & MGA_UPLOAD_CTX) - rv |= mgaVerifyContext(dev_priv); + if ( dirty & MGA_UPLOAD_CONTEXT ) + ret |= mga_verify_context( dev_priv ); - if (dirty & MGA_UPLOAD_TEX0) - rv |= mgaVerifyTex(dev_priv, 0); + if ( dirty & MGA_UPLOAD_TEX0 ) + ret |= mga_verify_tex( dev_priv, 0 ); - if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - if (dirty & MGA_UPLOAD_TEX1) - rv |= mgaVerifyTex(dev_priv, 1); + if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) { + if ( dirty & MGA_UPLOAD_TEX1 ) + ret |= mga_verify_tex( dev_priv, 1 ); - if (dirty & MGA_UPLOAD_PIPE) - rv |= (sarea_priv->WarpPipe > MGA_MAX_G400_PIPES); + if ( dirty & MGA_UPLOAD_PIPE ) + ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES ); } else { - if (dirty & MGA_UPLOAD_PIPE) - rv |= (sarea_priv->WarpPipe > MGA_MAX_G200_PIPES); + if ( dirty & MGA_UPLOAD_PIPE ) + ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES ); } - return rv == 0; + return ( ret == 0 ); } -static int mgaVerifyIload(drm_mga_private_t * dev_priv, - unsigned long bus_address, - unsigned int dstOrg, int length) +static int mga_verify_iload( drm_mga_private_t *dev_priv, + unsigned int dstorg, unsigned int length ) { - if (dstOrg < dev_priv->textureOffset || - dstOrg + length > - (dev_priv->textureOffset + dev_priv->textureSize)) { + if ( dstorg < dev_priv->texture_offset || + dstorg + length > (dev_priv->texture_offset + + dev_priv->texture_size) ) { return -EINVAL; } - if (length % 64) { + + if ( length & MGA_ILOAD_MASK ) { + return -EINVAL; + } + + return 0; +} + +static int mga_verify_blit( drm_mga_private_t *dev_priv, + unsigned int srcorg, unsigned int dstorg ) +{ + if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) || + (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) { return -EINVAL; } return 0; } -/* This copies a 64 byte aligned agp region to the frambuffer - * with a standard blit, the ioctl needs to do checking */ -static void mga_dma_dispatch_tex_blit(drm_device_t * dev, - unsigned long bus_address, - int length, unsigned int destOrg) +/* ================================================================ + * + */ + +static void mga_dma_dispatch_clear( drm_device_t *dev, + drm_mga_clear_t *clear ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - int use_agp = PDEA_pagpxfer_enable | 0x00000001; - u16 y2; - PRIMLOCALS; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + int i; + DMA_LOCALS; + DRM_DEBUG( __FUNCTION__ ":\n" ); - y2 = length / 64; + for ( i = 0 ; i < nbox ; i++ ) { + drm_clip_rect_t *box = &pbox[i]; + u32 height = box->y2 - box->y1; + + if ( clear->flags & MGA_FRONT ) { + BEGIN_DMA( 2 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->front_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); + + ADVANCE_DMA(); + } - PRIM_OVERFLOW(dev, dev_priv, 30); - PRIMOUTREG(MGAREG_DSTORG, destOrg); - PRIMOUTREG(MGAREG_MACCESS, 0x00000000); - PRIMOUTREG(MGAREG_SRCORG, (u32) bus_address | use_agp); - PRIMOUTREG(MGAREG_AR5, 64); + if ( clear->flags & MGA_BACK ) { + BEGIN_DMA( 2 ); - PRIMOUTREG(MGAREG_PITCH, 64); - PRIMOUTREG(MGAREG_PLNWT, ~0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->color_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); - PRIMOUTREG(MGAREG_AR0, 63); - PRIMOUTREG(MGAREG_AR3, 0); - PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16)); - PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2); + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_color, + MGA_DSTORG, dev_priv->back_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); - PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]); - PRIMOUTREG(MGAREG_SRCORG, 0); - PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); - PRIMADVANCE(dev_priv); + ADVANCE_DMA(); + } + + if ( clear->flags & MGA_DEPTH ) { + BEGIN_DMA( 2 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, clear->depth_mask, + MGA_YDSTLEN, (box->y1 << 16) | height, + MGA_FXBNDRY, (box->x2 << 16) | box->x1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_FCOL, clear->clear_depth, + MGA_DSTORG, dev_priv->depth_offset, + MGA_DWGCTL + MGA_EXEC, + dev_priv->clear_cmd ); + + ADVANCE_DMA(); + } + + } + + BEGIN_DMA( 1 ); + + /* Force reset of DWGCTL */ + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_DWGCTL, ctx->dwgctl ); + + ADVANCE_DMA(); + + FLUSH_DMA(); } -static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf) +static void mga_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int nbox = sarea_priv->nbox; + int i; + DMA_LOCALS; + DRM_DEBUG( __FUNCTION__ ":\n" ); + DRM_DEBUG( " head = 0x%06x\n", *dev_priv->prim.head ); + + sarea_priv->last_frame.head = dev_priv->prim.tail; + sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap; + + DRM_DEBUG( " tail = 0x%06x\n", dev_priv->prim.tail ); + DRM_DEBUG( " wrap = 0x%06x\n", dev_priv->prim.last_wrap ); + + BEGIN_DMA( 4 + nbox ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + DMA_BLOCK( MGA_DSTORG, dev_priv->front_offset, + MGA_MACCESS, dev_priv->maccess, + MGA_SRCORG, dev_priv->back_offset, + MGA_AR5, dev_priv->front_pitch ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_PLNWT, 0xffffffff, + MGA_DWGCTL, MGA_DWGCTL_COPY ); + + for ( i = 0 ; i < nbox ; i++ ) { + drm_clip_rect_t *box = &pbox[i]; + u32 height = box->y2 - box->y1; + u32 start = box->y1 * dev_priv->front_pitch; + + DMA_BLOCK( MGA_AR0, start + box->x2 - 1, + MGA_AR3, start + box->x1, + MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1, + MGA_YDSTLEN + MGA_EXEC, + (box->y1 << 16) | height ); + } + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, + MGA_DWGCTL, ctx->dwgctl ); + + ADVANCE_DMA(); + + FLUSH_DMA(); + + DRM_DEBUG( "%s... done.\n", __FUNCTION__ ); +} + +static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned long address = (unsigned long) buf->bus_address; - int length = buf->used; - int use_agp = PDEA_pagpxfer_enable; + u32 address = (u32) buf->bus_address; + u32 length = (u32) buf->used; int i = 0; - PRIMLOCALS; + DMA_LOCALS; + DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used ); - if (buf->used) { - /* WARNING: if you change any of the state functions verify - * these numbers (Overestimating this doesn't hurt). - */ + if ( buf->used ) { buf_priv->dispatched = 1; - PRIM_OVERFLOW(dev, dev_priv, - (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS))); - mgaEmitState(dev_priv); -#if 0 - length = dev_priv->vertexsize * 3 * 4; -#endif + MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); do { - if (i < sarea_priv->nbox) { - mgaEmitClipRect(dev_priv, - &sarea_priv->boxes[i]); + if ( i < sarea_priv->nbox ) { + mga_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); } - PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SECADDRESS, - ((u32) address) | TT_VERTEX); - PRIMOUTREG(MGAREG_SECEND, - (((u32) (address + length)) | use_agp)); - PRIMADVANCE(dev_priv); - } while (++i < sarea_priv->nbox); + BEGIN_DMA( 1 ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SECADDRESS, (address | + MGA_DMA_VERTEX), + MGA_SECEND, ((address + length) | + MGA_PAGPXFER) ); + + ADVANCE_DMA(); + } while ( ++i < sarea_priv->nbox ); } - if (buf_priv->discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); + + if ( buf_priv->discard ) { + AGE_BUFFER( buf_priv ); + buf->pending = 0; + buf->used = 0; buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } + mga_freelist_put( dev, buf ); + } + FLUSH_DMA(); } - -static void mga_dma_dispatch_indices(drm_device_t * dev, - drm_buf_t * buf, - unsigned int start, unsigned int end) +static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf, + unsigned int start, unsigned int end ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_buf_priv_t *buf_priv = buf->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int address = (unsigned int) buf->bus_address; - int use_agp = PDEA_pagpxfer_enable; + u32 address = (u32) buf->bus_address; int i = 0; - PRIMLOCALS; + DMA_LOCALS; + DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end ); - if (start != end) { - /* WARNING: if you change any of the state functions verify - * these numbers (Overestimating this doesn't hurt). - */ + if ( start != end ) { buf_priv->dispatched = 1; - PRIM_OVERFLOW(dev, dev_priv, - (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS))); - mgaEmitState(dev_priv); + + MGA_EMIT_STATE( dev_priv, sarea_priv->dirty ); do { - if (i < sarea_priv->nbox) { - mgaEmitClipRect(dev_priv, - &sarea_priv->boxes[i]); + if ( i < sarea_priv->nbox ) { + mga_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); } - PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SETUPADDRESS, - ((address + start) | - SETADD_mode_vertlist)); - PRIMOUTREG(MGAREG_SETUPEND, - ((address + end) | use_agp)); -/* ((address + start + 12) | use_agp)); */ - PRIMADVANCE(dev_priv); - } while (++i < sarea_priv->nbox); - } - if (buf_priv->discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } -} + BEGIN_DMA( 1 ); + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_SETUPADDRESS, address + start, + MGA_SETUPEND, ((address + end) | + MGA_PAGPXFER) ); -static void mga_dma_dispatch_clear(drm_device_t * dev, int flags, - unsigned int clear_color, - unsigned int clear_zval, - unsigned int clear_colormask, - unsigned int clear_depthmask) -{ - drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; - unsigned int cmd; - int i; - PRIMLOCALS; - - if (dev_priv->sgram) - cmd = MGA_CLEAR_CMD | DC_atype_blk; - else - cmd = MGA_CLEAR_CMD | DC_atype_rstr; - - PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS); - - for (i = 0; i < nbox; i++) { - unsigned int height = pbox[i].y2 - pbox[i].y1; - - if (flags & MGA_FRONT) { - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, clear_colormask); - PRIMOUTREG(MGAREG_YDSTLEN, - (pbox[i].y1 << 16) | height); - PRIMOUTREG(MGAREG_FXBNDRY, - (pbox[i].x2 << 16) | pbox[i].x1); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_FCOL, clear_color); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); - PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); - } + ADVANCE_DMA(); + } while ( ++i < sarea_priv->nbox ); + } - if (flags & MGA_BACK) { - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, clear_colormask); - PRIMOUTREG(MGAREG_YDSTLEN, - (pbox[i].y1 << 16) | height); - PRIMOUTREG(MGAREG_FXBNDRY, - (pbox[i].x2 << 16) | pbox[i].x1); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_FCOL, clear_color); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset); - PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); - } + if ( buf_priv->discard ) { + AGE_BUFFER( buf_priv ); + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; - if (flags & MGA_DEPTH) { - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, clear_depthmask); - PRIMOUTREG(MGAREG_YDSTLEN, - (pbox[i].y1 << 16) | height); - PRIMOUTREG(MGAREG_FXBNDRY, - (pbox[i].x2 << 16) | pbox[i].x1); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_FCOL, clear_zval); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset); - PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd); - } + mga_freelist_put( dev, buf ); } - /* Force reset of DWGCTL */ - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); - PRIMADVANCE(dev_priv); + FLUSH_DMA(); } -static void mga_dma_dispatch_swap(drm_device_t * dev) +/* This copies a 64 byte aligned agp region to the frambuffer with a + * standard blit, the ioctl needs to do checking. + */ +static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf, + unsigned int dstorg, unsigned int length ) { drm_mga_private_t *dev_priv = dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - int nbox = sarea_priv->nbox; - drm_clip_rect_t *pbox = sarea_priv->boxes; - int i; - int pixel_stride = dev_priv->stride / dev_priv->cpp; + drm_mga_buf_priv_t *buf_priv = buf->dev_private; + drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state; + u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM; + u32 y2; + DMA_LOCALS; + DRM_DEBUG( "%s: buf=%d used=%d\n", + __FUNCTION__, buf->idx, buf->used ); - PRIMLOCALS; + y2 = length / 64; - PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20); + BEGIN_DMA( 4 ); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7100); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); + DMA_BLOCK( MGA_DSTORG, dstorg, + MGA_MACCESS, 0x00000000, + MGA_SRCORG, srcorg, + MGA_AR5, 64 ); - PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); - PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset); - PRIMOUTREG(MGAREG_AR5, pixel_stride); + DMA_BLOCK( MGA_PITCH, 64, + MGA_PLNWT, 0xffffffff, + MGA_DMAPAD, 0x00000000, + MGA_DWGCTL, MGA_DWGCTL_COPY ); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, ~0); - PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); + DMA_BLOCK( MGA_AR0, 63, + MGA_AR3, 0, + MGA_FXBNDRY, (63 << 16) | 0, + MGA_YDSTLEN + MGA_EXEC, y2 ); - for (i = 0; i < nbox; i++) { - unsigned int h = pbox[i].y2 - pbox[i].y1; - unsigned int start = pbox[i].y1 * pixel_stride; + DMA_BLOCK( MGA_PLNWT, ctx->plnwt, + MGA_SRCORG, dev_priv->front_offset, + MGA_PITCH, dev_priv->front_pitch, + MGA_DWGSYNC, 0x00007000 ); - PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); - PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1); - PRIMOUTREG(MGAREG_FXBNDRY, - pbox[i].x1 | ((pbox[i].x2 - 1) << 16)); - PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, - (pbox[i].y1 << 16) | h); - } + ADVANCE_DMA(); - /* Force reset of DWGCTL */ - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]); - PRIMOUTREG(MGAREG_SRCORG, 0); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); + AGE_BUFFER( buf_priv ); + + buf->pending = 0; + buf->used = 0; + buf_priv->dispatched = 0; - PRIMADVANCE(dev_priv); + mga_freelist_put( dev, buf ); + + FLUSH_DMA(); } -/* #define BLIT_LEFT 1 */ -/* #define BLIT_UP 4 */ - -static void mga_dma_dispatch_blit(drm_device_t * dev, - unsigned int planemask, - unsigned int source, - unsigned int dest, - int delta_sx, int delta_sy, - int delta_dx, int delta_dy, - int source_pitch, - int dest_pitch, - int height, - int ydir) +static void mga_dma_dispatch_blit( drm_device_t *dev, + drm_mga_blit_t *blit ) { drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; - int nbox = sarea_priv->nbox; + drm_mga_context_regs_t *ctx = &sarea_priv->context_state; drm_clip_rect_t *pbox = sarea_priv->boxes; - int pixel_stride = dev_priv->stride / dev_priv->cpp; + int nbox = sarea_priv->nbox; u32 scandir = 0, i; - - PRIMLOCALS; - - PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20); - - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7100); - PRIMOUTREG(MGAREG_DWGSYNC, 0x7000); - - PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); - PRIMOUTREG(MGAREG_PLNWT, planemask); - PRIMOUTREG(MGAREG_SRCORG, source); - PRIMOUTREG(MGAREG_DSTORG, dest); - - PRIMOUTREG(MGAREG_SGN, scandir); - PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - PRIMOUTREG(MGAREG_AR5, ydir * source_pitch); - PRIMOUTREG(MGAREG_PITCH, dest_pitch); - - for (i = 0; i < nbox; i++) { - int srcx = pbox[i].x1 + delta_sx; - int srcy = pbox[i].y1 + delta_sy; - int dstx = pbox[i].x1 + delta_dx; - int dsty = pbox[i].y1 + delta_dy; + DMA_LOCALS; + DRM_DEBUG( __FUNCTION__ ":\n" ); + + BEGIN_DMA( 4 + nbox ); + + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_DMAPAD, 0x00000000, + MGA_DWGSYNC, 0x00007100, + MGA_DWGSYNC, 0x00007000 ); + + DMA_BLOCK( MGA_DWGCTL, MGA_DWGCTL_COPY, + MGA_PLNWT, blit->planemask, + MGA_SRCORG, blit->srcorg, + MGA_DSTORG, blit->dstorg ); + + DMA_BLOCK( MGA_SGN, scandir, + MGA_MACCESS, dev_priv->maccess, + MGA_AR5, blit->ydir * blit->src_pitch, + MGA_PITCH, blit->dst_pitch ); + + for ( i = 0 ; i < nbox ; i++ ) { + int srcx = pbox[i].x1 + blit->delta_sx; + int srcy = pbox[i].y1 + blit->delta_sy; + int dstx = pbox[i].x1 + blit->delta_dx; + int dsty = pbox[i].y1 + blit->delta_dy; int h = pbox[i].y2 - pbox[i].y1; int w = pbox[i].x2 - pbox[i].x1 - 1; int start; - if (ydir == -1) { - srcy = height - srcy - 1; + if ( blit->ydir == -1 ) { + srcy = blit->height - srcy - 1; } - start = srcy * source_pitch + srcx; + start = srcy * blit->src_pitch + srcx; - PRIMOUTREG(MGAREG_AR0, start + w); - PRIMOUTREG(MGAREG_AR3, start); - PRIMOUTREG(MGAREG_FXBNDRY, ((dstx+w) << 16) | (dstx & 0xffff)); - PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, (dsty << 16) | h); + DMA_BLOCK( MGA_AR0, start + w, + MGA_AR3, start, + MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff), + MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h ); } /* Do something to flush AGP? */ /* Force reset of DWGCTL */ - PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]); - PRIMOUTREG(MGAREG_PITCH, pixel_stride); - PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]); + DMA_BLOCK( MGA_DMAPAD, 0x00000000, + MGA_PLNWT, ctx->plnwt, + MGA_PITCH, dev_priv->front_pitch, + MGA_DWGCTL, ctx->dwgctl ); - PRIMADVANCE(dev_priv); + ADVANCE_DMA(); } -int mga_blit(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +/* ================================================================ + * + */ + +int mga_dma_clear( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_blit_t blit; + drm_mga_clear_t clear; - if (copy_from_user(&blit, (drm_mga_blit_t *) arg, sizeof(blit))) - return -EFAULT; - - DRM_DEBUG("%s\n", __FUNCTION__); + LOCK_TEST_WITH_RETURN( dev ); - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_blit_bufs called without lock held\n"); - return -EINVAL; - } + if ( copy_from_user( &clear, (drm_mga_clear_t *) arg, sizeof(clear) ) ) + return -EFAULT; - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; - - if ((blit.source & 0x3) != (SO_srcmap_sys|SO_srcacc_pci) && - (blit.dest & 0x3) != (SO_srcmap_sys|SO_srcacc_pci)) - { - mga_dma_dispatch_blit(dev, - blit.planemask, - blit.source, - blit.dest, - blit.delta_sx, blit.delta_sy, - blit.delta_dx, blit.delta_dy, - blit.source_pitch, - blit.dest_pitch, - blit.height, - blit.ydir); - } + WRAP_TEST_WITH_RETURN( dev_priv ); + mga_dma_dispatch_clear( dev, &clear ); - PRIMUPDATE(dev_priv); + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; -#ifdef __i386__ - mga_flush_write_combine(); -#endif - mga_dma_schedule(dev, 1); return 0; } - -int mga_clear_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int mga_dma_swap( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - drm_mga_clear_t clear; - if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear))) - return -EFAULT; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_clear_bufs called without lock held\n"); - return -EINVAL; - } + LOCK_TEST_WITH_RETURN( dev ); - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; - mga_dma_dispatch_clear(dev, clear.flags, - clear.clear_color, - clear.clear_depth, - clear.clear_color_mask, - clear.clear_depth_mask); - PRIMUPDATE(dev_priv); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); - return 0; -} + WRAP_TEST_WITH_RETURN( dev_priv ); -int mga_swap_bufs(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_swap_bufs called without lock held\n"); - return -EINVAL; - } - - if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + mga_dma_dispatch_swap( dev ); /* Make sure we restore the 3D state next time. */ - dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; - mga_dma_dispatch_swap(dev); - PRIMUPDATE(dev_priv); - set_bit(MGA_BUF_SWAP_PENDING, - &dev_priv->current_prim->buffer_status); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; + return 0; } -int mga_iload(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int mga_dma_vertex( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_mga_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_iload_t iload; - unsigned long bus_address; + drm_mga_vertex_t vertex; - if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload))) - return -EFAULT; + LOCK_TEST_WITH_RETURN( dev ); - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_iload called without lock held\n"); - return -EINVAL; - } + if ( copy_from_user( &vertex, + (drm_mga_vertex_t *)arg, + sizeof(vertex) ) ) + return -EFAULT; - buf = dma->buflist[iload.idx]; + buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; - bus_address = buf->bus_address; - if (mgaVerifyIload(dev_priv, - bus_address, iload.destOrg, iload.length)) { - mga_freelist_put(dev, buf); + buf->used = vertex.used; + buf_priv->discard = vertex.discard; + + if ( !mga_verify_state( dev_priv ) ) { + if ( vertex.discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); + buf_priv->dispatched = 0; + mga_freelist_put( dev, buf ); + } return -EINVAL; } - sarea_priv->dirty |= MGA_UPLOAD_CTX; + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_vertex( dev, buf ); - mga_dma_dispatch_tex_blit(dev, bus_address, iload.length, - iload.destOrg); - AGEBUF(dev_priv, buf_priv); - buf_priv->discard = 1; - mga_freelist_put(dev, buf); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); return 0; } -int mga_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int mga_dma_indices( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; + drm_mga_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_vertex_t vertex; + drm_mga_indices_t indices; - if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex))) - return -EFAULT; + LOCK_TEST_WITH_RETURN( dev ); - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_vertex called without lock held\n"); - return -EINVAL; - } + if ( copy_from_user( &indices, + (drm_mga_indices_t *)arg, + sizeof(indices) ) ) + return -EFAULT; - buf = dma->buflist[vertex.idx]; + buf = dma->buflist[indices.idx]; buf_priv = buf->dev_private; - buf->used = vertex.used; - buf_priv->discard = vertex.discard; + buf_priv->discard = indices.discard; - if (!mgaVerifyState(dev_priv)) { - if (vertex.discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); + if ( !mga_verify_state( dev_priv ) ) { + if ( indices.discard ) { + if ( buf_priv->dispatched == 1 ) + AGE_BUFFER( buf_priv ); buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); + mga_freelist_put( dev, buf ); } return -EINVAL; } - mga_dma_dispatch_vertex(dev, buf); + WRAP_TEST_WITH_RETURN( dev_priv ); + + mga_dma_dispatch_indices( dev, buf, indices.start, indices.end ); - PRIMUPDATE(dev_priv); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); return 0; } - -int mga_indices(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int mga_dma_iload( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_mga_private_t *dev_priv = - (drm_mga_private_t *) dev->dev_private; drm_device_dma_t *dma = dev->dma; + drm_mga_private_t *dev_priv = dev->dev_private; drm_buf_t *buf; drm_mga_buf_priv_t *buf_priv; - drm_mga_indices_t indices; + drm_mga_iload_t iload; + DRM_DEBUG( __FUNCTION__ ":\n" ); - if (copy_from_user(&indices, - (drm_mga_indices_t *)arg, sizeof(indices))) + LOCK_TEST_WITH_RETURN( dev ); + + if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) ) return -EFAULT; - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_indices called without lock held\n"); - return -EINVAL; - } + if ( mga_do_wait_for_idle( dev_priv ) < 0 ) + return -EBUSY; - buf = dma->buflist[indices.idx]; + buf = dma->buflist[iload.idx]; buf_priv = buf->dev_private; - buf_priv->discard = indices.discard; - - if (!mgaVerifyState(dev_priv)) { - if (indices.discard) { - if (buf_priv->dispatched == 1) - AGEBUF(dev_priv, buf_priv); - buf_priv->dispatched = 0; - mga_freelist_put(dev, buf); - } +#if 0 + DRM_INFO( " verifying iload...\n" ); + if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) { + mga_freelist_put( dev, buf ); return -EINVAL; } + DRM_INFO( " verifying iload... done.\n" ); +#endif - mga_dma_dispatch_indices(dev, buf, indices.start, indices.end); - - PRIMUPDATE(dev_priv); - mga_flush_write_combine(); - mga_dma_schedule(dev, 1); - return 0; -} - + WRAP_TEST_WITH_RETURN( dev_priv ); + mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length ); -static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d) -{ - int i; - drm_buf_t *buf; + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - for (i = d->granted_count; i < d->request_count; i++) { - buf = mga_freelist_get(dev); - if (!buf) - break; - buf->pid = current->pid; - if (copy_to_user(&d->request_indices[i], - &buf->idx, sizeof(buf->idx))) - return -EFAULT; - if (copy_to_user(&d->request_sizes[i], - &buf->total, sizeof(buf->total))) - return -EFAULT; - ++d->granted_count; - } return 0; } -int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +int mga_dma_blit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_dma_t d; + drm_mga_private_t *dev_priv = dev->dev_private; + drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_mga_blit_t blit; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + LOCK_TEST_WITH_RETURN( dev ); - if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d))) + if ( copy_from_user( &blit, (drm_mga_blit_t *)arg, sizeof(blit) ) ) return -EFAULT; - if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("mga_dma called without lock held\n"); - return -EINVAL; - } + if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS; - /* Please don't send us buffers. - */ - if (d.send_count != 0) { - DRM_ERROR - ("Process %d trying to send %d buffers via drmDMA\n", - current->pid, d.send_count); + if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) ) return -EINVAL; - } - /* We'll send you buffers. - */ - if (d.request_count < 0 || d.request_count > dma->buf_count) { - DRM_ERROR - ("Process %d trying to get %d buffers (of %d max)\n", - current->pid, d.request_count, dma->buf_count); - return -EINVAL; - } + WRAP_TEST_WITH_RETURN( dev_priv ); - d.granted_count = 0; + mga_dma_dispatch_blit( dev, &blit ); - if (d.request_count) { - retcode = mga_dma_get_buffers(dev, &d); - } + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT; - if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d))) - return -EFAULT; - return retcode; + return 0; } -- cgit v1.2.3