diff options
author | Kevin E Martin <kem@kem.org> | 2000-04-23 05:32:19 +0000 |
---|---|---|
committer | Kevin E Martin <kem@kem.org> | 2000-04-23 05:32:19 +0000 |
commit | b093c88f3884301348c2f5934d4a59e7b61b6905 (patch) | |
tree | 20d6f93aff9f9c99a5a0e3fcad1709bba4ab613e | |
parent | 7807a9237d457ddefd5c17db206ab3a11ac23d4e (diff) |
- Added unaccelerated CCE ddx driver support
- To enable, add `Option "UseCCEfor2D" "TRUE"' to "Device" section in
XF86Config file
- This fixed missing primitives problem
- Added minimal PCI support (PIO only with no VBs)
- Autodetect PCI cards -- selets CCE PIO mode and disables VBs
- Kernel module will now build without AGP support (for PCI cards only)
- Added BuildXF86DRM to host.def file so that the kernel module is
automatically built
- Fixed potential incorrectly fogged primitives by moving VB flush to
before mode changes
- Fixed initialization of dirty and dirty_context flags
- Fixed clear incorrectly resetting dirty flags
- Fixed timeout with WaitForIdle by separating out EngineFlush call
- Fixed flashing textures problem
- Fixed multiple clients rendering with incorrect HW state
- Fixed VB flush lockup with multiple clients
- Fixed DRIScreenInit failure crash
- Fixed uninitialized palette after VT switch problem
- Fixed the texture corruption problem by initializing endianness in
DP_DATATYPE reg
- Fixed cursor corruption and cursor flashing problems
- Removed "magic numbers" from kernel module
- Added wait_for_idle pixel cache flush in CCE ring buffer mode
- Cleaned up CCE ring buffer wrapping code
-rw-r--r-- | linux-core/r128_drv.c | 13 | ||||
-rw-r--r-- | linux/Makefile.linux | 18 | ||||
-rw-r--r-- | linux/drm.h | 9 | ||||
-rw-r--r-- | linux/r128_bufs.c | 36 | ||||
-rw-r--r-- | linux/r128_dma.c | 212 | ||||
-rw-r--r-- | linux/r128_drm.h | 9 | ||||
-rw-r--r-- | linux/r128_drv.c | 13 | ||||
-rw-r--r-- | linux/r128_drv.h | 30 | ||||
-rw-r--r-- | shared-core/drm.h | 9 | ||||
-rw-r--r-- | shared/drm.h | 9 |
10 files changed, 227 insertions, 131 deletions
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c index c00f2ff8..45ade1de 100644 --- a/linux-core/r128_drv.c +++ b/linux-core/r128_drv.c @@ -38,10 +38,10 @@ EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" #define R128_DESC "r128" -#define R128_DATE "20000415" +#define R128_DATE "20000422" #define R128_MAJOR 0 #define R128_MINOR 0 -#define R128_PATCHLEVEL 4 +#define R128_PATCHLEVEL 5 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -93,6 +93,7 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, +#ifdef DRM_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 }, @@ -101,9 +102,11 @@ static drm_ioctl_desc_t r128_ioctls[] = { [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 [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_eng_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_FLUSH)] = { r128_eng_flush, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_submit_pkt, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_CCEIDL)] = { r128_cce_idle, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_vertex_buf, 1, 0 }, @@ -252,6 +255,7 @@ static int r128_takedown(drm_device_t *dev) dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } +#ifdef DRM_AGP /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *entry; @@ -273,6 +277,7 @@ static int r128_takedown(drm_device_t *dev) dev->agp->acquired = 0; dev->agp->enabled = 0; } +#endif /* Clear vma list (only built for debugging) */ if (dev->vmalist) { @@ -362,6 +367,7 @@ int r128_init(void) drm_mem_init(); drm_proc_init(dev); +#ifdef DRM_AGP dev->agp = drm_agp_init(); #ifdef CONFIG_MTRR @@ -370,6 +376,7 @@ int r128_init(void) MTRR_TYPE_WRCOMB, 1); #endif +#endif if((retcode = drm_ctxbitmap_init(dev))) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); @@ -406,11 +413,13 @@ void r128_cleanup(void) } drm_ctxbitmap_cleanup(dev); r128_takedown(dev); +#ifdef DRM_AGP if (dev->agp) { /* FIXME -- free other information, too */ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } +#endif } int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 5341ee7a..368c3c85 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -32,7 +32,7 @@ # **** End of SMP/MODVERSIONS detection -MODS= gamma.o tdfx.o +MODS= gamma.o tdfx.o r128.o LIBS= libdrm.a PROGS= drmstat @@ -46,6 +46,9 @@ GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) TDFXOBJS= tdfx_drv.o tdfx_context.o TDFXHEADERS= tdfx_drv.h $(DRMHEADERS) +R128OBJS= r128_drv.o r128_dma.o r128_bufs.o r128_context.o +R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) + PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po PROGHEADERS= xf86drm.h $(DRMHEADERS) @@ -115,16 +118,13 @@ endif ifeq ($(AGP),1) MODCFLAGS += -DDRM_AGP DRMOBJS += agpsupport.o -MODS += mga.o i810.o r128.o +MODS += mga.o i810.o MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o MGAHEADERS= mga_drv.h $(DRMHEADERS) I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o I810HEADERS= i810_drv.h $(DRMHEADERS) - -R128OBJS= r128_drv.o r128_dma.o r128_bufs.o r128_context.o -R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) endif all::;@echo KERNEL HEADERS IN $(TREE): SMP=${SMP} MODVERSIONS=${MODVERSIONS} \ @@ -155,15 +155,15 @@ gamma.o: $(GAMMAOBJS) $(LIBS) tdfx.o: $(TDFXOBJS) $(LIBS) $(LD) -r $^ -o $@ +r128.o: $(R128OBJS) $(LIBS) + $(LD) -r $^ -o $@ + ifeq ($(AGP),1) mga.o: $(MGAOBJS) $(LIBS) $(LD) -r $^ -o $@ i810.o: $(I810OBJS) $(LIBS) $(LD) -r $^ -o $@ - -r128.o: $(R128OBJS) $(LIBS) - $(LD) -r $^ -o $@ endif drmstat: $(PROGOBJS) @@ -187,10 +187,10 @@ ChangeLog: $(DRMOBJS): $(DRMHEADERS) $(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) +$(R128OBJS): $(R128HEADERS) ifeq ($(AGP),1) $(MGAOBJS): $(MGAHEADERS) $(I810OBJS): $(I810HEADERS) -$(R128OBJS): $(R128HEADERS) endif $(PROGOBJS): $(PROGHEADERS) diff --git a/linux/drm.h b/linux/drm.h index fb073e1c..ce07bb61 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Tue Apr 18 16:33:42 2000 by kevin@precisioninsight.com + * Revised: Fri Apr 21 23:56:36 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -353,8 +353,9 @@ typedef struct drm_agp_info { /* Rage 128 specific ioctls */ #define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) #define DRM_IOCTL_R128_RESET DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x42) -#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x43, drm_r128_packet_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x44, drm_r128_vertex_t) +#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42) +#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43) +#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t) #endif diff --git a/linux/r128_bufs.c b/linux/r128_bufs.c index 55a246b1..bad6c571 100644 --- a/linux/r128_bufs.c +++ b/linux/r128_bufs.c @@ -37,6 +37,7 @@ #include "linux/un.h" +#ifdef DRM_AGP int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -182,37 +183,46 @@ int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd, atomic_dec(&dev->buf_alloc); return 0; } +#endif int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - drm_buf_desc_t request; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_buf_desc_t request; + + if (!dev_priv || dev_priv->is_pci) return -EINVAL; copy_from_user_ret(&request, (drm_buf_desc_t *)arg, sizeof(request), -EFAULT); +#ifdef DRM_AGP if (request.flags & _DRM_AGP_BUFFER) return r128_addbufs_agp(inode, filp, cmd, arg); else +#endif return -EINVAL; } int r128_mapbufs(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_device_dma_t *dma = dev->dma; - int retcode = 0; - const int zero = 0; - unsigned long virtual; - unsigned long address; - drm_buf_map_t request; - int i; - - if (!dma) return -EINVAL; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + int retcode = 0; + const int zero = 0; + unsigned long virtual; + unsigned long address; + drm_buf_map_t request; + int i; + + if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL; DRM_DEBUG("\n"); @@ -233,7 +243,7 @@ int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, if (dma->flags & _DRM_DMA_USE_AGP) { drm_map_t *map; - map = dev->maplist[R128_AGP_VERTBUFS()]; + map = dev_priv->agp_vertbufs; if (!map) { retcode = -EINVAL; goto done; diff --git a/linux/r128_dma.c b/linux/r128_dma.c index 13506840..860c4188 100644 --- a/linux/r128_dma.c +++ b/linux/r128_dma.c @@ -37,11 +37,34 @@ #include <linux/delay.h> + +#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) + +#define DO_REMAPFREE(_m) \ + do { \ + if ((_m)->handle && (_m)->size) \ + drm_ioremapfree((_m)->handle, (_m)->size); \ + } while (0) + +#define DO_FIND_MAP(_m, _o) \ + do { \ + int _i; \ + for (_i = 0; _i < dev->map_count; _i++) { \ + if (dev->maplist[_i]->offset == _o) { \ + _m = dev->maplist[_i]; \ + break; \ + } \ + } \ + } while (0) + + #define R128_MAX_VBUF_AGE 0x10000000 #define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0 int R128_READ_PLL(drm_device_t *dev, int addr) { + drm_r128_private_t *dev_priv = dev->dev_private; + R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); return R128_READ(R128_CLOCK_CNTL_DATA); } @@ -67,20 +90,16 @@ static void r128_flush_write_combine(void) static int r128_do_cleanup_cce(drm_device_t *dev) { -#define DO_REMAPFREE(v) \ - do { \ - drm_map_t *_m; \ - _m = dev->maplist[(v)]; \ - if (_m->handle && _m->size) \ - drm_ioremapfree(_m->handle, _m->size); \ - } while (0) - if (dev->dev_private) { - DO_REMAPFREE(R128_AGP_RING()); - DO_REMAPFREE(R128_AGP_READ_PTR()); - DO_REMAPFREE(R128_AGP_VERTBUFS()); - DO_REMAPFREE(R128_AGP_INDIRECTBUFS()); - DO_REMAPFREE(R128_AGP_TEXTURES()); + drm_r128_private_t *dev_priv = dev->dev_private; + + if (!dev_priv->is_pci) { + DO_REMAPFREE(dev_priv->agp_ring); + DO_REMAPFREE(dev_priv->agp_read_ptr); + DO_REMAPFREE(dev_priv->agp_vertbufs); + DO_REMAPFREE(dev_priv->agp_indbufs); + DO_REMAPFREE(dev_priv->agp_textures); + } drm_free(dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER); @@ -93,7 +112,7 @@ static int r128_do_cleanup_cce(drm_device_t *dev) static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init) { drm_r128_private_t *dev_priv; - drm_map_t *map = NULL; + int i; dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) return -ENOMEM; @@ -101,7 +120,9 @@ static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init) memset(dev_priv, 0, sizeof(drm_r128_private_t)); - dev_priv->usec_timeout = init->usec_timeout; + dev_priv->is_pci = init->is_pci; + + dev_priv->usec_timeout = init->usec_timeout; if (dev_priv->usec_timeout < 1 || dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) { drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); @@ -118,33 +139,51 @@ static int r128_do_init_cce(drm_device_t *dev, drm_r128_init_t *init) (init->cce_mode == R128_PM4_64BM_64VCBM_64INDBM)); dev_priv->cce_secure = init->cce_secure; - map = dev->maplist[R128_SAREA()]; - dev_priv->sarea_priv = (drm_r128_sarea_t *)((u8 *)map->handle + - init->sarea_priv_offset); + if (dev_priv->cce_is_bm_mode && dev_priv->is_pci) { + drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); + dev->dev_private = NULL; + return -EINVAL; + } -#define DO_REMAP(v) \ - do { \ - drm_map_t *_m; \ - _m = dev->maplist[(v)]; \ - _m->handle = drm_ioremap(_m->offset, _m->size); \ - } while (0) + for (i = 0; i < dev->map_count; i++) { + if (dev->maplist[i]->type == _DRM_SHM) { + dev_priv->sarea = dev->maplist[i]; + break; + } + } - DO_REMAP(R128_AGP_RING()); - DO_REMAP(R128_AGP_READ_PTR()); - DO_REMAP(R128_AGP_VERTBUFS()); + DO_FIND_MAP(dev_priv->fb, init->fb_offset); + if (!dev_priv->is_pci) { + DO_FIND_MAP(dev_priv->agp_ring, init->agp_ring_offset); + DO_FIND_MAP(dev_priv->agp_read_ptr, init->agp_read_ptr_offset); + DO_FIND_MAP(dev_priv->agp_vertbufs, init->agp_vertbufs_offset); + DO_FIND_MAP(dev_priv->agp_indbufs, init->agp_indbufs_offset); + DO_FIND_MAP(dev_priv->agp_textures, init->agp_textures_offset); + } + DO_FIND_MAP(dev_priv->mmio, init->mmio_offset); + + dev_priv->sarea_priv = + (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if (!dev_priv->is_pci) { + DO_REMAP(dev_priv->agp_ring); + DO_REMAP(dev_priv->agp_read_ptr); + DO_REMAP(dev_priv->agp_vertbufs); #if 0 - DO_REMAP(R128_AGP_INDIRECTBUFS()); - DO_REMAP(R128_AGP_TEXTURES()); + DO_REMAP(dev_priv->agp_indirectbufs); + DO_REMAP(dev_priv->agp_textures); #endif - dev_priv->ring_size = init->ring_size; - dev_priv->ring_sizel2qw = drm_order(init->ring_size/8); - dev_priv->ring_entries = init->ring_size/sizeof(u32); - dev_priv->ring_read_ptr = (__volatile__ u32 *) - dev->maplist[R128_AGP_READ_PTR()]->handle; - dev_priv->ring_start = (u32 *)dev->maplist[R128_AGP_RING()]->handle; - dev_priv->ring_end = ((u32 *)dev->maplist[R128_AGP_RING()]->handle - + dev_priv->ring_entries); + dev_priv->ring_size = init->ring_size; + dev_priv->ring_sizel2qw = drm_order(init->ring_size/8); + dev_priv->ring_entries = init->ring_size/sizeof(u32); + dev_priv->ring_read_ptr = ((__volatile__ u32 *) + dev_priv->agp_read_ptr->handle); + dev_priv->ring_start = (u32 *)dev_priv->agp_ring->handle; + dev_priv->ring_end = ((u32 *)dev_priv->agp_ring->handle + + dev_priv->ring_entries); + } dev_priv->submit_age = 0; R128_WRITE(R128_VB_AGE_REG, dev_priv->submit_age); @@ -184,7 +223,7 @@ static void r128_mark_vertbufs_done(drm_device_t *dev) } } -static int r128_do_engine_flush(drm_device_t *dev) +static int r128_do_pixcache_flush(drm_device_t *dev) { drm_r128_private_t *dev_priv = dev->dev_private; u32 tmp; @@ -224,7 +263,7 @@ static int r128_do_wait_for_idle(drm_device_t *dev) for (i = 0; i < dev_priv->usec_timeout; i++) { if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) { - r128_do_engine_flush(dev); + (void)r128_do_pixcache_flush(dev); return 0; } udelay(1); @@ -237,7 +276,7 @@ int r128_do_engine_reset(drm_device_t *dev) drm_r128_private_t *dev_priv = dev->dev_private; u32 clock_cntl_index, mclk_cntl, gen_reset_cntl; - (void)r128_do_engine_flush(dev); + (void)r128_do_pixcache_flush(dev); clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX); mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL); @@ -290,6 +329,32 @@ int r128_eng_reset(struct inode *inode, struct file *filp, return r128_do_engine_reset(dev); } +static int r128_do_engine_flush(drm_device_t *dev) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + u32 tmp; + + tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR); + R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp | R128_PM4_BUFFER_DL_DONE); + + return 0; +} + +int r128_eng_flush(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; + + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || + dev->lock.pid != current->pid) { + DRM_ERROR("r128_eng_flush called without holding the lock\n"); + return -EINVAL; + } + + return r128_do_engine_flush(dev); +} + static int r128_do_cce_wait_for_fifo(drm_device_t *dev, int entries) { drm_r128_private_t *dev_priv = dev->dev_private; @@ -309,17 +374,12 @@ int r128_do_cce_wait_for_idle(drm_device_t *dev) int i; if (dev_priv->cce_is_bm_mode) { - u32 tmp; - tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR); - R128_WRITE(R128_PM4_BUFFER_DL_WPTR, - tmp | R128_PM4_BUFFER_DL_DONE); - for (i = 0; i < dev_priv->usec_timeout; i++) { if (*dev_priv->ring_read_ptr == dev_priv->sarea_priv->ring_write) { int pm4stat = R128_READ(R128_PM4_STAT); if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size && !(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { - return 0; + return r128_do_pixcache_flush(dev); } } udelay(1); @@ -332,7 +392,7 @@ int r128_do_cce_wait_for_idle(drm_device_t *dev) for (i = 0; i < dev_priv->usec_timeout; i++) { int pm4stat = R128_READ(R128_PM4_STAT); if (!(pm4stat & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { - return r128_do_engine_flush(dev); + return r128_do_pixcache_flush(dev); } udelay(1); } @@ -362,7 +422,6 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, int write = dev_priv->sarea_priv->ring_write; int *write_ptr = dev_priv->ring_start + write; int c = *count; - int wrapped = 0; u32 tmp = 0; int psize = 0; int writing = 1; @@ -408,7 +467,6 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, if (write >= dev_priv->ring_entries) { write = 0; write_ptr = dev_priv->ring_start; - wrapped = 1; } timeout = 0; while (write == *dev_priv->ring_read_ptr) { @@ -420,14 +478,10 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, c--; } - if (wrapped) { - int size = write; - - if (size > 32) size = 32; - memcpy(dev_priv->ring_end, - dev_priv->ring_start, - size * sizeof(u32)); - } + if (write < 32) + memcpy(dev_priv->ring_end, + dev_priv->ring_start, + write * sizeof(u32)); /* Make sure WC cache has been flushed */ r128_flush_write_combine(); @@ -443,11 +497,12 @@ static int r128_submit_packets_ring_secure(drm_device_t *dev, static int r128_submit_packets_pio_secure(drm_device_t *dev, u32 *commands, int *count) { - u32 tmp = 0; - int psize = 0; - int writing = 1; - int addr = R128_PM4_FIFO_DATA_EVEN; - int ret; + drm_r128_private_t *dev_priv = dev->dev_private; + u32 tmp = 0; + int psize = 0; + int writing = 1; + int addr = R128_PM4_FIFO_DATA_EVEN; + int ret; while (*count > 0) { tmp = *commands++; @@ -507,7 +562,6 @@ static int r128_submit_packets_ring(drm_device_t *dev, int write = dev_priv->sarea_priv->ring_write; int *write_ptr = dev_priv->ring_start + write; int c = *count; - int wrapped = 0; int timeout; while (c > 0) { @@ -516,7 +570,6 @@ static int r128_submit_packets_ring(drm_device_t *dev, if (write >= dev_priv->ring_entries) { write = 0; write_ptr = dev_priv->ring_start; - wrapped = 1; } timeout = 0; while (write == *dev_priv->ring_read_ptr) { @@ -528,14 +581,10 @@ static int r128_submit_packets_ring(drm_device_t *dev, c--; } - if (wrapped) { - int size = write; - - if (size > 32) size = 32; - memcpy(dev_priv->ring_end, - dev_priv->ring_start, - size * sizeof(u32)); - } + if (write < 32) + memcpy(dev_priv->ring_end, + dev_priv->ring_start, + write * sizeof(u32)); /* Make sure WC cache has been flushed */ r128_flush_write_combine(); @@ -551,7 +600,8 @@ static int r128_submit_packets_ring(drm_device_t *dev, static int r128_submit_packets_pio(drm_device_t *dev, u32 *commands, int *count) { - int ret; + drm_r128_private_t *dev_priv = dev->dev_private; + int ret; while (*count > 1) { if ((ret = r128_do_cce_wait_for_fifo(dev, 2)) < 0) return ret; @@ -807,11 +857,12 @@ static int r128_get_vertbufs(drm_device_t *dev, drm_r128_vertex_t *v) int r128_vertex_buf(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_device_dma_t *dma = dev->dma; - int retcode = 0; - drm_r128_vertex_t v; + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_r128_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + int retcode = 0; + drm_r128_vertex_t v; if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) || dev->lock.pid != current->pid) { @@ -819,6 +870,11 @@ int r128_vertex_buf(struct inode *inode, struct file *filp, unsigned int cmd, return -EINVAL; } + if (!dev_priv || dev_priv->is_pci) { + DRM_ERROR("r128_vertex_buf called with a PCI card\n"); + return -EINVAL; + } + copy_from_user_ret(&v, (drm_r128_vertex_t *)arg, sizeof(v), -EFAULT); DRM_DEBUG("%d: %d send, %d req\n", current->pid, v.send_count, v.request_count); diff --git a/linux/r128_drm.h b/linux/r128_drm.h index 8ec39bd2..fa90d72d 100644 --- a/linux/r128_drm.h +++ b/linux/r128_drm.h @@ -40,11 +40,20 @@ typedef struct drm_r128_init { R128_CLEANUP_CCE = 0x02 } func; int sarea_priv_offset; + int is_pci; int cce_mode; int cce_fifo_size; int cce_secure; int ring_size; int usec_timeout; + + int fb_offset; + int agp_ring_offset; + int agp_read_ptr_offset; + int agp_vertbufs_offset; + int agp_indbufs_offset; + int agp_textures_offset; + int mmio_offset; } drm_r128_init_t; typedef struct drm_r128_packet { diff --git a/linux/r128_drv.c b/linux/r128_drv.c index c00f2ff8..45ade1de 100644 --- a/linux/r128_drv.c +++ b/linux/r128_drv.c @@ -38,10 +38,10 @@ EXPORT_SYMBOL(r128_cleanup); #define R128_NAME "r128" #define R128_DESC "r128" -#define R128_DATE "20000415" +#define R128_DATE "20000422" #define R128_MAJOR 0 #define R128_MINOR 0 -#define R128_PATCHLEVEL 4 +#define R128_PATCHLEVEL 5 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -93,6 +93,7 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, +#ifdef DRM_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 }, @@ -101,9 +102,11 @@ static drm_ioctl_desc_t r128_ioctls[] = { [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 [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_init_cce, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_eng_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_FLUSH)] = { r128_eng_flush, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_submit_pkt, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_CCEIDL)] = { r128_cce_idle, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_vertex_buf, 1, 0 }, @@ -252,6 +255,7 @@ static int r128_takedown(drm_device_t *dev) dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } +#ifdef DRM_AGP /* Clear AGP information */ if (dev->agp) { drm_agp_mem_t *entry; @@ -273,6 +277,7 @@ static int r128_takedown(drm_device_t *dev) dev->agp->acquired = 0; dev->agp->enabled = 0; } +#endif /* Clear vma list (only built for debugging) */ if (dev->vmalist) { @@ -362,6 +367,7 @@ int r128_init(void) drm_mem_init(); drm_proc_init(dev); +#ifdef DRM_AGP dev->agp = drm_agp_init(); #ifdef CONFIG_MTRR @@ -370,6 +376,7 @@ int r128_init(void) MTRR_TYPE_WRCOMB, 1); #endif +#endif if((retcode = drm_ctxbitmap_init(dev))) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); @@ -406,11 +413,13 @@ void r128_cleanup(void) } drm_ctxbitmap_cleanup(dev); r128_takedown(dev); +#ifdef DRM_AGP if (dev->agp) { /* FIXME -- free other information, too */ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } +#endif } int r128_version(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux/r128_drv.h b/linux/r128_drv.h index aa2a67a2..3b888c49 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -34,6 +34,8 @@ #define _R128_DRV_H_ typedef struct drm_r128_private { + int is_pci; + int cce_mode; int cce_fifo_size; int cce_is_bm_mode; @@ -52,6 +54,15 @@ typedef struct drm_r128_private { int submit_age; int usec_timeout; + + drm_map_t *sarea; + drm_map_t *fb; + drm_map_t *agp_ring; + drm_map_t *agp_read_ptr; + drm_map_t *agp_vertbufs; + drm_map_t *agp_indbufs; + drm_map_t *agp_textures; + drm_map_t *mmio; } drm_r128_private_t; typedef struct drm_r128_buf_priv { @@ -77,6 +88,8 @@ extern int r128_init_cce(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int r128_eng_reset(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); +extern int r128_eng_flush(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); extern int r128_submit_pkt(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int r128_cce_idle(struct inode *inode, struct file *filp, @@ -185,21 +198,8 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); #define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */ -/* WARNING!!! MAGIC NUMBERS!!! The number of regions already added to - the kernel must be specified here. This must match the order the X - server uses for instantiating register regions, or must be passed in - a new ioctl. */ -#define R128_SAREA() 0 -#define R128_FB() 1 -#define R128_AGP_RING() 2 -#define R128_AGP_READ_PTR() 3 -#define R128_AGP_VERTBUFS() 4 -#define R128_AGP_INDIRECTBUFS() 5 -#define R128_AGP_TEXTURES() 6 -#define R128_REG(reg) 7 - -#define R128_BASE(reg) \ - ((u32)((drm_device_t *)dev)->maplist[R128_REG(reg)]->handle) + +#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE(reg) + reg) #define R128_DEREF(reg) *(__volatile__ int *)R128_ADDR(reg) diff --git a/shared-core/drm.h b/shared-core/drm.h index fb073e1c..ce07bb61 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Tue Apr 18 16:33:42 2000 by kevin@precisioninsight.com + * Revised: Fri Apr 21 23:56:36 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -353,8 +353,9 @@ typedef struct drm_agp_info { /* Rage 128 specific ioctls */ #define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) #define DRM_IOCTL_R128_RESET DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x42) -#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x43, drm_r128_packet_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x44, drm_r128_vertex_t) +#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42) +#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43) +#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t) #endif diff --git a/shared/drm.h b/shared/drm.h index fb073e1c..ce07bb61 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -1,6 +1,6 @@ /* drm.h -- Header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com - * Revised: Tue Apr 18 16:33:42 2000 by kevin@precisioninsight.com + * Revised: Fri Apr 21 23:56:36 2000 by kevin@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * All rights reserved. @@ -353,8 +353,9 @@ typedef struct drm_agp_info { /* Rage 128 specific ioctls */ #define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) #define DRM_IOCTL_R128_RESET DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x42) -#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x43, drm_r128_packet_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x44, drm_r128_vertex_t) +#define DRM_IOCTL_R128_FLUSH DRM_IO( 0x42) +#define DRM_IOCTL_R128_CCEIDL DRM_IO( 0x43) +#define DRM_IOCTL_R128_PACKET DRM_IOW( 0x44, drm_r128_packet_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x45, drm_r128_vertex_t) #endif |