diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c index edd60148..25f06580 100644 --- a/linux-core/mga_drv.c +++ b/linux-core/mga_drv.c @@ -105,8 +105,8 @@ static drm_ioctl_desc_t mga_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_clear_bufs, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_swap_bufs, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 1 }, }; diff --git a/linux/mga_clear.c b/linux/mga_clear.c index 938f4c16..a4e2c501 100644 --- a/linux/mga_clear.c +++ b/linux/mga_clear.c @@ -36,19 +36,6 @@ #include "mga_dma.h" #include "mga_state.h" -#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ - DC_solid_enable | DC_transc_enable) - - -#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ - DC_solid_disable | DC_arzero_disable | \ - DC_sgnzero_enable | DC_shftzero_enable | \ - (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ - DC_pattern_disable | DC_transc_disable | \ - DC_clipdis_enable) \ - /* Build and queue a TT_GENERAL secondary buffer to do the clears. @@ -60,84 +47,35 @@ static int mgaClearBuffers(drm_device_t *dev, int clear_depth, int flags) { - int cmd, i; 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; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; + drm_freelist_t *freelist = &dma->bufs[MGA_DMA_BUF_ORDER].freelist; + drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; + drm_mga_buf_priv_t *buf_priv; drm_buf_t *buf; drm_dma_t d; - int order = 16; /* ??? what orders do we have ???*/ - DMALOCALS; + buf = drm_freelist_get(freelist, _DRM_DMA_WAIT); + if (!buf) return -1; - printk("dma %p dev_priv %p sarea_priv %p pbox %p nbox %d\n", - dma, dev_priv, sarea_priv, pbox, nbox); + buf->pid = current->pid; + buf_priv = buf->dev_private; + buf_priv->dma_type = MGA_DMA_CLEAR; + buf_priv->clear_color = clear_color; + buf_priv->clear_zval = clear_depth; + buf_priv->clear_flags = flags; - if (!nbox) + if (!mgaCopyAndVerifyState(dev_priv, buf_priv, MGA_UPLOAD_CLIPRECTS)) { + drm_freelist_put( dev, freelist, buf ); return -EINVAL; - - if ( dev_priv->sgram ) - cmd = MGA_CLEAR_CMD | DC_atype_blk; - else - 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 ); - - for (i = 0 ; i < nbox ; i++) { - unsigned int height = pbox[i].y2 - pbox[i].y1; - - /* Is it necessary to be this paranoid? I don't think so. - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); - DMAOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); - - 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_BACK ) { - DMAOUTREG(MGAREG_FCOL, clear_color); - DMAOUTREG(MGAREG_DSTORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - - if ( flags & MGA_CLEAR_DEPTH ) - { - DMAOUTREG(MGAREG_FCOL, clear_depth); - DMAOUTREG(MGAREG_DSTORG, dev_priv->depthOrg); - DMAOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); - } - } - - DMAADVANCE( buf ); + /* Make sure we restore the 3D state next time. */ - sarea_priv->dirty |= MGA_UPLOAD_CTX; + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; + buf->used = 1; - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; d.context = DRM_KERNEL_CONTEXT; d.send_count = 1; @@ -148,10 +86,10 @@ static int mgaClearBuffers(drm_device_t *dev, d.request_size = 0; d.request_indices = NULL; d.request_sizes = NULL; - d.granted_count = 0; + d.granted_count = 0; - atomic_inc(&dev_priv->pending_bufs); - if((drm_dma_enqueue(dev, &d)) != 0) + atomic_inc(&dev_priv->pending_bufs); + if((drm_dma_enqueue(dev, &d)) != 0) atomic_dec(&dev_priv->pending_bufs); mga_dma_schedule(dev, 1); return 0; @@ -160,60 +98,30 @@ static int mgaClearBuffers(drm_device_t *dev, int mgaSwapBuffers(drm_device_t *dev, int flags) { drm_device_dma_t *dma = dev->dma; + drm_freelist_t *freelist = &dma->bufs[MGA_DMA_BUF_ORDER].freelist; drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private; - drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - xf86drmClipRectRec *pbox = sarea_priv->boxes; - int nbox = sarea_priv->nbox; + drm_mga_buf_priv_t *buf_priv; drm_buf_t *buf; drm_dma_t d; - int order = 16; /* ??? */ - int i; - DMALOCALS; - if (!nbox) + buf = drm_freelist_get(freelist, _DRM_DMA_WAIT); + if (!buf) return -1; + + buf->pid = current->pid; + buf_priv = buf->dev_private; + buf_priv->dma_type = MGA_DMA_SWAP; + + if (!mgaCopyAndVerifyState(dev_priv, buf_priv, MGA_UPLOAD_CLIPRECTS)) { + drm_freelist_put( dev, freelist, buf ); 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); - - DMAOUTREG(MGAREG_DSTORG, dev_priv->frontOrg); - DMAOUTREG(MGAREG_MACCESS, dev_priv->mAccess); - DMAOUTREG(MGAREG_SRCORG, dev_priv->backOrg); - DMAOUTREG(MGAREG_AR5, dev_priv->stride); /* unnecessary? */ - DMAOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); - - for (i = 0 ; i < nbox; i++) { - unsigned int h = pbox[i].y2 - pbox[i].y1; - unsigned int start = pbox[i].y1 * dev_priv->stride; - - /* - if (pbox[i].x1 > dev_priv->width) continue; - if (pbox[i].y1 > dev_priv->height) continue; - if (pbox[i].x2 > dev_priv->width) continue; - if (pbox[i].y2 > dev_priv->height) continue; - if (pbox[i].x2 <= pbox[i].x1) continue; - if (pbox[i].y2 <= pbox[i].x1) continue; - */ - - DMAOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1); - DMAOUTREG(MGAREG_AR3, start + pbox[i].x1); - DMAOUTREG(MGAREG_FXBNDRY, pbox[i].x1|((pbox[i].x2 - 1)<<16)); - DMAOUTREG(MGAREG_YDSTLEN+MGAREG_MGA_EXEC, (pbox[i].y1<<16)|h); - } - - DMAOUTREG(MGAREG_SRCORG, 0); - DMAADVANCE( buf ); + /* Make sure we restore the 3D state next time. */ - sarea_priv->dirty |= MGA_UPLOAD_CTX; + dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX; + buf->used = 1; - ((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL; d.context = DRM_KERNEL_CONTEXT; d.send_count = 1; @@ -293,13 +201,6 @@ static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args) } -/* Necessary? Not necessary?? - */ -/* static int check_lock(void) */ -/* { */ -/* return 1; */ -/* } */ - int mga_clear_bufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -308,13 +209,11 @@ int mga_clear_bufs(struct inode *inode, struct file *filp, drm_mga_clear_t clear; int retcode; + return 0; copy_from_user_ret(&clear, (drm_mga_clear_t *)arg, sizeof(clear), -EFAULT); -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - retcode = mgaClearBuffers(dev, clear.clear_color, clear.clear_depth, clear.flags); @@ -331,9 +230,7 @@ int mga_swap_bufs(struct inode *inode, struct file *filp, int retcode = 0; return 0; -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - + copy_from_user_ret(&swap, (drm_mga_swap_t *)arg, sizeof(swap), -EFAULT); @@ -350,9 +247,6 @@ int mga_iload(struct inode *inode, struct file *filp, drm_mga_iload_t iload; int retcode = 0; -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload), -EFAULT); @@ -406,12 +300,9 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd, buf_priv->dma_type = MGA_DMA_VERTEX; -/* if (!check_lock( dev )) */ -/* return -EIEIO; */ - /* Snapshot the relevent bits of the sarea... */ - if (!mgaCopyAndVerifyState( dev_priv, buf_priv )) + if (!mgaCopyAndVerifyState( dev_priv, buf_priv, ~0 )) dma->buflist[ idx ]->used = 0; atomic_inc(&dev_priv->pending_bufs); diff --git a/linux/mga_dma.c b/linux/mga_dma.c index bc5bf066..4cb2eadb 100644 --- a/linux/mga_dma.c +++ b/linux/mga_dma.c @@ -187,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->frontOffset; + dev_priv->frontOffset = init->frontOffset; dev_priv->backOffset = init->backOffset; dev_priv->depthOffset = init->depthOffset; dev_priv->textureOffset = init->textureOffset; @@ -266,7 +266,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) { /* Poll for the first buffer to insure that * the status register will be correct */ - printk("phys_head : %lx\n", phys_head); + printk("phys_head : %x\n", phys_head); MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); @@ -308,10 +308,7 @@ int mga_dma_init(struct inode *inode, struct file *filp, return -EINVAL; } -#define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \ - DC_linear_linear | DC_bltmod_bfcol | \ - (0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \ - DC_shftzero_enable | DC_clipdis_enable) + static void __mga_iload_small(drm_device_t *dev, drm_buf_t *buf, @@ -350,8 +347,8 @@ static void __mga_iload_small(drm_device_t *dev, PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); - PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG(MGAREG_SECADDRESS, ((__u32)address) | TT_BLIT); + PRIMOUTREG(MGAREG_SECEND, ((__u32)(address + length)) | use_agp); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -424,8 +421,8 @@ static void __mga_iload_xy(drm_device_t *dev, PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); - PRIMOUTREG(MGAREG_SECADDRESS, address | TT_BLIT); - PRIMOUTREG(MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG(MGAREG_SECADDRESS, ((__u32)address) | TT_BLIT); + PRIMOUTREG(MGAREG_SECEND, ((__u32)(address + length)) | use_agp); PRIMOUTREG(MGAREG_DMAPAD, 0); PRIMOUTREG(MGAREG_DMAPAD, 0); @@ -480,7 +477,7 @@ 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", + printk("dispatch vertex addr 0x%lx, length 0x%x nbox %d\n", address, length, buf_priv->nbox); for (i = 0 ; i < count ; i++) { @@ -490,8 +487,9 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf) PRIMGETPTR(dev_priv); PRIMOUTREG( MGAREG_DMAPAD, 0); PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, address | TT_VERTEX); - PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG( MGAREG_SECADDRESS, ((__u32)address) | TT_VERTEX); + PRIMOUTREG( MGAREG_SECEND, (((__u32)(address + length)) | + use_agp)); PRIMOUTREG( MGAREG_DMAPAD, 0); PRIMOUTREG( MGAREG_DMAPAD, 0); @@ -526,8 +524,8 @@ static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) PRIMOUTREG( MGAREG_DMAPAD, 0); PRIMOUTREG( MGAREG_DMAPAD, 0); - PRIMOUTREG( MGAREG_SECADDRESS, address | TT_GENERAL); - PRIMOUTREG( MGAREG_SECEND, (address + length) | use_agp); + PRIMOUTREG( MGAREG_SECADDRESS, ((__u32)address) | TT_GENERAL); + PRIMOUTREG( MGAREG_SECEND, (((__u32)(address + length)) | use_agp)); PRIMOUTREG( MGAREG_DMAPAD, 0); PRIMOUTREG( MGAREG_DMAPAD, 0); @@ -539,6 +537,142 @@ static void mga_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf) MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); } + +static void mga_dma_dispatch_clear( 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; + int nbox = buf_priv->nbox; + xf86drmClipRectRec *pbox = buf_priv->boxes; + int flags = buf_priv->clear_flags; + unsigned int cmd; + int use_agp = PDEA_pagpxfer_enable; + int i; + PRIMLOCALS; + + if ( dev_priv->sgram ) + cmd = MGA_CLEAR_CMD | DC_atype_blk; + else + cmd = MGA_CLEAR_CMD | DC_atype_rstr; + + + PRIMRESET( dev_priv ); + PRIMGETPTR( dev_priv ); + + for (i = 0 ; i < nbox ; i++) { + unsigned int height = pbox[i].y2 - pbox[i].y1; + + printk("dispatch clear %d,%d-%d,%d flags %x!\n", + pbox[i].x1, + pbox[i].y1, + pbox[i].x2, + pbox[i].y2, + flags); + + +/* if ( flags & MGA_CLEAR_FRONT ) */ + { + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + printk("clear front\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + + if ( flags & MGA_CLEAR_BACK ) { + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + printk("clear back\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_color); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + + if ( flags & MGA_CLEAR_DEPTH ) + { + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height); + PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1); + + printk("clear depth\n"); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_zval); + PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset); + PRIMOUTREG(MGAREG_DWGCTL+MGAREG_MGA_EXEC, cmd ); + } + } + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_SOFTRAP, 0); + PRIMADVANCE(dev_priv); + + MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); + MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); +} + + + +static void mga_dma_dispatch_swap( 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; + int nbox = buf_priv->nbox; + xf86drmClipRectRec *pbox = buf_priv->boxes; + int use_agp = PDEA_pagpxfer_enable; + int i; + + PRIMLOCALS; + PRIMRESET( dev_priv ); + PRIMGETPTR( dev_priv ); + + PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset); + PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess); + PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset); + PRIMOUTREG(MGAREG_AR5, dev_priv->stride); + + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD); + + for (i = 0 ; i < nbox; i++) { + unsigned int h = pbox[i].y2 - pbox[i].y1; + unsigned int start = pbox[i].y1 * dev_priv->stride; + + printk("dispatch swap %d,%d-%d,%d!\n", + pbox[i].x1, + pbox[i].y1, + pbox[i].x2, + pbox[i].y2); + + 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); + } + + PRIMOUTREG( MGAREG_SRCORG, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_DMAPAD, 0); + PRIMOUTREG( MGAREG_SOFTRAP, 0); + PRIMADVANCE(dev_priv); + + MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL); + MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp); +} + /* Frees dispatch lock */ static inline void mga_dma_quiescent(drm_device_t *dev) { @@ -555,7 +689,8 @@ static inline void mga_dma_quiescent(drm_device_t *dev) #if 1 MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG); while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ; - MGA_WRITE(MGAREG_DWGSYNC, 0); + MGA_WRITE(MGAREG_DWGSYNC, 0); + while(MGA_READ(MGAREG_DWGSYNC) != 0) ; #endif atomic_dec(&dev_priv->dispatch_lock); } @@ -699,10 +834,17 @@ static int mga_do_dma(drm_device_t *dev, int locked) case MGA_DMA_ILOAD: mga_dma_dispatch_iload(dev, buf); break; + case MGA_DMA_SWAP: + mga_dma_dispatch_swap(dev, buf); + break; + case MGA_DMA_CLEAR: + mga_dma_dispatch_clear(dev, buf); + break; default: printk("bad buffer type %x in dispatch\n", buf_priv->dma_type); break; } + atomic_dec(&dev_priv->pending_bufs); if(dma->this_buffer) { diff --git a/linux/mga_dma.h b/linux/mga_dma.h index d398f43f..a6868cef 100644 --- a/linux/mga_dma.h +++ b/linux/mga_dma.h @@ -16,6 +16,10 @@ typedef struct { unsigned int WarpPipe; unsigned int dirty; + unsigned short clear_color; + unsigned short clear_zval; + unsigned int clear_flags; + unsigned int nbox; xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS]; } drm_mga_buf_priv_t; @@ -25,6 +29,9 @@ typedef struct { #define MGA_DMA_VERTEX 1 #define MGA_DMA_SETUP 2 #define MGA_DMA_ILOAD 3 +#define MGA_DMA_CLEAR 4 /* placeholder */ +#define MGA_DMA_SWAP 5 /* placeholder */ +#define MGA_DMA_BAD 6 #define DWGREG0 0x1c00 @@ -115,11 +122,14 @@ typedef struct { 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; \ +#define PRIMADVANCE(dev_priv) do { \ + if (VERBO) { \ + printk(KERN_INFO "PRIMADVANCE\n"); \ + if (outcount & 3) \ + printk(KERN_INFO " --- truncation\n"); \ + } \ + dev_priv->prim_num_dwords = num_dwords; \ + dev_priv->current_dma_ptr = dma_ptr; \ } while (0) @@ -139,4 +149,25 @@ typedef struct { }while (0) + + +#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \ + DC_solid_enable | DC_transc_enable) + + +#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \ + DC_solid_disable | DC_arzero_disable | \ + DC_sgnzero_enable | DC_shftzero_enable | \ + (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol | \ + DC_pattern_disable | DC_transc_disable | \ + DC_clipdis_enable) \ + +#define MGA_ILOAD_CMD (DC_opcod_iload | DC_atype_rpl | \ + DC_linear_linear | DC_bltmod_bfcol | \ + (0xC << DC_bop_SHIFT) | DC_sgnzero_enable | \ + DC_shftzero_enable | DC_clipdis_enable) + + #endif diff --git a/linux/mga_drm_public.h b/linux/mga_drm_public.h index 8072f9b0..09152648 100644 --- a/linux/mga_drm_public.h +++ b/linux/mga_drm_public.h @@ -155,9 +155,11 @@ typedef struct _xf86drmClipRectRec { #define MGA_UPLOAD_TEX1IMAGE 0x20 #define MGA_UPLOAD_2D 0x40 #define MGA_REQUIRE_QUIESCENT 0x80 +#define MGA_UPLOAD_CLIPRECTS 0x100 -#define MGA_DMA_BUF_SZ 65536 +#define MGA_DMA_BUF_ORDER 16 +#define MGA_DMA_BUF_SZ (1<depthOffset ); + PRIMOUTREG( MGAREG_ZORG, dev_priv->depthOffset ); /* invarient */ /* PRIMOUTREG( MGAREG_DMAPAD, 0 ); */ if (dev_priv->chipset == MGA_CARD_TYPE_G400) { @@ -258,8 +257,8 @@ static void mgaG400EmitPipe(drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR2, (dev_priv->WarpIndex[pipe].phys_addr | - WIA_wmode_start | WIA_wagp_agp)); + PRIMOUTREG(MGAREG_WIADDR2, (__u32)(dev_priv->WarpIndex[pipe].phys_addr | + WIA_wmode_start | WIA_wagp_agp)); PRIMADVANCE(dev_priv); } @@ -288,8 +287,8 @@ static void mgaG200EmitPipe( drm_mga_private_t *dev_priv, PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff); - PRIMOUTREG(MGAREG_WIADDR, (dev_priv->WarpIndex[pipe].phys_addr | - WIA_wmode_start | WIA_wagp_agp)); + PRIMOUTREG(MGAREG_WIADDR, (__u32)(dev_priv->WarpIndex[pipe].phys_addr | + WIA_wmode_start | WIA_wagp_agp)); PRIMADVANCE(dev_priv); } @@ -330,24 +329,28 @@ static int mgaCopyContext(drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int *regs = sarea_priv->ContextState; + unsigned int *regs = buf_priv->ContextState; int i; + memcpy(regs, + sarea_priv->ContextState, + sizeof(buf_priv->ContextState)); + 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) { + + if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset && + regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) { printk("BAD DSTORG: %x (front %x, back %x)\n\n", - regs[MGA_CTXREG_DSTORG], dev_priv->frontOrg, - dev_priv->backOrg); + regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset, + dev_priv->backOffset); + regs[MGA_CTXREG_DSTORG] = 0; return -1; } else printk("DSTORG OK: %x\n", regs[MGA_CTXREG_DSTORG]); - memcpy(buf_priv->ContextState, regs, sizeof(buf_priv->ContextState)); return 0; } @@ -360,10 +363,14 @@ 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) { + memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit], + sizeof(buf_priv->TexState[0])); + + if ((buf_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) { printk("BAD TEXREG_ORG: %x, unit %d\n", sarea_priv->TexState[unit][MGA_TEXREG_ORG], unit); + buf_priv->TexState[unit][MGA_TEXREG_ORG] = 0; return -1; } else @@ -371,27 +378,35 @@ static int mgaCopyTex(drm_mga_private_t *dev_priv, sarea_priv->TexState[unit][MGA_TEXREG_ORG], unit); - memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit], - sizeof(buf_priv->TexState[0])); - return 0; } int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ) + drm_mga_buf_priv_t *buf_priv, + unsigned int interested ) { drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; - unsigned int dirty = sarea_priv->dirty ; + unsigned int dirty = interested & sarea_priv->dirty; int rv = 0; - buf_priv->dirty = sarea_priv->dirty; + buf_priv->dirty = dirty; + sarea_priv->dirty &= ~interested; + buf_priv->WarpPipe = sarea_priv->WarpPipe; - if ((buf_priv->nbox = sarea_priv->nbox) != 0) - memcpy( buf_priv->boxes, - sarea_priv->boxes, - buf_priv->nbox * sizeof(xf86drmClipRectRec)); +/* if (interested & MGA_UPLOAD_CLIPRECTS) */ + { + buf_priv->nbox = sarea_priv->nbox; + + if (buf_priv->nbox >= MGA_NR_SAREA_CLIPRECTS) + buf_priv->nbox = MGA_NR_SAREA_CLIPRECTS; + + if (buf_priv->nbox) + memcpy( buf_priv->boxes, + sarea_priv->boxes, + buf_priv->nbox * sizeof(xf86drmClipRectRec)); + } if (dirty & MGA_UPLOAD_CTX) rv |= mgaCopyContext( dev_priv, buf_priv ); diff --git a/linux/mga_state.h b/linux/mga_state.h index e7b952e0..72ddb9a5 100644 --- a/linux/mga_state.h +++ b/linux/mga_state.h @@ -4,7 +4,8 @@ #include "mga_drv.h" int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv, - drm_mga_buf_priv_t *buf_priv ); + drm_mga_buf_priv_t *buf_priv, + unsigned int interested ); void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box );