Various mga state cleanups, possible fix for clipping bug on g200, revert

to old style of warp pipe management (fix for hangs on some g400 cards
    on initialization), make warp registers into defines
This commit is contained in:
Jeff Hartmann 2000-09-25 22:51:23 +00:00
parent 62a769c72c
commit dbb7bbe85d
2 changed files with 150 additions and 119 deletions

View file

@ -377,6 +377,72 @@ drm_mga_prim_buf_t *tmp_buf = \
#define MGAREG_YTOP 0x1c98
#define MGAREG_ZORG 0x1c0c
/* Warp registers */
#define MGAREG_WR0 0x2d00
#define MGAREG_WR1 0x2d04
#define MGAREG_WR2 0x2d08
#define MGAREG_WR3 0x2d0c
#define MGAREG_WR4 0x2d10
#define MGAREG_WR5 0x2d14
#define MGAREG_WR6 0x2d18
#define MGAREG_WR7 0x2d1c
#define MGAREG_WR8 0x2d20
#define MGAREG_WR9 0x2d24
#define MGAREG_WR10 0x2d28
#define MGAREG_WR11 0x2d2c
#define MGAREG_WR12 0x2d30
#define MGAREG_WR13 0x2d34
#define MGAREG_WR14 0x2d38
#define MGAREG_WR15 0x2d3c
#define MGAREG_WR16 0x2d40
#define MGAREG_WR17 0x2d44
#define MGAREG_WR18 0x2d48
#define MGAREG_WR19 0x2d4c
#define MGAREG_WR20 0x2d50
#define MGAREG_WR21 0x2d54
#define MGAREG_WR22 0x2d58
#define MGAREG_WR23 0x2d5c
#define MGAREG_WR24 0x2d60
#define MGAREG_WR25 0x2d64
#define MGAREG_WR26 0x2d68
#define MGAREG_WR27 0x2d6c
#define MGAREG_WR28 0x2d70
#define MGAREG_WR29 0x2d74
#define MGAREG_WR30 0x2d78
#define MGAREG_WR31 0x2d7c
#define MGAREG_WR32 0x2d80
#define MGAREG_WR33 0x2d84
#define MGAREG_WR34 0x2d88
#define MGAREG_WR35 0x2d8c
#define MGAREG_WR36 0x2d90
#define MGAREG_WR37 0x2d94
#define MGAREG_WR38 0x2d98
#define MGAREG_WR39 0x2d9c
#define MGAREG_WR40 0x2da0
#define MGAREG_WR41 0x2da4
#define MGAREG_WR42 0x2da8
#define MGAREG_WR43 0x2dac
#define MGAREG_WR44 0x2db0
#define MGAREG_WR45 0x2db4
#define MGAREG_WR46 0x2db8
#define MGAREG_WR47 0x2dbc
#define MGAREG_WR48 0x2dc0
#define MGAREG_WR49 0x2dc4
#define MGAREG_WR50 0x2dc8
#define MGAREG_WR51 0x2dcc
#define MGAREG_WR52 0x2dd0
#define MGAREG_WR53 0x2dd4
#define MGAREG_WR54 0x2dd8
#define MGAREG_WR55 0x2ddc
#define MGAREG_WR56 0x2de0
#define MGAREG_WR57 0x2de4
#define MGAREG_WR58 0x2de8
#define MGAREG_WR59 0x2dec
#define MGAREG_WR60 0x2df0
#define MGAREG_WR61 0x2df4
#define MGAREG_WR62 0x2df8
#define MGAREG_WR63 0x2dfc
#define PDEA_pagpxfer_enable 0x2
#define WIA_wmode_suspend 0x0
@ -430,6 +496,7 @@ drm_mga_prim_buf_t *tmp_buf = \
#define DC_clipdis_disable 0x0
#define DC_clipdis_enable 0x80000000
#define SETADD_mode_vertlist 0x0

View file

@ -43,7 +43,7 @@
#define MGAG200EMITTEX_SIZE 20
#define MGAG400EMITTEX0_SIZE 30
#define MGAG400EMITTEX1_SIZE 25
#define MGAG400EMITPIPE_SIZE 55
#define MGAG400EMITPIPE_SIZE 50
#define MGAG200EMITPIPE_SIZE 15
#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
@ -60,19 +60,20 @@ static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
/* This takes 10 dwords */
PRIMGETPTR(dev_priv);
/* Force reset of dwgctl (eliminates clip disable) */
/* 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]);
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);
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);
@ -143,9 +144,9 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
PRIMOUTREG(0x2d00 + 24 * 4, regs[MGA_TEXREG_WIDTH]);
PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]);
PRIMOUTREG(0x2d00 + 34 * 4, regs[MGA_TEXREG_HEIGHT]);
PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]);
PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
PRIMOUTREG(MGAREG_DMAPAD, 0);
@ -159,12 +160,11 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->TexState[0];
int multitex = regs[MGA_TEXREG_CTL2] & TMC_dualtex_enable;
PRIMLOCALS;
PRIMGETPTR(dev_priv);
/* This takes a max of 30 dwords */
/* This takes 30 dwords */
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
@ -179,22 +179,20 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
PRIMOUTREG(0x2d00 + 49 * 4, 0);
PRIMOUTREG(MGAREG_WR49, 0);
PRIMOUTREG(0x2d00 + 57 * 4, 0);
PRIMOUTREG(0x2d00 + 53 * 4, 0);
PRIMOUTREG(0x2d00 + 61 * 4, 0);
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);
if (!multitex || 1) {
PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
}
PRIMOUTREG(0x2d00 + 54 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
PRIMOUTREG(0x2d00 + 62 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
@ -203,10 +201,10 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
#define TMC_map1_enable 0x80000000
static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source )
static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->TexState[source];
unsigned int *regs = sarea_priv->TexState[1];
PRIMLOCALS;
PRIMGETPTR(dev_priv);
@ -227,14 +225,14 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source )
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
PRIMOUTREG(0x2d00 + 49 * 4, 0);
PRIMOUTREG(MGAREG_WR49, 0);
PRIMOUTREG(0x2d00 + 57 * 4, 0);
PRIMOUTREG(0x2d00 + 53 * 4, 0);
PRIMOUTREG(0x2d00 + 61 * 4, 0);
PRIMOUTREG(0x2d00 + 52 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
PRIMOUTREG(MGAREG_WR57, 0);
PRIMOUTREG(MGAREG_WR53, 0);
PRIMOUTREG(MGAREG_WR61, 0);
PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40);
PRIMOUTREG(0x2d00 + 60 * 4, regs[MGA_TEXREG_HEIGHT] | 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);
@ -242,49 +240,29 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source )
PRIMADVANCE(dev_priv);
}
#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 void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
float fParam = 12800.0f;
int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] &
TMC_dualtex_enable);
PRIMLOCALS;
PRIMGETPTR(dev_priv);
/* This takes 50 dwords */
/* Establish vertex size.
/* Establish vertex size.
*/
PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
if (sarea_priv->vertexsize == 10) {
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_DMAPAD, 0);
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
PRIMOUTREG(MGAREG_DMAPAD, 0);
if (multitex) {
PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
} else {
PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
}
if (pipe & MGA_T2) {
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
@ -295,21 +273,23 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
} else {
/* Flush the WARP pipe */
PRIMOUTREG(MGAREG_YDST, 0);
PRIMOUTREG(MGAREG_FXLEFT, 0);
PRIMOUTREG(MGAREG_FXRIGHT, 1);
PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
if (dev_priv->WarpPipe & 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_DMAPAD, 0);
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
PRIMOUTREG(MGAREG_DMAPAD, 0);
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, 0 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
}
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
PRIMOUTREG(MGAREG_DMAPAD, 0);
@ -324,29 +304,26 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
PRIMOUTREG(MGAREG_WFLAG, 0);
PRIMOUTREG(MGAREG_WFLAG1, 0);
PRIMOUTREG(0x2d00 + 56 * 4, *((u32 *) (&fParam)));
PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(0x2d00 + 49 * 4, 0); /* Tex stage 0 */
PRIMOUTREG(0x2d00 + 57 * 4, 0); /* Tex stage 0 */
PRIMOUTREG(0x2d00 + 53 * 4, 0); /* Tex stage 1 */
PRIMOUTREG(0x2d00 + 61 * 4, 0); /* Tex stage 1 */
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(0x2d00 + 54 * 4, 0x40); /* Tex stage 0 : w */
PRIMOUTREG(0x2d00 + 62 * 4, 0x40); /* Tex stage 0 : h */
PRIMOUTREG(0x2d00 + 52 * 4, 0x40); /* Tex stage 1 : w */
PRIMOUTREG(0x2d00 + 60 * 4, 0x40); /* Tex stage 1 : h */
if (dev_priv->WarpPipe != pipe || 1) {
/* 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));
}
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);
}
@ -363,12 +340,12 @@ static void mgaG200EmitPipe(drm_mga_private_t * dev_priv)
PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_WVRTXSZ, 7);
PRIMOUTREG(MGAREG_WFLAG, 0);
PRIMOUTREG(0x2d00 + 24 * 4, 0); /* tex w/h */
PRIMOUTREG(MGAREG_WR24, 0); /* tex w/h */
PRIMOUTREG(0x2d00 + 25 * 4, 0x100);
PRIMOUTREG(0x2d00 + 34 * 4, 0); /* tex w/h */
PRIMOUTREG(0x2d00 + 42 * 4, 0xFFFF);
PRIMOUTREG(0x2d00 + 60 * 4, 0xFFFF);
PRIMOUTREG(MGAREG_WR25, 0x100);
PRIMOUTREG(MGAREG_WR34, 0); /* tex w/h */
PRIMOUTREG(MGAREG_WR42, 0xFFFF);
PRIMOUTREG(MGAREG_WR60, 0xFFFF);
/* Dma pading required due to hw bug */
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
@ -387,20 +364,11 @@ static void mgaEmitState(drm_mga_private_t * dev_priv)
unsigned int dirty = sarea_priv->dirty;
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] &
TMC_dualtex_enable);
int multitex = sarea_priv->WarpPipe & MGA_T2;
dirty = ~0;
if (dirty & MGA_UPLOAD_PIPE
/* && (sarea_priv->WarpPipe != dev_priv->WarpPipe || */
/* sarea_priv->vertexsize != dev_priv->vertexsize) */
)
{
if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
mgaG400EmitPipe(dev_priv);
dev_priv->WarpPipe = sarea_priv->WarpPipe;
dev_priv->vertexsize = sarea_priv->vertexsize;
sarea_priv->dirty &= ~MGA_UPLOAD_PIPE;
}
if (dirty & MGA_UPLOAD_CTX) {
@ -413,11 +381,8 @@ static void mgaEmitState(drm_mga_private_t * dev_priv)
sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
}
if (dirty & MGA_UPLOAD_TEX1) {
if (multitex)
mgaG400EmitTex1(dev_priv, 1);
else
mgaG400EmitTex1(dev_priv, 0);
if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
mgaG400EmitTex1(dev_priv);
sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
}
} else {
@ -438,7 +403,6 @@ static void mgaEmitState(drm_mga_private_t * dev_priv)
}
}
/* Disallow all write destinations except the front and backbuffer.
*/
static int mgaVerifyContext(drm_mga_private_t * dev_priv)
@ -550,10 +514,10 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_SRCORG, 0);
PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
PRIMADVANCE(dev_priv);
}