diff options
-rw-r--r-- | linux/mga_clear.c | 44 | ||||
-rw-r--r-- | linux/mga_dma.c | 58 | ||||
-rw-r--r-- | linux/mga_dma.h | 68 | ||||
-rw-r--r-- | linux/mga_drm_public.h | 28 | ||||
-rw-r--r-- | linux/mga_state.c | 123 |
5 files changed, 233 insertions, 88 deletions
diff --git a/linux/mga_clear.c b/linux/mga_clear.c index cb2e9d02..938f4c16 100644 --- a/linux/mga_clear.c +++ b/linux/mga_clear.c @@ -68,10 +68,14 @@ static int mgaClearBuffers(drm_device_t *dev, int nbox = sarea_priv->nbox; drm_buf_t *buf; drm_dma_t d; - int order = 10; /* ??? what orders do we have ???*/ + int order = 16; /* ??? what orders do we have ???*/ DMALOCALS; + printk("dma %p dev_priv %p sarea_priv %p pbox %p nbox %d\n", + dma, dev_priv, sarea_priv, pbox, nbox); + + if (!nbox) return -EINVAL; @@ -81,7 +85,14 @@ static int mgaClearBuffers(drm_device_t *dev, cmd = MGA_CLEAR_CMD | DC_atype_rstr; buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); + if (!buf) { + printk("didn't get dma buffer for clear, order %d\n", order); + return 0; + } + printk("buf %p buf->address %p buf->used %d\n", buf, buf->address, + buf->used); + return 0; DMAGETPTR( buf ); @@ -100,19 +111,19 @@ static int mgaClearBuffers(drm_device_t *dev, DMAOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); DMAOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); - if ( flags & MGA_CLEAR_FRONTBUFFER ) { + if ( flags & MGA_CLEAR_FRONT ) { DMAOUTREG(MGAREG_FCOL, clear_color); DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); } - if ( flags & MGA_CLEAR_BACKBUFFER ) { + if ( flags & MGA_CLEAR_BACK ) { DMAOUTREG(MGAREG_FCOL, clear_color); DMAOUTREG(MGAREG_DSTORG, dev_priv->backOrg); DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); } - if ( flags & MGA_CLEAR_DEPTHBUFFER ) + if ( flags & MGA_CLEAR_DEPTH ) { DMAOUTREG(MGAREG_FCOL, clear_depth); DMAOUTREG(MGAREG_DSTORG, dev_priv->depthOrg); @@ -124,7 +135,7 @@ static int mgaClearBuffers(drm_device_t *dev, /* Make sure we restore the 3D state next time. */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; + sarea_priv->dirty |= MGA_UPLOAD_CTX; ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; @@ -155,7 +166,7 @@ int mgaSwapBuffers(drm_device_t *dev, int flags) int nbox = sarea_priv->nbox; drm_buf_t *buf; drm_dma_t d; - int order = 10; /* ??? */ + int order = 16; /* ??? */ int i; DMALOCALS; @@ -163,6 +174,10 @@ int mgaSwapBuffers(drm_device_t *dev, int flags) return -EINVAL; buf = drm_freelist_get(&dma->bufs[order].freelist, _DRM_DMA_WAIT); + if (!buf) { + printk("didn't get dma buffer for swap, order %d\n", order); + return 0; + } DMAGETPTR(buf); @@ -196,7 +211,7 @@ int mgaSwapBuffers(drm_device_t *dev, int flags) /* Make sure we restore the 3D state next time. */ - sarea_priv->dirty |= MGASAREA_NEW_CONTEXT; + sarea_priv->dirty |= MGA_UPLOAD_CTX; ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; @@ -238,7 +253,7 @@ static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) buf_priv->ContextState[MGA_CTXREG_MACCESS] = args->mAccess; buf_priv->ServerState[MGA_2DREG_PITCH] = args->pitch; buf_priv->nbox = 1; - sarea_priv->dirty |= (MGASAREA_NEW_CONTEXT | MGASAREA_NEW_2D); + sarea_priv->dirty |= (MGA_UPLOAD_CTX | MGA_UPLOAD_2D); switch((args->mAccess & 0x00000003)) { case 0: pixperdword = 4; @@ -280,10 +295,10 @@ static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) /* Necessary? Not necessary?? */ -static int check_lock(void) -{ - return 1; -} +/* static int check_lock(void) */ +/* { */ +/* return 1; */ +/* } */ int mga_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -293,6 +308,7 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, drm_mga_clear_t clear; int retcode; + copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear), -EFAULT); @@ -314,6 +330,7 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, drm_mga_swap_t swap; int retcode = 0; + return 0; /* if (!check_lock( dev )) */ /* return -EIEIO; */ @@ -394,7 +411,8 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, /* Snapshot the relevent bits of the sarea... */ - mgaCopyAndVerifyState( dev_priv, buf_priv ); + if (!mgaCopyAndVerifyState( dev_priv, buf_priv )) + dma->buflist[ idx ]->used = 0; atomic_inc(&dev_priv->pending_bufs); retcode = drm_dma_enqueue(dev, &d); diff --git a/linux/mga_dma.c b/linux/mga_dma.c index 402c13b0..bc5bf066 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -88,6 +88,7 @@ int mga_dma_cleanup(drm_device_t *dev) static int mga_alloc_kernel_queue(drm_device_t *dev) { drm_queue_t *queue = NULL; + /* Allocate a new queue */ down(&dev->struct_sem); @@ -148,6 +149,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { drm_map_t *prim_map = NULL; drm_map_t *sarea_map = NULL; int temp; + int i; dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); @@ -185,7 +187,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { PAGE_SIZE) * PAGE_SIZE; dev_priv->warp_ucode_size = init->warp_ucode_size; dev_priv->chipset = init->chipset; - dev_priv->fbOffset = init->fbOffset; + dev_priv->fbOffset = init->frontOffset; dev_priv->backOffset = init->backOffset; dev_priv->depthOffset = init->depthOffset; dev_priv->textureOffset = init->textureOffset; @@ -194,16 +196,31 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { dev_priv->sgram = init->sgram; dev_priv->stride = init->stride; - dev_priv->frontOrg = init->frontOrg; - dev_priv->backOrg = init->backOrg; - dev_priv->depthOrg = init->depthOrg; dev_priv->mAccess = init->mAccess; + + printk("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n", + dev_priv->chipset, dev_priv->warp_ucode_size, + dev_priv->backOffset, dev_priv->depthOffset); + printk("cpp: %d sgram: %d stride: %d maccess: %x\n", + dev_priv->cpp, dev_priv->sgram, dev_priv->stride, + dev_priv->mAccess); + printk("memcpy\n"); memcpy(&dev_priv->WarpIndex, &init->WarpIndex, sizeof(mgaWarpIndex) * MGA_MAX_WARP_PIPES); printk("memcpy done\n"); + + + for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++) + printk("warp pipe %d: installed: %d phys_addr: %lx size: %x\n", + i, + dev_priv->WarpIndex[i].installed, + dev_priv->WarpIndex[i].phys_addr, + dev_priv->WarpIndex[i].size); + + prim_map = dev->maplist[init->reserved_map_idx]; dev_priv->prim_phys_head = dev->agp->base + init->reserved_map_agpstart; temp = init->warp_ucode_size + dev_priv->primary_size; @@ -236,11 +253,14 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { { PRIMLOCALS; PRIMRESET( dev_priv ); + PRIMGETPTR( dev_priv ); + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DWGSYNC, 0); PRIMOUTREG(MGAREG_SOFTRAP, 0); + PRIMADVANCE( dev_priv ); /* Poll for the first buffer to insure that @@ -251,7 +271,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) { - int i; for(i = 0 ; i < 4096; i++) mga_delay(); } @@ -261,7 +280,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { PDEA_pagpxfer_enable)); while(MGA_READ(MGAREG_DWGSYNC) == MGA_SYNC_TAG) { - int i; for(i = 0; i < 4096; i++) mga_delay(); } @@ -301,7 +319,7 @@ static void __mga_iload_small(drm_device_t *dev, { 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; +/* drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; */ unsigned long address = (unsigned long)buf->bus_address; int length = buf->used; int y1 = buf_priv->boxes[0].y1; @@ -319,22 +337,27 @@ static void __mga_iload_small(drm_device_t *dev, PRIMOUTREG(MGAREG_MACCESS, maccess); PRIMOUTREG(MGAREG_PITCH, (1 << 15)); PRIMOUTREG(MGAREG_YDST, y1 * (x2 - x1)); + PRIMOUTREG(MGAREG_LEN, 1); PRIMOUTREG(MGAREG_FXBNDRY, ((x2 - x1) * (y2 - y1) - 1) << 16); PRIMOUTREG(MGAREG_AR0, (x2 - x1) * (y2 - y1) - 1); PRIMOUTREG(MGAREG_AR3, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, MGA_ILOAD_CMD); + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_SOFTRAP, 0); + PRIMADVANCE(dev_priv); #if 0 /* For now we need to set this in the ioctl */ @@ -351,7 +374,7 @@ static void __mga_iload_xy(drm_device_t *dev, { 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; +/* drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; */ unsigned long address = (unsigned long)buf->bus_address; int length = buf->used; int y1 = buf_priv->boxes[0].y1; @@ -426,6 +449,9 @@ static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf) int x1 = buf_priv->boxes[0].x1; int x2 = buf_priv->boxes[0].x2; + + printk("dispatch iload!\n"); + if((x2 - x1) < 32) { printk("using iload small\n"); __mga_iload_small(dev, buf, use_agp); @@ -453,6 +479,10 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) mgaEmitState( dev_priv, buf_priv ); + + printk("dispatch vertex addr 0x%x, length 0x%x nbox %d\n", + address, length, buf_priv->nbox); + for (i = 0 ; i < count ; i++) { if (i < buf_priv->nbox) mgaEmitClipRect( dev_priv, &buf_priv->boxes[i] ); @@ -488,6 +518,9 @@ static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) int use_agp = PDEA_pagpxfer_enable; PRIMLOCALS; + + printk("dispatch general!\n"); + PRIMRESET(dev_priv); PRIMGETPTR(dev_priv); @@ -653,7 +686,6 @@ static int mga_do_dma(drm_device_t *dev, int locked) buf_priv = buf->dev_private; - printk("dispatch!\n"); switch (buf_priv->dma_type) { case MGA_DMA_GENERAL: mga_dma_dispatch_general(dev, buf); @@ -703,10 +735,10 @@ static int mga_do_dma(drm_device_t *dev, int locked) return retcode; } -static void mga_dma_schedule_timer_wrapper(unsigned long dev) -{ - mga_dma_schedule((drm_device_t *)dev, 0); -} +/* static void mga_dma_schedule_timer_wrapper(unsigned long dev) */ +/* { */ +/* mga_dma_schedule((drm_device_t *)dev, 0); */ +/* } */ static void mga_dma_schedule_tq_wrapper(void *dev) { diff --git a/linux/mga_dma.h b/linux/mga_dma.h index 7f1c5795..d398f43f 100644 --- a/linux/mga_dma.h +++ b/linux/mga_dma.h @@ -41,22 +41,36 @@ typedef struct { /* Macros for inserting commands into a secondary dma buffer. */ + +#define VERBO 1 + + + #define DMALOCALS u8 tempIndex[4]; u32 *dma_ptr; \ int outcount, num_dwords; -#define DMAGETPTR(buf) do { \ +#define DMAGETPTR(buf) do { \ dma_ptr = (u32 *)((u8 *)buf->address + buf->used); \ - outcount = 0; \ - num_dwords = buf->used / 4; \ + outcount = 0; \ + num_dwords = buf->used / 4; \ + if (VERBO) \ + printk(KERN_INFO "DMAGETPTR in %s, start %d\n", \ + __FUNCTION__, num_dwords); \ } while(0) #define DMAADVANCE(buf) do { \ + if (VERBO) \ + printk(KERN_INFO "DMAADVANCE\n"); \ buf->used = num_dwords * 4; \ } while(0) #define DMAOUTREG(reg, val) do { \ tempIndex[outcount]=ADRINDEX(reg); \ dma_ptr[++outcount] = val; \ + if (VERBO) \ + printk(KERN_INFO \ + " DMAOUT %d: 0x%x -- 0x%x\n", \ + num_dwords +1+outcount, ADRINDEX(reg), val); \ if (outcount == 4) { \ outcount = 0; \ dma_ptr[0] = *(u32 *)tempIndex; \ @@ -67,9 +81,6 @@ typedef struct { -#define VERBO 0 - - /* Primary buffer versions of above -- pretty similar really. */ #define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \ @@ -80,32 +91,51 @@ typedef struct { dev_priv->current_dma_ptr = dev_priv->prim_head; \ } while (0) -#define PRIMGETPTR(dev_priv) do { \ - dma_ptr = dev_priv->current_dma_ptr; \ - phys_head = dev_priv->prim_phys_head; \ - num_dwords = dev_priv->prim_num_dwords; \ - outcount = 0; \ +#define PRIMGETPTR(dev_priv) do { \ + dma_ptr = dev_priv->current_dma_ptr; \ + phys_head = dev_priv->prim_phys_head; \ + num_dwords = dev_priv->prim_num_dwords; \ + outcount = 0; \ + if (VERBO) \ + printk(KERN_INFO "PRIMGETPTR in %s, start %d\n", \ + __FUNCTION__, num_dwords); \ } while (0) -#define PRIMADVANCE(dev_priv) do { \ - dev_priv->prim_num_dwords = num_dwords; \ - dev_priv->current_dma_ptr = dma_ptr; \ +#define PRIMADVANCEPAD(dev_priv) do { \ + while(outcount & 3) { \ + if (VERBO) \ + printk(KERN_INFO "PAD %d\n", \ + num_dwords + 1 + outcount); \ + tempIndex[outcount++]=0x15; \ + } \ + \ + if (VERBO) \ + printk(KERN_INFO "PRIMADVANCEPAD\n"); \ + dev_priv->prim_num_dwords = num_dwords; \ + dev_priv->current_dma_ptr = dma_ptr; \ } while (0) +#define PRIMADVANCE(dev_priv) do { \ + if (VERBO) \ + printk(KERN_INFO "PRIMADVANCE\n"); \ + dev_priv->prim_num_dwords = num_dwords; \ + dev_priv->current_dma_ptr = dma_ptr; \ +} while (0) + + #define PRIMOUTREG(reg, val) do { \ tempIndex[outcount]=ADRINDEX(reg); \ dma_ptr[1+outcount] = val; \ + if (VERBO) \ + printk(KERN_INFO \ + " PRIMOUT %d: 0x%x -- 0x%x\n", \ + num_dwords + 1 + outcount, ADRINDEX(reg), val); \ if( ++outcount == 4) { \ outcount = 0; \ dma_ptr[0] = *(u32 *)tempIndex; \ dma_ptr+=5; \ num_dwords += 5; \ } \ - if (VERBO) \ - printk(KERN_INFO \ - "OUT %x val %x dma_ptr %p nr_dwords %d\n", \ - outcount, ADRINDEX(reg), dma_ptr, \ - num_dwords); \ }while (0) diff --git a/linux/mga_drm_public.h b/linux/mga_drm_public.h index dae53982..8072f9b0 100644 --- a/linux/mga_drm_public.h +++ b/linux/mga_drm_public.h @@ -82,7 +82,7 @@ typedef struct drm_mga_init { int sarea_priv_offset; int primary_size; int warp_ucode_size; - int fbOffset; + int frontOffset; int backOffset; int depthOffset; int textureOffset; @@ -95,9 +95,6 @@ typedef struct drm_mga_init { /* Redundant? */ - int frontOrg; - int backOrg; - int depthOrg; int mAccess; } drm_mga_init_t; @@ -147,13 +144,21 @@ typedef struct _xf86drmClipRectRec { #define MGA_TEX_SETUP_SIZE 11 + /* What needs to be changed for the current vertex dma buffer? */ -#define MGASAREA_NEW_CONTEXT 0x1 -#define MGASAREA_NEW_TEX0 0x2 -#define MGASAREA_NEW_TEX1 0x4 -#define MGASAREA_NEW_PIPE 0x8 -#define MGASAREA_NEW_2D 0x10 +#define MGA_UPLOAD_CTX 0x1 +#define MGA_UPLOAD_TEX0 0x2 +#define MGA_UPLOAD_TEX1 0x4 +#define MGA_UPLOAD_PIPE 0x8 +#define MGA_UPLOAD_TEX0IMAGE 0x10 +#define MGA_UPLOAD_TEX1IMAGE 0x20 +#define MGA_UPLOAD_2D 0x40 +#define MGA_REQUIRE_QUIESCENT 0x80 + + +#define MGA_DMA_BUF_SZ 65536 +#define MGA_DMA_BUF_NR 63 /* Keep this small for testing @@ -185,7 +190,8 @@ typedef struct /* kernel doesn't touch from here down */ int ctxOwner; mgaTexRegion texList[MGA_NR_TEX_REGIONS+1]; - int texAge; + int texAge; + } drm_mga_sarea_t; @@ -203,7 +209,7 @@ typedef struct { } drm_mga_swap_t; typedef struct { - unsigned int destOrg; + unsigned int destOrg; unsigned int mAccess; unsigned int pitch; xf86drmClipRectRec texture; diff --git a/linux/mga_state.c b/linux/mga_state.c index e7740713..b7b36cc8 100644 --- a/linux/mga_state.c +++ b/linux/mga_state.c @@ -50,6 +50,8 @@ void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ) * circumstances is by inserting TWO dwgsync commands. */ if (dev_priv->chipset == MGA_CARD_TYPE_G400) { + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); PRIMOUTREG( MGAREG_DWGSYNC, 0 ); PRIMOUTREG( MGAREG_DWGSYNC, 0 ); } @@ -57,6 +59,8 @@ void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box ) PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) ); PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride ); PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMADVANCE( dev_priv ); } @@ -68,21 +72,28 @@ static void mgaEmitContext(drm_mga_private_t *dev_priv, PRIMLOCALS; 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 ); +/* PRIMOUTREG( MGAREG_DMAPAD, 0 ); */ + 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_DMAPAD, 0 ); } - PRIMADVANCE( dev_priv ); + PRIMADVANCE( dev_priv ); /* padded */ } static void mgaG200EmitTex( drm_mga_private_t *dev_priv, @@ -92,20 +103,26 @@ static void mgaG200EmitTex( drm_mga_private_t *dev_priv, PRIMLOCALS; PRIMGETPTR( dev_priv ); + 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] ); + 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] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] ); + PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); PRIMADVANCE( dev_priv ); } @@ -123,15 +140,17 @@ static void mgaG400EmitTex0( drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] ); PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] ); PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] ); + 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] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 49*4, 0); + PRIMOUTREG(0x2d00 + 57*4, 0); PRIMOUTREG(0x2d00 + 53*4, 0); PRIMOUTREG(0x2d00 + 61*4, 0); @@ -144,6 +163,11 @@ static void mgaG400EmitTex0( drm_mga_private_t *dev_priv, 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 ); /* some of these will be truncated */ + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMOUTREG( MGAREG_DMAPAD, 0 ); + PRIMADVANCE( dev_priv ); } @@ -163,25 +187,28 @@ static void mgaG400EmitTex1( drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] ); PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] ); PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] ); + 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] ); + PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] ); PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] ); - PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); - + PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] ); PRIMOUTREG(0x2d00 + 49*4, 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(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); + PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 ); PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] ); + PRIMOUTREG(MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DMAPAD, 0 ); - PRIMADVANCE( dev_priv ); + PRIMADVANCE( dev_priv ); /* padded */ } @@ -193,22 +220,26 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv, float fParam = 12800.0f; PRIMLOCALS; + printk("emit g400 pipe %x\n", pipe); + PRIMGETPTR(dev_priv); - PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); + /* Establish vertex size. */ if (pipe & MGA_T2) { + PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09); PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000); + PRIMOUTREG(MGAREG_WFLAG, 0); } else { + PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807); PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000); - } - - PRIMOUTREG(MGAREG_WFLAG, 0); - PRIMOUTREG(MGAREG_WFLAG1, 0); - + PRIMOUTREG(MGAREG_WFLAG, 0); + } + + PRIMOUTREG(MGAREG_WFLAG1, 0); PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam))); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -239,7 +270,10 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv, unsigned int pipe = sarea_priv->WarpPipe; PRIMLOCALS; + printk("emit g200 pipe %x\n", pipe); + PRIMGETPTR(dev_priv); + PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend); PRIMOUTREG(MGAREG_WVRTXSZ, 7); PRIMOUTREG(MGAREG_WFLAG, 0); @@ -265,25 +299,25 @@ void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv ) unsigned int dirty = buf_priv->dirty; if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - if (dirty & MGASAREA_NEW_CONTEXT) + if (dirty & MGA_UPLOAD_CTX) mgaEmitContext( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_TEX1) + if (dirty & MGA_UPLOAD_TEX1) mgaG400EmitTex1( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_TEX0) + if (dirty & MGA_UPLOAD_TEX0) mgaG400EmitTex0( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_PIPE) + if (dirty & MGA_UPLOAD_PIPE) mgaG400EmitPipe( dev_priv, buf_priv ); } else { - if (dirty & MGASAREA_NEW_CONTEXT) + if (dirty & MGA_UPLOAD_CTX) mgaEmitContext( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_TEX0) + if (dirty & MGA_UPLOAD_TEX0) mgaG200EmitTex( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_PIPE) + if (dirty & MGA_UPLOAD_PIPE) mgaG200EmitPipe( dev_priv, buf_priv ); } } @@ -297,13 +331,23 @@ static int mgaCopyContext(drm_mga_private_t *dev_priv, { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int *regs = sarea_priv->ContextState; + int i; + + for (i = 0 ; i < MGA_CTX_SETUP_SIZE ; i++) + printk("ctx %d: %x\n", i, regs[i]); + if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOrg && - regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg) + regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg) { + printk("BAD DSTORG: %x (front %x, back %x)\n\n", + regs[MGA_CTXREG_DSTORG], dev_priv->frontOrg, + dev_priv->backOrg); return -1; + } + else + printk("DSTORG OK: %x\n", regs[MGA_CTXREG_DSTORG]); - memcpy(buf_priv->ContextState, sarea_priv->ContextState, - sizeof(buf_priv->ContextState)); + memcpy(buf_priv->ContextState, regs, sizeof(buf_priv->ContextState)); return 0; } @@ -316,8 +360,16 @@ static int mgaCopyTex(drm_mga_private_t *dev_priv, { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) + if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) { + printk("BAD TEXREG_ORG: %x, unit %d\n", + sarea_priv->TexState[unit][MGA_TEXREG_ORG], + unit); return -1; + } + else + printk("using texreg_org: %x unit %d\n", + sarea_priv->TexState[unit][MGA_TEXREG_ORG], + unit); memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit], sizeof(buf_priv->TexState[0])); @@ -336,26 +388,33 @@ int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv, buf_priv->dirty = sarea_priv->dirty; buf_priv->WarpPipe = sarea_priv->WarpPipe; - if (dirty & MGASAREA_NEW_CONTEXT) + if ((buf_priv->nbox = sarea_priv->nbox) != 0) + memcpy( buf_priv->boxes, + sarea_priv->boxes, + buf_priv->nbox * sizeof(xf86drmClipRectRec)); + + if (dirty & MGA_UPLOAD_CTX) rv |= mgaCopyContext( dev_priv, buf_priv ); - if (dirty & MGASAREA_NEW_TEX0) + if (dirty & MGA_UPLOAD_TEX0) rv |= mgaCopyTex( dev_priv, buf_priv, 0 ); if (dev_priv->chipset == MGA_CARD_TYPE_G400) { - if (dirty & MGASAREA_NEW_TEX1) + if (dirty & MGA_UPLOAD_TEX1) rv |= mgaCopyTex( dev_priv, buf_priv, 1 ); - if (dirty & MGASAREA_NEW_PIPE) + if (dirty & MGA_UPLOAD_PIPE) rv |= (buf_priv->WarpPipe > MGA_MAX_G400_PIPES); } else { - if (dirty & MGASAREA_NEW_PIPE) + if (dirty & MGA_UPLOAD_PIPE) rv |= (buf_priv->WarpPipe > MGA_MAX_G200_PIPES); } + + return rv == 0; } |