Move clear and swap operations to primary dma, bugfixes.

Jeff's quiescence patch
This commit is contained in:
Keith Whitwell 2000-02-10 19:16:22 +00:00
parent 4117dcf0a3
commit 4468902a7e
9 changed files with 279 additions and 200 deletions

View file

@ -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 },
};

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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<<MGA_DMA_BUF_ORDER)
#define MGA_DMA_BUF_NR 63

View file

@ -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 },
};

View file

@ -40,7 +40,7 @@ typedef struct _drm_mga_private {
int primary_size;
int warp_ucode_size;
int chipset;
int fbOffset;
int frontOffset;
int backOffset;
int depthOffset;
int textureOffset;
@ -64,9 +64,6 @@ typedef struct _drm_mga_private {
/* Some validated register values:
*/
u32 frontOrg;
u32 backOrg;
u32 depthOrg;
u32 mAccess;
} drm_mga_private_t;

View file

@ -81,9 +81,8 @@ static void mgaEmitContext(drm_mga_private_t *dev_priv,
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_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 );

View file

@ -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 );