diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/Makefile.linux | 2 | ||||
-rw-r--r-- | linux/compat-pre24.h | 1 | ||||
-rw-r--r-- | linux/drm.h | 5 | ||||
-rw-r--r-- | linux/drm_stub.h | 13 | ||||
-rw-r--r-- | linux/mga_dma.c | 111 | ||||
-rw-r--r-- | linux/mga_drv.h | 13 | ||||
-rw-r--r-- | linux/mga_warp.c | 6 | ||||
-rw-r--r-- | linux/r128.h | 3 | ||||
-rw-r--r-- | linux/r128_drv.h | 15 | ||||
-rw-r--r-- | linux/radeon.h | 1 | ||||
-rw-r--r-- | linux/radeon_drv.c | 2 |
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 |