summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/Makefile.linux2
-rw-r--r--linux/compat-pre24.h1
-rw-r--r--linux/drm.h5
-rw-r--r--linux/drm_stub.h13
-rw-r--r--linux/mga_dma.c111
-rw-r--r--linux/mga_drv.h13
-rw-r--r--linux/mga_warp.c6
-rw-r--r--linux/r128.h3
-rw-r--r--linux/r128_drv.h15
-rw-r--r--linux/radeon.h1
-rw-r--r--linux/radeon_drv.c2
11 files changed, 124 insertions, 48 deletions
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index 7c1269c6f..d022557d8 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -174,7 +174,7 @@ all::;@echo === SMP=${SMP} MODULES=${MODULES} MODVERSIONS=${MODVERSIONS} AGP=${A
all::;@echo === kill_fasync has $(PARAMS) parameters
all::;@echo === Compiling for machine $(MACHINE)
all::;@echo === WARNING
-all::;@echo === WARNING 2.4.0 kernels before test11 DONT WORK
+all::;@echo === WARNING 2.4.0 kernels before 2.4.0-test11 DO NOT WORK
all::;@echo === WARNING
ifeq ($(MODULES),0)
diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h
index f6dae008d..0ad96b12a 100644
--- a/linux/compat-pre24.h
+++ b/linux/compat-pre24.h
@@ -45,6 +45,7 @@
/* This is a hack that only works for
this code base -- because we always
call this with dev->tq.* */
+#undef INIT_LIST_HEAD
#define INIT_LIST_HEAD(pointer) dev->tq.next = NULL
#endif
diff --git a/linux/drm.h b/linux/drm.h
index 138bfaa6e..30b75e1e3 100644
--- a/linux/drm.h
+++ b/linux/drm.h
@@ -44,11 +44,8 @@
#define DRM_IOCTL_NR(n) ((n) & 0xff)
#endif
-#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID 0
-#define DRM_DEV_GID 0
-
#define DRM_MAJOR 226
+#define DRM_MAX_MINOR 15
#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
diff --git a/linux/drm_stub.h b/linux/drm_stub.h
index a6a39d869..bc9587963 100644
--- a/linux/drm_stub.h
+++ b/linux/drm_stub.h
@@ -31,6 +31,10 @@
#define __NO_VERSION__
#include "drmP.h"
+#if LINUX_VERSION_CODE < 0x020400
+#include "stubsupport-pre24.h"
+#endif
+
#define DRM_STUB_MAXCARDS 16 /* Enough for one machine */
static struct drm_stub_list {
@@ -120,10 +124,13 @@ static int DRM(stub_putminor)(int minor)
int DRM(stub_register)(const char *name, struct file_operations *fops,
drm_device_t *dev)
{
- if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) {
- /* Already registered */
- struct drm_stub_info *i;
+ struct drm_stub_info *i = NULL;
+
+ if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops)))
i = (struct drm_stub_info *)inter_module_get("drm");
+
+ if (i) {
+ /* Already registered */
DRM(stub_info).info_register = i->info_register;
DRM(stub_info).info_unregister = i->info_unregister;
} else {
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index b1491823d..d314a1a8b 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -56,7 +56,10 @@ int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
- if ( status == MGA_ENDPRDMASTS ) return 0;
+ if ( status == MGA_ENDPRDMASTS ) {
+ MGA_WRITE8( MGA_CRTC_INDEX, 0 );
+ return 0;
+ }
udelay( 1 );
}
@@ -80,33 +83,37 @@ int mga_do_dma_idle( drm_mga_private_t *dev_priv )
return -EBUSY;
}
-int mga_do_dma_reset( drm_mga_private_t *dev_priv )
+int mga_do_dma_reset( drm_device_t *dev )
{
+ drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_mga_primary_buffer_t *primary = &dev_priv->prim;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ DRM_INFO( "%s\n", __FUNCTION__ );
/* The primary DMA stream should look like new right about now.
*/
primary->tail = 0;
primary->space = primary->size;
primary->last_flush = 0;
+ primary->last_wrap = 0;
- sarea_priv->last_wrap = 0;
+ primary->status[0] = dev_priv->primary->offset;
+ primary->status[1] = 0;
- /* FIXME: Reset counters, buffer ages etc...
- */
+ sarea_priv->last_wrap = 0;
+ sarea_priv->last_frame.head = 0;
+ sarea_priv->last_frame.wrap = 0;
- /* FIXME: What else do we need to reinitialize? WARP stuff?
- */
+ mga_freelist_reset( dev );
return 0;
}
-int mga_do_engine_reset( drm_mga_private_t *dev_priv )
+int mga_do_engine_reset( drm_device_t *dev )
{
- DRM_DEBUG( "%s\n", __FUNCTION__ );
+ drm_mga_private_t *dev_priv = dev->dev_private;
+ DRM_INFO( "%s\n", __FUNCTION__ );
/* Okay, so we've completely screwed up and locked the engine.
* How about we clean up after ourselves?
@@ -122,19 +129,21 @@ int mga_do_engine_reset( drm_mga_private_t *dev_priv )
* 3D clients should probably die after calling this. The X
* server should reset the engine state to known values.
*/
-#if 0
MGA_WRITE( MGA_PRIMPTR,
- virt_to_bus((void *)dev_priv->prim.status_page) |
- MGA_PRIMPTREN0 |
- MGA_PRIMPTREN1 );
-#endif
-
- MGA_WRITE( MGA_ICLEAR, MGA_SOFTRAPICLR );
- MGA_WRITE( MGA_IEN, MGA_SOFTRAPIEN );
+ virt_to_bus((void *)dev_priv->prim.status) |
+ MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */
+ MGA_PRIMPTREN1 ); /* DWGSYNC */
/* The primary DMA stream should look like new right about now.
*/
- mga_do_dma_reset( dev_priv );
+ mga_do_dma_reset( dev );
+
+ /* Initialize the WARP engine again.
+ */
+ if ( mga_warp_init( dev_priv ) < 0 ) {
+ /* Can we do anything else? */
+ DRM_ERROR( "failed to reinit WARP engine!\n" );
+ }
/* This bad boy will never fail.
*/
@@ -269,7 +278,8 @@ static void mga_freelist_print( drm_device_t *dev )
DRM_INFO( "\n" );
DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
dev_priv->sarea_priv->last_dispatch,
- *dev_priv->prim.head - dev_priv->primary->offset );
+ (unsigned int)(*dev_priv->prim.head -
+ dev_priv->primary->offset) );
DRM_INFO( "current freelist:\n" );
for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
@@ -350,7 +360,6 @@ static void mga_freelist_cleanup( drm_device_t *dev )
static void mga_freelist_reset( drm_device_t *dev )
{
drm_device_dma_t *dma = dev->dma;
- drm_mga_private_t *dev_priv = dev->dev_private;
drm_buf_t *buf;
drm_mga_buf_priv_t *buf_priv;
int i;
@@ -408,15 +417,17 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
dev_priv->primary->offset,
buf_priv->list_entry->age.wrap );
- if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
- SET_AGE( &next->age, MGA_BUFFER_FREE, 0 );
- }
-
/* Put buffer on the head + 1, as the head is a sentinal.
*/
+
next = buf_priv->list_entry;
head = dev_priv->head;
prev = head->next;
+
+ if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
+ SET_AGE( &next->age, MGA_BUFFER_FREE, 0 );
+ }
+
head->next = next;
prev->prev = next;
next->prev = head;
@@ -482,14 +493,14 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
DRM_IOREMAP( dev_priv->primary );
DRM_IOREMAP( dev_priv->buffers );
- ret = mga_warp_install_microcode( dev );
+ ret = mga_warp_install_microcode( dev_priv );
if ( ret < 0 ) {
DRM_ERROR( "failed to install WARP ucode!\n" );
mga_do_cleanup_dma( dev );
return ret;
}
- ret = mga_warp_init( dev );
+ ret = mga_warp_init( dev_priv );
if ( ret < 0 ) {
DRM_ERROR( "failed to init WARP engine!\n" );
mga_do_cleanup_dma( dev );
@@ -539,6 +550,49 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
return -ENOMEM;
}
+
+ if ( 0 ) {
+ drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+ u32 tail;
+ DMA_LOCALS;
+
+ BEGIN_DMA( 4 );
+
+ DMA_BLOCK( MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000 );
+
+ DMA_BLOCK( MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000 );
+
+ DMA_BLOCK( MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000 );
+
+ DMA_BLOCK( MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000,
+ MGA_DMAPAD, 0x00000000 );
+
+ ADVANCE_DMA();
+
+ tail = primary->tail + dev_priv->primary->offset - 4096;
+
+ mga_flush_write_combine();
+ MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
+
+
+ if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
+ DRM_INFO( "cool, we're fucked!\n" );
+ mga_do_engine_reset( dev );
+ }
+ }
+
+
return 0;
}
@@ -627,11 +681,10 @@ int mga_dma_reset( struct inode *inode, struct file *filp,
{
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;
LOCK_TEST_WITH_RETURN( dev );
- return mga_do_dma_reset( dev_priv );
+ return mga_do_dma_reset( dev );
}
diff --git a/linux/mga_drv.h b/linux/mga_drv.h
index be7298df9..349a9c64c 100644
--- a/linux/mga_drv.h
+++ b/linux/mga_drv.h
@@ -114,8 +114,9 @@ extern int mga_dma_buffers( struct inode *inode, struct file *filp,
extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
-extern int mga_do_dma_reset( drm_mga_private_t *dev_priv );
-extern int mga_do_engine_reset( drm_mga_private_t *dev_priv );
+
+extern int mga_do_dma_reset( drm_device_t *dev );
+extern int mga_do_engine_reset( drm_device_t *dev );
extern int mga_do_cleanup_dma( drm_device_t *dev );
extern void mga_do_dma_flush( drm_mga_private_t *dev_priv );
@@ -140,8 +141,8 @@ extern int mga_dma_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* mga_warp.c */
-extern int mga_warp_install_microcode( drm_device_t *dev );
-extern int mga_warp_init( drm_device_t *dev );
+extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
+extern int mga_warp_init( drm_mga_private_t *dev_priv );
#define mga_flush_write_combine() mb()
@@ -152,7 +153,8 @@ extern int mga_warp_init( drm_device_t *dev );
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
#define MGA_READ( reg ) MGA_DEREF( reg )
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
-
+#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
+#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
#define DWGREG0 0x1c00
#define DWGREG0_END 0x1dff
@@ -316,6 +318,7 @@ do { \
/* A reduced set of the mga registers.
*/
+#define MGA_CRTC_INDEX 0x1fd4
#define MGA_ALPHACTRL 0x2c7c
#define MGA_AR0 0x1c60
diff --git a/linux/mga_warp.c b/linux/mga_warp.c
index 5994ab0c0..436e24f5d 100644
--- a/linux/mga_warp.c
+++ b/linux/mga_warp.c
@@ -160,9 +160,8 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
return 0;
}
-int mga_warp_install_microcode( drm_device_t *dev )
+int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
{
- drm_mga_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
switch ( dev_priv->chipset ) {
@@ -177,9 +176,8 @@ int mga_warp_install_microcode( drm_device_t *dev )
#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
-int mga_warp_init( drm_device_t *dev )
+int mga_warp_init( drm_mga_private_t *dev_priv )
{
- drm_mga_private_t *dev_priv = dev->dev_private;
u32 wmisc;
DRM_DEBUG( "%s\n", __FUNCTION__ );
diff --git a/linux/r128.h b/linux/r128.h
index 2f045534d..83e002afa 100644
--- a/linux/r128.h
+++ b/linux/r128.h
@@ -60,11 +60,14 @@
*/
#define __HAVE_DMA 1
+#if 0
+/* GH: Remove this for now... */
#define __HAVE_DMA_QUIESCENT 1
#define DRIVER_DMA_QUIESCENT() do { \
drm_r128_private_t *dev_priv = dev->dev_private; \
return r128_do_cce_idle( dev_priv ); \
} while (0)
+#endif
/* Buffer customization:
*/
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index ba11f5b48..9f53746f8 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -454,7 +454,8 @@ do { \
#define R128_VERBOSE 0
-#define RING_LOCALS int write; unsigned int tail_mask; volatile u32 *ring;
+#define RING_LOCALS \
+ int write; unsigned int tail_mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
@@ -470,11 +471,23 @@ do { \
tail_mask = dev_priv->ring.tail_mask; \
} while (0)
+/* You can set this to zero if you want. If the card locks up, you'll
+ * need to keep this set. It works around a bug in early revs of the
+ * Rage 128 chipset, where the CCE would read 32 dwords past the end of
+ * the ring buffer before wrapping around.
+ */
+#define R128_BROKEN_CCE 1
+
#define ADVANCE_RING() do { \
if ( R128_VERBOSE ) { \
DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
+ if ( R128_BROKEN_CCE && write < 32 ) { \
+ memcpy( dev_priv->ring.end, \
+ dev_priv->ring.start, \
+ write * sizeof(u32) ); \
+ } \
r128_flush_write_combine(); \
dev_priv->ring.tail = write; \
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); \
diff --git a/linux/radeon.h b/linux/radeon.h
index ee27a9d6d..db238b1b4 100644
--- a/linux/radeon.h
+++ b/linux/radeon.h
@@ -61,6 +61,7 @@
#define __HAVE_DMA 1
#if 0
+/* GH: Remove this for now... */
#define __HAVE_DMA_QUIESCENT 1
#define DRIVER_DMA_QUIESCENT() do { \
drm_radeon_private_t *dev_priv = dev->dev_private; \
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 3bd921757..7d23859d9 100644
--- a/linux/radeon_drv.c
+++ b/linux/radeon_drv.c
@@ -36,7 +36,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20010216"
+#define DRIVER_DATE "20010301"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0