mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-07 19:18:04 +02:00
Move clear and swap operations to primary dma, bugfixes.
Jeff's quiescence patch
This commit is contained in:
parent
4117dcf0a3
commit
4468902a7e
9 changed files with 279 additions and 200 deletions
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
174
linux/mga_dma.c
174
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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue