summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin E Martin <kem@kem.org>2001-03-07 21:47:43 +0000
committerKevin E Martin <kem@kem.org>2001-03-07 21:47:43 +0000
commit5d66ea4fb42214c09449bb4a45c359440757ae5c (patch)
treee7baf1af0f35b1e1277d2cb535390a31c7d4de20
parent7e820fc7d89d06a11f448d7093469a0c765a84a6 (diff)
- Merge from trunk into branchsarea-1-0-0-20010307
-rw-r--r--libdrm/xf86drm.c382
-rw-r--r--linux-core/drmP.h103
-rw-r--r--linux-core/drm_agpsupport.c2
-rw-r--r--linux-core/drm_bufs.c23
-rw-r--r--linux-core/drm_context.c382
-rw-r--r--linux-core/drm_dma.c182
-rw-r--r--linux-core/drm_drv.c11
-rw-r--r--linux-core/drm_fops.c44
-rw-r--r--linux-core/drm_memory.h4
-rw-r--r--linux-core/drm_proc.c6
-rw-r--r--linux-core/drm_stub.c22
-rw-r--r--linux-core/i810_dma.c139
-rw-r--r--linux-core/i810_drv.c24
-rw-r--r--linux-core/i810_drv.h18
-rw-r--r--linux-core/mga_drv.c26
-rw-r--r--linux-core/r128_drv.c34
-rw-r--r--linux-core/radeon_drv.c36
-rw-r--r--linux-core/tdfx_drv.c6
-rw-r--r--linux/Makefile.linux72
-rw-r--r--linux/compat-pre24.h1
-rw-r--r--linux/drm.h7
-rw-r--r--linux/drmP.h103
-rw-r--r--linux/drm_agpsupport.h2
-rw-r--r--linux/drm_bufs.h23
-rw-r--r--linux/drm_context.h382
-rw-r--r--linux/drm_dma.h182
-rw-r--r--linux/drm_drv.h11
-rw-r--r--linux/drm_fops.h44
-rw-r--r--linux/drm_lists.h5
-rw-r--r--linux/drm_memory.h4
-rw-r--r--linux/drm_proc.h6
-rw-r--r--linux/drm_stub.h22
-rw-r--r--linux/gamma.h93
-rw-r--r--linux/gamma_context.c319
-rw-r--r--linux/gamma_dma.c247
-rw-r--r--linux/gamma_drm.c33
-rw-r--r--linux/gamma_drm.h41
-rw-r--r--linux/gamma_drv.c62
-rw-r--r--linux/gamma_drv.h67
-rw-r--r--linux/i810.h68
-rw-r--r--linux/i810_dma.c139
-rw-r--r--linux/i810_drv.c24
-rw-r--r--linux/i810_drv.h18
-rw-r--r--linux/mga.h25
-rw-r--r--linux/mga_dma.c17
-rw-r--r--linux/mga_drv.c26
-rw-r--r--linux/mga_drv.h17
-rw-r--r--linux/r128.h37
-rw-r--r--linux/r128_cce.c2
-rw-r--r--linux/r128_drm.h3
-rw-r--r--linux/r128_drv.c34
-rw-r--r--linux/r128_drv.h25
-rw-r--r--linux/r128_state.c1
-rw-r--r--linux/radeon.h37
-rw-r--r--linux/radeon_cp.c55
-rw-r--r--linux/radeon_drm.h21
-rw-r--r--linux/radeon_drv.c36
-rw-r--r--linux/radeon_drv.h95
-rw-r--r--linux/radeon_state.c234
-rw-r--r--linux/tdfx.h2
-rw-r--r--linux/tdfx_drv.c6
-rw-r--r--shared-core/drm.h7
-rw-r--r--shared/drm.h7
-rw-r--r--tests/dristat.c239
64 files changed, 2139 insertions, 2206 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index f5184020..a640d598 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -81,7 +81,18 @@ extern unsigned long _bus_base(void);
#include "xf86drm.h"
#include "drm.h"
-#define DRM_FIXED_DEVICE_MAJOR 145
+#ifndef DRM_MAJOR
+#define DRM_MAJOR 226 /* Linux */
+#endif
+
+#ifndef __linux__
+#undef DRM_MAJOR
+#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */
+#endif
+
+#ifndef DRM_MAX_MINOR
+#define DRM_MAX_MINOR 16
+#endif
#ifdef __linux__
#include <sys/sysmacros.h> /* for makedev() */
@@ -161,93 +172,108 @@ static drmHashEntry *drmGetEntry(int fd)
return entry;
}
-/* drm_open is used to open the /dev/dri device */
-
-static int drm_open(const char *file)
-{
- int fd = open(file, O_RDWR, 0);
-
- if (fd >= 0) return fd;
- return -errno;
-}
-
-static int drmOpenDevice(const char *path, long dev,
- mode_t mode, uid_t user, gid_t group)
+static int drmOpenDevice(long dev, int minor)
{
#ifdef XFree86LOADER
struct xf86stat st;
#else
struct stat st;
#endif
+ char buf[64];
+ int fd;
+ mode_t dirmode = DRM_DEV_DIRMODE;
+ mode_t devmode = DRM_DEV_MODE;
+ int isroot = !geteuid();
+#if defined(XFree86Server)
+ uid_t user = DRM_DEV_UID;
+ gid_t group = DRM_DEV_GID;
+#endif
- /* Fiddle mode to remove execute bits */
- mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+#if defined(XFree86Server)
+ devmode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
+ dirmode = (devmode & S_IRUSR) ? S_IXUSR : 0;
+ dirmode |= (devmode & S_IRGRP) ? S_IXGRP : 0;
+ dirmode |= (devmode & S_IROTH) ? S_IXOTH : 0;
+ dirmode |= devmode;
+ devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
+ group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID;
+#endif
- if (!stat(path, &st) && st.st_rdev == dev) {
- if (!geteuid()) {
- chown(path, user, group);
- chmod(path, mode);
- }
- return drm_open(path);
+ if (stat(DRM_DIR_NAME, &st)) {
+ if (!isroot) return DRM_ERR_NOT_ROOT;
+ remove(DRM_DIR_NAME);
+ mkdir(DRM_DIR_NAME, dirmode);
}
+#if defined(XFree86Server)
+ chown(DRM_DIR_NAME, user, group);
+ chmod(DRM_DIR_NAME, dirmode);
+#endif
- if (geteuid()) return DRM_ERR_NOT_ROOT;
- remove(path);
- if (mknod(path, S_IFCHR, dev)) {
- remove(path);
- return DRM_ERR_NOT_ROOT;
+ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+ if (stat(buf, &st) || st.st_rdev != dev) {
+ if (!isroot) return DRM_ERR_NOT_ROOT;
+ remove(buf);
+ mknod(buf, S_IFCHR | devmode, dev);
}
- chown(path, user, group);
- chmod(path, mode);
- return drm_open(path);
+#if defined(XFree86Server)
+ chown(buf, user, group);
+ chmod(buf, devmode);
+#endif
+
+ if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+ remove(buf);
+ return -errno;
}
-/* drmAvailable looks for /proc/dri, and returns 1 if it is present. On
- OSs that do not have a Linux-like /proc, this information will not be
- available, and we'll have to create a device and check if the driver is
- loaded that way. */
+int drmOpenMinor(int minor, int create)
+{
+ int fd;
+ char buf[64];
+
+ if (create) return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
+
+ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+ if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+ return -errno;
+}
+
+/* drmAvailable looks for (DRM_MAJOR, 0) and returns 1 if it returns
+ information for DRM_IOCTL_VERSION. For backward compatibility with
+ older Linux implementations, /proc/dri is also checked. */
int drmAvailable(void)
{
- char dev_name[64];
drmVersionPtr version;
int retval = 0;
int fd;
- if (!access("/proc/dri/0", R_OK)) return 1;
-
- sprintf(dev_name, "/dev/dri-temp-%d", getpid());
-
- remove(dev_name);
- if ((fd = drmOpenDevice(dev_name, makedev(DRM_FIXED_DEVICE_MAJOR, 0),
- S_IRUSR, geteuid(), getegid())) >= 0) {
- /* Read version to make sure this is
- actually a DRI device. */
- if ((version = drmGetVersion(fd))) {
- retval = 1;
- drmFreeVersion(version);
- }
- close(fd);
+ if ((fd = drmOpenMinor(0, 1)) < 0) {
+ /* Try proc for backward Linux compatibility */
+ if (!access("/proc/dri/0", R_OK)) return 1;
+ return 0;
}
- remove(dev_name);
+
+ if ((version = drmGetVersion(fd))) {
+ retval = 1;
+ drmFreeVersion(version);
+ }
+ close(fd);
return retval;
}
static int drmOpenByBusid(const char *busid)
{
- int i;
- char dev_name[64];
- char *buf;
- int fd;
-
- for (i = 0; i < 8; i++) {
- sprintf(dev_name, "/dev/dri/card%d", i);
- if ((fd = drm_open(dev_name)) >= 0) {
+ int i;
+ int fd;
+ const char *buf;
+
+ for (i = 0; i < DRM_MAX_MINOR; i++) {
+ if ((fd = drmOpenMinor(i, 0)) >= 0) {
buf = drmGetBusid(fd);
if (buf && !strcmp(buf, busid)) {
- drmFreeBusid(buf);
- return fd;
+ drmFreeBusid(buf);
+ return fd;
}
if (buf) drmFreeBusid(buf);
close(fd);
@@ -258,54 +284,43 @@ static int drmOpenByBusid(const char *busid)
static int drmOpenByName(const char *name)
{
- int i;
- char proc_name[64];
- char dev_name[64];
- char buf[512];
- mode_t mode = DRM_DEV_MODE;
- mode_t dirmode;
- gid_t group = DRM_DEV_GID;
- uid_t user = DRM_DEV_UID;
- int fd;
- char *pt;
- char *driver = NULL;
- char *devstring;
- long dev = 0;
- int retcode;
-
-#if defined(XFree86Server)
- mode = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
- group = (xf86ConfigDRI.group >= 0) ? xf86ConfigDRI.group : DRM_DEV_GID;
-#endif
-
-#if defined(XFree86Server)
+ int i;
+ int fd;
+ drmVersionPtr version;
+
if (!drmAvailable()) {
+#if !defined(XFree86Server)
+ return -1;
+#else
/* try to load the kernel module now */
if (!xf86LoadKernelModule(name)) {
ErrorF("[drm] failed to load kernel module \"%s\"\n",
name);
return -1;
}
- }
-#else
- if (!drmAvailable())
- return -1;
#endif
+ }
- if (!geteuid()) {
- dirmode = mode;
- if (dirmode & S_IRUSR) dirmode |= S_IXUSR;
- if (dirmode & S_IRGRP) dirmode |= S_IXGRP;
- if (dirmode & S_IROTH) dirmode |= S_IXOTH;
- dirmode &= ~(S_IWGRP | S_IWOTH);
- mkdir("/dev/dri", 0);
- chown("/dev/dri", user, group);
- chmod("/dev/dri", dirmode);
+ for (i = 0; i < DRM_MAX_MINOR; i++) {
+ if ((fd = drmOpenMinor(i, 1)) >= 0) {
+ if ((version = drmGetVersion(fd))) {
+ if (!strcmp(version->name, name)) {
+ drmFreeVersion(version);
+ return fd;
+ }
+ drmFreeVersion(version);
+ }
+ }
}
+#ifdef __linux__
+ /* Backward-compatibility /proc support */
for (i = 0; i < 8; i++) {
+ char proc_name[64], buf[512];
+ char *driver, *pt, *devstring;
+ int retcode;
+
sprintf(proc_name, "/proc/dri/%d/name", i);
- sprintf(dev_name, "/dev/dri/card%d", i);
if ((fd = open(proc_name, 0, 0)) >= 0) {
retcode = read(fd, buf, sizeof(buf)-1);
close(fd);
@@ -319,34 +334,17 @@ static int drmOpenByName(const char *name)
for (devstring = ++pt; *pt && *pt != ' '; ++pt)
;
if (*pt) { /* Found busid */
- return drmOpenByBusid(++pt);
+ return drmOpenByBusid(++pt);
} else { /* No busid */
- dev = strtol(devstring, NULL, 0);
- return drmOpenDevice(dev_name, dev,
- mode, user, group);
+ return drmOpenDevice(strtol(devstring, NULL, 0),i);
}
}
}
}
- } else {
- drmVersionPtr version;
- /* /proc/dri not available, possibly
- because we aren't on a Linux system.
- So, try to create the next device and
- see if it's active. */
- dev = makedev(DRM_FIXED_DEVICE_MAJOR, i);
- if ((fd = drmOpenDevice(dev_name, dev, mode, user, group))) {
- if ((version = drmGetVersion(fd))) {
- if (!strcmp(version->name, name)) {
- drmFreeVersion(version);
- return fd;
- }
- drmFreeVersion(version);
- }
- }
- remove(dev_name);
}
}
+#endif
+
return -1;
}
@@ -1123,6 +1121,160 @@ int drmGetContextPrivateMapping(int fd, drmContext ctx_id, drmHandlePtr handle)
return 0;
}
+int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
+ drmMapType *type, drmMapFlags *flags, drmHandle *handle,
+ int *mtrr)
+{
+ drm_map_t map;
+
+ map.offset = idx;
+ if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+ *offset = map.offset;
+ *size = map.size;
+ *type = map.type;
+ *flags = map.flags;
+ *handle = (unsigned long)map.handle;
+ *mtrr = map.mtrr;
+ return 0;
+}
+
+int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
+ unsigned long *magic, unsigned long *iocs)
+{
+ drm_client_t client;
+
+ client.idx = idx;
+ if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+ *auth = client.auth;
+ *pid = client.pid;
+ *uid = client.uid;
+ *magic = client.magic;
+ *iocs = client.iocs;
+ return 0;
+}
+
+int drmGetStats(int fd, drmStatsT *stats)
+{
+ drm_stats_t s;
+ int i;
+
+ if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+
+ stats->count = 0;
+ memset(stats, 0, sizeof(*stats));
+ if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
+ return -1;
+
+#define SET_VALUE \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%8.8s"; \
+ stats->data[i].isvalue = 1; \
+ stats->data[i].verbose = 0
+
+#define SET_COUNT \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%5.5s"; \
+ stats->data[i].isvalue = 0; \
+ stats->data[i].mult_names = "kgm"; \
+ stats->data[i].mult = 1000; \
+ stats->data[i].verbose = 0
+
+#define SET_BYTE \
+ stats->data[i].long_format = "%-20.20s"; \
+ stats->data[i].rate_format = "%5.5s"; \
+ stats->data[i].isvalue = 0; \
+ stats->data[i].mult_names = "KGM"; \
+ stats->data[i].mult = 1024; \
+ stats->data[i].verbose = 0
+
+
+ stats->count = s.count;
+ for (i = 0; i < s.count; i++) {
+ stats->data[i].value = s.data[i].value;
+ switch (s.data[i].type) {
+ case _DRM_STAT_LOCK:
+ stats->data[i].long_name = "Lock";
+ stats->data[i].rate_name = "Lock";
+ SET_VALUE;
+ break;
+ case _DRM_STAT_OPENS:
+ stats->data[i].long_name = "Opens";
+ stats->data[i].rate_name = "O";
+ SET_COUNT;
+ stats->data[i].verbose = 1;
+ break;
+ case _DRM_STAT_CLOSES:
+ stats->data[i].long_name = "Closes";
+ stats->data[i].rate_name = "Lock";
+ SET_COUNT;
+ stats->data[i].verbose = 1;
+ break;
+ case _DRM_STAT_IOCTLS:
+ stats->data[i].long_name = "Ioctls";
+ stats->data[i].rate_name = "Ioc/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_LOCKS:
+ stats->data[i].long_name = "Locks";
+ stats->data[i].rate_name = "Lck/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_UNLOCKS:
+ stats->data[i].long_name = "Unlocks";
+ stats->data[i].rate_name = "Unl/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_IRQ:
+ stats->data[i].long_name = "IRQs";
+ stats->data[i].rate_name = "IRQ/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_PRIMARY:
+ stats->data[i].long_name = "Primary Bytes";
+ stats->data[i].rate_name = "PB/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_SECONDARY:
+ stats->data[i].long_name = "Secondary Bytes";
+ stats->data[i].rate_name = "SB/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_DMA:
+ stats->data[i].long_name = "DMA";
+ stats->data[i].rate_name = "DMA/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_SPECIAL:
+ stats->data[i].long_name = "Special DMA";
+ stats->data[i].rate_name = "dma/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_MISSED:
+ stats->data[i].long_name = "Miss";
+ stats->data[i].rate_name = "Ms/s";
+ SET_COUNT;
+ break;
+ case _DRM_STAT_VALUE:
+ stats->data[i].long_name = "Value";
+ stats->data[i].rate_name = "Value";
+ SET_VALUE;
+ break;
+ case _DRM_STAT_BYTE:
+ stats->data[i].long_name = "Bytes";
+ stats->data[i].rate_name = "B/s";
+ SET_BYTE;
+ break;
+ case _DRM_STAT_COUNT:
+ default:
+ stats->data[i].long_name = "Count";
+ stats->data[i].rate_name = "Cnt/s";
+ SET_COUNT;
+ break;
+ }
+ }
+ return 0;
+}
+
#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
static void drmSIGIOHandler(int interrupt, void *closure)
{
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 804df409..a7e4d573 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -84,15 +84,24 @@
#ifndef __HAVE_MTRR
#define __HAVE_MTRR 0
#endif
+#ifndef __HAVE_CTX_BITMAP
+#define __HAVE_CTX_BITMAP 0
+#endif
#ifndef __HAVE_DMA
#define __HAVE_DMA 0
#endif
+#ifndef __HAVE_DMA_IRQ
+#define __HAVE_DMA_IRQ 0
+#endif
#ifndef __HAVE_DMA_WAITLIST
#define __HAVE_DMA_WAITLIST 0
#endif
#ifndef __HAVE_DMA_FREELIST
#define __HAVE_DMA_FREELIST 0
#endif
+#ifndef __HAVE_DMA_HISTOGRAM
+#define __HAVE_DMA_HISTOGRAM 0
+#endif
#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
defined(CONFIG_AGP_MODULE)))
@@ -104,7 +113,6 @@
#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
also include looping detection. */
-#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
#define DRM_HASH_SIZE 16 /* Size of key hash table */
#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
@@ -643,7 +651,7 @@ typedef struct drm_device {
struct tq_struct tq;
cycles_t ctx_start;
cycles_t lck_start;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
drm_histogram_t histo;
#endif
@@ -667,9 +675,11 @@ typedef struct drm_device {
} drm_device_t;
- /* Internal function definitions */
+/* ================================================================
+ * Internal function definitions
+ */
- /* Misc. support (init.c) */
+ /* Misc. support (drm_init.h) */
extern int DRM(flags);
extern void DRM(parse_options)( char *s );
extern int DRM(cpu_valid)( void );
@@ -686,7 +696,7 @@ extern int DRM(lock)(struct inode *inode, struct file *filp,
extern int DRM(unlock)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Device support (fops.c) */
+ /* Device support (drm_fops.h) */
extern int DRM(open_helper)(struct inode *inode, struct file *filp,
drm_device_t *dev);
extern int DRM(flush)(struct file *filp);
@@ -698,7 +708,7 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s);
extern unsigned int DRM(poll)(struct file *filp,
struct poll_table_struct *wait);
- /* Mapping support (vm.c) */
+ /* Mapping support (drm_vm.h) */
#if LINUX_VERSION_CODE < 0x020317
extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address,
@@ -728,17 +738,7 @@ extern int DRM(mmap_dma)(struct file *filp,
struct vm_area_struct *vma);
extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
-
- /* Proc support (proc.c) */
-extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev,
- int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry **dev_root);
-extern int drm_proc_cleanup(int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry *dev_root);
-
- /* Memory management support (memory.c) */
+ /* Memory management support (drm_memory.h) */
extern void DRM(mem_init)(void);
extern int DRM(mem_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
@@ -761,7 +761,7 @@ extern int DRM(bind_agp)(agp_memory *handle, unsigned int start);
extern int DRM(unbind_agp)(agp_memory *handle);
#endif
- /* Misc. IOCTL support (ioctl.c) */
+ /* Misc. IOCTL support (drm_ioctl.h) */
extern int DRM(irq_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getunique)(struct inode *inode, struct file *filp,
@@ -775,7 +775,7 @@ extern int DRM(getclient)(struct inode *inode, struct file *filp,
extern int DRM(getstats)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Context IOCTL support (context.c) */
+ /* Context IOCTL support (drm_context.h) */
extern int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(addctx)( struct inode *inode, struct file *filp,
@@ -794,14 +794,24 @@ extern int DRM(rmctx)( struct inode *inode, struct file *filp,
extern int DRM(context_switch)(drm_device_t *dev, int old, int new);
extern int DRM(context_switch_complete)(drm_device_t *dev, int new);
- /* Drawable IOCTL support (drawable.c) */
+#if __HAVE_CTX_BITMAP
+extern int DRM(ctxbitmap_init)( drm_device_t *dev );
+extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
+#endif
+
+extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
+ /* Drawable IOCTL support (drm_drawable.h) */
extern int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(rmdraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Authentication IOCTL support (auth.c) */
+ /* Authentication IOCTL support (drm_auth.h) */
extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv,
drm_magic_t magic);
extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic);
@@ -811,7 +821,7 @@ extern int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Locking IOCTL support (lock.c) */
+ /* Locking IOCTL support (drm_lock.h) */
extern int DRM(block)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(unblock)(struct inode *inode, struct file *filp,
@@ -832,20 +842,13 @@ extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int DRM(notifier)(void *priv);
- /* Context Bitmap support (ctxbitmap.c) */
-extern int DRM(ctxbitmap_init)( drm_device_t *dev );
-extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
-extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-
- /* Buffer management support (bufs.c) */
+ /* Buffer management support (drm_bufs.h) */
extern int DRM(order)( unsigned long size );
extern int DRM(addmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(rmmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+#if __HAVE_DMA
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(infobufs)( struct inode *inode, struct file *filp,
@@ -857,27 +860,37 @@ extern int DRM(freebufs)( struct inode *inode, struct file *filp,
extern int DRM(mapbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-
-#if __HAVE_DMA
- /* DMA support (dma.c) */
+ /* DMA support (drm_dma.h) */
extern int DRM(dma_setup)(drm_device_t *dev);
extern void DRM(dma_takedown)(drm_device_t *dev);
extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid);
+#if __HAVE_OLD_DMA
+/* GH: This is a dirty hack for now...
+ */
extern void DRM(clear_next_buffer)(drm_device_t *dev);
extern int DRM(select_queue)(drm_device_t *dev,
void (*wrapper)(unsigned long));
extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma);
-#if 0
extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
#endif
+#if __HAVE_DMA_IRQ
+extern int DRM(control)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int DRM(irq_install)( drm_device_t *dev, int irq );
+extern int DRM(irq_uninstall)( drm_device_t *dev );
+extern void DRM(dma_service)( int irq, void *device,
+ struct pt_regs *regs );
+#if __HAVE_DMA_IRQ_BH
+extern void DRM(dma_immediate_bh)( void *dev );
+#endif
+#endif
#if DRM_DMA_HISTOGRAM
extern int DRM(histogram_slot)(unsigned long count);
extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf);
#endif
-#endif
- /* Buffer list management support (lists.c) */
+ /* Buffer list support (drm_lists.h) */
#if __HAVE_DMA_WAITLIST
extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count);
extern int DRM(waitlist_destroy)(drm_waitlist_t *bl);
@@ -891,9 +904,10 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
drm_buf_t *buf);
extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
#endif
+#endif /* __HAVE_DMA */
#if __REALLY_HAVE_AGP
- /* AGP/GART support (agpsupport.c) */
+ /* AGP/GART support (drm_agpsupport.h) */
extern drm_agp_head_t *DRM(agp_init)(void);
extern void DRM(agp_uninit)(void);
extern int DRM(agp_acquire)(struct inode *inode, struct file *filp,
@@ -917,6 +931,7 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
extern int DRM(agp_free_memory)(agp_memory *handle);
extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
extern int DRM(agp_unbind_memory)(agp_memory *handle);
+#endif
/* Stub support (drm_stub.h) */
int DRM(stub_register)(const char *name,
@@ -924,6 +939,14 @@ int DRM(stub_register)(const char *name,
drm_device_t *dev);
int DRM(stub_unregister)(int minor);
-#endif
-#endif
+ /* Proc support (drm_proc.h) */
+extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
+ int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry **dev_root);
+extern int DRM(proc_cleanup)(int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry *dev_root);
+
+#endif /* __KERNEL__ */
#endif
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index b070a59e..dfd0d8fc 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -77,7 +77,7 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
+ if (!dev->agp|| dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
if ((retcode = drm_agp->acquire())) return retcode;
dev->agp->acquired = 1;
return 0;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index 02694f46..1d540322 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -135,6 +135,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
#if __REALLY_HAVE_AGP
case _DRM_AGP:
map->offset = map->offset + dev->agp->base;
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
break;
#endif
default:
@@ -332,7 +333,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
buf->order = order;
buf->used = 0;
- buf->offset = (dma->byte_count + offset); /* ******** */
+ buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
buf->address = (void *)(agp_offset + offset);
buf->next = NULL;
@@ -346,7 +347,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_MEM_BUFS );
memset( buf->dev_private, 0, buf->dev_priv_size );
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;
buf->time_completed = 0;
@@ -377,17 +378,12 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-/* GH: Please leave this disabled for now. I need to fix this properly...
- */
-#if 0
- /* FIXME: work this mess out...
- */
+#if __HAVE_DMA_FREELIST
DRM(freelist_create)( &entry->freelist, entry->buf_count );
for ( i = 0 ; i < entry->buf_count ; i++ ) {
DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
}
#endif
-
up( &dev->struct_sem );
request.count = entry->buf_count;
@@ -523,11 +519,11 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
buf->pending = 0;
init_waitqueue_head( &buf->dma_wait );
buf->pid = 0;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;
buf->time_completed = 0;
- buf->time_freed = 0;
+ buf->time_freed = 0;
#endif
DRM_DEBUG( "buffer %d @ %p\n",
entry->buf_count, buf->address );
@@ -549,17 +545,12 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
dma->page_count += entry->seg_count << page_order;
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-/* GH: Please leave this disabled for now. I need to fix this properly...
- */
-#if 0
- /* FIXME: work this mess out...
- */
+#if __HAVE_DMA_FREELIST
DRM(freelist_create)( &entry->freelist, entry->buf_count );
for ( i = 0 ; i < entry->buf_count ; i++ ) {
DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
}
#endif
-
up( &dev->struct_sem );
request.count = entry->buf_count;
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
index 8f891fd2..4ac896ef 100644
--- a/linux-core/drm_context.c
+++ b/linux-core/drm_context.c
@@ -29,6 +29,11 @@
* Gareth Hughes <gareth@valinux.com>
*/
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if __HAVE_CTX_BITMAP
+
/* ================================================================
* Context bitmap support
*/
@@ -210,7 +215,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new )
return -EBUSY;
}
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
dev->ctx_start = get_cycles();
#endif
@@ -243,7 +248,7 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new )
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- dev->ctx_start)] );
@@ -380,3 +385,376 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
return 0;
}
+
+
+#else /* __HAVE_CTX_BITMAP */
+
+/* ================================================================
+ * Old-style context support
+ */
+
+
+int DRM(context_switch)(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+ drm_queue_t *q;
+
+#if 0
+ atomic_inc(&dev->total_ctx);
+#endif
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if __HAVE_DMA_HISTOGRAM
+ dev->ctx_start = get_cycles();
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new >= dev->queue_count) {
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ q = dev->queuelist[new];
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ atomic_dec(&q->use_count);
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (DRM(flags) & DRM_FLAG_NOCTX) {
+ DRM(context_switch_complete)(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ DRM(write_string)(dev, buf);
+ }
+
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+int DRM(context_switch_complete)(drm_device_t *dev, int new)
+{
+ drm_device_dma_t *dma = dev->dma;
+
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
+ if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("Cannot free lock\n");
+ }
+ }
+
+#if __HAVE_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
+ - dev->ctx_start)]);
+
+#endif
+ clear_bit(0, &dev->context_flag);
+ wake_up_interruptible(&dev->context_wait);
+
+ return 0;
+}
+
+static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
+{
+ DRM_DEBUG("\n");
+
+ if (atomic_read(&q->use_count) != 1
+ || atomic_read(&q->finalization)
+ || atomic_read(&q->block_count)) {
+ DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count));
+ }
+
+ atomic_set(&q->finalization, 0);
+ atomic_set(&q->block_count, 0);
+ atomic_set(&q->block_read, 0);
+ atomic_set(&q->block_write, 0);
+ atomic_set(&q->total_queued, 0);
+ atomic_set(&q->total_flushed, 0);
+ atomic_set(&q->total_locks, 0);
+
+ init_waitqueue_head(&q->write_queue);
+ init_waitqueue_head(&q->read_queue);
+ init_waitqueue_head(&q->flush_queue);
+
+ q->flags = ctx->flags;
+
+ DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
+
+ return 0;
+}
+
+
+/* drm_alloc_queue:
+PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
+ disappear (so all deallocation must be done after IOCTLs are off)
+ 2) dev->queue_count < dev->queue_slots
+ 3) dev->queuelist[i].use_count == 0 and
+ dev->queuelist[i].finalization == 0 if i not in use
+POST: 1) dev->queuelist[i].use_count == 1
+ 2) dev->queue_count < dev->queue_slots */
+
+static int DRM(alloc_queue)(drm_device_t *dev)
+{
+ int i;
+ drm_queue_t *queue;
+ int oldslots;
+ int newslots;
+ /* Check for a free queue */
+ for (i = 0; i < dev->queue_count; i++) {
+ atomic_inc(&dev->queuelist[i]->use_count);
+ if (atomic_read(&dev->queuelist[i]->use_count) == 1
+ && !atomic_read(&dev->queuelist[i]->finalization)) {
+ DRM_DEBUG("%d (free)\n", i);
+ return i;
+ }
+ atomic_dec(&dev->queuelist[i]->use_count);
+ }
+ /* Allocate a new queue */
+ down(&dev->struct_sem);
+
+ queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+ memset(queue, 0, sizeof(*queue));
+ atomic_set(&queue->use_count, 1);
+
+ ++dev->queue_count;
+ if (dev->queue_count >= dev->queue_slots) {
+ oldslots = dev->queue_slots * sizeof(*dev->queuelist);
+ if (!dev->queue_slots) dev->queue_slots = 1;
+ dev->queue_slots *= 2;
+ newslots = dev->queue_slots * sizeof(*dev->queuelist);
+
+ dev->queuelist = DRM(realloc)(dev->queuelist,
+ oldslots,
+ newslots,
+ DRM_MEM_QUEUES);
+ if (!dev->queuelist) {
+ up(&dev->struct_sem);
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+ }
+ dev->queuelist[dev->queue_count-1] = queue;
+
+ up(&dev->struct_sem);
+ DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
+ return dev->queue_count - 1;
+}
+
+int DRM(resctx)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+ return -EFAULT;
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ if (copy_to_user(&res.contexts[i],
+ &i,
+ sizeof(i)))
+ return -EFAULT;
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+ return -EFAULT;
+ return 0;
+}
+
+int DRM(addctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Init kernel's context and get a new one. */
+ DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+ ctx.handle = DRM(alloc_queue)(dev);
+ }
+ DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+ DRM_DEBUG("%d\n", ctx.handle);
+ if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+ return -EFAULT;
+ return 0;
+}
+
+int DRM(modctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ if (DRM_BUFCOUNT(&q->waitlist)) {
+ atomic_dec(&q->use_count);
+ return -EBUSY;
+ }
+
+ q->flags = ctx.flags;
+
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+int DRM(getctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ ctx.flags = q->flags;
+ atomic_dec(&q->use_count);
+
+ if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int DRM(switchctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+ return DRM(context_switch)(dev, dev->last_context, ctx.handle);
+}
+
+int DRM(newctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+ DRM(context_switch_complete)(dev, ctx.handle);
+
+ return 0;
+}
+
+int DRM(rmctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ atomic_inc(&q->finalization); /* Mark queue in finalization state */
+ atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
+ finalization) */
+
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ schedule();
+ if (signal_pending(current)) {
+ clear_bit(0, &dev->interrupt_flag);
+ return -EINTR;
+ }
+ }
+ /* Remove queued buffers */
+ while ((buf = DRM(waitlist_get)(&q->waitlist))) {
+ DRM(free_buffer)(dev, buf);
+ }
+ clear_bit(0, &dev->interrupt_flag);
+
+ /* Wakeup blocked processes */
+ wake_up_interruptible(&q->read_queue);
+ wake_up_interruptible(&q->write_queue);
+ wake_up_interruptible(&q->flush_queue);
+
+ /* Finalization over. Queue is made
+ available when both use_count and
+ finalization become 0, which won't
+ happen until all the waiting processes
+ stop waiting. */
+ atomic_dec(&q->finalization);
+ return 0;
+}
+
+#endif /* __HAVE_CTX_BITMAP */
diff --git a/linux-core/drm_dma.c b/linux-core/drm_dma.c
index 35eb896e..e715bd41 100644
--- a/linux-core/drm_dma.c
+++ b/linux-core/drm_dma.c
@@ -118,7 +118,7 @@ void DRM(dma_takedown)(drm_device_t *dev)
}
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
/* This is slow, but is useful for debugging. */
int DRM(histogram_slot)(unsigned long count)
{
@@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
buf->pending = 0;
buf->pid = 0;
buf->used = 0;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_completed = get_cycles();
#endif
@@ -231,85 +231,6 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
*/
#if __HAVE_OLD_DMA
-int drm_context_switch(drm_device_t *dev, int old, int new)
-{
- char buf[64];
- drm_queue_t *q;
-
-#if 0
- atomic_inc(&dev->total_ctx);
-#endif
-
- if (test_and_set_bit(0, &dev->context_flag)) {
- DRM_ERROR("Reentering -- FIXME\n");
- return -EBUSY;
- }
-
-#if DRM_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
-#endif
-
- DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
- if (new >= dev->queue_count) {
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (new == dev->last_context) {
- clear_bit(0, &dev->context_flag);
- return 0;
- }
-
- q = dev->queuelist[new];
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- atomic_dec(&q->use_count);
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (DRM(flags) & DRM_FLAG_NOCTX) {
- drm_context_switch_complete(dev, new);
- } else {
- sprintf(buf, "C %d %d\n", old, new);
- DRM(write_string)(dev, buf);
- }
-
- atomic_dec(&q->use_count);
-
- return 0;
-}
-
-int drm_context_switch_complete(drm_device_t *dev, int new)
-{
- drm_device_dma_t *dma = dev->dma;
-
- dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
- dev->last_switch = jiffies;
-
- if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("Lock isn't held after context switch\n");
- }
-
- if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
- if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("Cannot free lock\n");
- }
- }
-
-#if DRM_DMA_HISTOGRAM
- atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- - dev->ctx_start)]);
-
-#endif
- clear_bit(0, &dev->context_flag);
- wake_up_interruptible(&dev->context_wait);
-
- return 0;
-}
-
void DRM(clear_next_buffer)(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -571,6 +492,103 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma)
return 0;
}
-#endif
+#endif /* __HAVE_OLD_DMA */
+
+
+#if __HAVE_DMA_IRQ
+
+int DRM(irq_install)( drm_device_t *dev, int irq )
+{
+ int ret;
+
+ if ( !irq )
+ return -EINVAL;
+
+ down( &dev->struct_sem );
+ if ( dev->irq ) {
+ up( &dev->struct_sem );
+ return -EBUSY;
+ }
+ dev->irq = irq;
+ up( &dev->struct_sem );
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+
+ dev->dma->next_buffer = NULL;
+ dev->dma->next_queue = NULL;
+ dev->dma->this_buffer = NULL;
+#if __HAVE_DMA_IRQ_BH
+ INIT_LIST_HEAD( &dev->tq.list );
+ dev->tq.sync = 0;
+ dev->tq.routine = DRM(dma_immediate_bh);
+ dev->tq.data = dev;
#endif
+
+ /* Before installing handler */
+ DRIVER_PREINSTALL();
+
+ /* Install handler */
+ ret = request_irq( dev->irq, DRM(dma_service),
+ 0, dev->devname, dev );
+ if ( ret < 0 ) {
+ down( &dev->struct_sem );
+ dev->irq = 0;
+ up( &dev->struct_sem );
+ return ret;
+ }
+
+ /* After installing handler */
+ DRIVER_POSTINSTALL();
+
+ return 0;
+}
+
+int DRM(irq_uninstall)( drm_device_t *dev )
+{
+ int irq;
+
+ down( &dev->struct_sem );
+ irq = dev->irq;
+ dev->irq = 0;
+ up( &dev->struct_sem );
+
+ if ( !irq )
+ return -EINVAL;
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+ DRIVER_UNINSTALL();
+
+ free_irq( irq, dev );
+
+ return 0;
+}
+
+int DRM(control)( 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_control_t ctl;
+
+ if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) )
+ return -EFAULT;
+
+ switch ( ctl.func ) {
+ case DRM_INST_HANDLER:
+ return DRM(irq_install)( dev, ctl.irq );
+ case DRM_UNINST_HANDLER:
+ return DRM(irq_uninstall)( dev );
+ default:
+ return -EINVAL;
+ }
+}
+
+#endif /* __HAVE_DMA_IRQ */
+
+#endif /* __HAVE_DMA */
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 05923b50..7447ca6d 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -492,7 +492,8 @@ static int __init drm_init( void )
}
#endif
#if __REALLY_HAVE_MTRR
- dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+ if (dev->agp)
+ dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
dev->agp->agp_info.aper_size*1024*1024,
MTRR_TYPE_WRCOMB,
1 );
@@ -646,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
if ( dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
dev->lock.pid == current->pid ) {
- DRM_ERROR( "Process %d dead, freeing lock for context %d\n",
+ DRM_DEBUG( "Process %d dead, freeing lock for context %d\n",
current->pid,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
#if __HAVE_RELEASE
@@ -697,7 +698,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_KERNEL_CONTEXT );
}
}
-#else
+#elif __HAVE_DMA
DRM(reclaim_buffers)( dev, priv->pid );
#endif
@@ -804,7 +805,7 @@ int DRM(lock)( struct inode *inode, struct file *filp,
#if __HAVE_MULTIPLE_DMA_QUEUES
drm_queue_t *q;
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
cycles_t start;
dev->lck_start = start = get_cycles();
@@ -892,7 +893,7 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]);
#endif
return ret;
diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c
index d646f318..dd574766 100644
--- a/linux-core/drm_fops.c
+++ b/linux-core/drm_fops.c
@@ -83,50 +83,6 @@ int DRM(flush)(struct file *filp)
return 0;
}
-#if 0
-/* drm_release is called whenever a process closes /dev/drm*. Linux calls
- this only if any mappings have been closed. */
-
-int drm_release(struct inode *inode, struct file *filp)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
-
- DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
- current->pid, dev->device, dev->open_count);
-
- if (dev->lock.hw_lock
- && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
- && dev->lock.pid == current->pid) {
- DRM_ERROR("Process %d dead, freeing lock for context %d\n",
- current->pid,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
- drm_lock_free(dev,
- &dev->lock.hw_lock->lock,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
- }
- drm_reclaim_buffers(dev, priv->pid);
-
- drm_fasync(-1, filp, 0);
-
- down(&dev->struct_sem);
- if (priv->prev) priv->prev->next = priv->next;
- else dev->file_first = priv->next;
- if (priv->next) priv->next->prev = priv->prev;
- else dev->file_last = priv->prev;
- up(&dev->struct_sem);
-
- drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-
- return 0;
-}
-#endif
-
int DRM(fasync)(int fd, struct file *filp, int on)
{
drm_file_t *priv = filp->private_data;
diff --git a/linux-core/drm_memory.h b/linux-core/drm_memory.h
index caf05394..1763d9b4 100644
--- a/linux-core/drm_memory.h
+++ b/linux-core/drm_memory.h
@@ -351,8 +351,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size)
}
}
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-#if __MUST_HAVE_AGP
+#if __REALLY_HAVE_AGP
agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
@@ -457,4 +456,3 @@ int DRM(unbind_agp)(agp_memory *handle)
return retcode;
}
#endif
-#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */
diff --git a/linux-core/drm_proc.c b/linux-core/drm_proc.c
index 60628660..f65f42b7 100644
--- a/linux-core/drm_proc.c
+++ b/linux-core/drm_proc.c
@@ -50,7 +50,7 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset,
static int DRM(vma_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
static int DRM(histo_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#endif
@@ -68,7 +68,7 @@ struct drm_proc_list {
#if DRM_DEBUG_CODE
{ "vma", DRM(vma_info) },
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
{ "histo", DRM(histo_info) },
#endif
};
@@ -488,7 +488,7 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
index ed37af4d..bc958796 100644
--- a/linux-core/drm_stub.c
+++ b/linux-core/drm_stub.c
@@ -1,4 +1,4 @@
-/* drm_stub.c -- -*- linux-c -*-
+/* drm_stub.h -- -*- linux-c -*-
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
*
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
@@ -28,6 +28,13 @@
*
*/
+#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 {
@@ -58,7 +65,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp)
filp->f_op = fops_get(old_fops);
}
fops_put(old_fops);
-
+
return err;
}
@@ -73,7 +80,7 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
drm_device_t *dev)
{
int i;
-
+
if (!DRM(stub_list)) {
DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
* DRM_STUB_MAXCARDS, DRM_MEM_STUB);
@@ -117,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-core/i810_dma.c b/linux-core/i810_dma.c
index 8c50b320..4c90496a 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -48,16 +48,6 @@
#define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1
-#define I810_BASE(reg) ((unsigned long) \
- dev_priv->mmio_map->handle)
-#define I810_ADDR(reg) (I810_BASE(reg) + reg)
-#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
-#define I810_READ(reg) I810_DEREF(reg)
-#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
-#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
-#define I810_READ16(reg) I810_DEREF16(reg)
-#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
-
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
#define BEGIN_LP_RING(n) do { \
@@ -875,7 +865,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
/* Interrupts are only for flushing */
-static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
+void i810_dma_service(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
@@ -893,7 +883,7 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
mark_bh(IMMEDIATE_BH);
}
-static void i810_dma_task_queue(void *device)
+void i810_dma_immediate_bh(void *device)
{
drm_device_t *dev = (drm_device_t *) device;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
@@ -902,131 +892,6 @@ static void i810_dma_task_queue(void *device)
wake_up_interruptible(&dev_priv->flush_queue);
}
-int i810_irq_install(drm_device_t *dev, int irq)
-{
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- int retcode;
- u16 temp;
-
- if (!irq) return -EINVAL;
-
- down(&dev->struct_sem);
- if (dev->irq) {
- up(&dev->struct_sem);
- return -EBUSY;
- }
- dev->irq = irq;
- up(&dev->struct_sem);
-
- DRM_DEBUG( "Interrupt Install : %d\n", irq);
- DRM_DEBUG("%d\n", irq);
-
- dev->context_flag = 0;
- dev->interrupt_flag = 0;
- dev->dma_flag = 0;
-
- dev->dma->next_buffer = NULL;
- dev->dma->next_queue = NULL;
- dev->dma->this_buffer = NULL;
-
- INIT_LIST_HEAD(&dev->tq.list);
- dev->tq.sync = 0;
- dev->tq.routine = i810_dma_task_queue;
- dev->tq.data = dev;
-
- /* Before installing handler */
- temp = I810_READ16(I810REG_HWSTAM);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_HWSTAM, temp);
-
- temp = I810_READ16(I810REG_INT_MASK_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */
-
- /* Install handler */
- if ((retcode = request_irq(dev->irq,
- i810_dma_service,
- SA_SHIRQ,
- dev->devname,
- dev))) {
- down(&dev->struct_sem);
- dev->irq = 0;
- up(&dev->struct_sem);
- return retcode;
- }
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- temp = temp | 0x0003;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Enable bp & user interrupts */
- return 0;
-}
-
-int i810_irq_uninstall(drm_device_t *dev)
-{
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- int irq;
- u16 temp;
-
-
-/* return 0; */
-
- down(&dev->struct_sem);
- irq = dev->irq;
- dev->irq = 0;
- up(&dev->struct_sem);
-
- if (!irq) return -EINVAL;
-
- DRM_DEBUG( "Interrupt UnInstall: %d\n", irq);
- DRM_DEBUG("%d\n", irq);
-
- temp = I810_READ16(I810REG_INT_IDENTITY_R);
- temp = temp & ~(0x6000);
- if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
- temp); /* Clear all interrupts */
-
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Disable all interrupts */
-
- free_irq(irq, dev);
-
- return 0;
-}
-
-int i810_control(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_control_t ctl;
- int retcode;
-
- DRM_DEBUG( "i810_control\n");
-
- if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
- return -EFAULT;
-
- switch (ctl.func) {
- case DRM_INST_HANDLER:
- if ((retcode = i810_irq_install(dev, ctl.irq)))
- return retcode;
- break;
- case DRM_UNINST_HANDLER:
- if ((retcode = i810_irq_uninstall(dev)))
- return retcode;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
static inline void i810_dma_emit_flush(drm_device_t *dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c
index 86ab394d..12a59dbf 100644
--- a/linux-core/i810_drv.c
+++ b/linux-core/i810_drv.c
@@ -56,42 +56,26 @@
[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
+
#define __HAVE_COUNTERS 4
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#define __HAVE_COUNTER9 _DRM_STAT_DMA
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() do { \
- i810_dma_quiescent( dev ); \
-} while (0)
-
-#define __HAVE_RELEASE 1
-#define DRIVER_RELEASE() do { \
- i810_reclaim_buffers( dev, priv->pid ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_i810_private_t *)((dev)->dev_private))->buffer_map
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_lock.h"
+#include "drm_lists.h"
#include "drm_memory.h"
#include "drm_proc.h"
#include "drm_vm.h"
diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h
index 1f6e1468..e1b17148 100644
--- a/linux-core/i810_drv.h
+++ b/linux-core/i810_drv.h
@@ -81,12 +81,6 @@ typedef struct drm_i810_private {
extern int i810_dma_schedule(drm_device_t *dev, int locked);
extern int i810_getbuf(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int i810_irq_install(drm_device_t *dev, int irq);
-extern int i810_irq_uninstall(drm_device_t *dev);
-extern int i810_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int i810_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int i810_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
@@ -114,6 +108,18 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
int i810_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+
+#define I810_BASE(reg) ((unsigned long) \
+ dev_priv->mmio_map->handle)
+#define I810_ADDR(reg) (I810_BASE(reg) + reg)
+#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
+#define I810_READ(reg) I810_DEREF(reg)
+#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
+#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
+#define I810_READ16(reg) I810_DEREF16(reg)
+#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
+
+
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
#define CMD_REPORT_HEAD (7<<23)
diff --git a/linux-core/mga_drv.c b/linux-core/mga_drv.c
index 7898c744..88fa53a6 100644
--- a/linux-core/mga_drv.c
+++ b/linux-core/mga_drv.c
@@ -38,7 +38,7 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
@@ -56,38 +56,20 @@
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 },
+
#define __HAVE_COUNTERS 3
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() \
-do { \
- drm_mga_private_t *dev_priv = dev->dev_private; \
- return mga_do_wait_for_idle( dev_priv ); \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_mga_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux-core/r128_drv.c b/linux-core/r128_drv.c
index 3bd27ae7..e42868ed 100644
--- a/linux-core/r128_drv.c
+++ b/linux-core/r128_drv.c
@@ -38,7 +38,7 @@
#define DRIVER_NAME "r128"
#define DRIVER_DESC "ATI Rage 128"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 1
@@ -62,6 +62,7 @@
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
+
#if 0
/* GH: Count data sent to card via ring or vertex/indirect buffers.
*/
@@ -71,41 +72,14 @@
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#endif
-#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)
-
-#define DRIVER_PRERELEASE() do { \
- if ( dev->dev_private ) { \
- drm_r128_private_t *dev_priv = dev->dev_private; \
- if ( dev_priv->page_flipping ) { \
- r128_do_cleanup_pageflip( dev ); \
- } \
- } \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_r128_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index 43f6e2e7..1aa889ae 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -36,7 +36,7 @@
#define DRIVER_NAME "radeon"
#define DRIVER_DESC "ATI Radeon"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010305"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
@@ -55,10 +55,11 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
+
#if 0
/* GH: Count data sent to card via ring or vertex/indirect buffers.
*/
@@ -68,41 +69,14 @@
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#endif
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() do { \
- drm_radeon_private_t *dev_priv = dev->dev_private; \
- return radeon_do_cp_idle( dev_priv ); \
-} while (0)
-
-#define DRIVER_PRERELEASE() do { \
- if ( dev->dev_private ) { \
- drm_radeon_private_t *dev_priv = dev->dev_private; \
- if ( dev_priv->page_flipping ) { \
- radeon_do_cleanup_pageflip( dev ); \
- } \
- } \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_radeon_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux-core/tdfx_drv.c b/linux-core/tdfx_drv.c
index e8d7955c..f478395f 100644
--- a/linux-core/tdfx_drv.c
+++ b/linux-core/tdfx_drv.c
@@ -38,21 +38,19 @@
#define DRIVER_NAME "tdfx"
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-#include "drm_drv.h"
-
-#include "drm_agpsupport.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux/Makefile.linux b/linux/Makefile.linux
index 26eed9a5..d022557d 100644
--- a/linux/Makefile.linux
+++ b/linux/Makefile.linux
@@ -47,38 +47,34 @@
# **** End of SMP/MODVERSIONS detection
-#MODS= gamma.o tdfx.o
-MODS= tdfx.o
-LIBS=
+MODS = gamma.o tdfx.o
+LIBS =
-#DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
-# lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
-DRMOBS=
-DRMTEMPLATES= drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \
- drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \
- drm_fops.h drm_vm.h drm_dma.h drm_stub.h
-DRMHEADERS= drm.h drmP.h compat-pre24.h
+DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
+ drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \
+ drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h
+DRMHEADERS = drm.h drmP.h compat-pre24.h
-#GAMMAOBJS= gamma_drv.o gamma_drm.o gamma_dma.o gamma_context.o
-#GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
+GAMMAOBJS = gamma_drv.o gamma_dma.o
+GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
-TDFXOBJS= tdfx_drv.o
-TDFXHEADERS= tdfx.h $(DRMHEADERS)
+TDFXOBJS = tdfx_drv.o
+TDFXHEADERS = tdfx.h $(DRMHEADERS)
-INC= /usr/include
+INC = /usr/include
-CFLAGS= -O2 $(WARNINGS)
-WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \
+CFLAGS = -O2 $(WARNINGS)
+WARNINGS = -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \
-Wstrict-prototypes -Wnested-externs \
-Wpointer-arith
# -Wshadow -Winline -- make output too noisy
-MODCFLAGS= $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer
-PRGCFLAGS= $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
+MODCFLAGS = $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer
+PRGCFLAGS = $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
-D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
-I../../../../../../include -I../../../../../../../../include \
-I../../../../../../../../programs/Xserver/hw/xfree86/common \
-I. -I../../.. -I../../../../../../../../lib/X11
-PRGLIBS=
+PRGLIBS =
# **** Start of SMP/MODVERSIONS detection
@@ -134,7 +130,8 @@ endif
ifeq ($(AGP),1)
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
-#DRMOBJS += agpsupport.o
+DRMTEMPLATES += drm_agpsupport.h
+DRMHEADERS += agpsupport-pre24.h
MODS += mga.o r128.o radeon.o
ifeq ($(MACHINE),i386)
MODS += i810.o
@@ -144,17 +141,17 @@ MODS += i810.o
endif
-MGAOBJS= mga_drv.o mga_dma.o mga_state.o mga_warp.o
-MGAHEADERS= mga.h mga_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
+MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o
+MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
-I810OBJS= i810_drv.o i810_dma.o
-I810HEADERS= i810.h i810_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
+I810OBJS = i810_drv.o i810_dma.o
+I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
-R128OBJS= r128_drv.o r128_cce.o r128_state.o
-R128HEADERS= r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
+R128OBJS = r128_drv.o r128_cce.o r128_state.o
+R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
-RADEONOBJS= radeon_drv.o radeon_cp.o radeon_state.o
-RADEONHEADERS= radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
+RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o
+RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
$(DRMTEMPLATES)
endif
@@ -177,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)
@@ -205,17 +202,13 @@ endif
# **** End of configuration
-libdrm.a: $(DRMOBJS)
- -$(RM) -f $@
- $(AR) rcs $@ $(DRMOBJS)
-
dristat: dristat.c
$(CC) $(PRGCFLAGS) $< -o $@
-#gamma_drv.o: gamma_drv.c
-# $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-#gamma.o: $(GAMMAOBJS)
-# $(LD) -r $^ -o $@
+gamma_drv.o: gamma_drv.c
+ $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
+gamma.o: $(GAMMAOBJS)
+ $(LD) -r $^ -o $@
tdfx_drv.o: tdfx_drv.c
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
@@ -260,8 +253,7 @@ ChangeLog:
%.o: %.c
$(CC) $(MODCFLAGS) -I$(TREE) -c $< -o $@
-$(DRMOBJS): $(DRMHEADERS)
-#$(GAMMAOBJS): $(GAMMAHEADERS)
+$(GAMMAOBJS): $(GAMMAHEADERS)
$(TDFXOBJS): $(TDFXHEADERS)
ifeq ($(AGP),1)
$(MGAOBJS): $(MGAHEADERS)
diff --git a/linux/compat-pre24.h b/linux/compat-pre24.h
index f6dae008..0ad96b12 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 7c65f5fc..ddabc277 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 */
@@ -453,7 +450,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/linux/drmP.h b/linux/drmP.h
index 804df409..a7e4d573 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -84,15 +84,24 @@
#ifndef __HAVE_MTRR
#define __HAVE_MTRR 0
#endif
+#ifndef __HAVE_CTX_BITMAP
+#define __HAVE_CTX_BITMAP 0
+#endif
#ifndef __HAVE_DMA
#define __HAVE_DMA 0
#endif
+#ifndef __HAVE_DMA_IRQ
+#define __HAVE_DMA_IRQ 0
+#endif
#ifndef __HAVE_DMA_WAITLIST
#define __HAVE_DMA_WAITLIST 0
#endif
#ifndef __HAVE_DMA_FREELIST
#define __HAVE_DMA_FREELIST 0
#endif
+#ifndef __HAVE_DMA_HISTOGRAM
+#define __HAVE_DMA_HISTOGRAM 0
+#endif
#define __REALLY_HAVE_AGP (__HAVE_AGP && (defined(CONFIG_AGP) || \
defined(CONFIG_AGP_MODULE)))
@@ -104,7 +113,6 @@
#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
also include looping detection. */
-#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
#define DRM_HASH_SIZE 16 /* Size of key hash table */
#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
@@ -643,7 +651,7 @@ typedef struct drm_device {
struct tq_struct tq;
cycles_t ctx_start;
cycles_t lck_start;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
drm_histogram_t histo;
#endif
@@ -667,9 +675,11 @@ typedef struct drm_device {
} drm_device_t;
- /* Internal function definitions */
+/* ================================================================
+ * Internal function definitions
+ */
- /* Misc. support (init.c) */
+ /* Misc. support (drm_init.h) */
extern int DRM(flags);
extern void DRM(parse_options)( char *s );
extern int DRM(cpu_valid)( void );
@@ -686,7 +696,7 @@ extern int DRM(lock)(struct inode *inode, struct file *filp,
extern int DRM(unlock)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Device support (fops.c) */
+ /* Device support (drm_fops.h) */
extern int DRM(open_helper)(struct inode *inode, struct file *filp,
drm_device_t *dev);
extern int DRM(flush)(struct file *filp);
@@ -698,7 +708,7 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s);
extern unsigned int DRM(poll)(struct file *filp,
struct poll_table_struct *wait);
- /* Mapping support (vm.c) */
+ /* Mapping support (drm_vm.h) */
#if LINUX_VERSION_CODE < 0x020317
extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address,
@@ -728,17 +738,7 @@ extern int DRM(mmap_dma)(struct file *filp,
struct vm_area_struct *vma);
extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
-
- /* Proc support (proc.c) */
-extern struct proc_dir_entry *drm_proc_init(drm_device_t *dev,
- int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry **dev_root);
-extern int drm_proc_cleanup(int minor,
- struct proc_dir_entry *root,
- struct proc_dir_entry *dev_root);
-
- /* Memory management support (memory.c) */
+ /* Memory management support (drm_memory.h) */
extern void DRM(mem_init)(void);
extern int DRM(mem_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
@@ -761,7 +761,7 @@ extern int DRM(bind_agp)(agp_memory *handle, unsigned int start);
extern int DRM(unbind_agp)(agp_memory *handle);
#endif
- /* Misc. IOCTL support (ioctl.c) */
+ /* Misc. IOCTL support (drm_ioctl.h) */
extern int DRM(irq_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getunique)(struct inode *inode, struct file *filp,
@@ -775,7 +775,7 @@ extern int DRM(getclient)(struct inode *inode, struct file *filp,
extern int DRM(getstats)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Context IOCTL support (context.c) */
+ /* Context IOCTL support (drm_context.h) */
extern int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(addctx)( struct inode *inode, struct file *filp,
@@ -794,14 +794,24 @@ extern int DRM(rmctx)( struct inode *inode, struct file *filp,
extern int DRM(context_switch)(drm_device_t *dev, int old, int new);
extern int DRM(context_switch_complete)(drm_device_t *dev, int new);
- /* Drawable IOCTL support (drawable.c) */
+#if __HAVE_CTX_BITMAP
+extern int DRM(ctxbitmap_init)( drm_device_t *dev );
+extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
+#endif
+
+extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+
+ /* Drawable IOCTL support (drm_drawable.h) */
extern int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(rmdraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Authentication IOCTL support (auth.c) */
+ /* Authentication IOCTL support (drm_auth.h) */
extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv,
drm_magic_t magic);
extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic);
@@ -811,7 +821,7 @@ extern int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
- /* Locking IOCTL support (lock.c) */
+ /* Locking IOCTL support (drm_lock.h) */
extern int DRM(block)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(unblock)(struct inode *inode, struct file *filp,
@@ -832,20 +842,13 @@ extern int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int DRM(notifier)(void *priv);
- /* Context Bitmap support (ctxbitmap.c) */
-extern int DRM(ctxbitmap_init)( drm_device_t *dev );
-extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
-extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-
- /* Buffer management support (bufs.c) */
+ /* Buffer management support (drm_bufs.h) */
extern int DRM(order)( unsigned long size );
extern int DRM(addmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(rmmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+#if __HAVE_DMA
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(infobufs)( struct inode *inode, struct file *filp,
@@ -857,27 +860,37 @@ extern int DRM(freebufs)( struct inode *inode, struct file *filp,
extern int DRM(mapbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-
-#if __HAVE_DMA
- /* DMA support (dma.c) */
+ /* DMA support (drm_dma.h) */
extern int DRM(dma_setup)(drm_device_t *dev);
extern void DRM(dma_takedown)(drm_device_t *dev);
extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
extern void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid);
+#if __HAVE_OLD_DMA
+/* GH: This is a dirty hack for now...
+ */
extern void DRM(clear_next_buffer)(drm_device_t *dev);
extern int DRM(select_queue)(drm_device_t *dev,
void (*wrapper)(unsigned long));
extern int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma);
-#if 0
extern int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
#endif
+#if __HAVE_DMA_IRQ
+extern int DRM(control)( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
+extern int DRM(irq_install)( drm_device_t *dev, int irq );
+extern int DRM(irq_uninstall)( drm_device_t *dev );
+extern void DRM(dma_service)( int irq, void *device,
+ struct pt_regs *regs );
+#if __HAVE_DMA_IRQ_BH
+extern void DRM(dma_immediate_bh)( void *dev );
+#endif
+#endif
#if DRM_DMA_HISTOGRAM
extern int DRM(histogram_slot)(unsigned long count);
extern void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf);
#endif
-#endif
- /* Buffer list management support (lists.c) */
+ /* Buffer list support (drm_lists.h) */
#if __HAVE_DMA_WAITLIST
extern int DRM(waitlist_create)(drm_waitlist_t *bl, int count);
extern int DRM(waitlist_destroy)(drm_waitlist_t *bl);
@@ -891,9 +904,10 @@ extern int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
drm_buf_t *buf);
extern drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block);
#endif
+#endif /* __HAVE_DMA */
#if __REALLY_HAVE_AGP
- /* AGP/GART support (agpsupport.c) */
+ /* AGP/GART support (drm_agpsupport.h) */
extern drm_agp_head_t *DRM(agp_init)(void);
extern void DRM(agp_uninit)(void);
extern int DRM(agp_acquire)(struct inode *inode, struct file *filp,
@@ -917,6 +931,7 @@ extern agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
extern int DRM(agp_free_memory)(agp_memory *handle);
extern int DRM(agp_bind_memory)(agp_memory *handle, off_t start);
extern int DRM(agp_unbind_memory)(agp_memory *handle);
+#endif
/* Stub support (drm_stub.h) */
int DRM(stub_register)(const char *name,
@@ -924,6 +939,14 @@ int DRM(stub_register)(const char *name,
drm_device_t *dev);
int DRM(stub_unregister)(int minor);
-#endif
-#endif
+ /* Proc support (drm_proc.h) */
+extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
+ int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry **dev_root);
+extern int DRM(proc_cleanup)(int minor,
+ struct proc_dir_entry *root,
+ struct proc_dir_entry *dev_root);
+
+#endif /* __KERNEL__ */
#endif
diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h
index b070a59e..dfd0d8fc 100644
--- a/linux/drm_agpsupport.h
+++ b/linux/drm_agpsupport.h
@@ -77,7 +77,7 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
int retcode;
- if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
+ if (!dev->agp|| dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
if ((retcode = drm_agp->acquire())) return retcode;
dev->agp->acquired = 1;
return 0;
diff --git a/linux/drm_bufs.h b/linux/drm_bufs.h
index 02694f46..1d540322 100644
--- a/linux/drm_bufs.h
+++ b/linux/drm_bufs.h
@@ -135,6 +135,7 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
#if __REALLY_HAVE_AGP
case _DRM_AGP:
map->offset = map->offset + dev->agp->base;
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
break;
#endif
default:
@@ -332,7 +333,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
buf->order = order;
buf->used = 0;
- buf->offset = (dma->byte_count + offset); /* ******** */
+ buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
buf->address = (void *)(agp_offset + offset);
buf->next = NULL;
@@ -346,7 +347,7 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_MEM_BUFS );
memset( buf->dev_private, 0, buf->dev_priv_size );
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;
buf->time_completed = 0;
@@ -377,17 +378,12 @@ int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
-/* GH: Please leave this disabled for now. I need to fix this properly...
- */
-#if 0
- /* FIXME: work this mess out...
- */
+#if __HAVE_DMA_FREELIST
DRM(freelist_create)( &entry->freelist, entry->buf_count );
for ( i = 0 ; i < entry->buf_count ; i++ ) {
DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
}
#endif
-
up( &dev->struct_sem );
request.count = entry->buf_count;
@@ -523,11 +519,11 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
buf->pending = 0;
init_waitqueue_head( &buf->dma_wait );
buf->pid = 0;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;
buf->time_completed = 0;
- buf->time_freed = 0;
+ buf->time_freed = 0;
#endif
DRM_DEBUG( "buffer %d @ %p\n",
entry->buf_count, buf->address );
@@ -549,17 +545,12 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
dma->page_count += entry->seg_count << page_order;
dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
-/* GH: Please leave this disabled for now. I need to fix this properly...
- */
-#if 0
- /* FIXME: work this mess out...
- */
+#if __HAVE_DMA_FREELIST
DRM(freelist_create)( &entry->freelist, entry->buf_count );
for ( i = 0 ; i < entry->buf_count ; i++ ) {
DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
}
#endif
-
up( &dev->struct_sem );
request.count = entry->buf_count;
diff --git a/linux/drm_context.h b/linux/drm_context.h
index 8f891fd2..4ac896ef 100644
--- a/linux/drm_context.h
+++ b/linux/drm_context.h
@@ -29,6 +29,11 @@
* Gareth Hughes <gareth@valinux.com>
*/
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if __HAVE_CTX_BITMAP
+
/* ================================================================
* Context bitmap support
*/
@@ -210,7 +215,7 @@ int DRM(context_switch)( drm_device_t *dev, int old, int new )
return -EBUSY;
}
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
dev->ctx_start = get_cycles();
#endif
@@ -243,7 +248,7 @@ int DRM(context_switch_complete)( drm_device_t *dev, int new )
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- dev->ctx_start)] );
@@ -380,3 +385,376 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
return 0;
}
+
+
+#else /* __HAVE_CTX_BITMAP */
+
+/* ================================================================
+ * Old-style context support
+ */
+
+
+int DRM(context_switch)(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+ drm_queue_t *q;
+
+#if 0
+ atomic_inc(&dev->total_ctx);
+#endif
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if __HAVE_DMA_HISTOGRAM
+ dev->ctx_start = get_cycles();
+#endif
+
+ DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+ if (new >= dev->queue_count) {
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ q = dev->queuelist[new];
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ atomic_dec(&q->use_count);
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (DRM(flags) & DRM_FLAG_NOCTX) {
+ DRM(context_switch_complete)(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ DRM(write_string)(dev, buf);
+ }
+
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+int DRM(context_switch_complete)(drm_device_t *dev, int new)
+{
+ drm_device_dma_t *dma = dev->dma;
+
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+
+ if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
+ if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("Cannot free lock\n");
+ }
+ }
+
+#if __HAVE_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
+ - dev->ctx_start)]);
+
+#endif
+ clear_bit(0, &dev->context_flag);
+ wake_up_interruptible(&dev->context_wait);
+
+ return 0;
+}
+
+static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
+{
+ DRM_DEBUG("\n");
+
+ if (atomic_read(&q->use_count) != 1
+ || atomic_read(&q->finalization)
+ || atomic_read(&q->block_count)) {
+ DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count));
+ }
+
+ atomic_set(&q->finalization, 0);
+ atomic_set(&q->block_count, 0);
+ atomic_set(&q->block_read, 0);
+ atomic_set(&q->block_write, 0);
+ atomic_set(&q->total_queued, 0);
+ atomic_set(&q->total_flushed, 0);
+ atomic_set(&q->total_locks, 0);
+
+ init_waitqueue_head(&q->write_queue);
+ init_waitqueue_head(&q->read_queue);
+ init_waitqueue_head(&q->flush_queue);
+
+ q->flags = ctx->flags;
+
+ DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
+
+ return 0;
+}
+
+
+/* drm_alloc_queue:
+PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
+ disappear (so all deallocation must be done after IOCTLs are off)
+ 2) dev->queue_count < dev->queue_slots
+ 3) dev->queuelist[i].use_count == 0 and
+ dev->queuelist[i].finalization == 0 if i not in use
+POST: 1) dev->queuelist[i].use_count == 1
+ 2) dev->queue_count < dev->queue_slots */
+
+static int DRM(alloc_queue)(drm_device_t *dev)
+{
+ int i;
+ drm_queue_t *queue;
+ int oldslots;
+ int newslots;
+ /* Check for a free queue */
+ for (i = 0; i < dev->queue_count; i++) {
+ atomic_inc(&dev->queuelist[i]->use_count);
+ if (atomic_read(&dev->queuelist[i]->use_count) == 1
+ && !atomic_read(&dev->queuelist[i]->finalization)) {
+ DRM_DEBUG("%d (free)\n", i);
+ return i;
+ }
+ atomic_dec(&dev->queuelist[i]->use_count);
+ }
+ /* Allocate a new queue */
+ down(&dev->struct_sem);
+
+ queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+ memset(queue, 0, sizeof(*queue));
+ atomic_set(&queue->use_count, 1);
+
+ ++dev->queue_count;
+ if (dev->queue_count >= dev->queue_slots) {
+ oldslots = dev->queue_slots * sizeof(*dev->queuelist);
+ if (!dev->queue_slots) dev->queue_slots = 1;
+ dev->queue_slots *= 2;
+ newslots = dev->queue_slots * sizeof(*dev->queuelist);
+
+ dev->queuelist = DRM(realloc)(dev->queuelist,
+ oldslots,
+ newslots,
+ DRM_MEM_QUEUES);
+ if (!dev->queuelist) {
+ up(&dev->struct_sem);
+ DRM_DEBUG("out of memory\n");
+ return -ENOMEM;
+ }
+ }
+ dev->queuelist[dev->queue_count-1] = queue;
+
+ up(&dev->struct_sem);
+ DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
+ return dev->queue_count - 1;
+}
+
+int DRM(resctx)(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+
+ DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+ if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+ return -EFAULT;
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ if (copy_to_user(&res.contexts[i],
+ &i,
+ sizeof(i)))
+ return -EFAULT;
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+ return -EFAULT;
+ return 0;
+}
+
+int DRM(addctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Init kernel's context and get a new one. */
+ DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+ ctx.handle = DRM(alloc_queue)(dev);
+ }
+ DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+ DRM_DEBUG("%d\n", ctx.handle);
+ if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+ return -EFAULT;
+ return 0;
+}
+
+int DRM(modctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ if (DRM_BUFCOUNT(&q->waitlist)) {
+ atomic_dec(&q->use_count);
+ return -EBUSY;
+ }
+
+ q->flags = ctx.flags;
+
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+int DRM(getctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ ctx.flags = q->flags;
+ atomic_dec(&q->use_count);
+
+ if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+ return -EFAULT;
+
+ return 0;
+}
+
+int DRM(switchctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+ return DRM(context_switch)(dev, dev->last_context, ctx.handle);
+}
+
+int DRM(newctx)(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_ctx_t ctx;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+ DRM(context_switch_complete)(dev, ctx.handle);
+
+ return 0;
+}
+
+int DRM(rmctx)(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_ctx_t ctx;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+
+ if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+ return -EFAULT;
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ atomic_inc(&q->finalization); /* Mark queue in finalization state */
+ atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
+ finalization) */
+
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ schedule();
+ if (signal_pending(current)) {
+ clear_bit(0, &dev->interrupt_flag);
+ return -EINTR;
+ }
+ }
+ /* Remove queued buffers */
+ while ((buf = DRM(waitlist_get)(&q->waitlist))) {
+ DRM(free_buffer)(dev, buf);
+ }
+ clear_bit(0, &dev->interrupt_flag);
+
+ /* Wakeup blocked processes */
+ wake_up_interruptible(&q->read_queue);
+ wake_up_interruptible(&q->write_queue);
+ wake_up_interruptible(&q->flush_queue);
+
+ /* Finalization over. Queue is made
+ available when both use_count and
+ finalization become 0, which won't
+ happen until all the waiting processes
+ stop waiting. */
+ atomic_dec(&q->finalization);
+ return 0;
+}
+
+#endif /* __HAVE_CTX_BITMAP */
diff --git a/linux/drm_dma.h b/linux/drm_dma.h
index 35eb896e..e715bd41 100644
--- a/linux/drm_dma.h
+++ b/linux/drm_dma.h
@@ -118,7 +118,7 @@ void DRM(dma_takedown)(drm_device_t *dev)
}
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
/* This is slow, but is useful for debugging. */
int DRM(histogram_slot)(unsigned long count)
{
@@ -182,7 +182,7 @@ void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
buf->pending = 0;
buf->pid = 0;
buf->used = 0;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_completed = get_cycles();
#endif
@@ -231,85 +231,6 @@ void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
*/
#if __HAVE_OLD_DMA
-int drm_context_switch(drm_device_t *dev, int old, int new)
-{
- char buf[64];
- drm_queue_t *q;
-
-#if 0
- atomic_inc(&dev->total_ctx);
-#endif
-
- if (test_and_set_bit(0, &dev->context_flag)) {
- DRM_ERROR("Reentering -- FIXME\n");
- return -EBUSY;
- }
-
-#if DRM_DMA_HISTOGRAM
- dev->ctx_start = get_cycles();
-#endif
-
- DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
- if (new >= dev->queue_count) {
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (new == dev->last_context) {
- clear_bit(0, &dev->context_flag);
- return 0;
- }
-
- q = dev->queuelist[new];
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- atomic_dec(&q->use_count);
- clear_bit(0, &dev->context_flag);
- return -EINVAL;
- }
-
- if (DRM(flags) & DRM_FLAG_NOCTX) {
- drm_context_switch_complete(dev, new);
- } else {
- sprintf(buf, "C %d %d\n", old, new);
- DRM(write_string)(dev, buf);
- }
-
- atomic_dec(&q->use_count);
-
- return 0;
-}
-
-int drm_context_switch_complete(drm_device_t *dev, int new)
-{
- drm_device_dma_t *dma = dev->dma;
-
- dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
- dev->last_switch = jiffies;
-
- if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("Lock isn't held after context switch\n");
- }
-
- if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
- if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("Cannot free lock\n");
- }
- }
-
-#if DRM_DMA_HISTOGRAM
- atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
- - dev->ctx_start)]);
-
-#endif
- clear_bit(0, &dev->context_flag);
- wake_up_interruptible(&dev->context_wait);
-
- return 0;
-}
-
void DRM(clear_next_buffer)(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
@@ -571,6 +492,103 @@ int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma)
return 0;
}
-#endif
+#endif /* __HAVE_OLD_DMA */
+
+
+#if __HAVE_DMA_IRQ
+
+int DRM(irq_install)( drm_device_t *dev, int irq )
+{
+ int ret;
+
+ if ( !irq )
+ return -EINVAL;
+
+ down( &dev->struct_sem );
+ if ( dev->irq ) {
+ up( &dev->struct_sem );
+ return -EBUSY;
+ }
+ dev->irq = irq;
+ up( &dev->struct_sem );
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+
+ dev->dma->next_buffer = NULL;
+ dev->dma->next_queue = NULL;
+ dev->dma->this_buffer = NULL;
+#if __HAVE_DMA_IRQ_BH
+ INIT_LIST_HEAD( &dev->tq.list );
+ dev->tq.sync = 0;
+ dev->tq.routine = DRM(dma_immediate_bh);
+ dev->tq.data = dev;
#endif
+
+ /* Before installing handler */
+ DRIVER_PREINSTALL();
+
+ /* Install handler */
+ ret = request_irq( dev->irq, DRM(dma_service),
+ 0, dev->devname, dev );
+ if ( ret < 0 ) {
+ down( &dev->struct_sem );
+ dev->irq = 0;
+ up( &dev->struct_sem );
+ return ret;
+ }
+
+ /* After installing handler */
+ DRIVER_POSTINSTALL();
+
+ return 0;
+}
+
+int DRM(irq_uninstall)( drm_device_t *dev )
+{
+ int irq;
+
+ down( &dev->struct_sem );
+ irq = dev->irq;
+ dev->irq = 0;
+ up( &dev->struct_sem );
+
+ if ( !irq )
+ return -EINVAL;
+
+ DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+ DRIVER_UNINSTALL();
+
+ free_irq( irq, dev );
+
+ return 0;
+}
+
+int DRM(control)( 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_control_t ctl;
+
+ if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) )
+ return -EFAULT;
+
+ switch ( ctl.func ) {
+ case DRM_INST_HANDLER:
+ return DRM(irq_install)( dev, ctl.irq );
+ case DRM_UNINST_HANDLER:
+ return DRM(irq_uninstall)( dev );
+ default:
+ return -EINVAL;
+ }
+}
+
+#endif /* __HAVE_DMA_IRQ */
+
+#endif /* __HAVE_DMA */
diff --git a/linux/drm_drv.h b/linux/drm_drv.h
index 05923b50..7447ca6d 100644
--- a/linux/drm_drv.h
+++ b/linux/drm_drv.h
@@ -492,7 +492,8 @@ static int __init drm_init( void )
}
#endif
#if __REALLY_HAVE_MTRR
- dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+ if (dev->agp)
+ dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
dev->agp->agp_info.aper_size*1024*1024,
MTRR_TYPE_WRCOMB,
1 );
@@ -646,7 +647,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
if ( dev->lock.hw_lock &&
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
dev->lock.pid == current->pid ) {
- DRM_ERROR( "Process %d dead, freeing lock for context %d\n",
+ DRM_DEBUG( "Process %d dead, freeing lock for context %d\n",
current->pid,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
#if __HAVE_RELEASE
@@ -697,7 +698,7 @@ int DRM(release)( struct inode *inode, struct file *filp )
DRM_KERNEL_CONTEXT );
}
}
-#else
+#elif __HAVE_DMA
DRM(reclaim_buffers)( dev, priv->pid );
#endif
@@ -804,7 +805,7 @@ int DRM(lock)( struct inode *inode, struct file *filp,
#if __HAVE_MULTIPLE_DMA_QUEUES
drm_queue_t *q;
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
cycles_t start;
dev->lck_start = start = get_cycles();
@@ -892,7 +893,7 @@ int DRM(lock)( struct inode *inode, struct file *filp,
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]);
#endif
return ret;
diff --git a/linux/drm_fops.h b/linux/drm_fops.h
index d646f318..dd574766 100644
--- a/linux/drm_fops.h
+++ b/linux/drm_fops.h
@@ -83,50 +83,6 @@ int DRM(flush)(struct file *filp)
return 0;
}
-#if 0
-/* drm_release is called whenever a process closes /dev/drm*. Linux calls
- this only if any mappings have been closed. */
-
-int drm_release(struct inode *inode, struct file *filp)
-{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
-
- DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
- current->pid, dev->device, dev->open_count);
-
- if (dev->lock.hw_lock
- && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
- && dev->lock.pid == current->pid) {
- DRM_ERROR("Process %d dead, freeing lock for context %d\n",
- current->pid,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
- drm_lock_free(dev,
- &dev->lock.hw_lock->lock,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
- }
- drm_reclaim_buffers(dev, priv->pid);
-
- drm_fasync(-1, filp, 0);
-
- down(&dev->struct_sem);
- if (priv->prev) priv->prev->next = priv->next;
- else dev->file_first = priv->next;
- if (priv->next) priv->next->prev = priv->prev;
- else dev->file_last = priv->prev;
- up(&dev->struct_sem);
-
- drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-
- return 0;
-}
-#endif
-
int DRM(fasync)(int fd, struct file *filp, int on)
{
drm_file_t *priv = filp->private_data;
diff --git a/linux/drm_lists.h b/linux/drm_lists.h
index b597ef77..f8dbaaa7 100644
--- a/linux/drm_lists.h
+++ b/linux/drm_lists.h
@@ -74,7 +74,7 @@ int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf)
buf->idx, buf->pid);
return -EINVAL;
}
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_queued = get_cycles();
#endif
buf->list = DRM_LIST_WAIT;
@@ -106,6 +106,7 @@ drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl)
#endif /* __HAVE_DMA_WAITLIST */
+
#if __HAVE_DMA_FREELIST
int DRM(freelist_create)(drm_freelist_t *bl, int count)
@@ -142,7 +143,7 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
buf->idx, buf->waiting, buf->pending, buf->list);
}
if (!bl) return 1;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
buf->time_freed = get_cycles();
DRM(histogram_compute)(dev, buf);
#endif
diff --git a/linux/drm_memory.h b/linux/drm_memory.h
index caf05394..1763d9b4 100644
--- a/linux/drm_memory.h
+++ b/linux/drm_memory.h
@@ -351,8 +351,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size)
}
}
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-#if __MUST_HAVE_AGP
+#if __REALLY_HAVE_AGP
agp_memory *DRM(alloc_agp)(int pages, u32 type)
{
@@ -457,4 +456,3 @@ int DRM(unbind_agp)(agp_memory *handle)
return retcode;
}
#endif
-#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */
diff --git a/linux/drm_proc.h b/linux/drm_proc.h
index 60628660..f65f42b7 100644
--- a/linux/drm_proc.h
+++ b/linux/drm_proc.h
@@ -50,7 +50,7 @@ static int DRM(bufs_info)(char *buf, char **start, off_t offset,
static int DRM(vma_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
static int DRM(histo_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#endif
@@ -68,7 +68,7 @@ struct drm_proc_list {
#if DRM_DEBUG_CODE
{ "vma", DRM(vma_info) },
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
{ "histo", DRM(histo_info) },
#endif
};
@@ -488,7 +488,7 @@ static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
#endif
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
diff --git a/linux/drm_stub.h b/linux/drm_stub.h
index ed37af4d..bc958796 100644
--- a/linux/drm_stub.h
+++ b/linux/drm_stub.h
@@ -1,4 +1,4 @@
-/* drm_stub.c -- -*- linux-c -*-
+/* drm_stub.h -- -*- linux-c -*-
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
*
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
@@ -28,6 +28,13 @@
*
*/
+#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 {
@@ -58,7 +65,7 @@ static int DRM(stub_open)(struct inode *inode, struct file *filp)
filp->f_op = fops_get(old_fops);
}
fops_put(old_fops);
-
+
return err;
}
@@ -73,7 +80,7 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
drm_device_t *dev)
{
int i;
-
+
if (!DRM(stub_list)) {
DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
* DRM_STUB_MAXCARDS, DRM_MEM_STUB);
@@ -117,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/gamma.h b/linux/gamma.h
index 5ca1f745..232ed018 100644
--- a/linux/gamma.h
+++ b/linux/gamma.h
@@ -1,3 +1,32 @@
+/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
#ifndef __GAMMA_H__
#define __GAMMA_H__
@@ -5,18 +34,60 @@
*/
#define DRM(x) gamma_##x
-#define __HAVE_MTRR 1
-#define __HAVE_PCI_DMA 1
-#define __HAVE_CTX_BITMAP 0
+/* General customization:
+ */
+#define __HAVE_MTRR 1
+
+/* DMA customization:
+ */
+#define __HAVE_DMA 1
+#define __HAVE_OLD_DMA 1
+#define __HAVE_PCI_DMA 1
+
#define __HAVE_MULTIPLE_DMA_QUEUES 1
+#define __HAVE_DMA_WAITQUEUE 1
+
+#define __HAVE_DMA_WAITLIST 1
+#define __HAVE_DMA_FREELIST 1
+
#define __HAVE_DMA_FLUSH 1
-#define __HAVE_DMA_QUEUE 0
#define __HAVE_DMA_SCHEDULE 1
-#define __HAVE_DMA_WAITQUEUE 1
-#define __HAVE_DMA_WAITLIST 1
-#define __HAVE_DMA_FREELIST 1
-#define __HAVE_DMA 1
-#define __HAVE_OLD_DMA 1
-#define __HAVE_DMA_IRQ 1
-#endif
+#define __HAVE_DMA_READY 1
+#define DRIVER_DMA_READY() do { \
+ gamma_dma_ready(dev); \
+} while (0)
+
+#define __HAVE_DMA_QUIESCENT 1
+#define DRIVER_DMA_QUIESCENT() do { \
+ /* FIXME ! */ \
+ gamma_dma_quiescent_dual(dev); \
+ return 0; \
+} while (0)
+
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_DMA_IRQ_BH 1
+#define DRIVER_PREINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
+ GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000000 ); \
+ GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \
+} while (0)
+
+#define DRIVER_POSTINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
+ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \
+ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \
+ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \
+} while (0)
+
+#define DRIVER_UNINSTALL() do { \
+ drm_gamma_private_t *dev_priv = \
+ (drm_gamma_private_t *)dev->dev_private;\
+ GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \
+ GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \
+ GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \
+} while (0)
+
+#endif /* __GAMMA_H__ */
diff --git a/linux/gamma_context.c b/linux/gamma_context.c
deleted file mode 100644
index d94054a2..00000000
--- a/linux/gamma_context.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* context.c -- IOCTLs for contexts and DMA queues -*- linux-c -*-
- * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "gamma.h"
-#include "drmP.h"
-
-static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
-{
- DRM_DEBUG("\n");
-
- if (atomic_read(&q->use_count) != 1
- || atomic_read(&q->finalization)
- || atomic_read(&q->block_count)) {
- DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
- atomic_read(&q->use_count),
- atomic_read(&q->finalization),
- atomic_read(&q->block_count));
- }
-
- atomic_set(&q->finalization, 0);
- atomic_set(&q->block_count, 0);
- atomic_set(&q->block_read, 0);
- atomic_set(&q->block_write, 0);
- atomic_set(&q->total_queued, 0);
- atomic_set(&q->total_flushed, 0);
- atomic_set(&q->total_locks, 0);
-
- init_waitqueue_head(&q->write_queue);
- init_waitqueue_head(&q->read_queue);
- init_waitqueue_head(&q->flush_queue);
-
- q->flags = ctx->flags;
-
- gamma_waitlist_create(&q->waitlist, dev->dma->buf_count);
-
- return 0;
-}
-
-
-/* drm_alloc_queue:
-PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
- disappear (so all deallocation must be done after IOCTLs are off)
- 2) dev->queue_count < dev->queue_slots
- 3) dev->queuelist[i].use_count == 0 and
- dev->queuelist[i].finalization == 0 if i not in use
-POST: 1) dev->queuelist[i].use_count == 1
- 2) dev->queue_count < dev->queue_slots */
-
-static int drm_alloc_queue(drm_device_t *dev)
-{
- int i;
- drm_queue_t *queue;
- int oldslots;
- int newslots;
- /* Check for a free queue */
- for (i = 0; i < dev->queue_count; i++) {
- atomic_inc(&dev->queuelist[i]->use_count);
- if (atomic_read(&dev->queuelist[i]->use_count) == 1
- && !atomic_read(&dev->queuelist[i]->finalization)) {
- DRM_DEBUG("%d (free)\n", i);
- return i;
- }
- atomic_dec(&dev->queuelist[i]->use_count);
- }
- /* Allocate a new queue */
- down(&dev->struct_sem);
-
- queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES);
- memset(queue, 0, sizeof(*queue));
- atomic_set(&queue->use_count, 1);
-
- ++dev->queue_count;
- if (dev->queue_count >= dev->queue_slots) {
- oldslots = dev->queue_slots * sizeof(*dev->queuelist);
- if (!dev->queue_slots) dev->queue_slots = 1;
- dev->queue_slots *= 2;
- newslots = dev->queue_slots * sizeof(*dev->queuelist);
-
- dev->queuelist = gamma_realloc(dev->queuelist,
- oldslots,
- newslots,
- DRM_MEM_QUEUES);
- if (!dev->queuelist) {
- up(&dev->struct_sem);
- DRM_DEBUG("out of memory\n");
- return -ENOMEM;
- }
- }
- dev->queuelist[dev->queue_count-1] = queue;
-
- up(&dev->struct_sem);
- DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
- return dev->queue_count - 1;
-}
-
-int gamma_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- drm_ctx_res_t res;
- drm_ctx_t ctx;
- int i;
-
- DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
- if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
- return -EFAULT;
- if (res.count >= DRM_RESERVED_CONTEXTS) {
- memset(&ctx, 0, sizeof(ctx));
- for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
- ctx.handle = i;
- if (copy_to_user(&res.contexts[i],
- &i,
- sizeof(i)))
- return -EFAULT;
- }
- }
- res.count = DRM_RESERVED_CONTEXTS;
- if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
- return -EFAULT;
- return 0;
-}
-
-
-int gamma_addctx(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_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
- /* Init kernel's context and get a new one. */
- drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
- ctx.handle = drm_alloc_queue(dev);
- }
- drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
- DRM_DEBUG("%d\n", ctx.handle);
- if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
- return -EFAULT;
- return 0;
-}
-
-int gamma_modctx(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_ctx_t ctx;
- drm_queue_t *q;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
-
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- if (DRM_BUFCOUNT(&q->waitlist)) {
- atomic_dec(&q->use_count);
- return -EBUSY;
- }
-
- q->flags = ctx.flags;
-
- atomic_dec(&q->use_count);
- return 0;
-}
-
-int gamma_getctx(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_ctx_t ctx;
- drm_queue_t *q;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
-
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- ctx.flags = q->flags;
- atomic_dec(&q->use_count);
-
- if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
- return -EFAULT;
-
- return 0;
-}
-
-int gamma_switchctx(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_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
- return drm_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int gamma_newctx(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_ctx_t ctx;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
- drm_context_switch_complete(dev, ctx.handle);
-
- return 0;
-}
-
-int gamma_rmctx(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_ctx_t ctx;
- drm_queue_t *q;
- drm_buf_t *buf;
-
- if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
- return -EFAULT;
- DRM_DEBUG("%d\n", ctx.handle);
-
- if (ctx.handle >= dev->queue_count) return -EINVAL;
- q = dev->queuelist[ctx.handle];
-
- atomic_inc(&q->use_count);
- if (atomic_read(&q->use_count) == 1) {
- /* No longer in use */
- atomic_dec(&q->use_count);
- return -EINVAL;
- }
-
- atomic_inc(&q->finalization); /* Mark queue in finalization state */
- atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
- finalization) */
-
- while (test_and_set_bit(0, &dev->interrupt_flag)) {
- schedule();
- if (signal_pending(current)) {
- clear_bit(0, &dev->interrupt_flag);
- return -EINTR;
- }
- }
- /* Remove queued buffers */
- while ((buf = gamma_waitlist_get(&q->waitlist))) {
- gamma_free_buffer(dev, buf);
- }
- clear_bit(0, &dev->interrupt_flag);
-
- /* Wakeup blocked processes */
- wake_up_interruptible(&q->read_queue);
- wake_up_interruptible(&q->write_queue);
- wake_up_interruptible(&q->flush_queue);
-
- /* Finalization over. Queue is made
- available when both use_count and
- finalization become 0, which won't
- happen until all the waiting processes
- stop waiting. */
- atomic_dec(&q->finalization);
- return 0;
-}
diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c
index e2ac6061..d3a9414d 100644
--- a/linux/gamma_dma.c
+++ b/linux/gamma_dma.c
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
*
@@ -37,76 +37,13 @@
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
-#if 0
-#define DO_IOREMAP( _map ) \
-do { \
- (_map)->handle = DRM(ioremap)( (_map)->offset, (_map)->size ); \
-} while (0)
-
-#define DO_IOREMAPFREE( _map ) \
-do { \
- if ( (_map)->handle && (_map)->size ) \
- DRM(ioremapfree)( (_map)->handle, (_map)->size ); \
-} while (0)
-
-#define DO_FIND_MAP( _map, _offset ) \
-do { \
- int _i; \
- for ( _i = 0 ; _i < dev->map_count ; _i++ ) { \
- if ( dev->maplist[_i]->offset == _offset ) { \
- _map = dev->maplist[_i]; \
- break; \
- } \
- } \
-} while (0)
-#endif
-
-/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the
- kernel must be specified here. Currently, the number is 2. This must
- match the order the X server uses for instantiating register regions ,
- or must be passed in a new ioctl. */
-#define GAMMA_REG(reg) \
- (2 \
- + ((reg < 0x1000) \
- ? 0 \
- : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3))))
-
-#define GAMMA_OFF(reg) \
- ((reg < 0x1000) \
- ? reg \
- : ((reg < 0x10000) \
- ? (reg - 0x1000) \
- : ((reg < 0x11000) \
- ? (reg - 0x10000) \
- : (reg - 0x11000))))
-
-#define GAMMA_BASE(reg) ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle)
-#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
-#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
-#define GAMMA_READ(reg) GAMMA_DEREF(reg)
-#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
-
-#define GAMMA_BROADCASTMASK 0x9378
-#define GAMMA_COMMANDINTENABLE 0x0c48
-#define GAMMA_DMAADDRESS 0x0028
-#define GAMMA_DMACOUNT 0x0030
-#define GAMMA_FILTERMODE 0x8c00
-#define GAMMA_GCOMMANDINTFLAGS 0x0c50
-#define GAMMA_GCOMMANDMODE 0x0c40
-#define GAMMA_GCOMMANDSTATUS 0x0c60
-#define GAMMA_GDELAYTIMER 0x0c38
-#define GAMMA_GDMACONTROL 0x0060
-#define GAMMA_GINTENABLE 0x0808
-#define GAMMA_GINTFLAGS 0x0810
-#define GAMMA_INFIFOSPACE 0x0018
-#define GAMMA_OUTFIFOWORDS 0x0020
-#define GAMMA_OUTPUTFIFO 0x2000
-#define GAMMA_SYNC 0x8c40
-#define GAMMA_SYNC_TAG 0x0188
static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
unsigned long length)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address));
while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
;
@@ -115,6 +52,9 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
void gamma_dma_quiescent_single(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -122,7 +62,7 @@ void gamma_dma_quiescent_single(drm_device_t *dev)
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
GAMMA_WRITE(GAMMA_SYNC, 0);
-
+
do {
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
;
@@ -131,6 +71,9 @@ void gamma_dma_quiescent_single(drm_device_t *dev)
void gamma_dma_quiescent_dual(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -140,13 +83,13 @@ void gamma_dma_quiescent_dual(drm_device_t *dev)
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
GAMMA_WRITE(GAMMA_SYNC, 0);
-
+
/* Read from first MX */
do {
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
;
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
-
+
/* Read from second MX */
do {
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
@@ -156,20 +99,28 @@ void gamma_dma_quiescent_dual(drm_device_t *dev)
void gamma_dma_ready(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
while (GAMMA_READ(GAMMA_DMACOUNT))
;
}
static inline int gamma_dma_is_ready(drm_device_t *dev)
{
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
return !GAMMA_READ(GAMMA_DMACOUNT);
}
-static void gamma_dma_service(int irq, void *device, struct pt_regs *regs)
+void gamma_dma_service(int irq, void *device, struct pt_regs *regs)
{
- drm_device_t *dev = (drm_device_t *)device;
- drm_device_dma_t *dma = dev->dma;
-
+ drm_device_t *dev = (drm_device_t *)device;
+ drm_device_dma_t *dma = dev->dma;
+ drm_gamma_private_t *dev_priv =
+ (drm_gamma_private_t *)dev->dev_private;
+
atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
@@ -202,7 +153,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
#endif
if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY;
-
+
#if DRM_DMA_HISTOGRAM
dma_start = get_cycles();
#endif
@@ -234,7 +185,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
clear_bit(0, &dev->dma_flag);
return 0;
}
-
+
if (!gamma_dma_is_ready(dev)) {
clear_bit(0, &dev->dma_flag);
return -EBUSY;
@@ -258,13 +209,14 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
&& !(dev->queuelist[buf->context]->flags
& _DRM_CONTEXT_PRESERVED)) {
/* PRE: dev->last_context != buf->context */
- if (drm_context_switch(dev, dev->last_context, buf->context)) {
- gamma_clear_next_buffer(dev);
- gamma_free_buffer(dev, buf);
+ if (DRM(context_switch)(dev, dev->last_context,
+ buf->context)) {
+ DRM(clear_next_buffer)(dev);
+ DRM(free_buffer)(dev, buf);
}
retcode = -EBUSY;
goto cleanup;
-
+
/* POST: we will wait for the context
switch and will dispatch on a later call
when dev->last_context == buf->context.
@@ -305,12 +257,12 @@ cleanup:
return retcode;
}
-static void gamma_dma_schedule_timer_wrapper(unsigned long dev)
+static void gamma_dma_timer_bh(unsigned long dev)
{
gamma_dma_schedule((drm_device_t *)dev, 0);
}
-static void gamma_dma_schedule_tq_wrapper(void *dev)
+void gamma_dma_immediate_bh(void *dev)
{
gamma_dma_schedule(dev, 0);
}
@@ -354,8 +306,7 @@ again:
if (!(retcode = gamma_do_dma(dev, locked))) ++processed;
} else {
do {
- next = gamma_select_queue(dev,
- gamma_dma_schedule_timer_wrapper);
+ next = gamma_select_queue(dev, gamma_dma_timer_bh);
if (next >= 0) {
q = dev->queuelist[next];
buf = gamma_waitlist_get(&q->waitlist);
@@ -383,9 +334,9 @@ again:
goto again;
}
}
-
+
clear_bit(0, &dev->interrupt_flag);
-
+
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles()
- schedule_start)]);
@@ -472,15 +423,15 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
goto cleanup;
}
buf->pending = 1;
-
+
if (dev->last_context != buf->context
&& !(dev->queuelist[buf->context]->flags
& _DRM_CONTEXT_PRESERVED)) {
add_wait_queue(&dev->context_wait, &entry);
current->state = TASK_INTERRUPTIBLE;
/* PRE: dev->last_context != buf->context */
- drm_context_switch(dev, dev->last_context,
- buf->context);
+ DRM(context_switch)(dev, dev->last_context,
+ buf->context);
/* POST: we will wait for the context
switch and will dispatch on a later call
when dev->last_context == buf->context.
@@ -507,7 +458,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
gamma_dma_dispatch(dev, address, length);
atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */
atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
-
+
if (last_buf) {
gamma_free_buffer(dev, last_buf);
}
@@ -520,7 +471,7 @@ cleanup:
gamma_dma_ready(dev);
gamma_free_buffer(dev, last_buf);
}
-
+
if (must_free && !dev->context_flag) {
if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
@@ -542,15 +493,15 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
last_buf = dma->buflist[d->send_indices[d->send_count-1]];
add_wait_queue(&last_buf->dma_wait, &entry);
}
-
+
if ((retcode = gamma_dma_enqueue(dev, d))) {
if (d->flags & _DRM_DMA_BLOCK)
remove_wait_queue(&last_buf->dma_wait, &entry);
return retcode;
}
-
+
gamma_dma_schedule(dev, 0);
-
+
if (d->flags & _DRM_DMA_BLOCK) {
DRM_DEBUG("%d waiting\n", current->pid);
for (;;) {
@@ -618,7 +569,7 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
if (d.send_count) {
if (d.flags & _DRM_DMA_PRIORITY)
retcode = gamma_dma_priority(dev, &d);
- else
+ else
retcode = gamma_dma_send_buffers(dev, &d);
}
@@ -635,105 +586,3 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
return retcode;
}
-
-int gamma_irq_install(drm_device_t *dev, int irq)
-{
- int retcode;
-
- if (!irq) return -EINVAL;
-
- down(&dev->struct_sem);
- if (dev->irq) {
- up(&dev->struct_sem);
- return -EBUSY;
- }
- dev->irq = irq;
- up(&dev->struct_sem);
-
- DRM_DEBUG("%d\n", irq);
-
- dev->context_flag = 0;
- dev->interrupt_flag = 0;
- dev->dma_flag = 0;
-
- dev->dma->next_buffer = NULL;
- dev->dma->next_queue = NULL;
- dev->dma->this_buffer = NULL;
-
- INIT_LIST_HEAD(&dev->tq.list);
- dev->tq.sync = 0;
- dev->tq.routine = gamma_dma_schedule_tq_wrapper;
- dev->tq.data = dev;
-
-
- /* Before installing handler */
- GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0);
- GAMMA_WRITE(GAMMA_GDMACONTROL, 0);
-
- /* Install handler */
- if ((retcode = request_irq(dev->irq,
- gamma_dma_service,
- 0,
- dev->devname,
- dev))) {
- down(&dev->struct_sem);
- dev->irq = 0;
- up(&dev->struct_sem);
- return retcode;
- }
-
- /* After installing handler */
- GAMMA_WRITE(GAMMA_GINTENABLE, 0x2001);
- GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008);
- GAMMA_WRITE(GAMMA_GDELAYTIMER, 0x39090);
-
- return 0;
-}
-
-int gamma_irq_uninstall(drm_device_t *dev)
-{
- int irq;
-
- down(&dev->struct_sem);
- irq = dev->irq;
- dev->irq = 0;
- up(&dev->struct_sem);
-
- if (!irq) return -EINVAL;
-
- DRM_DEBUG("%d\n", irq);
-
- GAMMA_WRITE(GAMMA_GDELAYTIMER, 0);
- GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0);
- GAMMA_WRITE(GAMMA_GINTENABLE, 0);
- free_irq(irq, dev);
-
- return 0;
-}
-
-
-int gamma_control(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_control_t ctl;
- int retcode;
-
- if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
- return -EFAULT;
-
- switch (ctl.func) {
- case DRM_INST_HANDLER:
- if ((retcode = gamma_irq_install(dev, ctl.irq)))
- return retcode;
- break;
- case DRM_UNINST_HANDLER:
- if ((retcode = gamma_irq_uninstall(dev)))
- return retcode;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
diff --git a/linux/gamma_drm.c b/linux/gamma_drm.c
deleted file mode 100644
index 4b12d8c4..00000000
--- a/linux/gamma_drm.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#define __NO_VERSION__
-#include "gamma.h"
-#include "drmP.h"
-#include "gamma_drv.h"
-
-#define DRIVER_DEV_PRIV_T drm_gamma_private_t
-#define DRIVER_AGP_BUFFER_MAP dev_priv->buffers
-
-#include "drm_auth.h"
-
-#include "drm_bufs.h"
-
-#include "drm_dma.h"
-
-#include "drm_drawable.h"
-
-#include "drm_fops.h"
-
-#include "drm_init.h"
-
-#include "drm_ioctl.h"
-
-#include "drm_lists.h"
-
-#include "drm_lock.h"
-
-#include "drm_memory.h"
-
-#include "drm_proc.h"
-
-#include "drm_vm.h"
-
-#include "drm_stub.h"
diff --git a/linux/gamma_drm.h b/linux/gamma_drm.h
deleted file mode 100644
index b4acd70a..00000000
--- a/linux/gamma_drm.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* gamma_drm.h -- Public header for the Gamma driver -*- linux-c -*-
- * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Jeff Hartmann <jhartmann@valinux.com>
- */
-
-#ifndef __GAMMA_DRM_H__
-#define __GAMMA_DRM_H__
-
-typedef struct drm_gamma_init {
- unsigned long hControlRegs0;
- unsigned long hControlRegs1;
- unsigned long hControlRegs2;
- unsigned long hControlRegs3;
-} drm_gamma_init_t;
-
-#endif
diff --git a/linux/gamma_drv.c b/linux/gamma_drv.c
index c24d5a33..98916bc5 100644
--- a/linux/gamma_drv.c
+++ b/linux/gamma_drv.c
@@ -26,7 +26,7 @@
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
- *
+ * Gareth Hughes <gareth@valinux.com>
*/
#include <linux/config.h>
@@ -38,29 +38,15 @@
#define DRIVER_NAME "gamma"
#define DRIVER_DESC "3DLabs gamma"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }
-#define __HAVE_MTRR 1
-#define __HAVE_CTX_BITMAP 0
-#define __HAVE_PCI_DMA 1
-#define __HAVE_MULTIPLE_DMA_QUEUES 1
-#define __HAVE_DMA_FLUSH 1
-#define __HAVE_DMA_QUEUE 0
-#define __HAVE_DMA_SCHEDULE 1
-#define __HAVE_DMA_WAITQUEUE 1
-#define __HAVE_DMA_WAITLIST 1
-#define __HAVE_DMA_FREELIST 1
-#define __HAVE_DMA 1
-#define __HAVE_OLD_DMA 1
-#define __HAVE_DMA_IRQ 1
#define __HAVE_COUNTERS 5
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
@@ -69,35 +55,19 @@
#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL
#define __HAVE_COUNTER10 _DRM_STAT_MISSED
-#define __HAVE_DMA_READY 1
-#define DRIVER_DMA_READY() \
-do { \
- gamma_dma_ready(dev); \
-} while (0)
-
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() \
-do { \
- /* FIXME ! */ \
- gamma_dma_quiescent_dual(dev); \
- return 0; \
-} while (0)
-
-#if 0
-#define __HAVE_DRIVER_RELEASE 1
-#define DRIVER_RELEASE() do { \
- gamma_reclaim_buffers( dev, priv->pid ); \
- if ( dev->dev_private ) { \
- drm_gamma_private_t *dev_priv = dev->dev_private; \
- dev_priv->dispatch_status &= MGA_IN_DISPATCH; \
- } \
-} while (0)
-#endif
-
-#if 0
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) gamma_do_cleanup_dma( dev ); \
-} while (0)
-#endif
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
#include "drm_drv.h"
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lists.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h
index 1bfa2650..68b52070 100644
--- a/linux/gamma_drv.h
+++ b/linux/gamma_drv.h
@@ -11,11 +11,11 @@
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,10 +23,10 @@
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
- *
+ *
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
- *
+ *
*/
#ifndef _GAMMA_DRV_H_
@@ -35,6 +35,10 @@
typedef struct drm_gamma_private {
drm_map_t *buffers;
+ drm_map_t *mmio0;
+ drm_map_t *mmio1;
+ drm_map_t *mmio2;
+ drm_map_t *mmio3;
} drm_gamma_private_t;
#define LOCK_TEST_WITH_RETURN( dev ) \
@@ -47,30 +51,55 @@ do { \
} \
} while (0)
+
extern void gamma_dma_ready(drm_device_t *dev);
extern void gamma_dma_quiescent_single(drm_device_t *dev);
extern void gamma_dma_quiescent_dual(drm_device_t *dev);
- /* gamma_drv.c */
-extern int gamma_version(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int gamma_open(struct inode *inode, struct file *filp);
-extern int gamma_release(struct inode *inode, struct file *filp);
-extern int gamma_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int gamma_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int gamma_unlock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
/* gamma_dma.c */
extern int gamma_dma_schedule(drm_device_t *dev, int locked);
extern int gamma_dma(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int gamma_irq_install(drm_device_t *dev, int irq);
-extern int gamma_irq_uninstall(drm_device_t *dev);
-extern int gamma_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int gamma_find_devices(void);
extern int gamma_found(void);
+
+#define GAMMA_OFF(reg) \
+ ((reg < 0x1000) \
+ ? reg \
+ : ((reg < 0x10000) \
+ ? (reg - 0x1000) \
+ : ((reg < 0x11000) \
+ ? (reg - 0x10000) \
+ : (reg - 0x11000))))
+
+#define GAMMA_BASE(reg) ((unsigned long) \
+ ((reg < 0x1000) ? dev_priv->mmio0->handle : \
+ ((reg < 0x10000) ? dev_priv->mmio1->handle : \
+ ((reg < 0x11000) ? dev_priv->mmio2->handle : \
+ dev_priv->mmio3->handle))))
+
+#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
+#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
+#define GAMMA_READ(reg) GAMMA_DEREF(reg)
+#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
+
+#define GAMMA_BROADCASTMASK 0x9378
+#define GAMMA_COMMANDINTENABLE 0x0c48
+#define GAMMA_DMAADDRESS 0x0028
+#define GAMMA_DMACOUNT 0x0030
+#define GAMMA_FILTERMODE 0x8c00
+#define GAMMA_GCOMMANDINTFLAGS 0x0c50
+#define GAMMA_GCOMMANDMODE 0x0c40
+#define GAMMA_GCOMMANDSTATUS 0x0c60
+#define GAMMA_GDELAYTIMER 0x0c38
+#define GAMMA_GDMACONTROL 0x0060
+#define GAMMA_GINTENABLE 0x0808
+#define GAMMA_GINTFLAGS 0x0810
+#define GAMMA_INFIFOSPACE 0x0018
+#define GAMMA_OUTFIFOWORDS 0x0020
+#define GAMMA_OUTPUTFIFO 0x2000
+#define GAMMA_SYNC 0x8c40
+#define GAMMA_SYNC_TAG 0x0188
+
#endif
diff --git a/linux/i810.h b/linux/i810.h
index 021d7988..ed25b2a9 100644
--- a/linux/i810.h
+++ b/linux/i810.h
@@ -34,17 +34,79 @@
*/
#define DRM(x) i810_##x
+/* General customization:
+ */
#define __HAVE_AGP 1
#define __MUST_HAVE_AGP 1
-
#define __HAVE_MTRR 1
-
#define __HAVE_CTX_BITMAP 1
+/* Driver customization:
+ */
+#define __HAVE_RELEASE 1
+#define DRIVER_RELEASE() do { \
+ i810_reclaim_buffers( dev, priv->pid ); \
+} while (0)
+
+/* DMA customization:
+ */
#define __HAVE_DMA 1
-#define __HAVE_DMA_IRQ 1
#define __HAVE_DMA_QUEUE 1
#define __HAVE_DMA_WAITLIST 1
#define __HAVE_DMA_RECLAIM 1
+#define __HAVE_DMA_QUIESCENT 1
+#define DRIVER_DMA_QUIESCENT() do { \
+ i810_dma_quiescent( dev ); \
+} while (0)
+
+#define __HAVE_DMA_IRQ 1
+#define __HAVE_DMA_IRQ_BH 1
+#define DRIVER_PREINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
+ u16 tmp; \
+ tmp = I810_READ16( I810REG_HWSTAM ); \
+ tmp = tmp & 0x6000; \
+ I810_WRITE16( I810REG_HWSTAM, tmp ); \
+ \
+ tmp = I810_READ16( I810REG_INT_MASK_R ); \
+ tmp = tmp & 0x6000; /* Unmask interrupts */ \
+ I810_WRITE16( I810REG_INT_MASK_R, tmp ); \
+ tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
+ tmp = tmp & 0x6000; /* Disable all interrupts */ \
+ I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
+} while (0)
+
+#define DRIVER_POSTINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
+ u16 tmp; \
+ tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
+ tmp = tmp & 0x6000; \
+ tmp = tmp | 0x0003; /* Enable bp & user interrupts */ \
+ I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
+} while (0)
+
+#define DRIVER_UNINSTALL() do { \
+ drm_i810_private_t *dev_priv = \
+ (drm_i810_private_t *)dev->dev_private; \
+ u16 tmp; \
+ tmp = I810_READ16( I810REG_INT_IDENTITY_R ); \
+ tmp = tmp & ~(0x6000); /* Clear all interrupts */ \
+ if ( tmp != 0 ) I810_WRITE16( I810REG_INT_IDENTITY_R, tmp ); \
+ \
+ tmp = I810_READ16( I810REG_INT_ENABLE_R ); \
+ tmp = tmp & 0x6000; /* Disable all interrupts */ \
+ I810_WRITE16( I810REG_INT_ENABLE_R, tmp ); \
+} while (0)
+
+/* Buffer customization:
+ */
+
+#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev ) \
+ ((drm_i810_private_t *)((dev)->dev_private))->buffer_map
+
#endif
diff --git a/linux/i810_dma.c b/linux/i810_dma.c
index 8c50b320..4c90496a 100644
--- a/linux/i810_dma.c
+++ b/linux/i810_dma.c
@@ -48,16 +48,6 @@
#define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1
-#define I810_BASE(reg) ((unsigned long) \
- dev_priv->mmio_map->handle)
-#define I810_ADDR(reg) (I810_BASE(reg) + reg)
-#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
-#define I810_READ(reg) I810_DEREF(reg)
-#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
-#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
-#define I810_READ16(reg) I810_DEREF16(reg)
-#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
-
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
#define BEGIN_LP_RING(n) do { \
@@ -875,7 +865,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
/* Interrupts are only for flushing */
-static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
+void i810_dma_service(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
@@ -893,7 +883,7 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
mark_bh(IMMEDIATE_BH);
}
-static void i810_dma_task_queue(void *device)
+void i810_dma_immediate_bh(void *device)
{
drm_device_t *dev = (drm_device_t *) device;
drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
@@ -902,131 +892,6 @@ static void i810_dma_task_queue(void *device)
wake_up_interruptible(&dev_priv->flush_queue);
}
-int i810_irq_install(drm_device_t *dev, int irq)
-{
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- int retcode;
- u16 temp;
-
- if (!irq) return -EINVAL;
-
- down(&dev->struct_sem);
- if (dev->irq) {
- up(&dev->struct_sem);
- return -EBUSY;
- }
- dev->irq = irq;
- up(&dev->struct_sem);
-
- DRM_DEBUG( "Interrupt Install : %d\n", irq);
- DRM_DEBUG("%d\n", irq);
-
- dev->context_flag = 0;
- dev->interrupt_flag = 0;
- dev->dma_flag = 0;
-
- dev->dma->next_buffer = NULL;
- dev->dma->next_queue = NULL;
- dev->dma->this_buffer = NULL;
-
- INIT_LIST_HEAD(&dev->tq.list);
- dev->tq.sync = 0;
- dev->tq.routine = i810_dma_task_queue;
- dev->tq.data = dev;
-
- /* Before installing handler */
- temp = I810_READ16(I810REG_HWSTAM);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_HWSTAM, temp);
-
- temp = I810_READ16(I810REG_INT_MASK_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */
-
- /* Install handler */
- if ((retcode = request_irq(dev->irq,
- i810_dma_service,
- SA_SHIRQ,
- dev->devname,
- dev))) {
- down(&dev->struct_sem);
- dev->irq = 0;
- up(&dev->struct_sem);
- return retcode;
- }
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- temp = temp | 0x0003;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Enable bp & user interrupts */
- return 0;
-}
-
-int i810_irq_uninstall(drm_device_t *dev)
-{
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- int irq;
- u16 temp;
-
-
-/* return 0; */
-
- down(&dev->struct_sem);
- irq = dev->irq;
- dev->irq = 0;
- up(&dev->struct_sem);
-
- if (!irq) return -EINVAL;
-
- DRM_DEBUG( "Interrupt UnInstall: %d\n", irq);
- DRM_DEBUG("%d\n", irq);
-
- temp = I810_READ16(I810REG_INT_IDENTITY_R);
- temp = temp & ~(0x6000);
- if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
- temp); /* Clear all interrupts */
-
- temp = I810_READ16(I810REG_INT_ENABLE_R);
- temp = temp & 0x6000;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Disable all interrupts */
-
- free_irq(irq, dev);
-
- return 0;
-}
-
-int i810_control(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_control_t ctl;
- int retcode;
-
- DRM_DEBUG( "i810_control\n");
-
- if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
- return -EFAULT;
-
- switch (ctl.func) {
- case DRM_INST_HANDLER:
- if ((retcode = i810_irq_install(dev, ctl.irq)))
- return retcode;
- break;
- case DRM_UNINST_HANDLER:
- if ((retcode = i810_irq_uninstall(dev)))
- return retcode;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
static inline void i810_dma_emit_flush(drm_device_t *dev)
{
drm_i810_private_t *dev_priv = dev->dev_private;
diff --git a/linux/i810_drv.c b/linux/i810_drv.c
index 86ab394d..12a59dbf 100644
--- a/linux/i810_drv.c
+++ b/linux/i810_drv.c
@@ -56,42 +56,26 @@
[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
+
#define __HAVE_COUNTERS 4
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#define __HAVE_COUNTER9 _DRM_STAT_DMA
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() do { \
- i810_dma_quiescent( dev ); \
-} while (0)
-
-#define __HAVE_RELEASE 1
-#define DRIVER_RELEASE() do { \
- i810_reclaim_buffers( dev, priv->pid ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_i810_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_i810_private_t *)((dev)->dev_private))->buffer_map
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_lock.h"
+#include "drm_lists.h"
#include "drm_memory.h"
#include "drm_proc.h"
#include "drm_vm.h"
diff --git a/linux/i810_drv.h b/linux/i810_drv.h
index 1f6e1468..e1b17148 100644
--- a/linux/i810_drv.h
+++ b/linux/i810_drv.h
@@ -81,12 +81,6 @@ typedef struct drm_i810_private {
extern int i810_dma_schedule(drm_device_t *dev, int locked);
extern int i810_getbuf(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int i810_irq_install(drm_device_t *dev, int irq);
-extern int i810_irq_uninstall(drm_device_t *dev);
-extern int i810_control(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
-extern int i810_lock(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg);
extern int i810_dma_init(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_flush_ioctl(struct inode *inode, struct file *filp,
@@ -114,6 +108,18 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
int i810_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
+
+#define I810_BASE(reg) ((unsigned long) \
+ dev_priv->mmio_map->handle)
+#define I810_ADDR(reg) (I810_BASE(reg) + reg)
+#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
+#define I810_READ(reg) I810_DEREF(reg)
+#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
+#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
+#define I810_READ16(reg) I810_DEREF16(reg)
+#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
+
+
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
#define CMD_REPORT_HEAD (7<<23)
diff --git a/linux/mga.h b/linux/mga.h
index 9b222404..277aa202 100644
--- a/linux/mga.h
+++ b/linux/mga.h
@@ -34,13 +34,34 @@
*/
#define DRM(x) mga_##x
+/* General customization:
+ */
#define __HAVE_AGP 1
#define __MUST_HAVE_AGP 1
-
#define __HAVE_MTRR 1
-
#define __HAVE_CTX_BITMAP 1
+/* Driver customization:
+ */
+#define DRIVER_PRETAKEDOWN() do { \
+ if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \
+} while (0)
+
+/* DMA customization:
+ */
#define __HAVE_DMA 1
+#define __HAVE_DMA_QUIESCENT 1
+#define DRIVER_DMA_QUIESCENT() do { \
+ drm_mga_private_t *dev_priv = dev->dev_private; \
+ return mga_do_wait_for_idle( dev_priv ); \
+} while (0)
+
+/* Buffer customization:
+ */
+#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev ) \
+ ((drm_mga_private_t *)((dev)->dev_private))->buffers
+
#endif
diff --git a/linux/mga_dma.c b/linux/mga_dma.c
index 275495dc..21e14f37 100644
--- a/linux/mga_dma.c
+++ b/linux/mga_dma.c
@@ -57,7 +57,6 @@ 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 ) {
- /* printk("I'm not busy, flushing pixel cache\n"); */
MGA_WRITE8( MGA_CRTC_INDEX, 0 );
return 0;
}
@@ -273,7 +272,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 ) {
@@ -354,7 +354,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;
@@ -400,7 +399,7 @@ static drm_buf_t *mga_freelist_get( drm_device_t *dev )
return NULL;
}
-static int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
+int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
@@ -412,15 +411,17 @@ static 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;
diff --git a/linux/mga_drv.c b/linux/mga_drv.c
index 7898c744..88fa53a6 100644
--- a/linux/mga_drv.c
+++ b/linux/mga_drv.c
@@ -38,7 +38,7 @@
#define DRIVER_NAME "mga"
#define DRIVER_DESC "Matrox G200/G400"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 3
#define DRIVER_MINOR 0
@@ -56,38 +56,20 @@
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_dma_iload, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)] = { mga_dma_blit, 1, 0 },
+
#define __HAVE_COUNTERS 3
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() \
-do { \
- drm_mga_private_t *dev_priv = dev->dev_private; \
- return mga_do_wait_for_idle( dev_priv ); \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) mga_do_cleanup_dma( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_mga_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_mga_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux/mga_drv.h b/linux/mga_drv.h
index ab6d9edb..f56186e1 100644
--- a/linux/mga_drv.h
+++ b/linux/mga_drv.h
@@ -102,18 +102,6 @@ typedef struct drm_mga_private {
drm_map_t *agp_textures;
} drm_mga_private_t;
- /* mga_drv.c */
-extern int mga_version( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_open( struct inode *inode, struct file *filp );
-extern int mga_release( struct inode *inode, struct file *filp );
-extern int mga_ioctl( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_lock( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-extern int mga_unlock( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
-
/* mga_dma.c */
extern int mga_dma_init( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -121,8 +109,6 @@ extern int mga_dma_flush( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int mga_dma_reset( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int mga_control( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
extern int mga_dma_buffers( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@@ -136,7 +122,8 @@ extern void mga_do_dma_flush( drm_mga_private_t *dev_priv );
extern void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv );
extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv );
-extern int mga_irq_uninstall( drm_device_t *dev );
+extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
+
/* mga_state.c */
extern int mga_dma_clear( struct inode *inode, struct file *filp,
diff --git a/linux/r128.h b/linux/r128.h
index 0440501e..83e002af 100644
--- a/linux/r128.h
+++ b/linux/r128.h
@@ -34,13 +34,46 @@
*/
#define DRM(x) r128_##x
+/* General customization:
+ */
#define __HAVE_AGP 1
#define __MUST_HAVE_AGP 1
-
#define __HAVE_MTRR 1
-
#define __HAVE_CTX_BITMAP 1
+/* Driver customization:
+ */
+#define DRIVER_PRERELEASE() do { \
+ if ( dev->dev_private ) { \
+ drm_r128_private_t *dev_priv = dev->dev_private; \
+ if ( dev_priv->page_flipping ) { \
+ r128_do_cleanup_pageflip( dev ); \
+ } \
+ } \
+} while (0)
+
+#define DRIVER_PRETAKEDOWN() do { \
+ if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \
+} while (0)
+
+/* DMA customization:
+ */
#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:
+ */
+#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev ) \
+ ((drm_r128_private_t *)((dev)->dev_private))->buffers
+
#endif
diff --git a/linux/r128_cce.c b/linux/r128_cce.c
index 5ffc1d0e..f4b4f0c4 100644
--- a/linux/r128_cce.c
+++ b/linux/r128_cce.c
@@ -25,7 +25,7 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Gareth Hughes <gareth@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
*/
#define __NO_VERSION__
diff --git a/linux/r128_drm.h b/linux/r128_drm.h
index aaf2ce3e..86aba175 100644
--- a/linux/r128_drm.h
+++ b/linux/r128_drm.h
@@ -25,9 +25,8 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- *
+ * Kevin E. Martin <martin@valinux.com>
*/
#ifndef __R128_DRM_H__
diff --git a/linux/r128_drv.c b/linux/r128_drv.c
index 3bd27ae7..e42868ed 100644
--- a/linux/r128_drv.c
+++ b/linux/r128_drv.c
@@ -38,7 +38,7 @@
#define DRIVER_NAME "r128"
#define DRIVER_DESC "ATI Rage 128"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 1
@@ -62,6 +62,7 @@
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 },
+
#if 0
/* GH: Count data sent to card via ring or vertex/indirect buffers.
*/
@@ -71,41 +72,14 @@
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#endif
-#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)
-
-#define DRIVER_PRERELEASE() do { \
- if ( dev->dev_private ) { \
- drm_r128_private_t *dev_priv = dev->dev_private; \
- if ( dev_priv->page_flipping ) { \
- r128_do_cleanup_pageflip( dev ); \
- } \
- } \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) r128_do_cleanup_cce( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_r128_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_r128_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index 950a4711..9f53746f 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -25,10 +25,9 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Kevin E. Martin <martin@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- *
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
*/
#ifndef __R128_DRV_H__
@@ -440,8 +439,7 @@ do { \
} \
} while (0)
-#define R128_WAIT_UNTIL_PAGE_FLIPPED() \
-do { \
+#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \
OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \
OUT_RING( R128_EVENT_CRTC_OFFSET ); \
} while (0)
@@ -456,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 ) { \
@@ -472,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/r128_state.c b/linux/r128_state.c
index a4683c4e..fa16f3ce 100644
--- a/linux/r128_state.c
+++ b/linux/r128_state.c
@@ -25,7 +25,6 @@
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
- *
*/
#define __NO_VERSION__
diff --git a/linux/radeon.h b/linux/radeon.h
index 6ef99277..db238b1b 100644
--- a/linux/radeon.h
+++ b/linux/radeon.h
@@ -34,13 +34,46 @@
*/
#define DRM(x) radeon_##x
+/* General customization:
+ */
#define __HAVE_AGP 1
#define __MUST_HAVE_AGP 1
-
#define __HAVE_MTRR 1
-
#define __HAVE_CTX_BITMAP 1
+/* Driver customization:
+ */
+#define DRIVER_PRERELEASE() do { \
+ if ( dev->dev_private ) { \
+ drm_radeon_private_t *dev_priv = dev->dev_private; \
+ if ( dev_priv->page_flipping ) { \
+ radeon_do_cleanup_pageflip( dev ); \
+ } \
+ } \
+} while (0)
+
+#define DRIVER_PRETAKEDOWN() do { \
+ if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \
+} while (0)
+
+/* DMA customization:
+ */
#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; \
+ return radeon_do_cp_idle( dev_priv ); \
+} while (0)
+#endif
+
+/* Buffer customization:
+ */
+#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev ) \
+ ((drm_radeon_private_t *)((dev)->dev_private))->buffers
+
#endif
diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c
index 28e64284..c80665ca 100644
--- a/linux/radeon_cp.c
+++ b/linux/radeon_cp.c
@@ -24,9 +24,8 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- *
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
*/
#define __NO_VERSION__
@@ -844,11 +843,8 @@ int radeon_cp_start( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( dev_priv->cp_running ) {
DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
return 0;
@@ -877,11 +873,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp,
int ret;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
return -EFAULT;
@@ -923,11 +915,8 @@ int radeon_cp_reset( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv ) {
DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
return -EINVAL;
@@ -949,11 +938,7 @@ int radeon_cp_idle( struct inode *inode, struct file *filp,
drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
return radeon_do_cp_idle( dev_priv );
}
@@ -965,11 +950,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
return radeon_do_engine_reset( dev );
}
@@ -1019,11 +1000,7 @@ int radeon_fullscreen( struct inode *inode, struct file *filp,
drm_device_t *dev = priv->dev;
drm_radeon_fullscreen_t fs;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
sizeof(fs) ) )
@@ -1247,14 +1224,10 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
int ret = 0;
drm_dma_t d;
- if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
- return -EFAULT;
+ LOCK_TEST_WITH_RETURN( dev );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
+ return -EFAULT;
/* Please don't send us buffers.
*/
@@ -1278,7 +1251,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
ret = radeon_cp_get_buffers( dev, &d );
}
- if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
+ if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
return -EFAULT;
return ret;
diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h
index 643253d2..50a7d6ed 100644
--- a/linux/radeon_drm.h
+++ b/linux/radeon_drm.h
@@ -26,7 +26,6 @@
* Authors:
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- *
*/
#ifndef __RADEON_DRM_H__
@@ -74,7 +73,7 @@
/* Vertex/indirect buffer size
*/
-#define RADEON_BUFFER_SIZE 16384
+#define RADEON_BUFFER_SIZE 65536
/* Byte offsets for indirect buffer data
*/
@@ -305,14 +304,20 @@ typedef struct drm_radeon_indices {
int discard; /* Client finished with buffer? */
} drm_radeon_indices_t;
-typedef struct drm_radeon_blit {
- int idx;
- int pitch;
+typedef struct drm_radeon_tex_image {
+ unsigned int x, y; /* Blit coordinates */
+ unsigned int width, height;
+ const void *data;
+} drm_radeon_tex_image_t;
+
+typedef struct drm_radeon_texture {
int offset;
+ int pitch;
int format;
- unsigned short x, y;
- unsigned short width, height;
-} drm_radeon_blit_t;
+ int width; /* Texture image coordinates */
+ int height;
+ drm_radeon_tex_image_t *image;
+} drm_radeon_texture_t;
typedef struct drm_radeon_stipple {
unsigned int *mask;
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 43f6e2e7..1aa889ae 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 "20010215"
+#define DRIVER_DATE "20010305"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
@@ -55,10 +55,11 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)] = { radeon_cp_texture, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 },
+
#if 0
/* GH: Count data sent to card via ring or vertex/indirect buffers.
*/
@@ -68,41 +69,14 @@
#define __HAVE_COUNTER8 _DRM_STAT_SECONDARY
#endif
-#define __HAVE_DMA_QUIESCENT 1
-#define DRIVER_DMA_QUIESCENT() do { \
- drm_radeon_private_t *dev_priv = dev->dev_private; \
- return radeon_do_cp_idle( dev_priv ); \
-} while (0)
-
-#define DRIVER_PRERELEASE() do { \
- if ( dev->dev_private ) { \
- drm_radeon_private_t *dev_priv = dev->dev_private; \
- if ( dev_priv->page_flipping ) { \
- radeon_do_cleanup_pageflip( dev ); \
- } \
- } \
-} while (0)
-
-#define DRIVER_PRETAKEDOWN() do { \
- if ( dev->dev_private ) radeon_do_cleanup_cp( dev ); \
-} while (0)
-
-#include "drm_drv.h"
-
-
-#define DRIVER_BUF_PRIV_T drm_radeon_buf_priv_t
-
-#define DRIVER_AGP_BUFFERS_MAP( dev ) \
- ((drm_radeon_private_t *)((dev)->dev_private))->buffers
-
-#include "drm_bufs.h"
-
#include "drm_agpsupport.h"
#include "drm_auth.h"
+#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h
index 656d6e03..d279b046 100644
--- a/linux/radeon_drv.h
+++ b/linux/radeon_drv.h
@@ -24,10 +24,8 @@
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Rickard E. (Rik) Faith <faith@valinux.com>
- * Kevin E. Martin <martin@valinux.com>
- * Gareth Hughes <gareth@valinux.com>
- *
+ * Kevin E. Martin <martin@valinux.com>
+ * Gareth Hughes <gareth@valinux.com>
*/
#ifndef __RADEON_DRV_H__
@@ -163,8 +161,8 @@ extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indices( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
-extern int radeon_cp_blit( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg );
+extern int radeon_cp_texture( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
@@ -480,14 +478,14 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#define RADEON_COLOR_FORMAT_RGB8 9
#define RADEON_COLOR_FORMAT_ARGB4444 15
-#define RADEON_TXF_8BPP_I 0
-#define RADEON_TXF_16BPP_AI88 1
-#define RADEON_TXF_8BPP_RGB332 2
-#define RADEON_TXF_16BPP_ARGB1555 3
-#define RADEON_TXF_16BPP_RGB565 4
-#define RADEON_TXF_16BPP_ARGB4444 5
-#define RADEON_TXF_32BPP_ARGB8888 6
-#define RADEON_TXF_32BPP_RGBA8888 7
+#define RADEON_TXFORMAT_I8 0
+#define RADEON_TXFORMAT_AI88 1
+#define RADEON_TXFORMAT_RGB332 2
+#define RADEON_TXFORMAT_ARGB1555 3
+#define RADEON_TXFORMAT_RGB565 4
+#define RADEON_TXFORMAT_ARGB4444 5
+#define RADEON_TXFORMAT_ARGB8888 6
+#define RADEON_TXFORMAT_RGBA8888 7
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -504,25 +502,23 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
-#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg)
+#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
-#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR(reg)
-#define RADEON_READ(reg) RADEON_DEREF(reg)
-#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0)
+#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg )
+#define RADEON_READ(reg) RADEON_DEREF( reg )
+#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
-#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR(reg)
-#define RADEON_READ8(reg) RADEON_DEREF8(reg)
-#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0)
+#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg )
+#define RADEON_READ8(reg) RADEON_DEREF8( reg )
+#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
-#define RADEON_WRITE_PLL(addr,val) \
-do { \
- RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \
- ((addr) & 0x1f) | RADEON_PLL_WR_EN); \
- RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \
+#define RADEON_WRITE_PLL( addr, val ) do { \
+ RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \
+ ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \
+ RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
} while (0)
-extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
-
+extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
#define CP_PACKET0( reg, n ) \
@@ -541,54 +537,46 @@ extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
* Engine control helper macros
*/
-#define RADEON_WAIT_UNTIL_2D_IDLE() \
-do { \
+#define RADEON_WAIT_UNTIL_2D_IDLE() do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
-#define RADEON_WAIT_UNTIL_3D_IDLE() \
-do { \
+#define RADEON_WAIT_UNTIL_3D_IDLE() do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
-#define RADEON_WAIT_UNTIL_IDLE() \
-do { \
+#define RADEON_WAIT_UNTIL_IDLE() do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
RADEON_WAIT_3D_IDLECLEAN | \
RADEON_WAIT_HOST_IDLECLEAN) ); \
} while (0)
-#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \
-do { \
+#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \
} while (0)
-#define RADEON_FLUSH_CACHE() \
-do { \
+#define RADEON_FLUSH_CACHE() do { \
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB2D_DC_FLUSH ); \
} while (0)
-#define RADEON_PURGE_CACHE() \
-do { \
+#define RADEON_PURGE_CACHE() do { \
OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \
} while (0)
-#define RADEON_FLUSH_ZCACHE() \
-do { \
+#define RADEON_FLUSH_ZCACHE() do { \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
} while (0)
-#define RADEON_PURGE_ZCACHE() \
-do { \
+#define RADEON_PURGE_ZCACHE() do { \
OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
} while (0)
@@ -598,6 +586,16 @@ do { \
* Misc helper macros
*/
+#define LOCK_TEST_WITH_RETURN( dev ) \
+do { \
+ if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
+ dev->lock.pid != current->pid ) { \
+ DRM_ERROR( "%s called without lock held\n", \
+ __FUNCTION__ ); \
+ return -EINVAL; \
+ } \
+} while (0)
+
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
do { \
drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \
@@ -627,20 +625,17 @@ do { \
} \
} while (0)
-#define RADEON_DISPATCH_AGE( age ) \
-do { \
+#define RADEON_DISPATCH_AGE( age ) do { \
OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
-#define RADEON_FRAME_AGE( age ) \
-do { \
+#define RADEON_FRAME_AGE( age ) do { \
OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
-#define RADEON_CLEAR_AGE( age ) \
-do { \
+#define RADEON_CLEAR_AGE( age ) do { \
OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \
OUT_RING( age ); \
} while (0)
diff --git a/linux/radeon_state.c b/linux/radeon_state.c
index 9b84a739..ff1b3512 100644
--- a/linux/radeon_state.c
+++ b/linux/radeon_state.c
@@ -972,50 +972,67 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
sarea_priv->nbox = 0;
}
-static int radeon_cp_dispatch_blit( drm_device_t *dev,
- drm_radeon_blit_t *blit )
+#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
+
+static int radeon_cp_dispatch_texture( drm_device_t *dev,
+ drm_radeon_texture_t *tex,
+ drm_radeon_tex_image_t *image )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_radeon_buf_priv_t *buf_priv;
u32 format;
- u32 *data;
- int dword_shift, dwords;
+ u32 *buffer;
+ u8 *data;
+ int size, dwords, tex_width, blit_width;
+ u32 y, height;
+ int ret = 0, i;
RING_LOCALS;
- DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
- blit->offset >> 10, blit->pitch, blit->format,
- blit->x, blit->y, blit->width, blit->height );
- radeon_update_ring_snapshot( dev_priv );
+ /* FIXME: Be smarter about this...
+ */
+ buf = radeon_freelist_get( dev );
+ if ( !buf ) return -EAGAIN;
+
+ DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+ tex->offset >> 10, tex->pitch, tex->format,
+ image->x, image->y, image->width, image->height );
+
+ buf_priv = buf->dev_private;
/* The compiler won't optimize away a division by a variable,
* even if the only legal values are powers of two. Thus, we'll
* use a shift instead.
*/
- switch ( blit->format ) {
- case RADEON_TXF_32BPP_ARGB8888:
- case RADEON_TXF_32BPP_RGBA8888:
+ switch ( tex->format ) {
+ case RADEON_TXFORMAT_ARGB8888:
+ case RADEON_TXFORMAT_RGBA8888:
format = RADEON_COLOR_FORMAT_ARGB8888;
- dword_shift = 0;
+ tex_width = tex->width * 4;
+ blit_width = image->width * 4;
break;
- case RADEON_TXF_16BPP_AI88:
- case RADEON_TXF_16BPP_ARGB1555:
- case RADEON_TXF_16BPP_RGB565:
- case RADEON_TXF_16BPP_ARGB4444:
+ case RADEON_TXFORMAT_AI88:
+ case RADEON_TXFORMAT_ARGB1555:
+ case RADEON_TXFORMAT_RGB565:
+ case RADEON_TXFORMAT_ARGB4444:
format = RADEON_COLOR_FORMAT_RGB565;
- dword_shift = 1;
+ tex_width = tex->width * 2;
+ blit_width = image->width * 2;
break;
- case RADEON_TXF_8BPP_I:
- case RADEON_TXF_8BPP_RGB332:
+ case RADEON_TXFORMAT_I8:
+ case RADEON_TXFORMAT_RGB332:
format = RADEON_COLOR_FORMAT_CI8;
- dword_shift = 2;
+ tex_width = tex->width * 1;
+ blit_width = image->width * 1;
break;
default:
- DRM_ERROR( "invalid blit format %d\n", blit->format );
+ DRM_ERROR( "invalid texture format %d\n", tex->format );
return -EINVAL;
}
+ DRM_DEBUG( " tex=%dx%d blit=%d\n",
+ tex_width, tex->height, blit_width );
+
/* Flush the pixel cache. This ensures no pixel data gets mixed
* up with the texture data from the host data blit, otherwise
* part of the texture image may be corrupted.
@@ -1027,46 +1044,81 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
ADVANCE_RING();
- /* Dispatch the indirect buffer.
+ /* Make a copy of the parameters in case we have to update them
+ * for a multi-pass texture blit.
*/
- buf = dma->buflist[blit->idx];
- buf_priv = buf->dev_private;
+ y = image->y;
+ height = image->height;
+ data = (u8 *)image->data;
- if ( buf->pid != current->pid ) {
- DRM_ERROR( "process %d using buffer owned by %d\n",
- current->pid, buf->pid );
- return -EINVAL;
- }
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", blit->idx );
- return -EINVAL;
- }
+ size = height * blit_width;
- buf_priv->discard = 1;
+ if ( size > RADEON_MAX_TEXTURE_SIZE ) {
+ /* Texture image is too large, do a multipass upload */
+ ret = -EAGAIN;
- dwords = (blit->width * blit->height) >> dword_shift;
- if ( !dwords ) dwords = 1;
+ /* Adjust the blit size to fit the indirect buffer */
+ height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+ size = height * blit_width;
- data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+ /* Update the input parameters for next time */
+ image->y += height;
+ image->height -= height;
+ image->data = (char *)image->data + size;
- data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
- data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (format << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP3_S |
- RADEON_DP_SRC_SOURCE_HOST_DATA |
- RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS);
+ if ( copy_to_user( tex->image, image, sizeof(*image) ) )
+ return -EFAULT;
+ } else if ( size < 4 ) {
+ size = 4;
+ }
- data[2] = (blit->pitch << 22) | (blit->offset >> 10);
- data[3] = 0xffffffff;
- data[4] = 0xffffffff;
- data[5] = (blit->y << 16) | blit->x;
- data[6] = (blit->height << 16) | blit->width;
- data[7] = dwords;
+ dwords = size / 4;
+
+ /* Dispatch the indirect buffer.
+ */
+ buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+
+ buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
+ buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (format << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_S |
+ RADEON_DP_SRC_SOURCE_HOST_DATA |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_WR_MSK_DIS);
+
+ buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
+ buffer[3] = 0xffffffff;
+ buffer[4] = 0xffffffff;
+ buffer[5] = (y << 16) | image->x;
+ buffer[6] = (height << 16) | image->width;
+ buffer[7] = dwords;
+
+ buffer += 8;
+
+ if ( tex_width >= 32 ) {
+ /* Texture image width is larger than the minimum, so we
+ * can upload it directly.
+ */
+ if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) )
+ return -EFAULT;
+ } else {
+ /* Texture image width is less than the minimum, so we
+ * need to pad out each image scanline to the minimum
+ * width.
+ */
+ for ( i = 0 ; i < tex->height ; i++ ) {
+ if ( copy_from_user( buffer, data, tex_width ) )
+ return -EFAULT;
+ buffer += 8;
+ data += tex_width;
+ }
+ }
+ buf->pid = current->pid;
buf->used = (dwords + 8) * sizeof(u32);
+ buf_priv->discard = 1;
radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
@@ -1081,7 +1133,7 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
ADVANCE_RING();
- return 0;
+ return ret;
}
static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
@@ -1122,11 +1174,7 @@ int radeon_cp_clear( struct inode *inode, struct file *filp,
drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg,
sizeof(clear) ) )
@@ -1156,11 +1204,7 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
DRM_DEBUG( "%s\n", __FUNCTION__ );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1189,11 +1233,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
drm_radeon_buf_priv_t *buf_priv;
drm_radeon_vertex_t vertex;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
@@ -1255,11 +1296,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
drm_radeon_indices_t elts;
int count;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
@@ -1321,38 +1359,34 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
return 0;
}
-int radeon_cp_blit( struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg )
+int radeon_cp_texture( 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_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- drm_radeon_blit_t blit;
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t image;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
- if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg,
- sizeof(blit) ) )
+ if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) )
return -EFAULT;
- DRM_DEBUG( "%s: pid=%d index=%d\n",
- __FUNCTION__, current->pid, blit.idx );
-
- if ( blit.idx < 0 || blit.idx > dma->buf_count ) {
- DRM_ERROR( "sending %d buffers (of %d max)\n",
- blit.idx, dma->buf_count );
+ if ( tex.image == NULL ) {
+ DRM_ERROR( "null texture image!\n" );
return -EINVAL;
}
+ if ( copy_from_user( &image,
+ (drm_radeon_tex_image_t *)tex.image,
+ sizeof(image) ) )
+ return -EFAULT;
+
RING_SPACE_TEST_WITH_RETURN( dev_priv );
VB_AGE_TEST_WITH_RETURN( dev_priv );
- return radeon_cp_dispatch_blit( dev, &blit );
+ return radeon_cp_dispatch_texture( dev, &tex, &image );
}
int radeon_cp_stipple( struct inode *inode, struct file *filp,
@@ -1364,18 +1398,13 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp,
drm_radeon_stipple_t stipple;
u32 mask[32];
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
sizeof(stipple) ) )
return -EFAULT;
- if ( copy_from_user( &mask, stipple.mask,
- 32 * sizeof(u32) ) )
+ if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) )
return -EFAULT;
RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1397,11 +1426,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
drm_radeon_indirect_t indirect;
RING_LOCALS;
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
+ LOCK_TEST_WITH_RETURN( dev );
+
if ( !dev_priv || dev_priv->is_pci ) {
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
return -EINVAL;
diff --git a/linux/tdfx.h b/linux/tdfx.h
index 6af675ff..40aba8fb 100644
--- a/linux/tdfx.h
+++ b/linux/tdfx.h
@@ -34,6 +34,8 @@
*/
#define DRM(x) tdfx_##x
+/* General customization:
+ */
#define __HAVE_MTRR 1
#define __HAVE_CTX_BITMAP 1
diff --git a/linux/tdfx_drv.c b/linux/tdfx_drv.c
index e8d7955c..f478395f 100644
--- a/linux/tdfx_drv.c
+++ b/linux/tdfx_drv.c
@@ -38,21 +38,19 @@
#define DRIVER_NAME "tdfx"
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
-#define DRIVER_DATE "20010215"
+#define DRIVER_DATE "20010216"
#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
-#include "drm_drv.h"
-
-#include "drm_agpsupport.h"
#include "drm_auth.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_drawable.h"
+#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 7c65f5fc..ddabc277 100644
--- a/shared-core/drm.h
+++ b/shared-core/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 */
@@ -453,7 +450,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/shared/drm.h b/shared/drm.h
index 7c65f5fc..ddabc277 100644
--- a/shared/drm.h
+++ b/shared/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 */
@@ -453,7 +450,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
+#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/tests/dristat.c b/tests/dristat.c
index f429efd3..47193ab4 100644
--- a/tests/dristat.c
+++ b/tests/dristat.c
@@ -35,28 +35,11 @@
#include "../xf86drmHash.c"
#include "../xf86drm.c"
-#define DRM_DIR_NAME "/dev/dri"
-#define DRM_DEV_NAME "%s/card%d"
-
#define DRM_VERSION 0x00000001
#define DRM_MEMORY 0x00000002
#define DRM_CLIENTS 0x00000004
#define DRM_STATS 0x00000008
-
-typedef struct drmStatsS {
- unsigned long count;
- struct {
- unsigned long value;
- const char *long_format;
- const char *long_name;
- const char *rate_format;
- const char *rate_name;
- int isvalue;
- const char *mult_names;
- int mult;
- int verbose;
- } data[15];
-} drmStatsT;
+#define DRM_BUSID 0x00000010
static void getversion(int fd)
{
@@ -78,6 +61,15 @@ static void getversion(int fd)
}
}
+static void getbusid(int fd)
+{
+ const char *busid = drmGetBusid(fd);
+
+ printf(" Busid: %s\n", *busid ? busid : "(not set)");
+ drmFreeBusid(busid);
+}
+
+#if 0
typedef struct {
unsigned long offset; /* Requested physical address (0 for SAREA)*/
unsigned long size; /* Requested physical size (bytes) */
@@ -88,160 +80,7 @@ typedef struct {
int mtrr; /* MTRR slot used */
/* Private data */
} drmVmRec, *drmVmPtr;
-
-int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
- drmMapType *type, drmMapFlags *flags, drmHandle *handle,
- int *mtrr)
-{
- drm_map_t map;
-
- map.offset = idx;
- if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
- *offset = map.offset;
- *size = map.size;
- *type = map.type;
- *flags = map.flags;
- *handle = (unsigned long)map.handle;
- *mtrr = map.mtrr;
- return 0;
-}
-
-int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
- unsigned long *magic, unsigned long *iocs)
-{
- drm_client_t client;
-
- client.idx = idx;
- if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
- *auth = client.auth;
- *pid = client.pid;
- *uid = client.uid;
- *magic = client.magic;
- *iocs = client.iocs;
- return 0;
-}
-
-int drmGetStats(int fd, drmStatsT *stats)
-{
- drm_stats_t s;
- int i;
-
- if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
-
- stats->count = 0;
- memset(stats, 0, sizeof(*stats));
- if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
- return -1;
-
-#define SET_VALUE \
- stats->data[i].long_format = "%-20.20s"; \
- stats->data[i].rate_format = "%8.8s"; \
- stats->data[i].isvalue = 1; \
- stats->data[i].verbose = 0
-
-#define SET_COUNT \
- stats->data[i].long_format = "%-20.20s"; \
- stats->data[i].rate_format = "%5.5s"; \
- stats->data[i].isvalue = 0; \
- stats->data[i].mult_names = "kgm"; \
- stats->data[i].mult = 1000; \
- stats->data[i].verbose = 0
-
-#define SET_BYTE \
- stats->data[i].long_format = "%-9.9s"; \
- stats->data[i].rate_format = "%5.5s"; \
- stats->data[i].isvalue = 0; \
- stats->data[i].mult_names = "KGM"; \
- stats->data[i].mult = 1024; \
- stats->data[i].verbose = 0
-
-
- stats->count = s.count;
- for (i = 0; i < s.count; i++) {
- stats->data[i].value = s.data[i].value;
- switch (s.data[i].type) {
- case _DRM_STAT_LOCK:
- stats->data[i].long_name = "Lock";
- stats->data[i].rate_name = "Lock";
- SET_VALUE;
- break;
- case _DRM_STAT_OPENS:
- stats->data[i].long_name = "Opens";
- stats->data[i].rate_name = "O";
- SET_COUNT;
- stats->data[i].verbose = 1;
- break;
- case _DRM_STAT_CLOSES:
- stats->data[i].long_name = "Closes";
- stats->data[i].rate_name = "Lock";
- SET_COUNT;
- stats->data[i].verbose = 1;
- break;
- case _DRM_STAT_IOCTLS:
- stats->data[i].long_name = "Ioctls";
- stats->data[i].rate_name = "Ioc/s";
- SET_COUNT;
- break;
- case _DRM_STAT_LOCKS:
- stats->data[i].long_name = "Locks";
- stats->data[i].rate_name = "Lck/s";
- SET_COUNT;
- break;
- case _DRM_STAT_UNLOCKS:
- stats->data[i].long_name = "Unlocks";
- stats->data[i].rate_name = "Unl/s";
- SET_COUNT;
- break;
- case _DRM_STAT_IRQ:
- stats->data[i].long_name = "IRQs";
- stats->data[i].rate_name = "IRQ/s";
- SET_COUNT;
- break;
- case _DRM_STAT_PRIMARY:
- stats->data[i].long_name = "Primary Bytes";
- stats->data[i].rate_name = "PB/s";
- SET_BYTE;
- break;
- case _DRM_STAT_SECONDARY:
- stats->data[i].long_name = "Secondary Bytes";
- stats->data[i].rate_name = "SB/s";
- SET_BYTE;
- break;
- case _DRM_STAT_DMA:
- stats->data[i].long_name = "DMA";
- stats->data[i].rate_name = "DMA/s";
- SET_COUNT;
- break;
- case _DRM_STAT_SPECIAL:
- stats->data[i].long_name = "Special DMA";
- stats->data[i].rate_name = "dma/s";
- SET_COUNT;
- break;
- case _DRM_STAT_MISSED:
- stats->data[i].long_name = "Miss";
- stats->data[i].rate_name = "Ms/s";
- SET_COUNT;
- break;
- case _DRM_STAT_VALUE:
- stats->data[i].long_name = "Value";
- stats->data[i].rate_name = "Value";
- SET_VALUE;
- break;
- case _DRM_STAT_BYTE:
- stats->data[i].long_name = "Bytes";
- stats->data[i].rate_name = "B/s";
- SET_BYTE;
- break;
- case _DRM_STAT_COUNT:
- default:
- stats->data[i].long_name = "Count";
- stats->data[i].rate_name = "Cnt/s";
- SET_COUNT;
- break;
- }
- }
- return 0;
-}
+#endif
static void getvm(int fd)
{
@@ -255,7 +94,7 @@ static void getvm(int fd)
drmHandle handle;
int mtrr;
- printf(" VM map information:\n");
+ printf(" VM map information (Restricted locked kernel WC Lock):\n");
printf(" slot offset size type flags address mtrr\n");
for (i = 0;
@@ -298,7 +137,7 @@ static void getclients(int fd)
int procfd;
printf(" DRI client information:\n");
- printf(" a pid uid magic ioctls prog\n");
+ printf(" a pid uid magic ioctls prog\n");
for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) {
sprintf(buf, "/proc/%d/cmdline", pid);
@@ -307,12 +146,16 @@ static void getclients(int fd)
read(procfd, cmd, sizeof(cmd)-1);
close(procfd);
}
- if (*cmd)
+ if (*cmd) {
+ char *pt;
+
+ for (pt = cmd; *pt; pt++) if (!isprint(*pt)) *pt = ' ';
printf(" %c %5d %5d %10lu %10lu %s\n",
auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
- else
+ } else {
printf(" %c %5d %5d %10lu %10lu\n",
auth ? 'y' : 'n', pid, uid, magic, iocs);
+ }
}
}
@@ -394,44 +237,6 @@ static void getstats(int fd, int i)
}
-static int drmOpenMinor(int minor, uid_t user, gid_t group,
- mode_t dirmode, mode_t devmode, int force)
-{
- struct stat st;
- char buf[64];
- long dev = makedev(DRM_MAJOR, minor);
- int setdir = 0;
- int setdev = 0;
- int fd;
-
- if (stat(DRM_DIR_NAME, &st) || !S_ISDIR(st.st_mode)) {
- remove(DRM_DIR_NAME);
- mkdir(DRM_DIR_NAME, dirmode);
- ++setdir;
- }
-
- if (force || setdir) {
- chown(DRM_DIR_NAME, user, group);
- chmod(DRM_DIR_NAME, dirmode);
- }
-
- sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
- if (stat(buf, &st) || st.st_rdev != dev) {
- remove(buf);
- mknod(buf, S_IFCHR, dev);
- ++setdev;
- }
-
- if (force || setdev) {
- chown(buf, user, group);
- chmod(buf, devmode);
- }
-
- if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
- if (setdev) remove(buf);
- return -errno;
-}
-
int main(int argc, char **argv)
{
int c;
@@ -442,13 +247,14 @@ int main(int argc, char **argv)
char buf[64];
int i;
- while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF)
+ while ((c = getopt(argc, argv, "avmcsbM:i:")) != EOF)
switch (c) {
case 'a': mask = ~0; break;
case 'v': mask |= DRM_VERSION; break;
case 'm': mask |= DRM_MEMORY; break;
case 'c': mask |= DRM_CLIENTS; break;
case 's': mask |= DRM_STATS; break;
+ case 'b': mask |= DRM_BUSID; break;
case 'i': interval = strtol(optarg, NULL, 0); break;
case 'M': minor = strtol(optarg, NULL, 0); break;
default:
@@ -458,9 +264,10 @@ int main(int argc, char **argv)
for (i = 0; i < 16; i++) if (!minor || i == minor) {
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
- fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0);
+ fd = drmOpenMinor(i, 1);
if (fd >= 0) {
printf("%s\n", buf);
+ if (mask & DRM_BUSID) getbusid(fd);
if (mask & DRM_VERSION) getversion(fd);
if (mask & DRM_MEMORY) getvm(fd);
if (mask & DRM_CLIENTS) getclients(fd);