summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth Hughes <gareth@users.sourceforge.net>2001-02-12 10:45:03 +0000
committerGareth Hughes <gareth@users.sourceforge.net>2001-02-12 10:45:03 +0000
commit6038ace5dca200c48d4a28a1130b396e378e763e (patch)
tree3591d2d88cc03678dbb738316e3b95a108dc91bc
parentb381e69d450ad7bec4ceb648d98e9d75ea4e1bcd (diff)
downloaddrm-6038ace5dca200c48d4a28a1130b396e378e763e.tar.gz
Right, I've had it. Interrupts are gone...
This commit will temporarily break the gamma driver. I'll fix it up tonight.
-rw-r--r--linux-core/drm_dma.c5
-rw-r--r--linux-core/drm_drv.c79
-rw-r--r--linux-core/mga_drv.c84
-rw-r--r--linux/Makefile.linux4
-rw-r--r--linux/drm_dma.h5
-rw-r--r--linux/drm_drv.h79
-rw-r--r--linux/mga.h1
-rw-r--r--linux/mga_dma.c1102
-rw-r--r--linux/mga_drv.c84
-rw-r--r--linux/mga_drv.h150
-rw-r--r--linux/mga_state.c155
11 files changed, 353 insertions, 1395 deletions
diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c
index 83766d54..f4220196 100644
--- a/linux-core/drm_dma.c
+++ b/linux-core/drm_dma.c
@@ -114,6 +114,7 @@ void DRM(dma_takedown)(drm_device_t *dev)
dev->dma = NULL;
}
+
#if DRM_DMA_HISTOGRAM
/* This is slow, but is useful for debugging. */
int DRM(histogram_slot)(unsigned long count)
@@ -220,6 +221,8 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
}
}
+#if __HAVE_OLD_DMA
+
#if 0
int drm_context_switch(drm_device_t *dev, int old, int new)
{
@@ -562,3 +565,5 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma)
}
#endif
+
+#endif
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index ae57b068..225c6127 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -75,8 +75,8 @@
#ifndef __HAVE_DMA_QUIESCENT
#define __HAVE_DMA_QUIESCENT 0
#endif
-#ifndef __HAVE_DRIVER_RELEASE
-#define __HAVE_DRIVER_RELEASE 0
+#ifndef __HAVE_RELEASE
+#define __HAVE_RELEASE 0
#endif
#ifndef __HAVE_COUNTERS
#define __HAVE_COUNTERS 0
@@ -91,6 +91,9 @@
#ifndef DRIVER_PRETAKEDOWN
#define DRIVER_PRETAKEDOWN()
#endif
+#ifndef DRIVER_IOCTLS
+#define DRIVER_IOCTLS
+#endif
static drm_device_t DRM(device);
@@ -111,6 +114,68 @@ static struct file_operations DRM(fops) = {
poll: DRM(poll),
};
+
+static drm_ioctl_desc_t DRM(ioctls)[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
+
+#if __HAVE_DMA
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
+
+ /* The DRM_IOCTL_DMA ioctl should be defined by the driver.
+ */
+#if __HAVE_DMA_IRQ
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
+#endif
+#endif
+
+#if __REALLY_HAVE_AGP
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
+#endif
+
+ DRIVER_IOCTLS
+};
+
+#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) )
+
#ifdef MODULE
static char *drm_opts = NULL;
#endif
@@ -186,7 +251,7 @@ static int DRM(setup)( drm_device_t *dev )
#ifdef __HAVE_COUNTER15
dev->types[14] = __HAVE_COUNTER14;
#endif
-
+
for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
atomic_set(&dev->counts[i], 0);
@@ -463,8 +528,7 @@ static void __exit drm_cleanup( void )
DRM(ctxbitmap_cleanup)( dev );
#endif
-#if __REALLY_HAVE_MTRR
-#if __REALLY_HAVE_AGP
+#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
if ( dev->agp && dev->agp->agp_mtrr ) {
int retval;
retval = mtrr_del( dev->agp->agp_mtrr,
@@ -473,7 +537,6 @@ static void __exit drm_cleanup( void )
DRM_DEBUG( "mtrr_del=%d\n", retval );
}
#endif
-#endif
DRM(takedown)( dev );
@@ -573,7 +636,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_ERROR( "Process %d dead, freeing lock for context %d\n",
current->pid,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-#if __HAVE_DRIVER_RELEASE
+#if __HAVE_RELEASE
DRIVER_RELEASE();
#endif
DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
@@ -584,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
processed via a callback to the X
server. */
}
-#if __HAVE_DRIVER_RELEASE
+#if __HAVE_RELEASE
else if ( dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index d458afb4..fdba9c5f 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -38,85 +38,23 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20010206"
+#define DRIVER_DATE "20010212"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-/* Now that we do this, we can move the DRM(ioctls) array into a
- * template file and have a DRIVER_IOCTLS block at the end.
- */
-static drm_ioctl_desc_t mga_ioctls[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { mga_getunique, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { mga_getmagic, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { mga_irq_busid, 0, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { mga_getmap, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { mga_getclient, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { mga_getstats, 0, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { mga_setunique, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { mga_block, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { mga_unblock, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { mga_authmagic, 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { mga_addmap, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 },
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { mga_agp_acquire, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { mga_agp_release, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { mga_agp_enable, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { mga_agp_info, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { mga_agp_alloc, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { mga_agp_free, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { mga_agp_bind, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { mga_agp_unbind, 1, 1 },
-#endif
-
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
+#define DRIVER_IOCTLS \
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 },
-#if 0
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
-#endif
-};
-
-#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
-
-#define __HAVE_AGP 1
-#define __MUST_HAVE_AGP 1
-
-#define __HAVE_MTRR 1
-
-#define __HAVE_CTX_BITMAP 1
-#define __HAVE_DMA 1
#define __HAVE_DMA_IRQ 1
#define __HAVE_COUNTERS 3
@@ -137,7 +75,7 @@ do { \
} while (0)
#if 0
-#define __HAVE_DRIVER_RELEASE 1
+#define __HAVE_RELEASE 1
#define DRIVER_RELEASE() do { \
mga_reclaim_buffers( dev, priv->pid ); \
if ( dev->dev_private ) { \
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index fa5ea894..75aadd45 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -136,7 +136,7 @@ endif
ifeq ($(AGP),1)
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
#DRMOBJS += agpsupport.o
-MODS += mga.o gamma.o
+MODS += mga.o
#ifeq ($(MACHINE),i386)
#MODS += i810.o
#endif
@@ -211,7 +211,7 @@ dristat: dristat.c
gamma_drv.o: gamma_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-gamma.o: $(GAMMAOBJS)
+gamma.o: $(GAMMAOBJS)
$(LD) -r $^ -o $@
tdfx_drv.o: tdfx_drv.c
diff --git a/linux/drm_dma.h b/linux/drm_dma.h
index 83766d54..f4220196 100644
--- a/linux/drm_dma.h
+++ b/linux/drm_dma.h
@@ -114,6 +114,7 @@ void DRM(dma_takedown)(drm_device_t *dev)
dev->dma = NULL;
}
+
#if DRM_DMA_HISTOGRAM
/* This is slow, but is useful for debugging. */
int DRM(histogram_slot)(unsigned long count)
@@ -220,6 +221,8 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
}
}
+#if __HAVE_OLD_DMA
+
#if 0
int drm_context_switch(drm_device_t *dev, int old, int new)
{
@@ -562,3 +565,5 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma)
}
#endif
+
+#endif
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index ae57b068..225c6127 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -75,8 +75,8 @@
#ifndef __HAVE_DMA_QUIESCENT
#define __HAVE_DMA_QUIESCENT 0
#endif
-#ifndef __HAVE_DRIVER_RELEASE
-#define __HAVE_DRIVER_RELEASE 0
+#ifndef __HAVE_RELEASE
+#define __HAVE_RELEASE 0
#endif
#ifndef __HAVE_COUNTERS
#define __HAVE_COUNTERS 0
@@ -91,6 +91,9 @@
#ifndef DRIVER_PRETAKEDOWN
#define DRIVER_PRETAKEDOWN()
#endif
+#ifndef DRIVER_IOCTLS
+#define DRIVER_IOCTLS
+#endif
static drm_device_t DRM(device);
@@ -111,6 +114,68 @@ static struct file_operations DRM(fops) = {
poll: DRM(poll),
};
+
+static drm_ioctl_desc_t DRM(ioctls)[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { DRM(version), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { DRM(getunique), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { DRM(getmagic), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { DRM(irq_busid), 0, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { DRM(getmap), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { DRM(getclient), 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { DRM(getstats), 0, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { DRM(setunique), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { DRM(block), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { DRM(unblock), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { DRM(authmagic), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { DRM(modctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { DRM(getctx), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { DRM(switchctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { DRM(newctx), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { DRM(resctx), 1, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { DRM(adddraw), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { DRM(rmdraw), 1, 1 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { DRM(lock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { DRM(unlock), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { DRM(finish), 1, 0 },
+
+#if __HAVE_DMA
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { DRM(addbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { DRM(markbufs), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { DRM(infobufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { DRM(mapbufs), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { DRM(freebufs), 1, 0 },
+
+ /* The DRM_IOCTL_DMA ioctl should be defined by the driver.
+ */
+#if __HAVE_DMA_IRQ
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { DRM(control), 1, 1 },
+#endif
+#endif
+
+#if __REALLY_HAVE_AGP
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { DRM(agp_acquire), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { DRM(agp_release), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { DRM(agp_enable), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { DRM(agp_info), 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { DRM(agp_alloc), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { DRM(agp_free), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { DRM(agp_bind), 1, 1 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
+#endif
+
+ DRIVER_IOCTLS
+};
+
+#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( DRM(ioctls) )
+
#ifdef MODULE
static char *drm_opts = NULL;
#endif
@@ -186,7 +251,7 @@ static int DRM(setup)( drm_device_t *dev )
#ifdef __HAVE_COUNTER15
dev->types[14] = __HAVE_COUNTER14;
#endif
-
+
for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
atomic_set(&dev->counts[i], 0);
@@ -463,8 +528,7 @@ static void __exit drm_cleanup( void )
DRM(ctxbitmap_cleanup)( dev );
#endif
-#if __REALLY_HAVE_MTRR
-#if __REALLY_HAVE_AGP
+#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
if ( dev->agp && dev->agp->agp_mtrr ) {
int retval;
retval = mtrr_del( dev->agp->agp_mtrr,
@@ -473,7 +537,6 @@ static void __exit drm_cleanup( void )
DRM_DEBUG( "mtrr_del=%d\n", retval );
}
#endif
-#endif
DRM(takedown)( dev );
@@ -573,7 +636,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_ERROR( "Process %d dead, freeing lock for context %d\n",
current->pid,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
-#if __HAVE_DRIVER_RELEASE
+#if __HAVE_RELEASE
DRIVER_RELEASE();
#endif
DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
@@ -584,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
processed via a callback to the X
server. */
}
-#if __HAVE_DRIVER_RELEASE
+#if __HAVE_RELEASE
else if ( dev->lock.hw_lock ) {
/* The lock is required to reclaim buffers */
DECLARE_WAITQUEUE( entry, current );
diff --git a/linux/mga.h b/linux/mga.h
index 6c0ed961..9b222404 100644
--- a/linux/mga.h
+++ b/linux/mga.h
@@ -42,6 +42,5 @@
#define __HAVE_CTX_BITMAP 1
#define __HAVE_DMA 1
-#define __HAVE_DMA_IRQ 1
#endif
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index 7b66e887..e99745d2 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -68,955 +68,6 @@ do { \
-#if 0
-
-
-#define MGA_REG(reg) 2
-#define MGA_BASE(reg) ((unsigned long) \
- ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle)
-#define MGA_ADDR(reg) (MGA_BASE(reg) + reg)
-#define MGA_DEREF(reg) *(__volatile__ int *)MGA_ADDR(reg)
-#define MGA_READ(reg) MGA_DEREF(reg)
-#define MGA_WRITE(reg,val) do { MGA_DEREF(reg) = val; } while (0)
-
-#define PDEA_pagpxfer_enable 0x2
-
-static int mga_flush_queue(drm_device_t *dev);
-
-static unsigned long mga_alloc_page(drm_device_t *dev)
-{
- unsigned long address;
-
- address = __get_free_page(GFP_KERNEL);
- if(address == 0UL) {
- return 0;
- }
- atomic_inc(&virt_to_page(address)->count);
- set_bit(PG_reserved, &virt_to_page(address)->flags);
-
- return address;
-}
-
-static void mga_free_page(drm_device_t *dev, unsigned long page)
-{
- if(!page) return;
- atomic_dec(&virt_to_page(page)->count);
- clear_bit(PG_reserved, &virt_to_page(page)->flags);
- free_page(page);
- return;
-}
-
-static void mga_delay(void)
-{
- return;
-}
-
-/* These are two age tags that will never be sent to
- * the hardware */
-#define MGA_BUF_USED 0xffffffff
-#define MGA_BUF_FREE 0
-
-static int mga_freelist_init(drm_device_t *dev)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf;
- drm_mga_buf_priv_t *buf_priv;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_freelist_t *item;
- int i;
-
- dev_priv->head = DRM(alloc)(sizeof(drm_mga_freelist_t),
- DRM_MEM_DRIVER);
- if(dev_priv->head == NULL) return -ENOMEM;
- memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
- dev_priv->head->age = MGA_BUF_USED;
-
- for (i = 0; i < dma->buf_count; i++) {
- buf = dma->buflist[ i ];
- buf_priv = buf->dev_private;
- item = drm_alloc(sizeof(drm_mga_freelist_t),
- DRM_MEM_DRIVER);
- if(item == NULL) return -ENOMEM;
- memset(item, 0, sizeof(drm_mga_freelist_t));
- item->age = MGA_BUF_FREE;
- item->prev = dev_priv->head;
- item->next = dev_priv->head->next;
- if(dev_priv->head->next != NULL)
- dev_priv->head->next->prev = item;
- if(item->next == NULL) dev_priv->tail = item;
- item->buf = buf;
- buf_priv->my_freelist = item;
- buf_priv->discard = 0;
- buf_priv->dispatched = 0;
- dev_priv->head->next = item;
- }
-
- return 0;
-}
-
-static void mga_freelist_cleanup(drm_device_t *dev)
-{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_freelist_t *item;
- drm_mga_freelist_t *prev;
-
- item = dev_priv->head;
- while(item) {
- prev = item;
- item = item->next;
- drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
- }
-
- dev_priv->head = dev_priv->tail = NULL;
-}
-
-/* Frees dispatch lock */
-static inline void mga_dma_quiescent(drm_device_t *dev)
-{
- 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;
- unsigned long end;
- int i;
-
- DRM_DEBUG("dispatch_status = 0x%02x\n", dev_priv->dispatch_status);
- end = jiffies + (HZ*3);
- while(1) {
- if(!test_and_set_bit(MGA_IN_DISPATCH,
- &dev_priv->dispatch_status)) {
- break;
- }
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
- atomic_read(&dma->total_lost));
- DRM_ERROR("lockup: dispatch_status = 0x%02x,"
- " jiffies = %lu, end = %lu\n",
- dev_priv->dispatch_status, jiffies, end);
- return;
- }
- for (i = 0 ; i < 2000 ; i++) mga_delay();
- }
- end = jiffies + (HZ*3);
- DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
- while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
- atomic_read(&dma->total_lost));
- DRM_ERROR("lockup\n");
- clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
- return;
- }
- for (i = 0 ; i < 2000 ; i++) mga_delay();
- }
- sarea_priv->dirty |= MGA_DMA_FLUSH;
-
- clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
- DRM_DEBUG("exit, dispatch_status = 0x%02x\n",
- dev_priv->dispatch_status);
-}
-
-static void mga_reset_freelist(drm_device_t *dev)
-{
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf;
- drm_mga_buf_priv_t *buf_priv;
- int i;
-
- for (i = 0; i < dma->buf_count; i++) {
- buf = dma->buflist[ i ];
- buf_priv = buf->dev_private;
- buf_priv->my_freelist->age = MGA_BUF_FREE;
- }
-}
-
-/* Least recently used :
- * These operations are not atomic b/c they are protected by the
- * hardware lock */
-
-drm_buf_t *mga_freelist_get(drm_device_t *dev)
-{
- DECLARE_WAITQUEUE(entry, current);
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
- drm_mga_freelist_t *prev;
- drm_mga_freelist_t *next;
- static int failed = 0;
- int return_null = 0;
-
- if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
- DRM_DEBUG("Waiting on freelist,"
- " tail->age = %d, last_prim_age= %d\n",
- dev_priv->tail->age,
- dev_priv->last_prim_age);
- add_wait_queue(&dev_priv->buf_queue, &entry);
- set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- mga_dma_schedule(dev, 0);
- if(dev_priv->tail->age < dev_priv->last_prim_age)
- break;
- atomic_inc(&dev->total_sleeps);
- schedule();
- if (signal_pending(current)) {
- ++return_null;
- break;
- }
- }
- clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->buf_queue, &entry);
- if (return_null) return NULL;
- }
-
- if(dev_priv->tail->age < dev_priv->last_prim_age) {
- prev = dev_priv->tail->prev;
- next = dev_priv->tail;
- prev->next = NULL;
- next->prev = next->next = NULL;
- dev_priv->tail = prev;
- next->age = MGA_BUF_USED;
- failed = 0;
- return next->buf;
- }
-
- failed++;
- return NULL;
-}
-
-int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
-{
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
- drm_mga_freelist_t *prev;
- drm_mga_freelist_t *head;
- drm_mga_freelist_t *next;
-
- if(buf_priv->my_freelist->age == MGA_BUF_USED) {
- /* Discarded buffer, put it on the tail */
- next = buf_priv->my_freelist;
- next->age = MGA_BUF_FREE;
- prev = dev_priv->tail;
- prev->next = next;
- next->prev = prev;
- next->next = NULL;
- dev_priv->tail = next;
- } else {
- /* Normally aged buffer, put it on the head + 1,
- * as the real head is a sentinal element
- */
- next = buf_priv->my_freelist;
- head = dev_priv->head;
- prev = head->next;
- head->next = next;
- prev->prev = next;
- next->prev = head;
- next->next = prev;
- }
-
- return 0;
-}
-
-static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_prim_buf_t *prim_buffer;
- int i, temp, size_of_buf;
- int offset = init->reserved_map_agpstart;
-
- dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
- PAGE_SIZE) * PAGE_SIZE;
- size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
- dev_priv->warp_ucode_size = init->warp_ucode_size;
- dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
- (MGA_NUM_PRIM_BUFS + 1),
- DRM_MEM_DRIVER);
- if(dev_priv->prim_bufs == NULL) {
- DRM_ERROR("Unable to allocate memory for prim_buf\n");
- return -ENOMEM;
- }
- memset(dev_priv->prim_bufs,
- 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
-
- temp = init->warp_ucode_size + dev_priv->primary_size;
- temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
-
- dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
- temp);
- if(dev_priv->ioremap == NULL) {
- DRM_ERROR("Ioremap failed\n");
- return -ENOMEM;
- }
- init_waitqueue_head(&dev_priv->wait_queue);
-
- for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
- prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
- DRM_MEM_DRIVER);
- if(prim_buffer == NULL) return -ENOMEM;
- memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
- prim_buffer->phys_head = offset + dev->agp->base;
- prim_buffer->current_dma_ptr =
- prim_buffer->head =
- (u32 *) (dev_priv->ioremap +
- offset -
- init->reserved_map_agpstart);
- prim_buffer->num_dwords = 0;
- prim_buffer->max_dwords = size_of_buf / sizeof(u32);
- prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
- prim_buffer->sec_used = 0;
- prim_buffer->idx = i;
- prim_buffer->prim_age = i + 1;
- offset = offset + size_of_buf;
- dev_priv->prim_bufs[i] = prim_buffer;
- }
- dev_priv->current_prim_idx = 0;
- dev_priv->next_prim =
- dev_priv->last_prim =
- dev_priv->current_prim =
- dev_priv->prim_bufs[0];
- dev_priv->next_prim_age = 2;
- dev_priv->last_prim_age = 1;
- set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
- return 0;
-}
-
-void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
-{
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int use_agp = PDEA_pagpxfer_enable;
- unsigned long end;
- int i;
- int next_idx;
- PRIMLOCALS;
-
- dev_priv->last_prim = prim;
-
- /* We never check for overflow, b/c there is always room */
- PRIMPTR(prim);
- if(num_dwords <= 0) {
- DRM_ERROR("num_dwords == 0 when dispatched\n");
- goto out_prim_wait;
- }
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_DMAPAD, 0);
- PRIMOUTREG( MGAREG_SOFTRAP, 0);
- PRIMFINISH(prim);
-
- end = jiffies + (HZ*3);
- if(sarea_priv->dirty & MGA_DMA_FLUSH) {
- while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
- atomic_read(&dma->total_lost));
- DRM_ERROR("lockup (flush)\n");
- goto out_prim_wait;
- }
-
- for (i = 0 ; i < 4096 ; i++) mga_delay();
- }
- sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
- } else {
- while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
- if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
- atomic_read(&dma->total_lost));
- DRM_ERROR("lockup (wait)\n");
- goto out_prim_wait;
- }
-
- for (i = 0 ; i < 4096 ; i++) mga_delay();
- }
- }
-
- mga_flush_write_combine();
- atomic_inc(&dev_priv->pending_bufs);
- MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
- MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
- prim->num_dwords = 0;
- sarea_priv->last_enqueue = prim->prim_age;
-
- next_idx = prim->idx + 1;
- if(next_idx >= MGA_NUM_PRIM_BUFS)
- next_idx = 0;
-
- dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
- return;
-
- out_prim_wait:
- prim->num_dwords = 0;
- prim->sec_used = 0;
- clear_bit(MGA_BUF_IN_USE, &prim->buffer_status);
- wake_up_interruptible(&dev_priv->wait_queue);
- clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status);
- clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-}
-
-int mga_advance_primary(drm_device_t *dev)
-{
- DECLARE_WAITQUEUE(entry, current);
- drm_mga_private_t *dev_priv = dev->dev_private;
- drm_mga_prim_buf_t *prim_buffer;
- drm_device_dma_t *dma = dev->dma;
- int next_prim_idx;
- int ret = 0;
-
- /* This needs to reset the primary buffer if available,
- * we should collect stats on how many times it bites
- * it's tail */
-
- next_prim_idx = dev_priv->current_prim_idx + 1;
- if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
- next_prim_idx = 0;
- prim_buffer = dev_priv->prim_bufs[next_prim_idx];
- set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-
- /* In use is cleared in interrupt handler */
-
- if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
- add_wait_queue(&dev_priv->wait_queue, &entry);
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- mga_dma_schedule(dev, 0);
- if(!test_and_set_bit(MGA_BUF_IN_USE,
- &prim_buffer->buffer_status))
- break;
- atomic_inc(&dev->total_sleeps);
- atomic_inc(&dma->total_missed_sched);
- schedule();
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->wait_queue, &entry);
- if(ret) return ret;
- }
- clear_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-
- /* This primary buffer is now free to use */
- prim_buffer->current_dma_ptr = prim_buffer->head;
- prim_buffer->num_dwords = 0;
- prim_buffer->sec_used = 0;
- prim_buffer->prim_age = dev_priv->next_prim_age++;
- if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
- mga_flush_queue(dev);
- mga_dma_quiescent(dev);
- mga_reset_freelist(dev);
- prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
- }
-
- /* Reset all buffer status stuff */
- clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status);
- clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status);
- clear_bit(MGA_BUF_SWAP_PENDING, &prim_buffer->buffer_status);
-
- dev_priv->current_prim = prim_buffer;
- dev_priv->current_prim_idx = next_prim_idx;
- return 0;
-}
-
-/* More dynamic performance decisions */
-static inline int mga_decide_to_fire(drm_device_t *dev)
-{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-
- if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
- return 1;
- }
-
- if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
- dev_priv->next_prim->num_dwords) {
- return 1;
- }
-
- if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
- dev_priv->next_prim->num_dwords) {
- return 1;
- }
-
- if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
- if(test_bit(MGA_BUF_SWAP_PENDING,
- &dev_priv->next_prim->buffer_status)) {
- return 1;
- }
- }
-
- if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
- if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
- return 1;
- }
- }
-
- if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
- if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int mga_dma_schedule(drm_device_t *dev, int locked)
-{
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- int retval = 0;
-
- if (!dev_priv) return -EBUSY;
-
- if (test_and_set_bit(0, &dev->dma_flag)) {
- retval = -EBUSY;
- goto sch_out_wakeup;
- }
-
- if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
- test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
- test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
- locked = 1;
- }
-
- if (!locked &&
- !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
- clear_bit(0, &dev->dma_flag);
- retval = -EBUSY;
- goto sch_out_wakeup;
- }
-
- if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
- /* Fire dma buffer */
- if(mga_decide_to_fire(dev)) {
- clear_bit(MGA_BUF_FORCE_FIRE,
- &dev_priv->next_prim->buffer_status);
- if(dev_priv->current_prim == dev_priv->next_prim) {
- /* Schedule overflow for a later time */
- set_bit(MGA_BUF_NEEDS_OVERFLOW,
- &dev_priv->next_prim->buffer_status);
- }
- mga_fire_primary(dev, dev_priv->next_prim);
- } else {
- clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
- }
- }
-
- if (!locked) {
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
- }
- }
-
- clear_bit(0, &dev->dma_flag);
-
-sch_out_wakeup:
- if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
- atomic_read(&dev_priv->pending_bufs) == 0) {
- /* Everything has been processed by the hardware */
- clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
- wake_up_interruptible(&dev_priv->flush_queue);
- }
-
- if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)
- && dev_priv->tail->age < dev_priv->last_prim_age)
- wake_up_interruptible(&dev_priv->buf_queue);
-
- return retval;
-}
-
-static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
-{
- drm_device_t *dev = (drm_device_t *)device;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_mga_prim_buf_t *last_prim_buffer;
-
- atomic_inc(&dev->total_irq);
- if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
- MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
- last_prim_buffer = dev_priv->last_prim;
- last_prim_buffer->num_dwords = 0;
- last_prim_buffer->sec_used = 0;
- dev_priv->sarea_priv->last_dispatch =
- dev_priv->last_prim_age = last_prim_buffer->prim_age;
- clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
- clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
- clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
- atomic_dec(&dev_priv->pending_bufs);
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- wake_up_interruptible(&dev_priv->wait_queue);
-}
-
-static void mga_dma_task_queue(void *device)
-{
- mga_dma_schedule((drm_device_t *)device, 0);
-}
-
-int mga_dma_cleanup(drm_device_t *dev)
-{
- if(dev->dev_private) {
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
-
- if (dev->irq) mga_flush_queue(dev);
- mga_dma_quiescent(dev);
-
- if(dev_priv->ioremap) {
- int temp = (dev_priv->warp_ucode_size +
- dev_priv->primary_size +
- PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
-
- drm_ioremapfree((void *) dev_priv->ioremap, temp);
- }
- if(dev_priv->status_page != NULL) {
- iounmap(dev_priv->status_page);
- }
- if(dev_priv->real_status_page != 0UL) {
- mga_free_page(dev, dev_priv->real_status_page);
- }
- if(dev_priv->prim_bufs != NULL) {
- int i;
- for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
- if(dev_priv->prim_bufs[i] != NULL) {
- drm_free(dev_priv->prim_bufs[i],
- sizeof(drm_mga_prim_buf_t),
- DRM_MEM_DRIVER);
- }
- }
- drm_free(dev_priv->prim_bufs, sizeof(void *) *
- (MGA_NUM_PRIM_BUFS + 1),
- DRM_MEM_DRIVER);
- }
- if(dev_priv->head != NULL) {
- mga_freelist_cleanup(dev);
- }
-
-
- drm_free(dev->dev_private, sizeof(drm_mga_private_t),
- DRM_MEM_DRIVER);
- dev->dev_private = NULL;
- }
-
- return 0;
-}
-
-static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
- drm_mga_private_t *dev_priv;
- drm_map_t *sarea_map = NULL;
-
- dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
- if(dev_priv == NULL) return -ENOMEM;
- dev->dev_private = (void *) dev_priv;
-
- memset(dev_priv, 0, sizeof(drm_mga_private_t));
-
- if((init->reserved_map_idx >= dev->map_count) ||
- (init->buffer_map_idx >= dev->map_count)) {
- mga_dma_cleanup(dev);
- return -EINVAL;
- }
-
- dev_priv->reserved_map_idx = init->reserved_map_idx;
- dev_priv->buffer_map_idx = init->buffer_map_idx;
- sarea_map = dev->maplist[0];
- dev_priv->sarea_priv = (drm_mga_sarea_t *)
- ((u8 *)sarea_map->handle +
- init->sarea_priv_offset);
-
- /* Scale primary size to the next page */
- dev_priv->chipset = init->chipset;
- dev_priv->frontOffset = init->frontOffset;
- dev_priv->backOffset = init->backOffset;
- dev_priv->depthOffset = init->depthOffset;
- dev_priv->textureOffset = init->textureOffset;
- dev_priv->textureSize = init->textureSize;
- dev_priv->cpp = init->cpp;
- dev_priv->sgram = init->sgram;
- dev_priv->stride = init->stride;
-
- dev_priv->mAccess = init->mAccess;
- init_waitqueue_head(&dev_priv->flush_queue);
- init_waitqueue_head(&dev_priv->buf_queue);
- dev_priv->WarpPipe = 0xff000000;
- dev_priv->vertexsize = 0;
-
- DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n",
- dev_priv->chipset, dev_priv->warp_ucode_size,
- dev_priv->backOffset, dev_priv->depthOffset);
- DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n",
- dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
- dev_priv->mAccess);
-
- memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
- sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
-
- if(mga_init_primary_bufs(dev, init) != 0) {
- DRM_ERROR("Can not initialize primary buffers\n");
- mga_dma_cleanup(dev);
- return -ENOMEM;
- }
- dev_priv->real_status_page = mga_alloc_page(dev);
- if(dev_priv->real_status_page == 0UL) {
- mga_dma_cleanup(dev);
- DRM_ERROR("Can not allocate status page\n");
- return -ENOMEM;
- }
-
- dev_priv->status_page =
- ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
- PAGE_SIZE);
-
- if(dev_priv->status_page == NULL) {
- mga_dma_cleanup(dev);
- DRM_ERROR("Can not remap status page\n");
- return -ENOMEM;
- }
-
- /* Write status page when secend or softrap occurs */
- MGA_WRITE(MGAREG_PRIMPTR,
- virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
-
-
- /* Private is now filled in, initialize the hardware */
- {
- PRIMLOCALS;
- PRIMGETPTR( dev_priv );
-
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
- PRIMOUTREG(MGAREG_SOFTRAP, 0);
- /* Poll for the first buffer to insure that
- * the status register will be correct
- */
-
- mga_flush_write_combine();
- MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
-
- MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
- PDEA_pagpxfer_enable));
-
- while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
- }
-
- if(mga_freelist_init(dev) != 0) {
- DRM_ERROR("Could not initialize freelist\n");
- mga_dma_cleanup(dev);
- return -ENOMEM;
- }
- return 0;
-}
-
-int mga_dma_init(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_mga_init_t init;
-
- if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
- return -EFAULT;
-
- switch(init.func) {
- case MGA_INIT_DMA:
- return mga_dma_initialize(dev, &init);
- case MGA_CLEANUP_DMA:
- return mga_dma_cleanup(dev);
- }
-
- return -EINVAL;
-}
-
-static int mga_flush_queue(drm_device_t *dev)
-{
- DECLARE_WAITQUEUE(entry, current);
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- int ret = 0;
-
- if(!dev_priv) return 0;
-
- if(dev_priv->next_prim->num_dwords != 0) {
- add_wait_queue(&dev_priv->flush_queue, &entry);
- if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status))
- DRM_ERROR("Incorrect mga_flush_queue logic\n");
- set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
- mga_dma_schedule(dev, 0);
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if (!test_bit(MGA_IN_FLUSH,
- &dev_priv->dispatch_status))
- break;
- atomic_inc(&dev->total_sleeps);
- schedule();
- if (signal_pending(current)) {
- ret = -EINTR; /* Can't restart */
- clear_bit(MGA_IN_FLUSH,
- &dev_priv->dispatch_status);
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev_priv->flush_queue, &entry);
- }
- return ret;
-}
-
-/* Must be called with the lock held */
-void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
-{
- drm_device_dma_t *dma = dev->dma;
- int i;
-
- if (!dma) return;
- if(dev->dev_private == NULL) return;
- if(dma->buflist == NULL) return;
-
- DRM_DEBUG("buf_count=%d\n", dma->buf_count);
-
- mga_flush_queue(dev);
-
- for (i = 0; i < dma->buf_count; i++) {
- drm_buf_t *buf = dma->buflist[ i ];
- drm_mga_buf_priv_t *buf_priv = buf->dev_private;
-
- /* Only buffers that need to get reclaimed ever
- * get set to free
- */
- if (buf->pid == pid && buf_priv) {
- if(buf_priv->my_freelist->age == MGA_BUF_USED)
- buf_priv->my_freelist->age = MGA_BUF_FREE;
- }
- }
-}
-
-int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- DECLARE_WAITQUEUE(entry, current);
- int ret = 0;
- drm_lock_t lock;
-
- if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
- return -EFAULT;
-
- if (lock.context == DRM_KERNEL_CONTEXT) {
- DRM_ERROR("Process %d using kernel context %d\n",
- current->pid, lock.context);
- return -EINVAL;
- }
-
- if (lock.context < 0) return -EINVAL;
-
- /* Only one queue:
- */
-
- if (!ret) {
- add_wait_queue(&dev->lock.lock_queue, &entry);
- for (;;) {
- current->state = TASK_INTERRUPTIBLE;
- if (!dev->lock.hw_lock) {
- /* Device has been unregistered */
- ret = -EINTR;
- break;
- }
- if (drm_lock_take(&dev->lock.hw_lock->lock,
- lock.context)) {
- dev->lock.pid = current->pid;
- dev->lock.lock_time = jiffies;
- atomic_inc(&dev->total_locks);
- break; /* Got lock */
- }
-
- /* Contention */
- atomic_inc(&dev->total_sleeps);
- schedule();
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&dev->lock.lock_queue, &entry);
- }
-
- if (!ret) {
- sigemptyset(&dev->sigmask);
- sigaddset(&dev->sigmask, SIGSTOP);
- sigaddset(&dev->sigmask, SIGTSTP);
- sigaddset(&dev->sigmask, SIGTTIN);
- sigaddset(&dev->sigmask, SIGTTOU);
- dev->sigdata.context = lock.context;
- dev->sigdata.lock = dev->lock.hw_lock;
- block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
- if (lock.flags & _DRM_LOCK_QUIESCENT) {
- DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
- mga_flush_queue(dev);
- mga_dma_quiescent(dev);
- }
- }
-
- if (ret) DRM_DEBUG("%d %s\n", lock.context,
- ret ? "interrupted" : "has lock");
- return ret;
-}
-
-int mga_flush_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_lock_t lock;
- drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-
- if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
- return -EFAULT;
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("lock not held\n");
- return -EINVAL;
- }
-
- if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
- drm_mga_prim_buf_t *temp_buf;
-
- temp_buf = dev_priv->current_prim;
-
- if(temp_buf && temp_buf->num_dwords) {
- set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
- mga_advance_primary(dev);
- }
- mga_dma_schedule(dev, 1);
- }
- if(lock.flags & _DRM_LOCK_QUIESCENT) {
- mga_flush_queue(dev);
- mga_dma_quiescent(dev);
- }
-
- return 0;
-}
-
-
-#endif
-
-
-
-
-/*
- * ****************************************************************
- *
- * START NEW CODE HERE
- *
- * ****************************************************************
- */
-
static unsigned long mga_alloc_page( void )
{
unsigned long address;
@@ -1042,8 +93,6 @@ static void mga_free_page( unsigned long address )
}
-
-
/* ================================================================
* Engine control
*/
@@ -1090,7 +139,7 @@ int mga_do_dma_reset( drm_mga_private_t *dev_priv )
/* The primary DMA stream should look like new right about now.
*/
primary->tail = 0;
- primary->space = primary->size - MGA_DMA_SOFTRAP_SIZE;
+ primary->space = primary->size;
primary->last_flush = 0;
sarea_priv->last_wrap = 0;
@@ -1150,15 +199,21 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
+ unsigned long flags;
DMA_LOCALS;
DRM_DEBUG( "%s:\n", __FUNCTION__ );
- if ( primary->tail == primary->last_flush ) {
+ if ( primary->tail == primary->last_flush + DMA_BLOCK_SIZE ) {
DRM_DEBUG( " bailing out...\n" );
return;
}
+ spin_lock_irqsave( &primary->flush_lock, flags );
+
tail = primary->tail + dev_priv->primary->offset;
+ primary->last_flush = primary->tail;
+
+ spin_unlock_irqrestore( &primary->flush_lock, flags );
BEGIN_DMA( 1 );
@@ -1169,24 +224,30 @@ void mga_do_dma_flush( drm_mga_private_t *dev_priv )
ADVANCE_DMA();
- mga_flush_write_combine();
- MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER );
-
head = *primary->head;
- DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset );
- DRM_DEBUG( " tail = 0x%06lx\n", tail - dev_priv->primary->offset );
-
if ( head <= tail ) {
primary->space = primary->size - primary->tail;
} else {
primary->space = head - tail;
}
- primary->space -= MGA_DMA_SOFTRAP_SIZE;
-
- DRM_DEBUG( " space = 0x%06x\n", primary->space );
- primary->last_flush = primary->tail;
+ if ( test_bit( 0, &primary->wrap_flag ) ) {
+ DRM_DEBUG( "%s: pending wrap...\n", __FUNCTION__ );
+ spin_unlock_irqrestore( &primary->flush_lock, flags );
+ return;
+ }
+
+#if 0
+ DRM_INFO( " head = 0x%06lx\n",
+ head - dev_priv->primary->offset );
+ DRM_INFO( " tail = 0x%06lx\n",
+ tail - dev_priv->primary->offset );
+ DRM_INFO( " space = 0x%06x\n", primary->space );
+#endif
+
+ mga_flush_write_combine();
+ MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER );
DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
}
@@ -1195,9 +256,12 @@ void mga_do_dma_wrap( drm_mga_private_t *dev_priv )
{
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
u32 head, tail;
+ unsigned long flags;
DMA_LOCALS;
DRM_DEBUG( "%s:\n", __FUNCTION__ );
+ spin_lock_irqsave( &primary->flush_lock, flags );
+
BEGIN_DMA_WRAP();
DMA_BLOCK( MGA_DMAPAD, 0x00000000,
@@ -1208,31 +272,38 @@ void mga_do_dma_wrap( drm_mga_private_t *dev_priv )
ADVANCE_DMA();
tail = primary->tail + dev_priv->primary->offset;
-
- mga_flush_write_combine();
- MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER );
-
- spin_lock_irqsave( &primary->tail_lock, flags );
primary->tail = 0;
- spin_unlock_irqrestore( &primary->tail_lock, flags );
head = *primary->head;
- DRM_DEBUG( " head = 0x%06lx\n", head - dev_priv->primary->offset );
- DRM_DEBUG( " tail = 0x%06x\n", 0 );
-
- if ( head <= tail ) {
- primary->space = primary->size - primary->tail;
+ if ( head == dev_priv->primary->offset ) {
+ primary->space = primary->size;
} else {
- primary->space = head - tail;
+ primary->space = head - dev_priv->primary->offset;
}
- primary->space -= MGA_DMA_SOFTRAP_SIZE;
-
- DRM_DEBUG( " space = 0x%06lx\n", (unsigned long)primary->space );
primary->last_flush = 0;
+ primary->last_wrap++;
+
+ set_bit( 0, &primary->wrap_flag );
+
+ if ( 0 ) {
+ DRM_INFO( "%s:\n", __FUNCTION__ );
+ DRM_INFO( " head = 0x%06lx\n",
+ head - dev_priv->primary->offset );
+ DRM_INFO( " tail = 0x%06x\n", primary->tail );
+ DRM_INFO( " wrap = %d\n", primary->last_wrap );
+ DRM_INFO( " space = 0x%06x\n", primary->space );
+ }
+
+ mga_flush_write_combine();
+ MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER );
+
+ spin_unlock_irqrestore( &primary->flush_lock, flags );
DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
+
+ mga_do_wait_for_idle( dev_priv );
}
@@ -1247,7 +318,7 @@ static void mga_dma_service( int irq, void *device, struct pt_regs *regs )
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 head = dev_priv->primary->offset;
- u32 tail;
+ u32 flush;
/* Verify the interrupt we're servicing is actually the one we
* want to service.
@@ -1256,29 +327,36 @@ static void mga_dma_service( int irq, void *device, struct pt_regs *regs )
return;
atomic_inc( &dev->counts[_DRM_STAT_IRQ] );
-
+
+ spin_lock( &primary->flush_lock );
+
MGA_WRITE( MGA_ICLEAR, MGA_SOFTRAPICLR );
- spin_lock( &primary->tail_lock );
- tail = primary->tail + dev_priv->primary->offset;
+ flush = primary->last_flush + dev_priv->primary->offset;
sarea_priv->last_wrap++;
- spin_unlock( &primary->tail_lock );
- DRM_DEBUG( " *** wrap interrupt:\n" );
- DRM_DEBUG( " head = 0x%06lx\n",
- head - dev_priv->primary->offset );
- DRM_DEBUG( " tail = 0x%06lx\n",
- tail - dev_priv->primary->offset );
- DRM_DEBUG( " wrap = %d\n", sarea_priv->last_wrap );
+ clear_bit( 0, &primary->wrap_flag );
+
+#if 0
+ DRM_INFO( " *** wrap interrupt:\n" );
+ DRM_INFO( " head = 0x%06lx\n",
+ head - dev_priv->primary->offset );
+ DRM_INFO( " flush = 0x%06lx\n", primary->last_flush );
+ DRM_INFO( " tail = 0x%06lx %s\n",
+ primary->tail,
+ primary->tail != primary->last_flush + DMA_BLOCK_SIZE
+ ? "***" : "" );
+ DRM_INFO( " wrap = %d\n", sarea_priv->last_wrap );
+#endif
mga_flush_write_combine();
MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
- MGA_WRITE( MGA_PRIMEND, tail | MGA_PRIMNOSTART | MGA_PAGPXFER );
-#if 0
- queue_task( &dev->tq, &tq_immediate );
- mark_bh( IMMEDIATE_BH );
-#endif
+ if ( primary->last_flush > 0 ) {
+ MGA_WRITE( MGA_PRIMEND, flush | MGA_PAGPXFER );
+ }
+
+ spin_unlock( &primary->flush_lock );
}
static int mga_dma_task_queue( void *dev )
@@ -1545,6 +623,9 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
DO_FIND_MAP( dev_priv->status, init->status_offset );
+ DRM_INFO( "status handle = 0x%08lx\n", dev_priv->status->handle );
+ DRM_INFO( "status offset = 0x%08lx\n", dev_priv->status->offset );
+
DO_FIND_MAP( dev_priv->warp, init->warp_offset );
DO_FIND_MAP( dev_priv->primary, init->primary_offset );
DO_FIND_MAP( dev_priv->buffers, init->buffers_offset );
@@ -1571,24 +652,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return ret;
}
-#if 0
- dev_priv->prim.status_page = mga_alloc_page();
- if ( !dev_priv->prim.status_page ) {
- DRM_ERROR( "failed to allocate status page!\n" );
- mga_do_cleanup_dma( dev );
- return -ENOMEM;
- }
- dev_priv->prim.status = (u32 *)dev_priv->prim.status_page;
-
- if ( !dev_priv->prim.status ) {
- DRM_ERROR( "failed to remap status page!\n" );
- mga_do_cleanup_dma( dev );
- return -ENOMEM;
- }
-#endif
- dev_priv->sarea_priv->last_wrap = 0;
-
- dev_priv->prim.status = (u32 *)&dev_priv->status->handle;
+ dev_priv->prim.status = (u32 *)dev_priv->status->handle;
mga_do_wait_for_idle( dev_priv );
@@ -1609,17 +673,24 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
dev_priv->prim.head = &dev_priv->prim.status[0];
dev_priv->prim.tail = 0;
- dev_priv->prim.space = dev_priv->prim.size - MGA_DMA_SOFTRAP_SIZE;
+ dev_priv->prim.space = dev_priv->prim.size;
dev_priv->prim.last_flush = 0;
+ dev_priv->prim.last_wrap = 0;
+ clear_bit( 0, &dev_priv->prim.wrap_flag );
+
dev_priv->prim.high_mark = 0;
- spin_lock_init( &dev_priv->prim.tail_lock );
+ spin_lock_init( &dev_priv->prim.flush_lock );
spin_lock_init( &dev_priv->prim.list_lock );
dev_priv->prim.status[0] = dev_priv->primary->offset;
dev_priv->prim.status[1] = 0;
+ dev_priv->sarea_priv->last_wrap = 0;
+ dev_priv->sarea_priv->last_frame.head = 0;
+ dev_priv->sarea_priv->last_frame.wrap = 0;
+
if ( mga_freelist_init( dev ) < 0 ) {
DRM_ERROR( "could not initialize freelist\n" );
mga_do_cleanup_dma( dev );
@@ -1893,8 +964,7 @@ if ( 0 ) {
DRM_INFO( "sync = 0x%08x\n", dev_priv->prim.status[1] );
DRM_INFO( "\n" );
DRM_INFO( "space = 0x%x / 0x%x\n",
- dev_priv->prim.space,
- dev_priv->prim.size - MGA_DMA_SOFTRAP_SIZE );
+ dev_priv->prim.space, dev_priv->prim.size );
DRM_INFO( "\n" );
DRM_INFO( " irqs = %d\n", atomic_read( &dev->counts[_DRM_STAT_IRQ] ) );
diff --git a/linux/mga_drv.c b/linux/mga_drv.c
index d458afb4..fdba9c5f 100644
--- a/linux/mga_drv.c
+++ b/linux/mga_drv.c
@@ -38,85 +38,23 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20010206"
+#define DRIVER_DATE "20010212"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-/* Now that we do this, we can move the DRM(ioctls) array into a
- * template file and have a DRIVER_IOCTLS block at the end.
- */
-static drm_ioctl_desc_t mga_ioctls[] = {
- [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { mga_version, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { mga_getunique, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { mga_getmagic, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { mga_irq_busid, 0, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { mga_getmap, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { mga_getclient, 0, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { mga_getstats, 0, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { mga_setunique, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { mga_block, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { mga_unblock, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { mga_control, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { mga_authmagic, 1, 1 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { mga_addmap, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { mga_addbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { mga_markbufs, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { mga_infobufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { mga_mapbufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { mga_freebufs, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { mga_addctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { mga_rmctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { mga_modctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { mga_getctx, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { mga_switchctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { mga_newctx, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { mga_resctx, 1, 0 },
-
- [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { mga_adddraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { mga_rmdraw, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { mga_lock, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { mga_unlock, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { mga_finish, 1, 0 },
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { mga_agp_acquire, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { mga_agp_release, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { mga_agp_enable, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { mga_agp_info, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { mga_agp_alloc, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { mga_agp_free, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { mga_agp_bind, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { mga_agp_unbind, 1, 1 },
-#endif
-
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 },
+#define DRIVER_IOCTLS \
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { mga_dma_buffers, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)] = { mga_dma_flush, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)] = { mga_dma_reset, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_dma_swap, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_dma_clear, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_dma_vertex, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 },
-#if 0
- [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices, 1, 0 },
-#endif
-};
-
-#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
-
-#define __HAVE_AGP 1
-#define __MUST_HAVE_AGP 1
-
-#define __HAVE_MTRR 1
-
-#define __HAVE_CTX_BITMAP 1
-#define __HAVE_DMA 1
#define __HAVE_DMA_IRQ 1
#define __HAVE_COUNTERS 3
@@ -137,7 +75,7 @@ do { \
} while (0)
#if 0
-#define __HAVE_DRIVER_RELEASE 1
+#define __HAVE_RELEASE 1
#define DRIVER_RELEASE() do { \
mga_reclaim_buffers( dev, priv->pid ); \
if ( dev->dev_private ) { \
diff --git a/linux/mga_drv.h b/linux/mga_drv.h
index 510ee05b..5b575eb6 100644
--- a/linux/mga_drv.h
+++ b/linux/mga_drv.h
@@ -64,13 +64,15 @@ typedef struct drm_mga_primary_buffer {
u32 tail;
int space;
- unsigned long status_page;
volatile u32 *status;
u32 last_flush;
+ u32 last_wrap;
+ __volatile__ long wrap_flag;
+
u32 high_mark;
- spinlock_t tail_lock;
+ spinlock_t flush_lock;
spinlock_t list_lock;
} drm_mga_primary_buffer_t;
@@ -173,20 +175,11 @@ extern int mga_dma_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int mga_dma_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int mga_dma_indices( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
extern int mga_dma_iload( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-#if 0
-extern int mga_clear_bufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_swap_bufs( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_iload( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_indices( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-#endif
-
/* mga_warp.c */
extern int mga_warp_install_microcode( drm_device_t *dev );
extern int mga_warp_init( drm_device_t *dev );
@@ -201,13 +194,6 @@ extern int mga_warp_init( drm_device_t *dev );
#define MGA_READ( reg ) MGA_DEREF( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
-typedef enum {
- TT_GENERAL,
- TT_BLIT,
- TT_VECTOR,
- TT_VERTEX
-} transferType_t;
-
#define DWGREG0 0x1c00
#define DWGREG0_END 0x1dff
@@ -219,104 +205,6 @@ typedef enum {
#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
-#define MGA_NUM_PRIM_BUFS 8
-
-#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
- int outcount, num_dwords
-
-#define PRIM_OVERFLOW(dev, dev_priv, length) do { \
- drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) { \
- mga_advance_primary(dev); \
- mga_dma_schedule(dev, 1); \
- tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \
- tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
- set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \
- mga_advance_primary(dev); \
- mga_dma_schedule(dev, 1); \
- tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- } \
- if(MGA_VERBOSE) \
- DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \
- dma_ptr = tmp_buf->current_dma_ptr; \
- num_dwords = tmp_buf->num_dwords; \
- phys_head = tmp_buf->phys_head; \
- outcount = 0; \
-} while(0)
-
-#define PRIMGETPTR(dev_priv) do { \
- drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- if(MGA_VERBOSE) \
- DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \
- dma_ptr = tmp_buf->current_dma_ptr; \
- num_dwords = tmp_buf->num_dwords; \
- phys_head = tmp_buf->phys_head; \
- outcount = 0; \
-} while(0)
-
-#define PRIMPTR(prim_buf) do { \
- if(MGA_VERBOSE) \
- DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__); \
- dma_ptr = prim_buf->current_dma_ptr; \
- num_dwords = prim_buf->num_dwords; \
- phys_head = prim_buf->phys_head; \
- outcount = 0; \
-} while(0)
-
-#define PRIMFINISH(prim_buf) do { \
- if (MGA_VERBOSE) { \
- DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \
- if (outcount & 3) \
- DRM_DEBUG(" --- truncation\n"); \
- } \
- prim_buf->num_dwords = num_dwords; \
- prim_buf->current_dma_ptr = dma_ptr; \
-} while(0)
-
-#define PRIMADVANCE(dev_priv) do { \
-drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- if (MGA_VERBOSE) { \
- DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \
- if (outcount & 3) \
- DRM_DEBUG(" --- truncation\n"); \
- } \
- tmp_buf->num_dwords = num_dwords; \
- tmp_buf->current_dma_ptr = dma_ptr; \
-} while (0)
-
-#define PRIMUPDATE(dev_priv) do { \
- drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- tmp_buf->sec_used++; \
-} while (0)
-
-#define AGEBUF(dev_priv, buf_priv) do { \
- drm_mga_prim_buf_t *tmp_buf = \
- dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- buf_priv->my_freelist->age = tmp_buf->prim_age; \
-} while (0)
-
-
-#define PRIMOUTREG(reg, val) do { \
- tempIndex[outcount]=ADRINDEX(reg); \
- dma_ptr[1+outcount] = val; \
- if (MGA_VERBOSE) \
- DRM_DEBUG(" PRIMOUT %d: 0x%x -- 0x%x\n", \
- num_dwords + 1 + outcount, ADRINDEX(reg), val); \
- if( ++outcount == 4) { \
- outcount = 0; \
- dma_ptr[0] = *(unsigned long *)tempIndex; \
- dma_ptr+=5; \
- num_dwords += 5; \
- } \
-}while (0)
-
-
-
/* ================================================================
@@ -349,10 +237,10 @@ do { \
* Primary DMA command stream
*/
-#define MGA_VERBOSE 0
+#define MGA_VERBOSE ( 0 /*dev_priv->prim.space < 0x100*/ )
+
+#define DMA_LOCALS unsigned int write; volatile u8 *prim;
-#define DMA_LOCALS unsigned int write; volatile u8 *prim; \
- unsigned long flags;
#define DMA_BLOCK_SIZE (5 * sizeof(u32))
#define BEGIN_DMA( n ) \
@@ -363,7 +251,8 @@ do { \
DRM_INFO( " space=0x%x req=0x%x\n", \
dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
} \
- if ( dev_priv->prim.space < (int)((n) * DMA_BLOCK_SIZE) ) { \
+ if ( dev_priv->prim.space < (int)((n) * DMA_BLOCK_SIZE + \
+ MGA_DMA_SOFTRAP_SIZE) ) { \
mga_do_dma_wrap( dev_priv ); \
} \
prim = dev_priv->prim.start; \
@@ -382,16 +271,27 @@ do { \
#define ADVANCE_DMA() \
do { \
- dev_priv->prim.space -= (write - dev_priv->prim.tail); \
- spin_lock_irqsave( &dev_priv->prim.tail_lock, flags ); \
dev_priv->prim.tail = write; \
- spin_unlock_irqrestore( &dev_priv->prim.tail_lock, flags ); \
if ( MGA_VERBOSE ) { \
DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \
write, dev_priv->prim.space ); \
} \
} while (0)
+#if 0
+#define FLUSH_DMA() \
+do { \
+ if ( dev_priv->prim.space < (int)(128 * DMA_BLOCK_SIZE + \
+ MGA_DMA_SOFTRAP_SIZE) ) { \
+ mga_do_dma_wrap( dev_priv ); \
+ } else { \
+ mga_do_dma_flush( dev_priv ); \
+ } \
+} while (0)
+#else
+#define FLUSH_DMA() mga_do_dma_flush( dev_priv );
+#endif
+
/* Never use this, always use DMA_BLOCK(...) for primary DMA output.
*/
#define DMA_WRITE( offset, val ) \
diff --git a/linux/mga_state.c b/linux/mga_state.c
index f1328d9e..a3c96aa1 100644
--- a/linux/mga_state.c
+++ b/linux/mga_state.c
@@ -598,7 +598,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev,
ADVANCE_DMA();
#endif
- mga_do_dma_flush( dev_priv );
+ FLUSH_DMA();
}
static void mga_dma_dispatch_swap( drm_device_t *dev )
@@ -611,7 +611,8 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
u32 pitch = dev_priv->front_pitch / dev_priv->fb_cpp;
int i;
DMA_LOCALS;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_DEBUG( "%s:\n", __FUNCTION__ );
+ DRM_DEBUG( " head = 0x%06x\n", *dev_priv->prim.head );
BEGIN_DMA( 2 + nbox );
@@ -645,7 +646,13 @@ static void mga_dma_dispatch_swap( drm_device_t *dev )
ADVANCE_DMA();
- mga_do_dma_flush( dev_priv );
+ sarea_priv->last_frame.head = dev_priv->prim.tail;
+ sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
+
+ DRM_DEBUG( " tail = 0x%06x\n", dev_priv->prim.tail );
+ DRM_DEBUG( " wrap = 0x%06x\n", dev_priv->prim.last_wrap );
+
+ FLUSH_DMA();
}
static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
@@ -695,65 +702,56 @@ static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
mga_freelist_put( dev, buf );
}
- mga_do_dma_flush( dev_priv );
+ FLUSH_DMA();
}
-
-
-#if 0
-
-
-static void mga_dma_dispatch_indices(drm_device_t * dev,
- drm_buf_t * buf,
- unsigned int start, unsigned int end)
+static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
+ unsigned int start, unsigned int end )
{
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;
- unsigned int address = (unsigned int) buf->bus_address;
- int use_agp = PDEA_pagpxfer_enable;
+ u32 address = (u32) buf->bus_address;
int i = 0;
- PRIMLOCALS;
+ DMA_LOCALS;
+ DRM_INFO( __FUNCTION__ ": buf=%d start=%d end=%d\n",
+ buf->idx, start, end );
- if (start != end) {
- /* WARNING: if you change any of the state functions verify
- * these numbers (Overestimating this doesn't hurt).
- */
+ if ( start != end ) {
buf_priv->dispatched = 1;
- PRIM_OVERFLOW(dev, dev_priv,
- (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
- mgaEmitState(dev_priv);
+
+ MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
do {
- if (i < sarea_priv->nbox) {
- mgaEmitClipRect(dev_priv,
- &sarea_priv->boxes[i]);
+ if ( i < sarea_priv->nbox ) {
+ mga_emit_clip_rect( dev_priv,
+ &sarea_priv->boxes[i] );
}
- PRIMGETPTR(dev_priv);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_SETUPADDRESS,
- ((address + start) |
- SETADD_mode_vertlist));
- PRIMOUTREG(MGAREG_SETUPEND,
- ((address + end) | use_agp));
-/* ((address + start + 12) | use_agp)); */
- PRIMADVANCE(dev_priv);
- } while (++i < sarea_priv->nbox);
- }
- if (buf_priv->discard) {
- if (buf_priv->dispatched == 1)
- AGEBUF(dev_priv, buf_priv);
- buf_priv->dispatched = 0;
- mga_freelist_put(dev, buf);
- }
-}
+ BEGIN_DMA( 1 );
+ DMA_BLOCK( MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_SETUPADDRESS, address + start,
+ MGA_SETUPEND, ((address + end) |
+ MGA_PAGPXFER) );
+ ADVANCE_DMA();
+ } while ( ++i < sarea_priv->nbox );
+ }
-#endif
+ if ( buf_priv->discard ) {
+ if ( buf_priv->dispatched == 1 )
+ AGE_BUFFER( buf_priv );
+ buf->pending = 0;
+ buf->used = 0;
+ buf_priv->dispatched = 0;
+
+ mga_freelist_put( dev, buf );
+ }
+ FLUSH_DMA();
+}
/* This copies a 64 byte aligned agp region to the frambuffer with a
* standard blit, the ioctl needs to do checking.
@@ -767,6 +765,9 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
u32 y2;
DMA_LOCALS;
+ DRM_DEBUG( "%s: buf=%d used=%d\n",
+ __FUNCTION__, buf->idx, buf->used );
+
y2 = length / 64;
BEGIN_DMA( 4 );
@@ -793,11 +794,12 @@ static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
ADVANCE_DMA();
-#if 0
AGE_BUFFER( buf_priv );
-#endif
+
buf_priv->discard = 1;
mga_freelist_put( dev, buf );
+
+ FLUSH_DMA();
}
@@ -871,12 +873,6 @@ int mga_dma_vertex( struct inode *inode, struct file *filp,
(drm_mga_vertex_t *)arg,
sizeof(vertex) ) )
return -EFAULT;
-#if 0
- /* HACK: oh well...
- */
- if ( mga_do_wait_for_idle( dev_priv ) < 0 )
- return -EBUSY;
-#endif
buf = dma->buflist[vertex.idx];
buf_priv = buf->dev_private;
@@ -886,10 +882,8 @@ int mga_dma_vertex( struct inode *inode, struct file *filp,
if ( !mga_verify_state( dev_priv ) ) {
if ( vertex.discard ) {
-#if 0
if ( buf_priv->dispatched == 1 )
- AGEBUF(dev_priv, buf_priv);
-#endif
+ AGE_BUFFER( buf_priv );
buf_priv->dispatched = 0;
mga_freelist_put( dev, buf );
}
@@ -901,59 +895,45 @@ int mga_dma_vertex( struct inode *inode, struct file *filp,
return 0;
}
-
-
-#if 0
-
-
-int mga_indices(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+int mga_dma_indices( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- drm_mga_private_t *dev_priv =
- (drm_mga_private_t *) dev->dev_private;
+ drm_mga_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
drm_mga_indices_t indices;
+ DRM_INFO( __FUNCTION__ "\n" );
- if (copy_from_user(&indices,
- (drm_mga_indices_t *)arg, sizeof(indices)))
- return -EFAULT;
+ LOCK_TEST_WITH_RETURN( dev );
- if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("mga_indices called without lock held\n");
- return -EINVAL;
- }
+ if ( copy_from_user( &indices,
+ (drm_mga_indices_t *)arg,
+ sizeof(indices) ) )
+ return -EFAULT;
buf = dma->buflist[indices.idx];
buf_priv = buf->dev_private;
buf_priv->discard = indices.discard;
- if (!mgaVerifyState(dev_priv)) {
- if (indices.discard) {
- if (buf_priv->dispatched == 1)
- AGEBUF(dev_priv, buf_priv);
+ if ( !mga_verify_state( dev_priv ) ) {
+ if ( indices.discard ) {
+ if ( buf_priv->dispatched == 1 )
+ AGE_BUFFER( buf_priv );
buf_priv->dispatched = 0;
- mga_freelist_put(dev, buf);
+ mga_freelist_put( dev, buf );
}
return -EINVAL;
}
- mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
+ mga_dma_dispatch_indices( dev, buf, indices.start, indices.end );
- PRIMUPDATE(dev_priv);
- mga_flush_write_combine();
- mga_dma_schedule(dev, 1);
return 0;
}
-
-#endif
-
-
int mga_dma_iload( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -970,12 +950,9 @@ int mga_dma_iload( struct inode *inode, struct file *filp,
if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) )
return -EFAULT;
-#if 1
- /* HACK: oh well...
- */
+
if ( mga_do_wait_for_idle( dev_priv ) < 0 )
return -EBUSY;
-#endif
buf = dma->buflist[iload.idx];
buf_priv = buf->dev_private;