summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin E Martin <kem@kem.org>2000-04-23 05:32:19 +0000
committerKevin E Martin <kem@kem.org>2000-04-23 05:32:19 +0000
commitb093c88f3884301348c2f5934d4a59e7b61b6905 (patch)
tree20d6f93aff9f9c99a5a0e3fcad1709bba4ab613e
parent7807a9237d457ddefd5c17db206ab3a11ac23d4e (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.c13
-rw-r--r--linux/Makefile.linux18
-rw-r--r--linux/drm.h9
-rw-r--r--linux/r128_bufs.c36
-rw-r--r--linux/r128_dma.c212
-rw-r--r--linux/r128_drm.h9
-rw-r--r--linux/r128_drv.c13
-rw-r--r--linux/r128_drv.h30
-rw-r--r--shared-core/drm.h9
-rw-r--r--shared/drm.h9
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