mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 01:58:02 +02:00
merge from DRI trunk (first pass)
This commit is contained in:
parent
20a0360fdd
commit
29922e54e2
80 changed files with 2023 additions and 1890 deletions
|
|
@ -1,5 +1,5 @@
|
|||
# $FreeBSD$
|
||||
|
||||
SUBDIR = drm tdfx gamma
|
||||
SUBDIR = drm tdfx mga gamma
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.1 2000/06/17 00:03:28 martin Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.3 2001/03/06 16:45:26 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -49,11 +49,11 @@
|
|||
#include <sys/sysctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/bus.h>
|
||||
#if __FreeBSD_version >= 500005
|
||||
#if __FreeBSD_version >= 400005
|
||||
#include <sys/taskqueue.h>
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version >= 500006
|
||||
#if __FreeBSD_version >= 400006
|
||||
#define DRM_AGP
|
||||
#endif
|
||||
|
||||
|
|
@ -73,6 +73,11 @@ typedef u_int32_t spinlock_t;
|
|||
#define atomic_add(n, p) atomic_add_int(p, n)
|
||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
||||
|
||||
/* The version number here is a guess */
|
||||
#if __FreeBSD_version >= 500010
|
||||
#define callout_init(a) callout_init(a, 0)
|
||||
#endif
|
||||
|
||||
/* Fake this */
|
||||
static __inline u_int32_t
|
||||
test_and_set_bit(int b, volatile u_int32_t *p)
|
||||
|
|
@ -128,14 +133,14 @@ find_first_zero_bit(volatile u_int32_t *p, int max)
|
|||
* Fake out the module macros for versions of FreeBSD where they don't
|
||||
* exist.
|
||||
*/
|
||||
#if __FreeBSD_version < 500002
|
||||
#if __FreeBSD_version < 400002
|
||||
|
||||
#define MODULE_VERSION(a,b) struct __hack
|
||||
#define MODULE_DEPEND(a,b,c,d,e) struct __hack
|
||||
|
||||
#endif
|
||||
|
||||
#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
|
||||
#define DRM_DEBUG_CODE 0 /* Include debugging code (if > 1, then
|
||||
also include looping detection. */
|
||||
#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
|
||||
|
||||
|
|
@ -340,6 +345,7 @@ typedef struct drm_freelist {
|
|||
int low_mark; /* Low water mark */
|
||||
int high_mark; /* High water mark */
|
||||
atomic_t wfh; /* If waiting for high mark */
|
||||
struct simplelock lock; /* hope this doesn't need to be linux compatible */
|
||||
} drm_freelist_t;
|
||||
|
||||
typedef struct drm_buf_entry {
|
||||
|
|
@ -509,15 +515,15 @@ typedef struct drm_device {
|
|||
/* Context support */
|
||||
struct resource *irq; /* Interrupt used by board */
|
||||
void *irqh; /* Handle from bus_setup_intr */
|
||||
__volatile__ int context_flag; /* Context swapping flag */
|
||||
__volatile__ int interrupt_flag;/* Interruption handler flag */
|
||||
__volatile__ int dma_flag; /* DMA dispatch flag */
|
||||
__volatile__ long context_flag; /* Context swapping flag */
|
||||
__volatile__ long interrupt_flag;/* Interruption handler flag */
|
||||
__volatile__ long dma_flag; /* DMA dispatch flag */
|
||||
struct callout timer; /* Timer for delaying ctx switch */
|
||||
int context_wait; /* Processes waiting on ctx switch */
|
||||
int last_checked; /* Last context checked for DMA */
|
||||
int last_context; /* Last current context */
|
||||
int last_switch; /* Time at last context switch */
|
||||
#if __FreeBSD_version >= 500005
|
||||
#if __FreeBSD_version >= 400005
|
||||
struct task task;
|
||||
#endif
|
||||
struct timespec ctx_start;
|
||||
|
|
@ -594,7 +600,13 @@ extern int drm_sysctl_cleanup(drm_device_t *dev);
|
|||
|
||||
/* Memory management support (memory.c) */
|
||||
extern void drm_mem_init(void);
|
||||
extern int drm_mem_info SYSCTL_HANDLER_ARGS;
|
||||
|
||||
#if __FreeBSD_version < 411000
|
||||
#define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
|
||||
#else
|
||||
#define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS)
|
||||
#endif
|
||||
extern int drm_mem_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
extern void *drm_alloc(size_t size, int area);
|
||||
extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
|
||||
int area);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
KMOD = tdfx
|
||||
SRCS = tdfx_drv.c tdfx_context.c
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
CFLAGS += ${DEBUG_FLAGS} -I..
|
||||
CFLAGS += ${DEBUG_FLAGS} -I. -I..
|
||||
KMODDEPS = drm
|
||||
|
||||
@:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile,v 1.4 2001/01/12 19:28:34 dawes Exp $
|
||||
XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/Imakefile,v 1.6 2001/04/18 14:52:43 dawes Exp $
|
||||
|
||||
#include <Server.tmpl>
|
||||
|
||||
#if 0
|
||||
LinkSourceFile(xf86drm.c,..)
|
||||
LinkSourceFile(xf86drmHash.c,..)
|
||||
LinkSourceFile(xf86drmRandom.c,..)
|
||||
|
|
@ -9,6 +10,7 @@ LinkSourceFile(xf86drmSL.c,..)
|
|||
LinkSourceFile(xf86drm.h,$(XF86OSSRC))
|
||||
LinkSourceFile(xf86_OSproc.h,$(XF86OSSRC))
|
||||
LinkSourceFile(sigio.c,$(XF86OSSRC)/shared)
|
||||
#endif
|
||||
|
||||
XCOMM Try to use the Linux version of the DRM headers. This avoids skew
|
||||
XCOMM and missing headers. If there's a need to break them out, they
|
||||
|
|
@ -35,7 +37,7 @@ install::
|
|||
$(MAKE) -f Makefile.bsd install
|
||||
#else
|
||||
all::
|
||||
echo 'Use "make -f Makefile.bsd" to manually build drm.o'
|
||||
@echo 'Use "make -f Makefile.bsd" to manually build drm.o'
|
||||
#endif
|
||||
|
||||
clean::
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# $FreeBSD$
|
||||
|
||||
SUBDIR = drm tdfx gamma
|
||||
SUBDIR = drm tdfx mga gamma
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# $FreeBSD$
|
||||
|
||||
SUBDIR = drm tdfx gamma
|
||||
SUBDIR = drm tdfx mga gamma
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
|
|
|||
|
|
@ -135,12 +135,12 @@ int drm_getmagic(dev_t kdev, u_long cmd, caddr_t data,
|
|||
if (priv->magic) {
|
||||
auth.magic = priv->magic;
|
||||
} else {
|
||||
simple_lock(&lock);
|
||||
do {
|
||||
simple_lock(&lock);
|
||||
if (!sequence) ++sequence; /* reserve 0 */
|
||||
auth.magic = sequence++;
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
simple_unlock(&lock);
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
priv->magic = auth.magic;
|
||||
drm_add_magic(dev, priv, auth.magic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ int drm_freelist_create(drm_freelist_t *bl, int count)
|
|||
bl->low_mark = 0;
|
||||
bl->high_mark = 0;
|
||||
atomic_set(&bl->wfh, 0);
|
||||
/* bl->lock = SPIN_LOCK_UNLOCKED; */
|
||||
++bl->initialized;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -159,6 +160,7 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
|
|||
drm_histogram_compute(dev, buf);
|
||||
#endif
|
||||
buf->list = DRM_LIST_FREE;
|
||||
/*
|
||||
do {
|
||||
old = (unsigned long)bl->next;
|
||||
buf->next = (void *)old;
|
||||
|
|
@ -169,6 +171,13 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
|
|||
return 1;
|
||||
}
|
||||
} while (failed);
|
||||
*/
|
||||
|
||||
simple_lock(&bl->lock);
|
||||
buf->next = bl->next;
|
||||
bl->next = buf;
|
||||
simple_unlock(&bl->lock);
|
||||
|
||||
atomic_inc(&bl->count);
|
||||
if (atomic_read(&bl->count) > dma->buf_count) {
|
||||
DRM_ERROR("%d of %d buffers free after addition of %d\n",
|
||||
|
|
@ -195,6 +204,7 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
|
|||
if (!bl) return NULL;
|
||||
|
||||
/* Get buffer */
|
||||
/*
|
||||
do {
|
||||
old = (unsigned int)bl->next;
|
||||
if (!old) {
|
||||
|
|
@ -210,6 +220,16 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
|
|||
atomic_dec(&bl->count);
|
||||
|
||||
buf = (drm_buf_t *)old;
|
||||
*/
|
||||
simple_lock(&bl->lock);
|
||||
if(!bl->next){
|
||||
simple_unlock(&bl->lock);
|
||||
return NULL;
|
||||
}
|
||||
buf = bl->next;
|
||||
bl->next = bl->next->next;
|
||||
simple_unlock(&bl->lock);
|
||||
atomic_dec(&bl->count);
|
||||
buf->next = NULL;
|
||||
buf->list = DRM_LIST_NONE;
|
||||
DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
|
||||
|
|
|
|||
|
|
@ -135,9 +135,12 @@ static int drm_flush_queue(drm_device_t *dev, int context)
|
|||
if (atomic_read(&q->use_count) > 1) {
|
||||
atomic_inc(&q->block_write);
|
||||
atomic_inc(&q->block_count);
|
||||
error = tsleep(&q->flush_queue, PCATCH|PZERO, "drmfq", 0);
|
||||
if (error)
|
||||
return error;
|
||||
for (;;) {
|
||||
if (!DRM_BUFCOUNT(&q->waitlist)) break;
|
||||
error = tsleep(&q->flush_queue, PCATCH|PZERO, "drmfq", 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
atomic_dec(&q->block_count);
|
||||
}
|
||||
atomic_dec(&q->use_count);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void drm_mem_init(void)
|
|||
|
||||
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
|
||||
|
||||
static int _drm_mem_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_mem_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_mem_stats_t *pt;
|
||||
char buf[128];
|
||||
|
|
@ -127,7 +127,7 @@ static int _drm_mem_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
int drm_mem_info SYSCTL_HANDLER_ARGS
|
||||
int drm_mem_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.4 1999/08/20 15:36:46 faith Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c,v 1.1 2000/06/17 00:03:30 martin Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/proc.c,v 1.2 2001/03/02 02:45:38 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
|||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
drm_map_t *map;
|
||||
const char *types[] = { "FB", "REG", "SHM" };
|
||||
const char *types[] = { "FB", "REG", "SHM", "AGP" };
|
||||
const char *type;
|
||||
int i;
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
|
|||
"address mtrr\n\n");
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
if (map->type < 0 || map->type > 2) type = "??";
|
||||
if (map->type < 0 || map->type > 3) type = "??";
|
||||
else type = types[map->type];
|
||||
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
|
||||
i,
|
||||
|
|
@ -226,7 +226,7 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
|
|||
atomic_inc(&q->use_count);
|
||||
DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
|
||||
"%5d/0x%03x %5d %5d"
|
||||
" %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
|
||||
" %5d/%c%c/%c%c%c %5Zd %10d %10d %10d\n",
|
||||
i,
|
||||
q->flags,
|
||||
atomic_read(&q->use_count),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* $PI$
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c,v 1.1 2000/06/17 00:03:31 martin Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drm/sysctl.c,v 1.2 2001/03/02 02:45:38 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -35,21 +35,21 @@
|
|||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics");
|
||||
|
||||
static int drm_name_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_vm_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_clients_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_queues_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_bufs_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_name_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int drm_queues_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
#if DRM_DEBUG_CODExx
|
||||
static int drm_vma_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_vma_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
#endif
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int drm_histo_info SYSCTL_HANDLER_ARGS;
|
||||
static int drm_histo_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
#endif
|
||||
|
||||
struct drm_sysctl_list {
|
||||
const char *name;
|
||||
int (*f) SYSCTL_HANDLER_ARGS;
|
||||
int (*f) DRM_SYSCTL_HANDLER_ARGS;
|
||||
} drm_sysctl_list[] = {
|
||||
{ "name", drm_name_info },
|
||||
{ "mem", drm_mem_info },
|
||||
|
|
@ -137,7 +137,7 @@ int drm_sysctl_cleanup(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_name_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_name_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
char buf[128];
|
||||
|
|
@ -155,11 +155,11 @@ static int drm_name_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _drm_vm_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_vm_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
drm_map_t *map;
|
||||
const char *types[] = { "FB", "REG", "SHM" };
|
||||
const char *types[] = { "FB", "REG", "SHM", "AGP" };
|
||||
const char *type;
|
||||
int i;
|
||||
char buf[128];
|
||||
|
|
@ -172,7 +172,7 @@ static int _drm_vm_info SYSCTL_HANDLER_ARGS
|
|||
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
if (map->type < 0 || map->type > 2) type = "??";
|
||||
if (map->type < 0 || map->type > 3) type = "??";
|
||||
else type = types[map->type];
|
||||
DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
|
||||
i,
|
||||
|
|
@ -192,7 +192,7 @@ static int _drm_vm_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_vm_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
@ -205,7 +205,7 @@ static int drm_vm_info SYSCTL_HANDLER_ARGS
|
|||
}
|
||||
|
||||
|
||||
static int _drm_queues_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_queues_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int i;
|
||||
|
|
@ -221,7 +221,7 @@ static int _drm_queues_info SYSCTL_HANDLER_ARGS
|
|||
atomic_inc(&q->use_count);
|
||||
DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
|
||||
"%5d/0x%03x %5d %5d"
|
||||
" %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
|
||||
" %5d/%c%c/%c%c%c %5Zd %10d %10d %10d\n",
|
||||
i,
|
||||
q->flags,
|
||||
atomic_read(&q->use_count),
|
||||
|
|
@ -243,7 +243,7 @@ static int _drm_queues_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_queues_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_queues_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
@ -257,7 +257,7 @@ static int drm_queues_info SYSCTL_HANDLER_ARGS
|
|||
/* drm_bufs_info is called whenever a process reads
|
||||
hw.dri.0.bufs. */
|
||||
|
||||
static int _drm_bufs_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -293,7 +293,7 @@ static int _drm_bufs_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_bufs_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
@ -305,7 +305,7 @@ static int drm_bufs_info SYSCTL_HANDLER_ARGS
|
|||
}
|
||||
|
||||
|
||||
static int _drm_clients_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_clients_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
drm_file_t *priv;
|
||||
|
|
@ -327,7 +327,7 @@ static int _drm_clients_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_clients_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
@ -340,7 +340,7 @@ static int drm_clients_info SYSCTL_HANDLER_ARGS
|
|||
|
||||
#if DRM_DEBUG_CODExx
|
||||
|
||||
static int _drm_vma_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_vma_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
drm_vma_entry_t *pt;
|
||||
|
|
@ -412,7 +412,7 @@ static int _drm_vma_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_vma_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_vma_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
@ -426,7 +426,7 @@ static int drm_vma_info SYSCTL_HANDLER_ARGS
|
|||
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
static int _drm_histo_info SYSCTL_HANDLER_ARGS
|
||||
static int _drm_histo_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
|
@ -498,9 +498,9 @@ static int _drm_histo_info SYSCTL_HANDLER_ARGS
|
|||
} else {
|
||||
DRM_SYSCTL_PRINT("lock none\n");
|
||||
}
|
||||
DRM_SYSCTL_PRINT("context_flag 0x%08x\n", dev->context_flag);
|
||||
DRM_SYSCTL_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
|
||||
DRM_SYSCTL_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
|
||||
DRM_SYSCTL_PRINT("context_flag 0x%08lx\n", dev->context_flag);
|
||||
DRM_SYSCTL_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
|
||||
DRM_SYSCTL_PRINT("dma_flag 0x%08lx\n", dev->dma_flag);
|
||||
|
||||
DRM_SYSCTL_PRINT("queue_count %10d\n", dev->queue_count);
|
||||
DRM_SYSCTL_PRINT("last_context %10d\n", dev->last_context);
|
||||
|
|
@ -541,7 +541,7 @@ static int _drm_histo_info SYSCTL_HANDLER_ARGS
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_histo_info SYSCTL_HANDLER_ARGS
|
||||
static int drm_histo_info DRM_SYSCTL_HANDLER_ARGS
|
||||
{
|
||||
drm_device_t *dev = arg1;
|
||||
int ret;
|
||||
|
|
|
|||
32
bsd/drmP.h
32
bsd/drmP.h
|
|
@ -25,7 +25,7 @@
|
|||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.1 2000/06/17 00:03:28 martin Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/drm/kernel/drmP.h,v 1.3 2001/03/06 16:45:26 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -49,11 +49,11 @@
|
|||
#include <sys/sysctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/bus.h>
|
||||
#if __FreeBSD_version >= 500005
|
||||
#if __FreeBSD_version >= 400005
|
||||
#include <sys/taskqueue.h>
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version >= 500006
|
||||
#if __FreeBSD_version >= 400006
|
||||
#define DRM_AGP
|
||||
#endif
|
||||
|
||||
|
|
@ -73,6 +73,11 @@ typedef u_int32_t spinlock_t;
|
|||
#define atomic_add(n, p) atomic_add_int(p, n)
|
||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
||||
|
||||
/* The version number here is a guess */
|
||||
#if __FreeBSD_version >= 500010
|
||||
#define callout_init(a) callout_init(a, 0)
|
||||
#endif
|
||||
|
||||
/* Fake this */
|
||||
static __inline u_int32_t
|
||||
test_and_set_bit(int b, volatile u_int32_t *p)
|
||||
|
|
@ -128,14 +133,14 @@ find_first_zero_bit(volatile u_int32_t *p, int max)
|
|||
* Fake out the module macros for versions of FreeBSD where they don't
|
||||
* exist.
|
||||
*/
|
||||
#if __FreeBSD_version < 500002
|
||||
#if __FreeBSD_version < 400002
|
||||
|
||||
#define MODULE_VERSION(a,b) struct __hack
|
||||
#define MODULE_DEPEND(a,b,c,d,e) struct __hack
|
||||
|
||||
#endif
|
||||
|
||||
#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
|
||||
#define DRM_DEBUG_CODE 0 /* Include debugging code (if > 1, then
|
||||
also include looping detection. */
|
||||
#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
|
||||
|
||||
|
|
@ -340,6 +345,7 @@ typedef struct drm_freelist {
|
|||
int low_mark; /* Low water mark */
|
||||
int high_mark; /* High water mark */
|
||||
atomic_t wfh; /* If waiting for high mark */
|
||||
struct simplelock lock; /* hope this doesn't need to be linux compatible */
|
||||
} drm_freelist_t;
|
||||
|
||||
typedef struct drm_buf_entry {
|
||||
|
|
@ -509,15 +515,15 @@ typedef struct drm_device {
|
|||
/* Context support */
|
||||
struct resource *irq; /* Interrupt used by board */
|
||||
void *irqh; /* Handle from bus_setup_intr */
|
||||
__volatile__ int context_flag; /* Context swapping flag */
|
||||
__volatile__ int interrupt_flag;/* Interruption handler flag */
|
||||
__volatile__ int dma_flag; /* DMA dispatch flag */
|
||||
__volatile__ long context_flag; /* Context swapping flag */
|
||||
__volatile__ long interrupt_flag;/* Interruption handler flag */
|
||||
__volatile__ long dma_flag; /* DMA dispatch flag */
|
||||
struct callout timer; /* Timer for delaying ctx switch */
|
||||
int context_wait; /* Processes waiting on ctx switch */
|
||||
int last_checked; /* Last context checked for DMA */
|
||||
int last_context; /* Last current context */
|
||||
int last_switch; /* Time at last context switch */
|
||||
#if __FreeBSD_version >= 500005
|
||||
#if __FreeBSD_version >= 400005
|
||||
struct task task;
|
||||
#endif
|
||||
struct timespec ctx_start;
|
||||
|
|
@ -594,7 +600,13 @@ extern int drm_sysctl_cleanup(drm_device_t *dev);
|
|||
|
||||
/* Memory management support (memory.c) */
|
||||
extern void drm_mem_init(void);
|
||||
extern int drm_mem_info SYSCTL_HANDLER_ARGS;
|
||||
|
||||
#if __FreeBSD_version < 411000
|
||||
#define DRM_SYSCTL_HANDLER_ARGS SYSCTL_HANDLER_ARGS
|
||||
#else
|
||||
#define DRM_SYSCTL_HANDLER_ARGS (SYSCTL_HANDLER_ARGS)
|
||||
#endif
|
||||
extern int drm_mem_info DRM_SYSCTL_HANDLER_ARGS;
|
||||
extern void *drm_alloc(size_t size, int area);
|
||||
extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
|
||||
int area);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
KMOD = gamma
|
||||
SRCS = gamma_drv.c gamma_dma.c
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
CFLAGS += ${DEBUG_FLAGS} -I..
|
||||
CFLAGS += ${DEBUG_FLAGS} -I. -I..
|
||||
KMODDEPS = drm
|
||||
|
||||
@:
|
||||
|
|
|
|||
|
|
@ -188,7 +188,11 @@ int mga_rmctx(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
|
|||
|
||||
ctx = *(drm_ctx_t *) data;
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if(ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
/*
|
||||
if(ctx.handle == DRM_KERNEL_CONTEXT+1)
|
||||
priv->remove_auth_on_close = 1;
|
||||
*/
|
||||
if(ctx.handle != DRM_KERNEL_CONTEXT ) {
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,6 @@ static int mga_freelist_init(drm_device_t *dev)
|
|||
item->buf = buf;
|
||||
buf_priv->my_freelist = item;
|
||||
buf_priv->discard = 0;
|
||||
buf_priv->dispatched = 0;
|
||||
dev_priv->head->next = item;
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +175,7 @@ static __inline void mga_dma_quiescent(drm_device_t *dev)
|
|||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_nolock;
|
||||
return;
|
||||
}
|
||||
for (i = 0 ; i < 2000 ; i++) mga_delay();
|
||||
}
|
||||
|
|
@ -188,15 +187,15 @@ static __inline void mga_dma_quiescent(drm_device_t *dev)
|
|||
atomic_read(&dev->total_irq),
|
||||
atomic_read(&dma->total_lost));
|
||||
DRM_ERROR("lockup\n");
|
||||
goto out_status;
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
return;
|
||||
}
|
||||
for (i = 0 ; i < 2000 ; i++) mga_delay();
|
||||
}
|
||||
sarea_priv->dirty |= MGA_DMA_FLUSH;
|
||||
|
||||
out_status:
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
out_nolock:
|
||||
DRM_DEBUG("exit, dispatch_status = 0x%02x\n",dev_priv->dispatch_status);
|
||||
}
|
||||
|
||||
static void mga_reset_freelist(drm_device_t *dev)
|
||||
|
|
@ -236,20 +235,22 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev)
|
|||
set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
|
||||
for (;;) {
|
||||
mga_dma_schedule(dev, 0);
|
||||
if(!test_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status))
|
||||
/* if(!test_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status)) */
|
||||
if(dev_priv->tail->age < dev_priv->last_prim_age)
|
||||
break;
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
ret = tsleep(&dev_priv->buf_queue, PZERO|PCATCH,
|
||||
"mgafg", 0);
|
||||
if (ret) {
|
||||
if (ret == EINTR) {
|
||||
clear_bit(MGA_IN_GETBUF,
|
||||
&dev_priv->dispatch_status);
|
||||
splx(s);
|
||||
goto failed_getbuf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
|
||||
if (ret) return NULL;
|
||||
}
|
||||
|
||||
if(dev_priv->tail->age < dev_priv->last_prim_age) {
|
||||
|
|
@ -263,7 +264,6 @@ drm_buf_t *mga_freelist_get(drm_device_t *dev)
|
|||
return next->buf;
|
||||
}
|
||||
|
||||
failed_getbuf:
|
||||
failed++;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -520,61 +520,55 @@ int mga_advance_primary(drm_device_t *dev)
|
|||
static __inline int mga_decide_to_fire(drm_device_t *dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords) {
|
||||
atomic_inc(&dma->total_prio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
|
||||
if(test_bit(MGA_BUF_SWAP_PENDING,
|
||||
&dev_priv->next_prim->buffer_status)) {
|
||||
atomic_inc(&dma->total_dmas);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
|
||||
if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
|
||||
atomic_inc(&dma->total_hit);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
|
||||
if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
|
||||
atomic_inc(&dma->total_missed_free);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
atomic_inc(&dma->total_tried);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mga_dma_schedule(drm_device_t *dev, int locked)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int retval =0 ;
|
||||
|
||||
if (!dev_priv) return EBUSY;
|
||||
|
||||
if (test_and_set_bit(0, &dev->dma_flag)) {
|
||||
atomic_inc(&dma->total_missed_dma);
|
||||
return EBUSY;
|
||||
retval = EBUSY;
|
||||
goto sch_out_wakeup;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
|
@ -591,17 +585,15 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
|
||||
if (!locked &&
|
||||
!drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
|
||||
atomic_inc(&dma->total_missed_lock);
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
DRM_DEBUG("Not locked\n");
|
||||
return EBUSY;
|
||||
retval = EBUSY;
|
||||
goto sch_out_wakeup;
|
||||
}
|
||||
DRM_DEBUG("I'm locked\n");
|
||||
|
||||
if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
|
||||
/* Fire dma buffer */
|
||||
if(mga_decide_to_fire(dev)) {
|
||||
DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
|
||||
clear_bit(MGA_BUF_FORCE_FIRE,
|
||||
&dev_priv->next_prim->buffer_status);
|
||||
if(dev_priv->current_prim == dev_priv->next_prim) {
|
||||
|
|
@ -613,8 +605,6 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
} else {
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
}
|
||||
} else {
|
||||
DRM_DEBUG("I can't get the dispatch lock\n");
|
||||
}
|
||||
|
||||
if (!locked) {
|
||||
|
|
@ -623,9 +613,9 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
sch_out_wakeup:
|
||||
if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
|
||||
dev_priv->next_prim->num_dwords == 0 &&
|
||||
atomic_read(&dev_priv->pending_bufs) == 0) {
|
||||
/* Everything has been processed by the hardware */
|
||||
clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
|
||||
|
|
@ -633,18 +623,10 @@ int mga_dma_schedule(drm_device_t *dev, int locked)
|
|||
}
|
||||
|
||||
if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
|
||||
dev_priv->tail->age < dev_priv->last_prim_age) {
|
||||
clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
|
||||
DRM_DEBUG("Waking up buf queue\n");
|
||||
dev_priv->tail->age < dev_priv->last_prim_age)
|
||||
wakeup(&dev_priv->buf_queue);
|
||||
} else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
|
||||
DRM_DEBUG("Not waking buf_queue on %d %d\n",
|
||||
atomic_read(&dev->total_irq),
|
||||
dev_priv->last_prim_age);
|
||||
}
|
||||
|
||||
clear_bit(0, &dev->dma_flag);
|
||||
return 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void mga_dma_service(void *arg)
|
||||
|
|
@ -653,7 +635,6 @@ static void mga_dma_service(void *arg)
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_prim_buf_t *last_prim_buffer;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
atomic_inc(&dev->total_irq);
|
||||
if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
|
||||
MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
|
||||
|
|
@ -663,11 +644,11 @@ static void mga_dma_service(void *arg)
|
|||
dev_priv->sarea_priv->last_dispatch =
|
||||
dev_priv->last_prim_age = last_prim_buffer->prim_age;
|
||||
clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
|
||||
wakeup(&dev_priv->wait_queue);
|
||||
clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
|
||||
clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
|
||||
atomic_dec(&dev_priv->pending_bufs);
|
||||
taskqueue_enqueue(taskqueue_swi, &dev->task);
|
||||
wakeup(&dev_priv->wait_queue);
|
||||
}
|
||||
|
||||
static void mga_dma_task_queue(void *device, int pending)
|
||||
|
|
@ -684,6 +665,8 @@ int mga_dma_cleanup(drm_device_t *dev)
|
|||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
|
||||
if (dev->irq) mga_flush_queue(dev);
|
||||
mga_dma_quiescent(dev);
|
||||
if(dev_priv->ioremap) {
|
||||
int temp = (dev_priv->warp_ucode_size +
|
||||
dev_priv->primary_size +
|
||||
|
|
@ -723,9 +706,6 @@ int mga_dma_cleanup(drm_device_t *dev)
|
|||
static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
||||
drm_mga_private_t *dev_priv;
|
||||
drm_map_t *sarea_map = NULL;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
|
||||
if(dev_priv == NULL) return ENOMEM;
|
||||
|
|
@ -760,8 +740,8 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
|
||||
dev_priv->mAccess = init->mAccess;
|
||||
dev_priv->flush_queue = 0;
|
||||
dev_priv->buf_queue = 0;
|
||||
dev_priv->WarpPipe = -1;
|
||||
dev_priv->WarpPipe = 0xff000000;
|
||||
dev_priv->vertexsize = 0;
|
||||
|
||||
DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
|
||||
dev_priv->chipset, dev_priv->warp_ucode_size,
|
||||
|
|
@ -773,13 +753,6 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
|
|||
memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
|
||||
sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
|
||||
|
||||
for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++)
|
||||
DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n",
|
||||
i,
|
||||
dev_priv->WarpIndex[i].installed,
|
||||
dev_priv->WarpIndex[i].phys_addr,
|
||||
dev_priv->WarpIndex[i].size);
|
||||
|
||||
if(mga_init_primary_bufs(dev, init) != 0) {
|
||||
DRM_ERROR("Can not initialize primary buffers\n");
|
||||
mga_dma_cleanup(dev);
|
||||
|
|
@ -951,9 +924,7 @@ static int mga_flush_queue(drm_device_t *dev)
|
|||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if(dev_priv == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if(!dev_priv) return 0;
|
||||
|
||||
if(dev_priv->next_prim->num_dwords != 0) {
|
||||
s = splsofttq();
|
||||
|
|
@ -1065,7 +1036,7 @@ int mga_lock(dev_t kdev, u_long cmd, caddr_t data,
|
|||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
if (ret) DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1086,16 +1057,16 @@ int mga_flush_ioctl(dev_t kdev, u_long cmd, caddr_t data,
|
|||
}
|
||||
|
||||
if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
|
||||
drm_mga_prim_buf_t *temp_buf =
|
||||
dev_priv->prim_bufs[dev_priv->current_prim_idx];
|
||||
drm_mga_prim_buf_t *temp_buf;
|
||||
temp_buf = dev_priv->current_prim;
|
||||
|
||||
if(temp_buf && temp_buf->num_dwords) {
|
||||
s = splsofttq();
|
||||
if(temp_buf && temp_buf->num_dwords) {
|
||||
set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
|
||||
mga_advance_primary(dev);
|
||||
}
|
||||
mga_dma_schedule(dev, 1);
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
if(lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
mga_flush_queue(dev);
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ MODULE_DEPEND(mga, agp, 1, 1, 1);
|
|||
|
||||
#define MGA_NAME "mga"
|
||||
#define MGA_DESC "Matrox g200/g400"
|
||||
#define MGA_DATE "19991213"
|
||||
#define MGA_MAJOR 1
|
||||
#define MGA_DATE "20000928"
|
||||
#define MGA_MAJOR 2
|
||||
#define MGA_MINOR 0
|
||||
#define MGA_PATCHLEVEL 0
|
||||
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@
|
|||
|
||||
typedef struct {
|
||||
u_int32_t buffer_status;
|
||||
unsigned int num_dwords;
|
||||
unsigned int max_dwords;
|
||||
int num_dwords;
|
||||
int max_dwords;
|
||||
u_int32_t *current_dma_ptr;
|
||||
u_int32_t *head;
|
||||
u_int32_t phys_head;
|
||||
|
|
@ -50,7 +50,7 @@ typedef struct {
|
|||
} drm_mga_prim_buf_t;
|
||||
|
||||
typedef struct _drm_mga_freelist {
|
||||
unsigned int age;
|
||||
__volatile__ unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
struct _drm_mga_freelist *next;
|
||||
struct _drm_mga_freelist *prev;
|
||||
|
|
@ -82,6 +82,7 @@ typedef struct _drm_mga_private {
|
|||
int use_agp;
|
||||
drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
|
||||
unsigned int WarpPipe;
|
||||
unsigned int vertexsize;
|
||||
atomic_t pending_bufs;
|
||||
void *status_page;
|
||||
unsigned long real_status_page;
|
||||
|
|
@ -191,12 +192,20 @@ typedef struct {
|
|||
&tmp_buf->buffer_status)) { \
|
||||
mga_advance_primary(dev); \
|
||||
mga_dma_schedule(dev, 1); \
|
||||
tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
} else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||\
|
||||
tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
|
||||
set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \
|
||||
mga_advance_primary(dev); \
|
||||
mga_dma_schedule(dev, 1); \
|
||||
tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
|
||||
} \
|
||||
if(MGA_VERBOSE) \
|
||||
DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__); \
|
||||
dma_ptr = tmp_buf->current_dma_ptr; \
|
||||
num_dwords = tmp_buf->num_dwords; \
|
||||
phys_head = tmp_buf->phys_head; \
|
||||
outcount = 0; \
|
||||
} while(0)
|
||||
|
||||
#define PRIMGETPTR(dev_priv) do { \
|
||||
|
|
@ -344,6 +353,73 @@ drm_mga_prim_buf_t *tmp_buf = \
|
|||
#define MGAREG_YTOP 0x1c98
|
||||
#define MGAREG_ZORG 0x1c0c
|
||||
|
||||
/* Warp registers */
|
||||
#define MGAREG_WR0 0x2d00
|
||||
#define MGAREG_WR1 0x2d04
|
||||
#define MGAREG_WR2 0x2d08
|
||||
#define MGAREG_WR3 0x2d0c
|
||||
#define MGAREG_WR4 0x2d10
|
||||
#define MGAREG_WR5 0x2d14
|
||||
#define MGAREG_WR6 0x2d18
|
||||
#define MGAREG_WR7 0x2d1c
|
||||
#define MGAREG_WR8 0x2d20
|
||||
#define MGAREG_WR9 0x2d24
|
||||
#define MGAREG_WR10 0x2d28
|
||||
#define MGAREG_WR11 0x2d2c
|
||||
#define MGAREG_WR12 0x2d30
|
||||
#define MGAREG_WR13 0x2d34
|
||||
#define MGAREG_WR14 0x2d38
|
||||
#define MGAREG_WR15 0x2d3c
|
||||
#define MGAREG_WR16 0x2d40
|
||||
#define MGAREG_WR17 0x2d44
|
||||
#define MGAREG_WR18 0x2d48
|
||||
#define MGAREG_WR19 0x2d4c
|
||||
#define MGAREG_WR20 0x2d50
|
||||
#define MGAREG_WR21 0x2d54
|
||||
#define MGAREG_WR22 0x2d58
|
||||
#define MGAREG_WR23 0x2d5c
|
||||
#define MGAREG_WR24 0x2d60
|
||||
#define MGAREG_WR25 0x2d64
|
||||
#define MGAREG_WR26 0x2d68
|
||||
#define MGAREG_WR27 0x2d6c
|
||||
#define MGAREG_WR28 0x2d70
|
||||
#define MGAREG_WR29 0x2d74
|
||||
#define MGAREG_WR30 0x2d78
|
||||
#define MGAREG_WR31 0x2d7c
|
||||
#define MGAREG_WR32 0x2d80
|
||||
#define MGAREG_WR33 0x2d84
|
||||
#define MGAREG_WR34 0x2d88
|
||||
#define MGAREG_WR35 0x2d8c
|
||||
#define MGAREG_WR36 0x2d90
|
||||
#define MGAREG_WR37 0x2d94
|
||||
#define MGAREG_WR38 0x2d98
|
||||
#define MGAREG_WR39 0x2d9c
|
||||
#define MGAREG_WR40 0x2da0
|
||||
#define MGAREG_WR41 0x2da4
|
||||
#define MGAREG_WR42 0x2da8
|
||||
#define MGAREG_WR43 0x2dac
|
||||
#define MGAREG_WR44 0x2db0
|
||||
#define MGAREG_WR45 0x2db4
|
||||
#define MGAREG_WR46 0x2db8
|
||||
#define MGAREG_WR47 0x2dbc
|
||||
#define MGAREG_WR48 0x2dc0
|
||||
#define MGAREG_WR49 0x2dc4
|
||||
#define MGAREG_WR50 0x2dc8
|
||||
#define MGAREG_WR51 0x2dcc
|
||||
#define MGAREG_WR52 0x2dd0
|
||||
#define MGAREG_WR53 0x2dd4
|
||||
#define MGAREG_WR54 0x2dd8
|
||||
#define MGAREG_WR55 0x2ddc
|
||||
#define MGAREG_WR56 0x2de0
|
||||
#define MGAREG_WR57 0x2de4
|
||||
#define MGAREG_WR58 0x2de8
|
||||
#define MGAREG_WR59 0x2dec
|
||||
#define MGAREG_WR60 0x2df0
|
||||
#define MGAREG_WR61 0x2df4
|
||||
#define MGAREG_WR62 0x2df8
|
||||
#define MGAREG_WR63 0x2dfc
|
||||
|
||||
|
||||
#define PDEA_pagpxfer_enable 0x2
|
||||
|
||||
#define WIA_wmode_suspend 0x0
|
||||
|
|
|
|||
|
|
@ -37,6 +37,20 @@
|
|||
typedef u_int16_t u16;
|
||||
typedef u_int32_t u32;
|
||||
|
||||
#define MGAEMITCLIP_SIZE 10
|
||||
#define MGAEMITCTX_SIZE 20
|
||||
#define MGAG200EMITTEX_SIZE 20
|
||||
#define MGAG400EMITTEX0_SIZE 30
|
||||
#define MGAG400EMITTEX1_SIZE 25
|
||||
#define MGAG400EMITPIPE_SIZE 50
|
||||
#define MGAG200EMITPIPE_SIZE 15
|
||||
|
||||
#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
|
||||
MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \
|
||||
MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE)
|
||||
|
||||
|
||||
|
||||
static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
|
||||
drm_clip_rect_t * box)
|
||||
{
|
||||
|
|
@ -49,6 +63,7 @@ static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
|
|||
PRIMGETPTR(dev_priv);
|
||||
|
||||
/* Force reset of dwgctl (eliminates clip disable) */
|
||||
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
|
||||
#if 0
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0);
|
||||
|
|
@ -60,11 +75,11 @@ static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
|
|||
PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
|
||||
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
|
||||
#endif
|
||||
|
||||
}
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1));
|
||||
PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / 2);
|
||||
PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / 2);
|
||||
PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp);
|
||||
PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp);
|
||||
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
|
@ -76,7 +91,7 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
|
|||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
/* This takes a max of 15 dwords */
|
||||
/* This takes a max of 20 dwords */
|
||||
PRIMGETPTR(dev_priv);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]);
|
||||
|
|
@ -94,6 +109,12 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]);
|
||||
PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]);
|
||||
PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
|
||||
|
||||
PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]);
|
||||
PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
||||
} else {
|
||||
PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
|
@ -128,9 +149,9 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
|
||||
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
|
||||
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
|
||||
PRIMOUTREG(0x2d00 + 24 * 4, regs[MGA_TEXREG_WIDTH]);
|
||||
PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]);
|
||||
|
||||
PRIMOUTREG(0x2d00 + 34 * 4, regs[MGA_TEXREG_HEIGHT]);
|
||||
PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]);
|
||||
PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
|
||||
PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
|
@ -138,11 +159,12 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
|
|||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
#define TMC_dualtex_enable 0x80
|
||||
|
||||
static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int *regs = sarea_priv->TexState[0];
|
||||
int multitex = sarea_priv->WarpPipe & MGA_T2;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
|
|
@ -163,22 +185,21 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
|
||||
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
|
||||
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
|
||||
PRIMOUTREG(0x2d00 + 49 * 4, 0);
|
||||
PRIMOUTREG(MGAREG_WR49, 0);
|
||||
|
||||
PRIMOUTREG(0x2d00 + 57 * 4, 0);
|
||||
PRIMOUTREG(0x2d00 + 53 * 4, 0);
|
||||
PRIMOUTREG(0x2d00 + 61 * 4, 0);
|
||||
PRIMOUTREG(MGAREG_WR57, 0);
|
||||
PRIMOUTREG(MGAREG_WR53, 0);
|
||||
PRIMOUTREG(MGAREG_WR61, 0);
|
||||
PRIMOUTREG(MGAREG_WR52, 0x40);
|
||||
|
||||
PRIMOUTREG(MGAREG_WR60, 0x40);
|
||||
PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40);
|
||||
PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
||||
if (!multitex) {
|
||||
PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
|
||||
PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
}
|
||||
|
||||
PRIMOUTREG(0x2d00 + 54 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
|
||||
PRIMOUTREG(0x2d00 + 62 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
|
||||
PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
|
||||
PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
|
||||
|
||||
|
|
@ -212,14 +233,15 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
|
||||
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
|
||||
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
|
||||
PRIMOUTREG(0x2d00 + 49 * 4, 0);
|
||||
PRIMOUTREG(MGAREG_WR49, 0);
|
||||
|
||||
PRIMOUTREG(0x2d00 + 57 * 4, 0);
|
||||
PRIMOUTREG(0x2d00 + 53 * 4, 0);
|
||||
PRIMOUTREG(0x2d00 + 61 * 4, 0);
|
||||
PRIMOUTREG(0x2d00 + 52 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
|
||||
PRIMOUTREG(MGAREG_WR57, 0);
|
||||
PRIMOUTREG(MGAREG_WR53, 0);
|
||||
PRIMOUTREG(MGAREG_WR61, 0);
|
||||
PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40);
|
||||
|
||||
PRIMOUTREG(MGAREG_WR60, regs[MGA_TEXREG_HEIGHT] | 0x40);
|
||||
|
||||
PRIMOUTREG(0x2d00 + 60 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
|
||||
PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
|
||||
PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
|
||||
|
|
@ -227,12 +249,17 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
|
|||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
#define MAGIC_FPARAM_HEX_VALUE 0x46480000
|
||||
/* This is the hex value of 12800.0f which is a magic value we must
|
||||
* set in wr56.
|
||||
*/
|
||||
|
||||
|
||||
#define EMIT_PIPE 50
|
||||
static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
unsigned int pipe = sarea_priv->WarpPipe;
|
||||
float fParam = 12800.0f;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
|
|
@ -266,14 +293,14 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
|
||||
|
||||
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
|
||||
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
|
||||
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
|
||||
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
|
||||
PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
}
|
||||
|
||||
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
|
||||
|
|
@ -289,18 +316,20 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
|
|||
|
||||
PRIMOUTREG(MGAREG_WFLAG, 0);
|
||||
PRIMOUTREG(MGAREG_WFLAG1, 0);
|
||||
PRIMOUTREG(0x2d00 + 56 * 4, *((u32 *) (&fParam)));
|
||||
PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
|
||||
PRIMOUTREG(0x2d00 + 49 * 4, 0); /* Tex stage 0 */
|
||||
PRIMOUTREG(0x2d00 + 57 * 4, 0); /* Tex stage 0 */
|
||||
PRIMOUTREG(0x2d00 + 53 * 4, 0); /* Tex stage 1 */
|
||||
PRIMOUTREG(0x2d00 + 61 * 4, 0); /* Tex stage 1 */
|
||||
PRIMOUTREG(MGAREG_WR49, 0); /* Tex stage 0 */
|
||||
PRIMOUTREG(MGAREG_WR57, 0); /* Tex stage 0 */
|
||||
PRIMOUTREG(MGAREG_WR53, 0); /* Tex stage 1 */
|
||||
PRIMOUTREG(MGAREG_WR61, 0); /* Tex stage 1 */
|
||||
|
||||
|
||||
PRIMOUTREG(MGAREG_WR54, 0x40); /* Tex stage 0 : w */
|
||||
PRIMOUTREG(MGAREG_WR62, 0x40); /* Tex stage 0 : h */
|
||||
PRIMOUTREG(MGAREG_WR52, 0x40); /* Tex stage 1 : w */
|
||||
PRIMOUTREG(MGAREG_WR60, 0x40); /* Tex stage 1 : h */
|
||||
|
||||
PRIMOUTREG(0x2d00 + 54 * 4, 0x40); /* Tex stage 0 : w */
|
||||
PRIMOUTREG(0x2d00 + 62 * 4, 0x40); /* Tex stage 0 : h */
|
||||
PRIMOUTREG(0x2d00 + 52 * 4, 0x40); /* Tex stage 1 : w */
|
||||
PRIMOUTREG(0x2d00 + 60 * 4, 0x40); /* Tex stage 1 : h */
|
||||
|
||||
/* Dma pading required due to hw bug */
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
|
|
@ -326,12 +355,12 @@ static void mgaG200EmitPipe(drm_mga_private_t * dev_priv)
|
|||
PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
|
||||
PRIMOUTREG(MGAREG_WVRTXSZ, 7);
|
||||
PRIMOUTREG(MGAREG_WFLAG, 0);
|
||||
PRIMOUTREG(0x2d00 + 24 * 4, 0); /* tex w/h */
|
||||
PRIMOUTREG(MGAREG_WR24, 0); /* tex w/h */
|
||||
|
||||
PRIMOUTREG(0x2d00 + 25 * 4, 0x100);
|
||||
PRIMOUTREG(0x2d00 + 34 * 4, 0); /* tex w/h */
|
||||
PRIMOUTREG(0x2d00 + 42 * 4, 0xFFFF);
|
||||
PRIMOUTREG(0x2d00 + 60 * 4, 0xFFFF);
|
||||
PRIMOUTREG(MGAREG_WR25, 0x100);
|
||||
PRIMOUTREG(MGAREG_WR34, 0); /* tex w/h */
|
||||
PRIMOUTREG(MGAREG_WR42, 0xFFFF);
|
||||
PRIMOUTREG(MGAREG_WR60, 0xFFFF);
|
||||
|
||||
/* Dma pading required due to hw bug */
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
|
||||
|
|
@ -495,7 +524,6 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
|
|||
y2 = length / 64;
|
||||
|
||||
PRIM_OVERFLOW(dev, dev_priv, 30);
|
||||
PRIMGETPTR(dev_priv);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, destOrg);
|
||||
PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
|
||||
|
|
@ -513,10 +541,11 @@ static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
|
|||
PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
|
||||
PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_SRCORG, 0);
|
||||
PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
|
||||
|
||||
PRIMADVANCE(dev_priv);
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +558,6 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
|
|||
int length = buf->used;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int i = 0;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
|
|
@ -545,11 +573,16 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
|
|||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
buf_priv->dispatched = 1;
|
||||
primary_needed = (50 + 15 + 15 + 30 + 25 +
|
||||
10 + 15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIM_OVERFLOW(dev, dev_priv,
|
||||
(MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
|
||||
mgaEmitState(dev_priv);
|
||||
|
||||
#if 0
|
||||
length = dev_priv->vertexsize * 3 * 4;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
do {
|
||||
if (i < sarea_priv->nbox) {
|
||||
DRM_DEBUG("idx %d Emit box %d/%d:"
|
||||
|
|
@ -597,7 +630,6 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
|
|||
unsigned int address = (unsigned int) buf->bus_address;
|
||||
int use_agp = PDEA_pagpxfer_enable;
|
||||
int i = 0;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
|
|
@ -611,9 +643,9 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
|
|||
* these numbers (Overestimating this doesn't hurt).
|
||||
*/
|
||||
buf_priv->dispatched = 1;
|
||||
primary_needed = (50 + 15 + 15 + 30 + 25 +
|
||||
10 + 15 * MGA_NR_SAREA_CLIPRECTS);
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIM_OVERFLOW(dev, dev_priv,
|
||||
(MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
|
||||
|
||||
mgaEmitState(dev_priv);
|
||||
|
||||
do {
|
||||
|
|
@ -639,6 +671,7 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
|
|||
SETADD_mode_vertlist));
|
||||
PRIMOUTREG(MGAREG_SETUPEND,
|
||||
((address + end) | use_agp));
|
||||
|
||||
PRIMADVANCE(dev_priv);
|
||||
} while (++i < sarea_priv->nbox);
|
||||
}
|
||||
|
|
@ -653,7 +686,10 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
|
|||
|
||||
static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
||||
unsigned int clear_color,
|
||||
unsigned int clear_zval)
|
||||
unsigned int clear_zval,
|
||||
unsigned int clear_colormask,
|
||||
unsigned int clear_depthmask)
|
||||
|
||||
{
|
||||
drm_mga_private_t *dev_priv = dev->dev_private;
|
||||
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
|
|
@ -662,7 +698,6 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
|||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
unsigned int cmd;
|
||||
int i;
|
||||
int primary_needed;
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
|
|
@ -671,11 +706,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
|||
else
|
||||
cmd = MGA_CLEAR_CMD | DC_atype_rstr;
|
||||
|
||||
primary_needed = nbox * 70;
|
||||
if (primary_needed == 0)
|
||||
primary_needed = 70;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR(dev_priv);
|
||||
PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS);
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
unsigned int height = pbox[i].y2 - pbox[i].y1;
|
||||
|
|
@ -687,7 +718,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
|||
if (flags & MGA_FRONT) {
|
||||
DRM_DEBUG("clear front\n");
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
|
||||
PRIMOUTREG(MGAREG_YDSTLEN,
|
||||
(pbox[i].y1 << 16) | height);
|
||||
PRIMOUTREG(MGAREG_FXBNDRY,
|
||||
|
|
@ -702,7 +733,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
|||
if (flags & MGA_BACK) {
|
||||
DRM_DEBUG("clear back\n");
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
|
||||
PRIMOUTREG(MGAREG_YDSTLEN,
|
||||
(pbox[i].y1 << 16) | height);
|
||||
PRIMOUTREG(MGAREG_FXBNDRY,
|
||||
|
|
@ -717,7 +748,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
|
|||
if (flags & MGA_DEPTH) {
|
||||
DRM_DEBUG("clear depth\n");
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);
|
||||
PRIMOUTREG(MGAREG_YDSTLEN,
|
||||
(pbox[i].y1 << 16) | height);
|
||||
PRIMOUTREG(MGAREG_FXBNDRY,
|
||||
|
|
@ -746,31 +777,32 @@ static void mga_dma_dispatch_swap(drm_device_t * dev)
|
|||
int nbox = sarea_priv->nbox;
|
||||
drm_clip_rect_t *pbox = sarea_priv->boxes;
|
||||
int i;
|
||||
int primary_needed;
|
||||
int pixel_stride = dev_priv->stride / dev_priv->cpp;
|
||||
|
||||
PRIMLOCALS;
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
primary_needed = nbox * 5;
|
||||
primary_needed += 60;
|
||||
PRIM_OVERFLOW(dev, dev_priv, primary_needed);
|
||||
PRIMGETPTR(dev_priv);
|
||||
PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);
|
||||
PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
|
||||
|
||||
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
|
||||
PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
|
||||
PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
|
||||
PRIMOUTREG(MGAREG_AR5, dev_priv->stride / 2);
|
||||
PRIMOUTREG(MGAREG_AR5, pixel_stride);
|
||||
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DMAPAD, 0);
|
||||
PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
|
||||
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
unsigned int h = pbox[i].y2 - pbox[i].y1;
|
||||
unsigned int start = pbox[i].y1 * dev_priv->stride / 2;
|
||||
|
||||
DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
|
||||
pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2);
|
||||
unsigned int start = pbox[i].y1 * pixel_stride;
|
||||
|
||||
PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
|
||||
PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
|
||||
|
|
@ -814,7 +846,10 @@ int mga_clear_bufs(dev_t kdev, u_long cmd, caddr_t data,
|
|||
*/
|
||||
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
|
||||
mga_dma_dispatch_clear(dev, clear.flags,
|
||||
clear.clear_color, clear.clear_depth);
|
||||
clear.clear_color,
|
||||
clear.clear_depth,
|
||||
clear.clear_color_mask,
|
||||
clear.clear_depth_mask);
|
||||
PRIMUPDATE(dev_priv);
|
||||
mga_flush_write_combine();
|
||||
s = splsofttq();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
KMOD = tdfx
|
||||
SRCS = tdfx_drv.c tdfx_context.c
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
CFLAGS += ${DEBUG_FLAGS} -I..
|
||||
CFLAGS += ${DEBUG_FLAGS} -I. -I..
|
||||
KMODDEPS = drm
|
||||
|
||||
@:
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ MODULE_DEPEND(tdfx, agp, 1, 1, 1);
|
|||
|
||||
#define TDFX_NAME "tdfx"
|
||||
#define TDFX_DESC "tdfx"
|
||||
#define TDFX_DATE "19991009"
|
||||
#define TDFX_DATE "20000928"
|
||||
#define TDFX_MAJOR 1
|
||||
#define TDFX_MINOR 0
|
||||
#define TDFX_PATCHLEVEL 0
|
||||
|
|
@ -64,6 +64,9 @@ static int tdfx_probe(device_t dev)
|
|||
case 0x0005121a:
|
||||
s = "3Dfx Voodoo 3 graphics accelerator";
|
||||
break;
|
||||
case 0x0009121a:
|
||||
s = "3Dfx Voodoo 5 graphics accelerator";
|
||||
break;
|
||||
}
|
||||
|
||||
if (s) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
*
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.17 2000/09/24 13:51:32 alanh Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.22 2001/05/19 00:26:45 dawes Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -35,11 +35,9 @@
|
|||
# include "xf86.h"
|
||||
# include "xf86_OSproc.h"
|
||||
# include "xf86_ansic.h"
|
||||
# include "xf86Priv.h"
|
||||
# define _DRM_MALLOC xalloc
|
||||
# define _DRM_FREE xfree
|
||||
# ifndef XFree86LOADER
|
||||
# include <sys/stat.h>
|
||||
# include <sys/mman.h>
|
||||
# endif
|
||||
#else
|
||||
|
|
@ -53,6 +51,7 @@
|
|||
# include <signal.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# define stat_t struct stat
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/time.h>
|
||||
|
|
@ -68,10 +67,12 @@ extern int xf86RemoveSIGIOHandler(int fd);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __alpha__
|
||||
/* No longer needed with CVS kernel modules on alpha
|
||||
#if defined(__alpha__) && defined(__linux__)
|
||||
extern unsigned long _bus_base(void);
|
||||
#define BUS_BASE _bus_base()
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* Not all systems have MAP_FAILED defined */
|
||||
#ifndef MAP_FAILED
|
||||
|
|
@ -141,11 +142,7 @@ static char *drmStrdup(const char *s)
|
|||
|
||||
static unsigned long drmGetKeyFromFd(int fd)
|
||||
{
|
||||
#ifdef XFree86LOADER
|
||||
struct xf86stat st;
|
||||
#else
|
||||
struct stat st;
|
||||
#endif
|
||||
stat_t st;
|
||||
|
||||
st.st_rdev = 0;
|
||||
fstat(fd, &st);
|
||||
|
|
@ -174,11 +171,7 @@ static drmHashEntry *drmGetEntry(int fd)
|
|||
|
||||
static int drmOpenDevice(long dev, int minor)
|
||||
{
|
||||
#ifdef XFree86LOADER
|
||||
struct xf86stat st;
|
||||
#else
|
||||
struct stat st;
|
||||
#endif
|
||||
stat_t st;
|
||||
char buf[64];
|
||||
int fd;
|
||||
mode_t dirmode = DRM_DEV_DIRMODE;
|
||||
|
|
@ -225,13 +218,13 @@ static int drmOpenDevice(long dev, int minor)
|
|||
return -errno;
|
||||
}
|
||||
|
||||
int drmOpenMinor(int minor, int create)
|
||||
static 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;
|
||||
|
|
@ -252,7 +245,7 @@ int drmAvailable(void)
|
|||
if (!access("/proc/dri/0", R_OK)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if ((version = drmGetVersion(fd))) {
|
||||
retval = 1;
|
||||
drmFreeVersion(version);
|
||||
|
|
@ -267,7 +260,7 @@ static int drmOpenByBusid(const char *busid)
|
|||
int i;
|
||||
int fd;
|
||||
const char *buf;
|
||||
|
||||
|
||||
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
||||
if ((fd = drmOpenMinor(i, 0)) >= 0) {
|
||||
buf = drmGetBusid(fd);
|
||||
|
|
@ -287,7 +280,7 @@ static int drmOpenByName(const char *name)
|
|||
int i;
|
||||
int fd;
|
||||
drmVersionPtr version;
|
||||
|
||||
|
||||
if (!drmAvailable()) {
|
||||
#if !defined(XFree86Server)
|
||||
return -1;
|
||||
|
|
@ -319,7 +312,7 @@ static int drmOpenByName(const char *name)
|
|||
char proc_name[64], buf[512];
|
||||
char *driver, *pt, *devstring;
|
||||
int retcode;
|
||||
|
||||
|
||||
sprintf(proc_name, "/proc/dri/%d/name", i);
|
||||
if ((fd = open(proc_name, 0, 0)) >= 0) {
|
||||
retcode = read(fd, buf, sizeof(buf)-1);
|
||||
|
|
@ -499,11 +492,12 @@ int drmAddMap(int fd,
|
|||
drm_map_t map;
|
||||
|
||||
map.offset = offset;
|
||||
/* No longer needed with CVS kernel modules on alpha
|
||||
#ifdef __alpha__
|
||||
/* Make sure we add the bus_base to all but shm */
|
||||
if (type != DRM_SHM)
|
||||
map.offset += BUS_BASE;
|
||||
#endif
|
||||
*/
|
||||
map.size = size;
|
||||
map.handle = 0;
|
||||
map.type = type;
|
||||
|
|
@ -1007,6 +1001,28 @@ unsigned int drmAgpDeviceId(int fd)
|
|||
return i.id_device;
|
||||
}
|
||||
|
||||
int drmScatterGatherAlloc(int fd, unsigned long size, unsigned long *handle)
|
||||
{
|
||||
drm_scatter_gather_t sg;
|
||||
|
||||
*handle = 0;
|
||||
sg.size = size;
|
||||
sg.handle = 0;
|
||||
if (ioctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) return -errno;
|
||||
*handle = sg.handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmScatterGatherFree(int fd, unsigned long handle)
|
||||
{
|
||||
drm_scatter_gather_t sg;
|
||||
|
||||
sg.size = 0;
|
||||
sg.handle = handle;
|
||||
if (ioctl(fd, DRM_IOCTL_SG_FREE, &sg)) return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drmError(int err, const char *label)
|
||||
{
|
||||
switch (err) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
*
|
||||
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.3 2000/06/17 00:03:34 martin Exp $
|
||||
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.4 2001/03/21 18:08:54 dawes Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/smp_lock.h> /* For (un)lock_kernel */
|
||||
#include <linux/mm.h>
|
||||
#ifdef __alpha__
|
||||
#if defined(__alpha__) || defined(__powerpc__)
|
||||
#include <asm/pgtable.h> /* For pte_wrprotect */
|
||||
#endif
|
||||
#include <asm/io.h>
|
||||
|
|
@ -145,6 +145,7 @@
|
|||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
#define DRM_MEM_STUB 19
|
||||
#define DRM_MEM_SGLISTS 20
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
|
@ -199,7 +200,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
|
|||
unsigned long prev, cmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%2\n"
|
||||
"1: ldl_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
" beq %1,2f\n"
|
||||
" mov %4,%1\n"
|
||||
|
|
@ -210,7 +211,8 @@ __cmpxchg_u32(volatile int *m, int old, int new)
|
|||
"3: br 1b\n"
|
||||
".previous"
|
||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
||||
: "r"((long) old), "r"(new), "m"(*m));
|
||||
: "r"((long) old), "r"(new), "m"(*m)
|
||||
: "memory" );
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
|
@ -221,7 +223,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
|||
unsigned long prev, cmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%2\n"
|
||||
"1: ldq_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
" beq %1,2f\n"
|
||||
" mov %4,%1\n"
|
||||
|
|
@ -232,7 +234,8 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
|||
"3: br 1b\n"
|
||||
".previous"
|
||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
||||
: "r"((long) old), "r"(new), "m"(*m));
|
||||
: "r"((long) old), "r"(new), "m"(*m)
|
||||
: "memory" );
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
|
@ -284,12 +287,43 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
return old;
|
||||
}
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
||||
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
unsigned long prev;
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
__asm__ __volatile__(
|
||||
"sync;"
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" cmpl 0,%0,%3;"
|
||||
" bne 1f;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
"sync;"
|
||||
: "=&r"(prev)
|
||||
: "r"(ptr), "r"(new), "r"(old)
|
||||
: "cr0", "memory");
|
||||
return prev;
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
#endif /* i386, powerpc & alpha */
|
||||
|
||||
#ifndef __alpha__
|
||||
#define cmpxchg(ptr,o,n) \
|
||||
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
|
||||
(unsigned long)(n),sizeof(*(ptr))))
|
||||
#endif /* i386 & alpha */
|
||||
#endif
|
||||
|
||||
#endif /* !__HAVE_ARCH_CMPXCHG */
|
||||
|
||||
/* Macros to make printk easier */
|
||||
#define DRM_ERROR(fmt, arg...) \
|
||||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
|
||||
|
|
@ -547,7 +581,8 @@ typedef struct drm_device_dma {
|
|||
unsigned long *pagelist;
|
||||
unsigned long byte_count;
|
||||
enum {
|
||||
_DRM_DMA_USE_AGP = 0x01
|
||||
_DRM_DMA_USE_AGP = 0x01,
|
||||
_DRM_DMA_USE_SG = 0x02
|
||||
} flags;
|
||||
|
||||
/* DMA support */
|
||||
|
|
@ -579,6 +614,13 @@ typedef struct drm_agp_head {
|
|||
} drm_agp_head_t;
|
||||
#endif
|
||||
|
||||
typedef struct drm_sg_mem {
|
||||
unsigned long handle;
|
||||
void *virtual;
|
||||
int pages;
|
||||
struct page **pagelist;
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
int context;
|
||||
drm_hw_lock_t *lock;
|
||||
|
|
@ -667,6 +709,14 @@ typedef struct drm_device {
|
|||
#if __REALLY_HAVE_AGP
|
||||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
#if LINUX_VERSION_CODE < 0x020403
|
||||
struct pci_controler *hose;
|
||||
#else
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
#endif
|
||||
drm_sg_mem_t *sg; /* Scatter gather memory */
|
||||
unsigned long *ctx_bitmap;
|
||||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
|
|
@ -674,7 +724,7 @@ typedef struct drm_device {
|
|||
} drm_device_t;
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Internal function definitions
|
||||
*/
|
||||
|
||||
|
|
@ -718,6 +768,9 @@ extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
||||
|
|
@ -729,6 +782,9 @@ extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
#endif
|
||||
extern void DRM(vm_open)(struct vm_area_struct *vma);
|
||||
extern void DRM(vm_close)(struct vm_area_struct *vma);
|
||||
|
|
@ -947,5 +1003,18 @@ extern int DRM(proc_cleanup)(int minor,
|
|||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root);
|
||||
|
||||
#if __HAVE_SG
|
||||
/* Scatter Gather Support (drm_scatter.h) */
|
||||
extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
|
||||
extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(sg_free)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern unsigned long DRM(ati_pcigart_init)(drm_device_t *dev);
|
||||
extern int DRM(ati_pcigart_cleanup)(unsigned long address);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
|
|||
agp_kern_info *kern;
|
||||
drm_agp_info_t info;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
|
||||
return -EINVAL;
|
||||
|
||||
kern = &dev->agp->agp_info;
|
||||
info.agp_version_major = kern->version.major;
|
||||
|
|
@ -77,7 +78,8 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
int retcode;
|
||||
|
||||
if (!dev->agp|| 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;
|
||||
|
|
@ -89,7 +91,8 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->release) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
|
||||
return -EINVAL;
|
||||
drm_agp->release();
|
||||
dev->agp->acquired = 0;
|
||||
return 0;
|
||||
|
|
@ -108,7 +111,8 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_agp_mode_t mode;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
|
||||
return -EFAULT;
|
||||
|
|
@ -131,7 +135,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
|
|||
unsigned long pages;
|
||||
u32 type;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
|
||||
|
|
@ -188,7 +192,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
|
|||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
@ -207,7 +211,8 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
|
|||
int retcode;
|
||||
int page;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
@ -229,7 +234,7 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
|
|||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
#define __HAVE_PCI_DMA 0
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_SG
|
||||
#define __HAVE_SG 0
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_BUF_PRIV_T
|
||||
#define DRIVER_BUF_PRIV_T u32
|
||||
#endif
|
||||
|
|
@ -103,13 +107,16 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
switch ( map->type ) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifndef __sparc__
|
||||
#if !defined(__sparc__) && !defined(__alpha__)
|
||||
if ( map->offset + map->size < map->offset ||
|
||||
map->offset < virt_to_phys(high_memory) ) {
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
map->offset += dev->hose->mem_space->start;
|
||||
#endif
|
||||
#if __REALLY_HAVE_MTRR
|
||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||
|
|
@ -135,10 +142,21 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
break;
|
||||
#if __REALLY_HAVE_AGP
|
||||
case _DRM_AGP:
|
||||
#ifdef __alpha__
|
||||
map->offset += dev->hose->mem_space->start;
|
||||
#endif
|
||||
map->offset = map->offset + dev->agp->base;
|
||||
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
||||
break;
|
||||
#endif
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if (!dev->sg) {
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
map->offset = map->offset + dev->sg->handle;
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
return -EINVAL;
|
||||
|
|
@ -191,7 +209,6 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
|
|||
|
||||
down(&dev->struct_sem);
|
||||
list = &dev->maplist->head;
|
||||
r_list = NULL;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
|
||||
|
|
@ -238,6 +255,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
|
|||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
case _DRM_SCATTER_GATHER:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
|
|
@ -566,6 +584,159 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
|
|||
}
|
||||
#endif /* __HAVE_PCI_DMA */
|
||||
|
||||
#ifdef __HAVE_SG
|
||||
int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
drm_buf_entry_t *entry;
|
||||
drm_buf_t *buf;
|
||||
unsigned long offset;
|
||||
unsigned long agp_offset;
|
||||
int count;
|
||||
int order;
|
||||
int size;
|
||||
int alignment;
|
||||
int page_order;
|
||||
int total;
|
||||
int byte_count;
|
||||
int i;
|
||||
|
||||
if ( !dma ) return -EINVAL;
|
||||
|
||||
if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
|
||||
sizeof(request) ) )
|
||||
return -EFAULT;
|
||||
|
||||
count = request.count;
|
||||
order = DRM(order)( request.size );
|
||||
size = 1 << order;
|
||||
|
||||
alignment = (request.flags & _DRM_PAGE_ALIGN)
|
||||
? PAGE_ALIGN(size) : size;
|
||||
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
|
||||
total = PAGE_SIZE << page_order;
|
||||
|
||||
byte_count = 0;
|
||||
agp_offset = request.agp_start;
|
||||
|
||||
DRM_DEBUG( "count: %d\n", count );
|
||||
DRM_DEBUG( "order: %d\n", order );
|
||||
DRM_DEBUG( "size: %d\n", size );
|
||||
DRM_DEBUG( "agp_offset: %ld\n", agp_offset );
|
||||
DRM_DEBUG( "alignment: %d\n", alignment );
|
||||
DRM_DEBUG( "page_order: %d\n", page_order );
|
||||
DRM_DEBUG( "total: %d\n", total );
|
||||
|
||||
if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
|
||||
if ( dev->queue_count ) return -EBUSY; /* Not while in use */
|
||||
|
||||
spin_lock( &dev->count_lock );
|
||||
if ( dev->buf_use ) {
|
||||
spin_unlock( &dev->count_lock );
|
||||
return -EBUSY;
|
||||
}
|
||||
atomic_inc( &dev->buf_alloc );
|
||||
spin_unlock( &dev->count_lock );
|
||||
|
||||
down( &dev->struct_sem );
|
||||
entry = &dma->bufs[order];
|
||||
if ( entry->buf_count ) {
|
||||
up( &dev->struct_sem );
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return -ENOMEM; /* May only call once for each order */
|
||||
}
|
||||
|
||||
entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS );
|
||||
if ( !entry->buflist ) {
|
||||
up( &dev->struct_sem );
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
|
||||
|
||||
entry->buf_size = size;
|
||||
entry->page_order = page_order;
|
||||
|
||||
offset = 0;
|
||||
|
||||
while ( entry->buf_count < count ) {
|
||||
buf = &entry->buflist[entry->buf_count];
|
||||
buf->idx = dma->buf_count + entry->buf_count;
|
||||
buf->total = alignment;
|
||||
buf->order = order;
|
||||
buf->used = 0;
|
||||
|
||||
buf->offset = (dma->byte_count + offset);
|
||||
buf->bus_address = agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + offset + dev->sg->handle);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head( &buf->dma_wait );
|
||||
buf->pid = 0;
|
||||
|
||||
buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
|
||||
buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
|
||||
DRM_MEM_BUFS );
|
||||
memset( buf->dev_private, 0, buf->dev_priv_size );
|
||||
|
||||
#if __HAVE_DMA_HISTOGRAM
|
||||
buf->time_queued = 0;
|
||||
buf->time_dispatched = 0;
|
||||
buf->time_completed = 0;
|
||||
buf->time_freed = 0;
|
||||
#endif
|
||||
DRM_DEBUG( "buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address );
|
||||
|
||||
offset += alignment;
|
||||
entry->buf_count++;
|
||||
byte_count += PAGE_SIZE << page_order;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "byte_count: %d\n", byte_count );
|
||||
|
||||
dma->buflist = DRM(realloc)( dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
(dma->buf_count + entry->buf_count)
|
||||
* sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS );
|
||||
for ( i = 0 ; i < entry->buf_count ; i++ ) {
|
||||
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
|
||||
}
|
||||
|
||||
dma->buf_count += entry->buf_count;
|
||||
dma->byte_count += byte_count;
|
||||
|
||||
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
|
||||
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
|
||||
|
||||
#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;
|
||||
request.size = size;
|
||||
|
||||
if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
|
||||
return -EFAULT;
|
||||
|
||||
dma->flags = _DRM_DMA_USE_SG;
|
||||
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return 0;
|
||||
}
|
||||
#endif /* __HAVE_SG */
|
||||
|
||||
int DRM(addbufs)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
|
|
@ -580,6 +751,11 @@ int DRM(addbufs)( struct inode *inode, struct file *filp,
|
|||
return DRM(addbufs_agp)( inode, filp, cmd, arg );
|
||||
else
|
||||
#endif
|
||||
#if __HAVE_SG
|
||||
if ( request.flags & _DRM_SG_BUFFER )
|
||||
return DRM(addbufs_sg)( inode, filp, cmd, arg );
|
||||
else
|
||||
#endif
|
||||
#if __HAVE_PCI_DMA
|
||||
return DRM(addbufs_pci)( inode, filp, cmd, arg );
|
||||
#else
|
||||
|
|
@ -761,7 +937,8 @@ int DRM(mapbufs)( struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
if ( request.count >= dma->buf_count ) {
|
||||
if ( __HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP) ) {
|
||||
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
||||
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
||||
drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
||||
|
||||
if ( !map ) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#if __HAVE_CTX_BITMAP
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Context bitmap support
|
||||
*/
|
||||
|
||||
|
|
@ -72,16 +72,16 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
|||
if(dev->context_sareas) {
|
||||
dev->context_sareas = DRM(realloc)(
|
||||
dev->context_sareas,
|
||||
(dev->max_context - 1) *
|
||||
(dev->max_context - 1) *
|
||||
sizeof(*dev->context_sareas),
|
||||
dev->max_context *
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
} else {
|
||||
/* max_context == 1 at this point */
|
||||
dev->context_sareas = DRM(alloc)(
|
||||
dev->max_context *
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
|
|
@ -123,14 +123,14 @@ void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
|
|||
{
|
||||
down(&dev->struct_sem);
|
||||
if( dev->context_sareas ) DRM(free)( dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context,
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Per Context SAREA Support
|
||||
*/
|
||||
|
||||
|
|
@ -178,7 +178,6 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
r_list = NULL;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
if(r_list->map &&
|
||||
|
|
@ -203,7 +202,7 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* The actual DRM context handling routines
|
||||
*/
|
||||
|
||||
|
|
@ -390,7 +389,7 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
|
|||
|
||||
#else /* __HAVE_CTX_BITMAP */
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Old-style context support
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@
|
|||
#ifndef __HAVE_DMA_RECLAIM
|
||||
#define __HAVE_DMA_RECLAIM 0
|
||||
#endif
|
||||
#ifndef __HAVE_SHARED_IRQ
|
||||
#define __HAVE_SHARED_IRQ 0
|
||||
#endif
|
||||
|
||||
#if __HAVE_SHARED_IRQ
|
||||
#define DRM_IRQ_TYPE SA_SHIRQ
|
||||
#else
|
||||
#define DRM_IRQ_TYPE 0
|
||||
#endif
|
||||
|
||||
#if __HAVE_DMA
|
||||
|
||||
|
|
@ -534,7 +543,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
|
||||
/* Install handler */
|
||||
ret = request_irq( dev->irq, DRM(dma_service),
|
||||
0, dev->devname, dev );
|
||||
DRM_IRQ_TYPE, dev->devname, dev );
|
||||
if ( ret < 0 ) {
|
||||
down( &dev->struct_sem );
|
||||
dev->irq = 0;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@
|
|||
#ifndef __HAVE_COUNTERS
|
||||
#define __HAVE_COUNTERS 0
|
||||
#endif
|
||||
#ifndef __HAVE_SG
|
||||
#define __HAVE_SG 0
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_PREINIT
|
||||
#define DRIVER_PREINIT()
|
||||
|
|
@ -135,8 +138,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 },
|
||||
|
||||
#if __HAVE_CTX_BITMAP
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
|
||||
#endif
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
|
||||
|
|
@ -178,6 +183,11 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
|
||||
#endif
|
||||
|
||||
#if __HAVE_SG
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
|
||||
#endif
|
||||
|
||||
DRIVER_IOCTLS
|
||||
};
|
||||
|
||||
|
|
@ -415,6 +425,17 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
* handled in the AGP/GART driver.
|
||||
*/
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
/* Handle it, but do nothing, if HAVE_SG
|
||||
* isn't defined.
|
||||
*/
|
||||
#if __HAVE_SG
|
||||
if(dev->sg) {
|
||||
DRM(sg_cleanup)(dev->sg);
|
||||
dev->sg = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,21 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
|
|||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Default the hose
|
||||
*/
|
||||
if (!dev->hose) {
|
||||
struct pci_dev *pci_dev;
|
||||
pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
|
||||
if (pci_dev) dev->hose = pci_dev->sysdata;
|
||||
if (!dev->hose) {
|
||||
struct pci_bus *b = pci_bus_b(pci_root_buses.next);
|
||||
if (b) dev->hose = b->sysdata;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@
|
|||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
|
||||
#if 0
|
||||
int DRM(flags) = DRM_FLAG_DEBUG;
|
||||
#else
|
||||
int DRM(flags) = 0;
|
||||
#endif
|
||||
|
||||
/* drm_parse_option parses a single option. See description for
|
||||
* drm_parse_options for details.
|
||||
|
|
|
|||
|
|
@ -95,6 +95,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
DRM_MEM_DRIVER);
|
||||
sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
|
||||
|
||||
#ifdef __alpha__
|
||||
do {
|
||||
struct pci_dev *pci_dev;
|
||||
int b, d, f;
|
||||
char *p;
|
||||
|
||||
for(p = dev->unique; p && *p && *p != ':'; p++);
|
||||
if (!p || !*p) break;
|
||||
b = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p != ':') break;
|
||||
d = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p != ':') break;
|
||||
f = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p) break;
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev)
|
||||
dev->hose = pci_dev->sysdata;
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
|
|||
[DRM_MEM_MAPPINGS] = { "mappings" },
|
||||
[DRM_MEM_BUFLISTS] = { "buflists" },
|
||||
[DRM_MEM_AGPLISTS] = { "agplist" },
|
||||
[DRM_MEM_SGLISTS] = { "sglist" },
|
||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ struct vm_operations_struct drm_vm_dma_ops = {
|
|||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_sg_ops = {
|
||||
nopage: DRM(vm_sg_nopage),
|
||||
open: DRM(vm_open),
|
||||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
|
|
@ -93,7 +99,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
offset = address - vma->vm_start;
|
||||
i = (unsigned long)map->handle + offset;
|
||||
/* We have to walk page tables here because we need large SAREA's, and
|
||||
* they need to be virtually contigious in kernel space.
|
||||
* they need to be virtually contiguous in kernel space.
|
||||
*/
|
||||
pgd = pgd_offset_k( i );
|
||||
if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
|
||||
|
|
@ -187,6 +193,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
|
|||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
case _DRM_SCATTER_GATHER:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
|
|
@ -230,6 +237,48 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
|
||||
#else
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_pte;
|
||||
#endif
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long offset;
|
||||
unsigned long map_offset;
|
||||
unsigned long page_offset;
|
||||
struct page *page;
|
||||
|
||||
if (!entry) return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
|
||||
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
map_offset = map->offset - dev->sg->handle;
|
||||
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
|
||||
page = entry->pagelist[page_offset];
|
||||
atomic_inc(&page->count); /* Dec. by kernel */
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return (unsigned long)virt_to_phys(page->virtual);
|
||||
#else
|
||||
return page;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRM(vm_open)(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
|
|
@ -322,11 +371,14 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
unsigned long offset = 0;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
||||
if ( !priv->authenticated ) return -EACCES;
|
||||
|
||||
if (!VM_OFFSET(vma)) return DRM(mmap_dma)(filp, vma);
|
||||
|
||||
/* A sequential search of a linked list is
|
||||
|
|
@ -374,19 +426,26 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
}
|
||||
#elif defined(__ia64__)
|
||||
if (map->type != _DRM_AGP)
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
vma->vm_page_prot =
|
||||
pgprot_writecombine(vma->vm_page_prot);
|
||||
#elif defined(__powerpc__)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
|
||||
#endif
|
||||
vma->vm_flags |= VM_IO; /* not in core dump */
|
||||
}
|
||||
#ifdef __alpha__
|
||||
offset = dev->hose->dense_mem_base -
|
||||
dev->hose->mem_space->start;
|
||||
#endif
|
||||
if (remap_page_range(vma->vm_start,
|
||||
VM_OFFSET(vma),
|
||||
VM_OFFSET(vma) + offset,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
|
||||
" offset = 0x%lx\n",
|
||||
map->type,
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
|
||||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
|
|
@ -400,6 +459,15 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
vma->vm_ops = &drm_vm_sg_ops;
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
vma->vm_private_data = (void *)map;
|
||||
#else
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
#endif
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL; /* This should never happen. */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,7 +183,11 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
down(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
|
|
@ -199,7 +203,11 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
up(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
} else {
|
||||
buf_priv->virtual = buf_priv->kernel_virtual;
|
||||
buf_priv->currently_mapped = I810_BUF_MAPPED;
|
||||
|
|
@ -215,7 +223,11 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
if(VM_DONTCOPY != 0) {
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
down(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < 0x020399
|
||||
retcode = do_munmap((unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
|
|
@ -224,7 +236,11 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#endif
|
||||
up(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
}
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
|
@ -339,8 +355,8 @@ static int i810_wait_ring(drm_device_t *dev, int n)
|
|||
if (ring->head != last_head)
|
||||
end = jiffies + (HZ*3);
|
||||
|
||||
if (iters==1)
|
||||
printk("wait for space in ring\n");
|
||||
/* if (iters==1) */
|
||||
/* printk("wait for space in ring\n"); */
|
||||
|
||||
iters++;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
|
|
@ -576,8 +592,8 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
|
||||
for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++)
|
||||
printk("texreg %d: %x\n", i, code[i]);
|
||||
/* for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++) */
|
||||
/* printk("texreg %d: %x\n", i, code[i]); */
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define DRIVER_NAME "i810"
|
||||
#define DRIVER_DESC "Intel i810"
|
||||
#define DRIVER_DATE "20010215"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 1
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "mga"
|
||||
#define DRIVER_DESC "Matrox G200/G400"
|
||||
#define DRIVER_DATE "20010321"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 3
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
|
|||
|
|
@ -33,12 +33,13 @@
|
|||
#include "r128.h"
|
||||
#include "drmP.h"
|
||||
#include "r128_drv.h"
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
|
||||
|
||||
#define DRIVER_NAME "r128"
|
||||
#define DRIVER_DESC "ATI Rage 128"
|
||||
#define DRIVER_DATE "20010308"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 1
|
||||
|
|
@ -88,3 +89,4 @@
|
|||
#include "drm_proc.h"
|
||||
#include "drm_vm.h"
|
||||
#include "drm_stub.h"
|
||||
#include "drm_scatter.h"
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@
|
|||
#include "radeon.h"
|
||||
#include "drmP.h"
|
||||
#include "radeon_drv.h"
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
|
||||
|
||||
#define DRIVER_NAME "radeon"
|
||||
#define DRIVER_DESC "ATI Radeon"
|
||||
#define DRIVER_DATE "20010402"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
@ -84,3 +85,4 @@
|
|||
#include "drm_proc.h"
|
||||
#include "drm_vm.h"
|
||||
#include "drm_stub.h"
|
||||
#include "drm_scatter.h"
|
||||
|
|
|
|||
|
|
@ -26,669 +26,49 @@
|
|||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include "sis.h"
|
||||
#include "drmP.h"
|
||||
#include "sis_drm.h"
|
||||
#include "sis_drv.h"
|
||||
|
||||
#define SIS_NAME "sis"
|
||||
#define SIS_DESC "SIS 300/630/540"
|
||||
#define SIS_DATE "20000831"
|
||||
#define SIS_MAJOR 1
|
||||
#define SIS_MINOR 0
|
||||
#define SIS_PATCHLEVEL 0
|
||||
#define DRIVER_AUTHOR "SIS"
|
||||
#define DRIVER_NAME "sis"
|
||||
#define DRIVER_DESC "SIS 300/630/540"
|
||||
#define DRIVER_DATE "20010624"
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
static drm_device_t sis_device;
|
||||
drm_ctx_t sis_res_ctx;
|
||||
|
||||
static struct file_operations sis_fops = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
/* This started being used during 2.4.0-test */
|
||||
owner: THIS_MODULE,
|
||||
#endif
|
||||
open: sis_open,
|
||||
flush: drm_flush,
|
||||
release: sis_release,
|
||||
ioctl: sis_ioctl,
|
||||
mmap: drm_mmap,
|
||||
read: drm_read,
|
||||
fasync: drm_fasync,
|
||||
poll: drm_poll,
|
||||
};
|
||||
|
||||
static struct miscdevice sis_misc = {
|
||||
minor: MISC_DYNAMIC_MINOR,
|
||||
name: SIS_NAME,
|
||||
fops: &sis_fops,
|
||||
};
|
||||
|
||||
static drm_ioctl_desc_t sis_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { sis_version, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { sis_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { sis_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { sis_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { sis_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { sis_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
|
||||
#endif
|
||||
/* FB Memory Management */
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 },
|
||||
|
||||
/* AGP Memory Management */
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sis_agp_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sis_agp_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sis_agp_free, 1, 1 },
|
||||
|
||||
#if defined(SIS_STEREO)
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 },
|
||||
#endif
|
||||
};
|
||||
#define SIS_IOCTL_COUNT DRM_ARRAY_SIZE(sis_ioctls)
|
||||
|
||||
#ifdef MODULE
|
||||
static char *sis = NULL;
|
||||
#define DRIVER_IOCTLS \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 }, \
|
||||
/* AGP Memory Management */ \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 1 }
|
||||
#if 0 /* these don't appear to be defined */
|
||||
/* SIS Stereo */
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 }
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("VA Linux Systems, Inc.");
|
||||
MODULE_DESCRIPTION("sis");
|
||||
MODULE_PARM(sis, "s");
|
||||
#define __HAVE_COUNTERS 5
|
||||
|
||||
#ifndef MODULE
|
||||
/* sis_options is called by the kernel to parse command-line options
|
||||
* passed via the boot-loader (e.g., LILO). It calls the insmod option
|
||||
* routine, drm_parse_drm.
|
||||
*/
|
||||
|
||||
static int __init sis_options(char *str)
|
||||
{
|
||||
drm_parse_options(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("sis=", sis_options);
|
||||
#endif
|
||||
|
||||
static int sis_setup(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
atomic_set(&dev->ioctl_count, 0);
|
||||
atomic_set(&dev->vma_count, 0);
|
||||
dev->buf_use = 0;
|
||||
atomic_set(&dev->buf_alloc, 0);
|
||||
|
||||
atomic_set(&dev->total_open, 0);
|
||||
atomic_set(&dev->total_close, 0);
|
||||
atomic_set(&dev->total_ioctl, 0);
|
||||
atomic_set(&dev->total_irq, 0);
|
||||
atomic_set(&dev->total_ctx, 0);
|
||||
atomic_set(&dev->total_locks, 0);
|
||||
atomic_set(&dev->total_unlocks, 0);
|
||||
atomic_set(&dev->total_contends, 0);
|
||||
atomic_set(&dev->total_sleeps, 0);
|
||||
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
dev->magiclist[i].head = NULL;
|
||||
dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
dev->vmalist = NULL;
|
||||
dev->lock.hw_lock = NULL;
|
||||
init_waitqueue_head(&dev->lock.lock_queue);
|
||||
dev->queue_count = 0;
|
||||
dev->queue_reserved = 0;
|
||||
dev->queue_slots = 0;
|
||||
dev->queuelist = NULL;
|
||||
dev->irq = 0;
|
||||
dev->context_flag = 0;
|
||||
dev->interrupt_flag = 0;
|
||||
dev->dma = 0;
|
||||
dev->dma_flag = 0;
|
||||
dev->last_context = 0;
|
||||
dev->last_switch = 0;
|
||||
dev->last_checked = 0;
|
||||
init_timer(&dev->timer);
|
||||
init_waitqueue_head(&dev->context_wait);
|
||||
|
||||
dev->ctx_start = 0;
|
||||
dev->lck_start = 0;
|
||||
|
||||
dev->buf_rp = dev->buf;
|
||||
dev->buf_wp = dev->buf;
|
||||
dev->buf_end = dev->buf + DRM_BSZ;
|
||||
dev->buf_async = NULL;
|
||||
init_waitqueue_head(&dev->buf_readers);
|
||||
init_waitqueue_head(&dev->buf_writers);
|
||||
|
||||
sis_res_ctx.handle=-1;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
/* The kernel's context could be created here, but is now created
|
||||
in drm_dma_enqueue. This is more resource-efficient for
|
||||
hardware that does not do DMA, but may mean that
|
||||
drm_select_queue fails between the time the interrupt is
|
||||
initialized and the time the queues are initialized. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int sis_takedown(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_t *map;
|
||||
drm_vma_entry_t *vma, *vma_next;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
#if defined(SIS_STEREO)
|
||||
if (dev->irq) sis_irq_uninstall(dev);
|
||||
#endif
|
||||
|
||||
down(&dev->struct_sem);
|
||||
del_timer(&dev->timer);
|
||||
|
||||
if (dev->devname) {
|
||||
drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
|
||||
dev->devname = NULL;
|
||||
}
|
||||
|
||||
if (dev->unique) {
|
||||
drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
|
||||
dev->unique = NULL;
|
||||
dev->unique_len = 0;
|
||||
}
|
||||
/* Clear pid list */
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
for (pt = dev->magiclist[i].head; pt; pt = next) {
|
||||
next = pt->next;
|
||||
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
|
||||
}
|
||||
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
/* Clear AGP information */
|
||||
if (dev->agp) {
|
||||
drm_agp_mem_t *temp;
|
||||
drm_agp_mem_t *temp_next;
|
||||
|
||||
temp = dev->agp->memory;
|
||||
while(temp != NULL) {
|
||||
temp_next = temp->next;
|
||||
drm_free_agp(temp->memory, temp->pages);
|
||||
drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS);
|
||||
temp = temp_next;
|
||||
}
|
||||
if (dev->agp->acquired) _drm_agp_release();
|
||||
}
|
||||
#endif
|
||||
/* Clear vma list (only built for debugging) */
|
||||
if (dev->vmalist) {
|
||||
for (vma = dev->vmalist; vma; vma = vma_next) {
|
||||
vma_next = vma->next;
|
||||
drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
|
||||
}
|
||||
dev->vmalist = NULL;
|
||||
}
|
||||
|
||||
/* Clear map area and mtrr information */
|
||||
if (dev->maplist) {
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifdef CONFIG_MTRR
|
||||
if (map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr,
|
||||
map->offset,
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
#endif
|
||||
drm_ioremapfree(map->handle, map->size);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
drm_free_pages((unsigned long)map->handle,
|
||||
drm_order(map->size)
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
/* Do nothing here, because this is all
|
||||
handled in the AGP/GART driver. */
|
||||
break;
|
||||
}
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
drm_free(dev->maplist,
|
||||
dev->map_count * sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS);
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
}
|
||||
|
||||
if (dev->lock.hw_lock) {
|
||||
dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
dev->lock.pid = 0;
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sis_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
|
||||
static int sis_init(void)
|
||||
{
|
||||
int retcode;
|
||||
drm_device_t *dev = &sis_device;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
memset((void *)dev, 0, sizeof(*dev));
|
||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||
sema_init(&dev->struct_sem, 1);
|
||||
|
||||
#ifdef MODULE
|
||||
drm_parse_options(sis);
|
||||
#endif
|
||||
|
||||
if ((retcode = misc_register(&sis_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", SIS_NAME);
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV(MISC_MAJOR, sis_misc.minor);
|
||||
dev->name = SIS_NAME;
|
||||
|
||||
drm_mem_init();
|
||||
drm_proc_init(dev);
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
dev->agp = drm_agp_init();
|
||||
#endif
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&sis_misc);
|
||||
sis_takedown(dev);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
|
||||
SIS_NAME,
|
||||
SIS_MAJOR,
|
||||
SIS_MINOR,
|
||||
SIS_PATCHLEVEL,
|
||||
SIS_DATE,
|
||||
sis_misc.minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sis_cleanup is called via cleanup_module at module unload time. */
|
||||
|
||||
static void sis_cleanup(void)
|
||||
{
|
||||
drm_device_t *dev = &sis_device;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
drm_proc_cleanup();
|
||||
if (misc_deregister(&sis_misc)) {
|
||||
DRM_ERROR("Cannot unload module\n");
|
||||
} else {
|
||||
DRM_INFO("Module unloaded\n");
|
||||
}
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
sis_takedown(dev);
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
if (dev->agp) {
|
||||
drm_agp_uninit();
|
||||
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
|
||||
dev->agp = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(sis_init);
|
||||
module_exit(sis_cleanup);
|
||||
|
||||
|
||||
int sis_version(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_version_t version;
|
||||
int len;
|
||||
|
||||
if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version)))
|
||||
return -EFAULT;
|
||||
|
||||
#define DRM_COPY(name,value) \
|
||||
len = strlen(value); \
|
||||
if (len > name##_len) len = name##_len; \
|
||||
name##_len = strlen(value); \
|
||||
if (len && name) { \
|
||||
if (copy_to_user(name, value, len)) \
|
||||
return -EFAULT; \
|
||||
}
|
||||
|
||||
version.version_major = SIS_MAJOR;
|
||||
version.version_minor = SIS_MINOR;
|
||||
version.version_patchlevel = SIS_PATCHLEVEL;
|
||||
|
||||
DRM_COPY(version.name, SIS_NAME);
|
||||
DRM_COPY(version.date, SIS_DATE);
|
||||
DRM_COPY(version.desc, SIS_DESC);
|
||||
|
||||
if (copy_to_user((drm_version_t *)arg, &version, sizeof(version)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sis_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_device_t *dev = &sis_device;
|
||||
int retcode = 0;
|
||||
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
if (!(retcode = drm_open_helper(inode, filp, dev))) {
|
||||
#if LINUX_VERSION_CODE < 0x020333
|
||||
MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
|
||||
#endif
|
||||
atomic_inc(&dev->total_open);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!dev->open_count++) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return sis_setup(dev);
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int sis_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
int retcode = 0;
|
||||
|
||||
lock_kernel();
|
||||
dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
if (!(retcode = drm_release(inode, filp))) {
|
||||
#if LINUX_VERSION_CODE < 0x020333
|
||||
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
|
||||
#endif
|
||||
atomic_inc(&dev->total_close);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!--dev->open_count) {
|
||||
if (atomic_read(&dev->ioctl_count) || dev->blocked) {
|
||||
DRM_ERROR("Device busy: %d %d\n",
|
||||
atomic_read(&dev->ioctl_count),
|
||||
dev->blocked);
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return -EBUSY;
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return sis_takedown(dev);
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
}
|
||||
|
||||
unlock_kernel();
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* sis_ioctl is called whenever a process performs an ioctl on /dev/drm. */
|
||||
|
||||
int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
int retcode = 0;
|
||||
drm_ioctl_desc_t *ioctl;
|
||||
drm_ioctl_t *func;
|
||||
|
||||
atomic_inc(&dev->ioctl_count);
|
||||
atomic_inc(&dev->total_ioctl);
|
||||
++priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
|
||||
current->pid, cmd, nr, dev->device, priv->authenticated);
|
||||
|
||||
if (nr >= SIS_IOCTL_COUNT) {
|
||||
retcode = -EINVAL;
|
||||
} else {
|
||||
ioctl = &sis_ioctls[nr];
|
||||
func = ioctl->func;
|
||||
|
||||
if (!func) {
|
||||
DRM_DEBUG("no function\n");
|
||||
retcode = -EINVAL;
|
||||
} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
|
||||
|| (ioctl->auth_needed && !priv->authenticated)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
retcode = (func)(inode, filp, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int sis_lock(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;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
int ret = 0;
|
||||
drm_lock_t lock;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
cycles_t start;
|
||||
|
||||
dev->lck_start = start = get_cycles();
|
||||
#endif
|
||||
|
||||
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid, dev->lock.hw_lock->lock,
|
||||
lock.flags);
|
||||
|
||||
#if 0
|
||||
/* dev->queue_count == 0 right now for
|
||||
sis. FIXME? */
|
||||
if (lock.context < 0 || lock.context >= dev->queue_count)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
!= lock.context) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
||||
if (lock.context == sis_res_ctx.handle &&
|
||||
j >= 0 && j < DRM_LOCK_SLICE) {
|
||||
/* Can't take lock if we just had it and
|
||||
there is contention. */
|
||||
DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
|
||||
lock.context, current->pid, j,
|
||||
dev->lock.lock_time, jiffies);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule_timeout(DRM_LOCK_SLICE-j);
|
||||
DRM_DEBUG("jiffies=%d\n", jiffies);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
lock.context)) {
|
||||
dev->lock.pid = current->pid;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->total_locks);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
#if 1
|
||||
current->policy |= SCHED_YIELD;
|
||||
#endif
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!ret && dev->last_context != lock.context &&
|
||||
lock.context != sis_res_ctx.handle &&
|
||||
dev->last_context != sis_res_ctx.handle) {
|
||||
add_wait_queue(&dev->context_wait, &entry);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
/* PRE: dev->last_context != lock.context */
|
||||
sis_context_switch(dev, dev->last_context, lock.context);
|
||||
/* POST: we will wait for the context
|
||||
switch and will dispatch on a later call
|
||||
when dev->last_context == lock.context
|
||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
||||
TIME! */
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule();
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->context_wait, &entry);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
} else if (dev->last_context != lock.context) {
|
||||
DRM_ERROR("Context mismatch: %d %d\n",
|
||||
dev->last_context, lock.context);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
sigemptyset(&dev->sigmask);
|
||||
sigaddset(&dev->sigmask, SIGSTOP);
|
||||
sigaddset(&dev->sigmask, SIGTSTP);
|
||||
sigaddset(&dev->sigmask, SIGTTIN);
|
||||
sigaddset(&dev->sigmask, SIGTTOU);
|
||||
dev->sigdata.context = lock.context;
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
|
||||
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
/* Make hardware quiescent */
|
||||
#if 0
|
||||
sis_quiescent(dev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sis_unlock(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_lock_t lock;
|
||||
|
||||
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d frees lock (%d holds)\n",
|
||||
lock.context,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
atomic_inc(&dev->total_unlocks);
|
||||
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
|
||||
atomic_inc(&dev->total_contends);
|
||||
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
|
||||
/* FIXME: Try to send data to card here */
|
||||
if (!dev->context_flag) {
|
||||
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
unblock_all_signals();
|
||||
return 0;
|
||||
}
|
||||
#include "drm_auth.h"
|
||||
#include "drm_agpsupport.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"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "tdfx"
|
||||
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
|
||||
#define DRIVER_DATE "20010216"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
# **** End of SMP/MODVERSIONS detection
|
||||
|
||||
MODS = gamma.o tdfx.o
|
||||
MODS = gamma.o tdfx.o r128.o radeon.o
|
||||
LIBS =
|
||||
|
||||
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
|
||||
|
|
@ -59,7 +59,14 @@ GAMMAOBJS = gamma_drv.o gamma_dma.o
|
|||
GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
|
||||
|
||||
TDFXOBJS = tdfx_drv.o
|
||||
TDFXHEADERS = tdfx.h $(DRMHEADERS)
|
||||
TDFXHEADERS = tdfx.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) \
|
||||
$(DRMTEMPLATES)
|
||||
|
||||
INC = /usr/include
|
||||
|
||||
|
|
@ -83,9 +90,10 @@ PRGLIBS =
|
|||
# This may not be correct, but it is the best assumption we can make.
|
||||
|
||||
VERSION := $(shell uname -r)
|
||||
A := /usr/src/linux-$(VERSION)/include
|
||||
B := /usr/src/linux/include
|
||||
C := /usr/include
|
||||
A := /lib/modules/$(VERSION)/build/include
|
||||
B := /usr/src/linux-$(VERSION)/include
|
||||
C := /usr/src/linux/include
|
||||
D := /usr/include
|
||||
|
||||
V := $(shell gcc -E -nostdinc -I$A picker.c 2>/dev/null \
|
||||
| grep -s 'RELEASE = ' | cut -d' ' -f3)
|
||||
|
|
@ -100,15 +108,21 @@ else
|
|||
V := $(shell gcc -E -nostdinc -I$C picker.c 2>/dev/null \
|
||||
| grep -s 'RELEASE = ' | cut -d' ' -f3)
|
||||
ifeq ($(V),"$(VERSION)")
|
||||
TREE := $C
|
||||
TREE := $C
|
||||
else
|
||||
V := $(shell gcc -E -nostdinc -I$D picker.c 2>/dev/null \
|
||||
| grep -s 'RELEASE = ' | cut -d' ' -f3)
|
||||
ifeq ($(V),"$(VERSION)")
|
||||
TREE := $D
|
||||
else
|
||||
TREE := 0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TREE),0)
|
||||
all:; @echo Error: Could not locate kernel tree in $A $B $C
|
||||
all:; @echo Error: Could not locate kernel tree in $A $B $C $D
|
||||
else
|
||||
SMP := $(shell gcc -E -nostdinc -I$(TREE) picker.c 2>/dev/null \
|
||||
| grep -s 'SMP = ' | cut -d' ' -f3)
|
||||
|
|
@ -132,7 +146,7 @@ ifeq ($(AGP),1)
|
|||
MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
|
||||
DRMTEMPLATES += drm_agpsupport.h
|
||||
DRMHEADERS += agpsupport-pre24.h
|
||||
MODS += mga.o r128.o radeon.o
|
||||
MODS += mga.o
|
||||
ifeq ($(MACHINE),i386)
|
||||
MODS += i810.o
|
||||
endif
|
||||
|
|
@ -140,19 +154,16 @@ ifeq ($(MACHINE),i686)
|
|||
MODS += i810.o
|
||||
endif
|
||||
|
||||
|
||||
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 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)
|
||||
endif
|
||||
|
||||
RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o
|
||||
RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
|
||||
$(DRMTEMPLATES)
|
||||
ifeq ($(MACHINE),alpha)
|
||||
MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6
|
||||
endif
|
||||
|
||||
ifeq ($(SIS),1)
|
||||
|
|
@ -164,8 +175,8 @@ ifeq ($(SIS),1)
|
|||
# file to see if we can, at least, compile the driver.
|
||||
MODS += sis.o
|
||||
|
||||
SISOBJS= sis_drv.o sis_context.o sis_ds.o sis_mm.o
|
||||
SISHEADERS= sis_drv.h sis_ds.h sis_drm.h $(DRMHEADERS)
|
||||
SISOBJS= sis_drv.o sis_mm.o sis_ds.o
|
||||
SISHEADERS= sis_drv.h sis_drm.h $(DRMHEADERS)
|
||||
MODCFLAGS += -DCONFIG_DRM_SIS
|
||||
endif
|
||||
|
||||
|
|
@ -205,6 +216,9 @@ endif
|
|||
dristat: dristat.c
|
||||
$(CC) $(PRGCFLAGS) $< -o $@
|
||||
|
||||
DRIsetup: DRIsetup.c
|
||||
$(CC) $(PRGCFLAGS) $< -o $@ -L/usr/X11R6/lib -lGL -lm ../../../../parser/libxf86config.a ../libdrm.a
|
||||
|
||||
gamma_drv.o: gamma_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
gamma.o: $(GAMMAOBJS)
|
||||
|
|
@ -218,6 +232,16 @@ tdfx.o: $(TDFXOBJS) $(LIBS)
|
|||
sis.o: $(SISOBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
r128_drv.o: r128_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
r128.o: $(R128OBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
radeon_drv.o: radeon_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
radeon.o: $(RADEONOBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
ifeq ($(AGP),1)
|
||||
mga_drv.o: mga_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
|
|
@ -229,15 +253,6 @@ i810_drv.o: i810_drv.c
|
|||
i810.o: $(I810OBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
r128_drv.o: r128_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
r128.o: $(R128OBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
|
||||
radeon_drv.o: radeon_drv.c
|
||||
$(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
|
||||
radeon.o: $(RADEONOBJS) $(LIBS)
|
||||
$(LD) -r $^ -o $@
|
||||
endif
|
||||
|
||||
.PHONY: ChangeLog
|
||||
|
|
|
|||
59
linux/drm.h
59
linux/drm.h
|
|
@ -44,8 +44,27 @@
|
|||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||
#endif
|
||||
|
||||
#define XFREE86_VERSION(major,minor,patch,snap) \
|
||||
((major << 16) | (minor < 8) | patch)
|
||||
|
||||
#ifndef CONFIG_XFREE86_VERSION
|
||||
#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_PROC_DEVICES "/proc/devices"
|
||||
#define DRM_PROC_MISC "/proc/misc"
|
||||
#define DRM_PROC_DRM "/proc/drm"
|
||||
#define DRM_DEV_DRM "/dev/drm"
|
||||
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
||||
#define DRM_DEV_UID 0
|
||||
#define DRM_DEV_GID 0
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_MAJOR 226
|
||||
#define DRM_MAX_MINOR 15
|
||||
#endif
|
||||
#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 */
|
||||
|
|
@ -127,10 +146,11 @@ typedef struct drm_control {
|
|||
} drm_control_t;
|
||||
|
||||
typedef enum drm_map_type {
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3 /* AGP/GART */
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3, /* AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
|
||||
} drm_map_type_t;
|
||||
|
||||
typedef enum drm_map_flags {
|
||||
|
|
@ -239,7 +259,8 @@ typedef struct drm_buf_desc {
|
|||
int high_mark; /* High water mark */
|
||||
enum {
|
||||
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
|
||||
_DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
|
||||
_DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
|
||||
} flags;
|
||||
unsigned long agp_start; /* Start address of where the agp buffers
|
||||
* are in the agp aperture */
|
||||
|
|
@ -345,6 +366,11 @@ typedef struct drm_agp_info {
|
|||
unsigned short id_device;
|
||||
} drm_agp_info_t;
|
||||
|
||||
typedef struct drm_scatter_gather {
|
||||
unsigned long size; /* In bytes -- will round to page boundary */
|
||||
unsigned long handle; /* Used for mapping / unmapping */
|
||||
} drm_scatter_gather_t;
|
||||
|
||||
#define DRM_IOCTL_BASE 'd'
|
||||
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
|
||||
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
|
||||
|
|
@ -400,6 +426,9 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
|
||||
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
|
||||
|
||||
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
|
||||
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
|
||||
|
||||
/* MGA specific ioctls */
|
||||
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
|
||||
|
|
@ -419,6 +448,7 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
|
||||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
|
|
@ -428,15 +458,15 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
|
||||
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -449,9 +479,10 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
|
||||
#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_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_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)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
85
linux/drmP.h
85
linux/drmP.h
|
|
@ -53,7 +53,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/smp_lock.h> /* For (un)lock_kernel */
|
||||
#include <linux/mm.h>
|
||||
#ifdef __alpha__
|
||||
#if defined(__alpha__) || defined(__powerpc__)
|
||||
#include <asm/pgtable.h> /* For pte_wrprotect */
|
||||
#endif
|
||||
#include <asm/io.h>
|
||||
|
|
@ -145,6 +145,7 @@
|
|||
#define DRM_MEM_BOUNDAGP 17
|
||||
#define DRM_MEM_CTXBITMAP 18
|
||||
#define DRM_MEM_STUB 19
|
||||
#define DRM_MEM_SGLISTS 20
|
||||
|
||||
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
|
||||
|
||||
|
|
@ -199,7 +200,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
|
|||
unsigned long prev, cmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%2\n"
|
||||
"1: ldl_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
" beq %1,2f\n"
|
||||
" mov %4,%1\n"
|
||||
|
|
@ -210,7 +211,8 @@ __cmpxchg_u32(volatile int *m, int old, int new)
|
|||
"3: br 1b\n"
|
||||
".previous"
|
||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
||||
: "r"((long) old), "r"(new), "m"(*m));
|
||||
: "r"((long) old), "r"(new), "m"(*m)
|
||||
: "memory" );
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
|
@ -221,7 +223,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
|||
unsigned long prev, cmp;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0,%2\n"
|
||||
"1: ldq_l %0,%5\n"
|
||||
" cmpeq %0,%3,%1\n"
|
||||
" beq %1,2f\n"
|
||||
" mov %4,%1\n"
|
||||
|
|
@ -232,7 +234,8 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
|
|||
"3: br 1b\n"
|
||||
".previous"
|
||||
: "=&r"(prev), "=&r"(cmp), "=m"(*m)
|
||||
: "r"((long) old), "r"(new), "m"(*m));
|
||||
: "r"((long) old), "r"(new), "m"(*m)
|
||||
: "memory" );
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
|
@ -284,12 +287,43 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
return old;
|
||||
}
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
||||
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
unsigned long prev;
|
||||
|
||||
switch (size) {
|
||||
case 4:
|
||||
__asm__ __volatile__(
|
||||
"sync;"
|
||||
"0: lwarx %0,0,%1 ;"
|
||||
" cmpl 0,%0,%3;"
|
||||
" bne 1f;"
|
||||
" stwcx. %2,0,%1;"
|
||||
" bne- 0b;"
|
||||
"1: "
|
||||
"sync;"
|
||||
: "=&r"(prev)
|
||||
: "r"(ptr), "r"(new), "r"(old)
|
||||
: "cr0", "memory");
|
||||
return prev;
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
#endif /* i386, powerpc & alpha */
|
||||
|
||||
#ifndef __alpha__
|
||||
#define cmpxchg(ptr,o,n) \
|
||||
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
|
||||
(unsigned long)(n),sizeof(*(ptr))))
|
||||
#endif /* i386 & alpha */
|
||||
#endif
|
||||
|
||||
#endif /* !__HAVE_ARCH_CMPXCHG */
|
||||
|
||||
/* Macros to make printk easier */
|
||||
#define DRM_ERROR(fmt, arg...) \
|
||||
printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
|
||||
|
|
@ -547,7 +581,8 @@ typedef struct drm_device_dma {
|
|||
unsigned long *pagelist;
|
||||
unsigned long byte_count;
|
||||
enum {
|
||||
_DRM_DMA_USE_AGP = 0x01
|
||||
_DRM_DMA_USE_AGP = 0x01,
|
||||
_DRM_DMA_USE_SG = 0x02
|
||||
} flags;
|
||||
|
||||
/* DMA support */
|
||||
|
|
@ -579,6 +614,13 @@ typedef struct drm_agp_head {
|
|||
} drm_agp_head_t;
|
||||
#endif
|
||||
|
||||
typedef struct drm_sg_mem {
|
||||
unsigned long handle;
|
||||
void *virtual;
|
||||
int pages;
|
||||
struct page **pagelist;
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
int context;
|
||||
drm_hw_lock_t *lock;
|
||||
|
|
@ -667,6 +709,14 @@ typedef struct drm_device {
|
|||
#if __REALLY_HAVE_AGP
|
||||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
#if LINUX_VERSION_CODE < 0x020403
|
||||
struct pci_controler *hose;
|
||||
#else
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
#endif
|
||||
drm_sg_mem_t *sg; /* Scatter gather memory */
|
||||
unsigned long *ctx_bitmap;
|
||||
void *dev_private;
|
||||
drm_sigdata_t sigdata; /* For block_all_signals */
|
||||
|
|
@ -674,7 +724,7 @@ typedef struct drm_device {
|
|||
} drm_device_t;
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Internal function definitions
|
||||
*/
|
||||
|
||||
|
|
@ -718,6 +768,9 @@ extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
||||
|
|
@ -729,6 +782,9 @@ extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access);
|
||||
#endif
|
||||
extern void DRM(vm_open)(struct vm_area_struct *vma);
|
||||
extern void DRM(vm_close)(struct vm_area_struct *vma);
|
||||
|
|
@ -947,5 +1003,18 @@ extern int DRM(proc_cleanup)(int minor,
|
|||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root);
|
||||
|
||||
#if __HAVE_SG
|
||||
/* Scatter Gather Support (drm_scatter.h) */
|
||||
extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
|
||||
extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int DRM(sg_free)(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
#endif
|
||||
|
||||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern unsigned long DRM(ati_pcigart_init)(drm_device_t *dev);
|
||||
extern int DRM(ati_pcigart_cleanup)(unsigned long address);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ int DRM(agp_info)(struct inode *inode, struct file *filp,
|
|||
agp_kern_info *kern;
|
||||
drm_agp_info_t info;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
|
||||
return -EINVAL;
|
||||
|
||||
kern = &dev->agp->agp_info;
|
||||
info.agp_version_major = kern->version.major;
|
||||
|
|
@ -77,7 +78,8 @@ int DRM(agp_acquire)(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
int retcode;
|
||||
|
||||
if (!dev->agp|| 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;
|
||||
|
|
@ -89,7 +91,8 @@ int DRM(agp_release)(struct inode *inode, struct file *filp,
|
|||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->release) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
|
||||
return -EINVAL;
|
||||
drm_agp->release();
|
||||
dev->agp->acquired = 0;
|
||||
return 0;
|
||||
|
|
@ -108,7 +111,8 @@ int DRM(agp_enable)(struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_agp_mode_t mode;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
|
||||
return -EFAULT;
|
||||
|
|
@ -131,7 +135,7 @@ int DRM(agp_alloc)(struct inode *inode, struct file *filp,
|
|||
unsigned long pages;
|
||||
u32 type;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
|
||||
|
|
@ -188,7 +192,7 @@ int DRM(agp_unbind)(struct inode *inode, struct file *filp,
|
|||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
@ -207,7 +211,8 @@ int DRM(agp_bind)(struct inode *inode, struct file *filp,
|
|||
int retcode;
|
||||
int page;
|
||||
|
||||
if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
@ -229,7 +234,7 @@ int DRM(agp_free)(struct inode *inode, struct file *filp,
|
|||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp->acquired) return -EINVAL;
|
||||
if (!dev->agp || !dev->agp->acquired) return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
|
||||
|
|
|
|||
183
linux/drm_bufs.h
183
linux/drm_bufs.h
|
|
@ -37,6 +37,10 @@
|
|||
#define __HAVE_PCI_DMA 0
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_SG
|
||||
#define __HAVE_SG 0
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_BUF_PRIV_T
|
||||
#define DRIVER_BUF_PRIV_T u32
|
||||
#endif
|
||||
|
|
@ -103,13 +107,16 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
switch ( map->type ) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifndef __sparc__
|
||||
#if !defined(__sparc__) && !defined(__alpha__)
|
||||
if ( map->offset + map->size < map->offset ||
|
||||
map->offset < virt_to_phys(high_memory) ) {
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
map->offset += dev->hose->mem_space->start;
|
||||
#endif
|
||||
#if __REALLY_HAVE_MTRR
|
||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||
|
|
@ -135,10 +142,21 @@ int DRM(addmap)( struct inode *inode, struct file *filp,
|
|||
break;
|
||||
#if __REALLY_HAVE_AGP
|
||||
case _DRM_AGP:
|
||||
#ifdef __alpha__
|
||||
map->offset += dev->hose->mem_space->start;
|
||||
#endif
|
||||
map->offset = map->offset + dev->agp->base;
|
||||
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
||||
break;
|
||||
#endif
|
||||
case _DRM_SCATTER_GATHER:
|
||||
if (!dev->sg) {
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
return -EINVAL;
|
||||
}
|
||||
map->offset = map->offset + dev->sg->handle;
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||
return -EINVAL;
|
||||
|
|
@ -191,7 +209,6 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
|
|||
|
||||
down(&dev->struct_sem);
|
||||
list = &dev->maplist->head;
|
||||
r_list = NULL;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
|
||||
|
|
@ -238,6 +255,7 @@ int DRM(rmmap)(struct inode *inode, struct file *filp,
|
|||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
case _DRM_SCATTER_GATHER:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
|
|
@ -566,6 +584,159 @@ int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
|
|||
}
|
||||
#endif /* __HAVE_PCI_DMA */
|
||||
|
||||
#ifdef __HAVE_SG
|
||||
int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_desc_t request;
|
||||
drm_buf_entry_t *entry;
|
||||
drm_buf_t *buf;
|
||||
unsigned long offset;
|
||||
unsigned long agp_offset;
|
||||
int count;
|
||||
int order;
|
||||
int size;
|
||||
int alignment;
|
||||
int page_order;
|
||||
int total;
|
||||
int byte_count;
|
||||
int i;
|
||||
|
||||
if ( !dma ) return -EINVAL;
|
||||
|
||||
if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
|
||||
sizeof(request) ) )
|
||||
return -EFAULT;
|
||||
|
||||
count = request.count;
|
||||
order = DRM(order)( request.size );
|
||||
size = 1 << order;
|
||||
|
||||
alignment = (request.flags & _DRM_PAGE_ALIGN)
|
||||
? PAGE_ALIGN(size) : size;
|
||||
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
|
||||
total = PAGE_SIZE << page_order;
|
||||
|
||||
byte_count = 0;
|
||||
agp_offset = request.agp_start;
|
||||
|
||||
DRM_DEBUG( "count: %d\n", count );
|
||||
DRM_DEBUG( "order: %d\n", order );
|
||||
DRM_DEBUG( "size: %d\n", size );
|
||||
DRM_DEBUG( "agp_offset: %ld\n", agp_offset );
|
||||
DRM_DEBUG( "alignment: %d\n", alignment );
|
||||
DRM_DEBUG( "page_order: %d\n", page_order );
|
||||
DRM_DEBUG( "total: %d\n", total );
|
||||
|
||||
if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
|
||||
if ( dev->queue_count ) return -EBUSY; /* Not while in use */
|
||||
|
||||
spin_lock( &dev->count_lock );
|
||||
if ( dev->buf_use ) {
|
||||
spin_unlock( &dev->count_lock );
|
||||
return -EBUSY;
|
||||
}
|
||||
atomic_inc( &dev->buf_alloc );
|
||||
spin_unlock( &dev->count_lock );
|
||||
|
||||
down( &dev->struct_sem );
|
||||
entry = &dma->bufs[order];
|
||||
if ( entry->buf_count ) {
|
||||
up( &dev->struct_sem );
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return -ENOMEM; /* May only call once for each order */
|
||||
}
|
||||
|
||||
entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
|
||||
DRM_MEM_BUFS );
|
||||
if ( !entry->buflist ) {
|
||||
up( &dev->struct_sem );
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( entry->buflist, 0, count * sizeof(*entry->buflist) );
|
||||
|
||||
entry->buf_size = size;
|
||||
entry->page_order = page_order;
|
||||
|
||||
offset = 0;
|
||||
|
||||
while ( entry->buf_count < count ) {
|
||||
buf = &entry->buflist[entry->buf_count];
|
||||
buf->idx = dma->buf_count + entry->buf_count;
|
||||
buf->total = alignment;
|
||||
buf->order = order;
|
||||
buf->used = 0;
|
||||
|
||||
buf->offset = (dma->byte_count + offset);
|
||||
buf->bus_address = agp_offset + offset;
|
||||
buf->address = (void *)(agp_offset + offset + dev->sg->handle);
|
||||
buf->next = NULL;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
init_waitqueue_head( &buf->dma_wait );
|
||||
buf->pid = 0;
|
||||
|
||||
buf->dev_priv_size = sizeof(DRIVER_BUF_PRIV_T);
|
||||
buf->dev_private = DRM(alloc)( sizeof(DRIVER_BUF_PRIV_T),
|
||||
DRM_MEM_BUFS );
|
||||
memset( buf->dev_private, 0, buf->dev_priv_size );
|
||||
|
||||
#if __HAVE_DMA_HISTOGRAM
|
||||
buf->time_queued = 0;
|
||||
buf->time_dispatched = 0;
|
||||
buf->time_completed = 0;
|
||||
buf->time_freed = 0;
|
||||
#endif
|
||||
DRM_DEBUG( "buffer %d @ %p\n",
|
||||
entry->buf_count, buf->address );
|
||||
|
||||
offset += alignment;
|
||||
entry->buf_count++;
|
||||
byte_count += PAGE_SIZE << page_order;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "byte_count: %d\n", byte_count );
|
||||
|
||||
dma->buflist = DRM(realloc)( dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
(dma->buf_count + entry->buf_count)
|
||||
* sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS );
|
||||
for ( i = 0 ; i < entry->buf_count ; i++ ) {
|
||||
dma->buflist[i + dma->buf_count] = &entry->buflist[i];
|
||||
}
|
||||
|
||||
dma->buf_count += entry->buf_count;
|
||||
dma->byte_count += byte_count;
|
||||
|
||||
DRM_DEBUG( "dma->buf_count : %d\n", dma->buf_count );
|
||||
DRM_DEBUG( "entry->buf_count : %d\n", entry->buf_count );
|
||||
|
||||
#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;
|
||||
request.size = size;
|
||||
|
||||
if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
|
||||
return -EFAULT;
|
||||
|
||||
dma->flags = _DRM_DMA_USE_SG;
|
||||
|
||||
atomic_dec( &dev->buf_alloc );
|
||||
return 0;
|
||||
}
|
||||
#endif /* __HAVE_SG */
|
||||
|
||||
int DRM(addbufs)( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
{
|
||||
|
|
@ -580,6 +751,11 @@ int DRM(addbufs)( struct inode *inode, struct file *filp,
|
|||
return DRM(addbufs_agp)( inode, filp, cmd, arg );
|
||||
else
|
||||
#endif
|
||||
#if __HAVE_SG
|
||||
if ( request.flags & _DRM_SG_BUFFER )
|
||||
return DRM(addbufs_sg)( inode, filp, cmd, arg );
|
||||
else
|
||||
#endif
|
||||
#if __HAVE_PCI_DMA
|
||||
return DRM(addbufs_pci)( inode, filp, cmd, arg );
|
||||
#else
|
||||
|
|
@ -761,7 +937,8 @@ int DRM(mapbufs)( struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
if ( request.count >= dma->buf_count ) {
|
||||
if ( __HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP) ) {
|
||||
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
||||
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
||||
drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
||||
|
||||
if ( !map ) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#if __HAVE_CTX_BITMAP
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Context bitmap support
|
||||
*/
|
||||
|
||||
|
|
@ -72,16 +72,16 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
|||
if(dev->context_sareas) {
|
||||
dev->context_sareas = DRM(realloc)(
|
||||
dev->context_sareas,
|
||||
(dev->max_context - 1) *
|
||||
(dev->max_context - 1) *
|
||||
sizeof(*dev->context_sareas),
|
||||
dev->max_context *
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
} else {
|
||||
/* max_context == 1 at this point */
|
||||
dev->context_sareas = DRM(alloc)(
|
||||
dev->max_context *
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
dev->context_sareas[bit] = NULL;
|
||||
|
|
@ -123,14 +123,14 @@ void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
|
|||
{
|
||||
down(&dev->struct_sem);
|
||||
if( dev->context_sareas ) DRM(free)( dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context,
|
||||
DRM_MEM_MAPS );
|
||||
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Per Context SAREA Support
|
||||
*/
|
||||
|
||||
|
|
@ -178,7 +178,6 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
r_list = NULL;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
if(r_list->map &&
|
||||
|
|
@ -203,7 +202,7 @@ int DRM(setsareactx)(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* The actual DRM context handling routines
|
||||
*/
|
||||
|
||||
|
|
@ -390,7 +389,7 @@ int DRM(rmctx)( struct inode *inode, struct file *filp,
|
|||
|
||||
#else /* __HAVE_CTX_BITMAP */
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Old-style context support
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@
|
|||
#ifndef __HAVE_DMA_RECLAIM
|
||||
#define __HAVE_DMA_RECLAIM 0
|
||||
#endif
|
||||
#ifndef __HAVE_SHARED_IRQ
|
||||
#define __HAVE_SHARED_IRQ 0
|
||||
#endif
|
||||
|
||||
#if __HAVE_SHARED_IRQ
|
||||
#define DRM_IRQ_TYPE SA_SHIRQ
|
||||
#else
|
||||
#define DRM_IRQ_TYPE 0
|
||||
#endif
|
||||
|
||||
#if __HAVE_DMA
|
||||
|
||||
|
|
@ -534,7 +543,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
|||
|
||||
/* Install handler */
|
||||
ret = request_irq( dev->irq, DRM(dma_service),
|
||||
0, dev->devname, dev );
|
||||
DRM_IRQ_TYPE, dev->devname, dev );
|
||||
if ( ret < 0 ) {
|
||||
down( &dev->struct_sem );
|
||||
dev->irq = 0;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@
|
|||
#ifndef __HAVE_COUNTERS
|
||||
#define __HAVE_COUNTERS 0
|
||||
#endif
|
||||
#ifndef __HAVE_SG
|
||||
#define __HAVE_SG 0
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_PREINIT
|
||||
#define DRIVER_PREINIT()
|
||||
|
|
@ -135,8 +138,10 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { DRM(addmap), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { DRM(rmmap), 1, 0 },
|
||||
|
||||
#if __HAVE_CTX_BITMAP
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
|
||||
#endif
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { DRM(addctx), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { DRM(rmctx), 1, 1 },
|
||||
|
|
@ -178,6 +183,11 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { DRM(agp_unbind), 1, 1 },
|
||||
#endif
|
||||
|
||||
#if __HAVE_SG
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { DRM(sg_alloc), 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { DRM(sg_free), 1, 1 },
|
||||
#endif
|
||||
|
||||
DRIVER_IOCTLS
|
||||
};
|
||||
|
||||
|
|
@ -415,6 +425,17 @@ static int DRM(takedown)( drm_device_t *dev )
|
|||
* handled in the AGP/GART driver.
|
||||
*/
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
/* Handle it, but do nothing, if HAVE_SG
|
||||
* isn't defined.
|
||||
*/
|
||||
#if __HAVE_SG
|
||||
if(dev->sg) {
|
||||
DRM(sg_cleanup)(dev->sg);
|
||||
dev->sg = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,21 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
|
|||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Default the hose
|
||||
*/
|
||||
if (!dev->hose) {
|
||||
struct pci_dev *pci_dev;
|
||||
pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
|
||||
if (pci_dev) dev->hose = pci_dev->sysdata;
|
||||
if (!dev->hose) {
|
||||
struct pci_bus *b = pci_bus_b(pci_root_buses.next);
|
||||
if (b) dev->hose = b->sysdata;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@
|
|||
#define __NO_VERSION__
|
||||
#include "drmP.h"
|
||||
|
||||
#if 0
|
||||
int DRM(flags) = DRM_FLAG_DEBUG;
|
||||
#else
|
||||
int DRM(flags) = 0;
|
||||
#endif
|
||||
|
||||
/* drm_parse_option parses a single option. See description for
|
||||
* drm_parse_options for details.
|
||||
|
|
|
|||
|
|
@ -95,6 +95,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
DRM_MEM_DRIVER);
|
||||
sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
|
||||
|
||||
#ifdef __alpha__
|
||||
do {
|
||||
struct pci_dev *pci_dev;
|
||||
int b, d, f;
|
||||
char *p;
|
||||
|
||||
for(p = dev->unique; p && *p && *p != ':'; p++);
|
||||
if (!p || !*p) break;
|
||||
b = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p != ':') break;
|
||||
d = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p != ':') break;
|
||||
f = (int)simple_strtoul(p+1, &p, 10);
|
||||
if (*p) break;
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev)
|
||||
dev->hose = pci_dev->sysdata;
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ static drm_mem_stats_t DRM(mem_stats)[] = {
|
|||
[DRM_MEM_MAPPINGS] = { "mappings" },
|
||||
[DRM_MEM_BUFLISTS] = { "buflists" },
|
||||
[DRM_MEM_AGPLISTS] = { "agplist" },
|
||||
[DRM_MEM_SGLISTS] = { "sglist" },
|
||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ struct vm_operations_struct drm_vm_dma_ops = {
|
|||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
struct vm_operations_struct drm_vm_sg_ops = {
|
||||
nopage: DRM(vm_sg_nopage),
|
||||
open: DRM(vm_open),
|
||||
close: DRM(vm_close),
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
|
|
@ -93,7 +99,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
|
|||
offset = address - vma->vm_start;
|
||||
i = (unsigned long)map->handle + offset;
|
||||
/* We have to walk page tables here because we need large SAREA's, and
|
||||
* they need to be virtually contigious in kernel space.
|
||||
* they need to be virtually contiguous in kernel space.
|
||||
*/
|
||||
pgd = pgd_offset_k( i );
|
||||
if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
|
||||
|
|
@ -187,6 +193,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
|
|||
vfree(map->handle);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
case _DRM_SCATTER_GATHER:
|
||||
break;
|
||||
}
|
||||
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
|
|
@ -230,6 +237,48 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#else
|
||||
/* Return type changed in 2.3.23 */
|
||||
struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int write_access)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
|
||||
#else
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_pte;
|
||||
#endif
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long offset;
|
||||
unsigned long map_offset;
|
||||
unsigned long page_offset;
|
||||
struct page *page;
|
||||
|
||||
if (!entry) return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
|
||||
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
map_offset = map->offset - dev->sg->handle;
|
||||
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
|
||||
page = entry->pagelist[page_offset];
|
||||
atomic_inc(&page->count); /* Dec. by kernel */
|
||||
|
||||
#if LINUX_VERSION_CODE < 0x020317
|
||||
return (unsigned long)virt_to_phys(page->virtual);
|
||||
#else
|
||||
return page;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRM(vm_open)(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
|
|
@ -322,11 +371,14 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
unsigned long offset = 0;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
||||
if ( !priv->authenticated ) return -EACCES;
|
||||
|
||||
if (!VM_OFFSET(vma)) return DRM(mmap_dma)(filp, vma);
|
||||
|
||||
/* A sequential search of a linked list is
|
||||
|
|
@ -374,19 +426,26 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
}
|
||||
#elif defined(__ia64__)
|
||||
if (map->type != _DRM_AGP)
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
vma->vm_page_prot =
|
||||
pgprot_writecombine(vma->vm_page_prot);
|
||||
#elif defined(__powerpc__)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
|
||||
#endif
|
||||
vma->vm_flags |= VM_IO; /* not in core dump */
|
||||
}
|
||||
#ifdef __alpha__
|
||||
offset = dev->hose->dense_mem_base -
|
||||
dev->hose->mem_space->start;
|
||||
#endif
|
||||
if (remap_page_range(vma->vm_start,
|
||||
VM_OFFSET(vma),
|
||||
VM_OFFSET(vma) + offset,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
return -EAGAIN;
|
||||
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
|
||||
" offset = 0x%lx\n",
|
||||
map->type,
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
|
||||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
|
|
@ -400,6 +459,15 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
vma->vm_ops = &drm_vm_sg_ops;
|
||||
#if LINUX_VERSION_CODE >= 0x020300
|
||||
vma->vm_private_data = (void *)map;
|
||||
#else
|
||||
vma->vm_pte = (unsigned long)map;
|
||||
#endif
|
||||
vma->vm_flags |= VM_LOCKED;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL; /* This should never happen. */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "gamma"
|
||||
#define DRIVER_DESC "3DLabs gamma"
|
||||
#define DRIVER_DATE "20010216"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
|
||||
#define __HAVE_DMA_IRQ 0
|
||||
#define __HAVE_DMA_IRQ_BH 0
|
||||
#define __HAVE_SHARED_IRQ 1
|
||||
|
||||
/* Buffer customization:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -183,7 +183,11 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
|
||||
|
||||
if(VM_DONTCOPY != 0) {
|
||||
down(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
old_fops = filp->f_op;
|
||||
filp->f_op = &i810_buffer_fops;
|
||||
dev_priv->mmap_buffer = buf;
|
||||
|
|
@ -199,7 +203,11 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
|
|||
retcode = (signed int)buf_priv->virtual;
|
||||
buf_priv->virtual = 0;
|
||||
}
|
||||
up(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
} else {
|
||||
buf_priv->virtual = buf_priv->kernel_virtual;
|
||||
buf_priv->currently_mapped = I810_BUF_MAPPED;
|
||||
|
|
@ -215,7 +223,11 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
if(VM_DONTCOPY != 0) {
|
||||
if(buf_priv->currently_mapped != I810_BUF_MAPPED)
|
||||
return -EINVAL;
|
||||
down(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
down( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
down_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < 0x020399
|
||||
retcode = do_munmap((unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
|
|
@ -224,7 +236,11 @@ static int i810_unmap_buffer(drm_buf_t *buf)
|
|||
(unsigned long)buf_priv->virtual,
|
||||
(size_t) buf->total);
|
||||
#endif
|
||||
up(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE <= 0x020402
|
||||
up( ¤t->mm->mmap_sem );
|
||||
#else
|
||||
up_write( ¤t->mm->mmap_sem );
|
||||
#endif
|
||||
}
|
||||
buf_priv->currently_mapped = I810_BUF_UNMAPPED;
|
||||
buf_priv->virtual = 0;
|
||||
|
|
@ -339,8 +355,8 @@ static int i810_wait_ring(drm_device_t *dev, int n)
|
|||
if (ring->head != last_head)
|
||||
end = jiffies + (HZ*3);
|
||||
|
||||
if (iters==1)
|
||||
printk("wait for space in ring\n");
|
||||
/* if (iters==1) */
|
||||
/* printk("wait for space in ring\n"); */
|
||||
|
||||
iters++;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
|
|
@ -576,8 +592,8 @@ static void i810EmitTexVerified( drm_device_t *dev,
|
|||
if (j & 1)
|
||||
OUT_RING( 0 );
|
||||
|
||||
for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++)
|
||||
printk("texreg %d: %x\n", i, code[i]);
|
||||
/* for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++) */
|
||||
/* printk("texreg %d: %x\n", i, code[i]); */
|
||||
|
||||
ADVANCE_LP_RING();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#define DRIVER_NAME "i810"
|
||||
#define DRIVER_DESC "Intel i810"
|
||||
#define DRIVER_DATE "20010215"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 1
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#define MGA_FREELIST_DEBUG 0
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Engine control
|
||||
*/
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ int mga_do_engine_reset( drm_mga_private_t *dev_priv )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Primary DMA stream
|
||||
*/
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Freelist management
|
||||
*/
|
||||
|
||||
|
|
@ -444,7 +444,7 @@ int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* DMA initialization, cleanup
|
||||
*/
|
||||
|
||||
|
|
@ -619,7 +619,7 @@ int mga_dma_init( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Primary DMA stream management
|
||||
*/
|
||||
|
||||
|
|
@ -675,7 +675,7 @@ int mga_dma_reset( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* DMA buffer management
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "mga"
|
||||
#define DRIVER_DESC "Matrox G200/G400"
|
||||
#define DRIVER_DATE "20010321"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 3
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ extern int mga_warp_init( drm_device_t *dev );
|
|||
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Helper macross...
|
||||
*/
|
||||
|
||||
|
|
@ -218,7 +218,7 @@ do { \
|
|||
} while (0)
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Primary DMA command stream
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "drm.h"
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* DMA hardware state programming functions
|
||||
*/
|
||||
|
||||
|
|
@ -396,7 +396,7 @@ static void mga_g400_emit_state( drm_mga_private_t *dev_priv )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* SAREA state verification
|
||||
*/
|
||||
|
||||
|
|
@ -500,7 +500,7 @@ static int mga_verify_blit( drm_mga_private_t *dev_priv,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -870,7 +870,7 @@ static void mga_dma_dispatch_blit( drm_device_t *dev,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@
|
|||
/* General customization:
|
||||
*/
|
||||
#define __HAVE_AGP 1
|
||||
#define __MUST_HAVE_AGP 1
|
||||
#define __MUST_HAVE_AGP 0
|
||||
#define __HAVE_MTRR 1
|
||||
#define __HAVE_CTX_BITMAP 1
|
||||
#define __HAVE_SG 1
|
||||
#define __HAVE_PCI_DMA 1
|
||||
|
||||
/* Driver customization:
|
||||
*/
|
||||
|
|
|
|||
111
linux/r128_cce.c
111
linux/r128_cce.c
|
|
@ -112,7 +112,7 @@ static void r128_status( drm_r128_private_t *dev_priv )
|
|||
#endif
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Engine, FIFO control
|
||||
*/
|
||||
|
||||
|
|
@ -131,7 +131,9 @@ static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
#if R128_FIFO_DEBUG
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
#endif
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +147,9 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
#if R128_FIFO_DEBUG
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
#endif
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -164,12 +168,14 @@ int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
|
|||
udelay( 1 );
|
||||
}
|
||||
|
||||
#if R128_FIFO_DEBUG
|
||||
DRM_ERROR( "%s failed!\n", __FUNCTION__ );
|
||||
#endif
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CCE control, initialization
|
||||
*/
|
||||
|
||||
|
|
@ -178,6 +184,8 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
|
|||
{
|
||||
int i;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
r128_do_wait_for_idle( dev_priv );
|
||||
|
||||
R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
|
||||
|
|
@ -208,7 +216,7 @@ int r128_do_cce_idle( drm_r128_private_t *dev_priv )
|
|||
int i;
|
||||
|
||||
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
|
||||
if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
|
||||
if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) {
|
||||
int pm4stat = R128_READ( R128_PM4_STAT );
|
||||
if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
|
||||
dev_priv->cce_fifo_size ) &&
|
||||
|
|
@ -249,7 +257,7 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
|
|||
{
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
|
||||
*dev_priv->ring.head = 0;
|
||||
SET_RING_HEAD( &dev_priv->ring, 0 );
|
||||
dev_priv->ring.tail = 0;
|
||||
}
|
||||
|
||||
|
|
@ -312,19 +320,43 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
|
|||
u32 ring_start;
|
||||
u32 tmp;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
/* The manual (p. 2) says this address is in "VM space". This
|
||||
* means it's an offset from the start of AGP space.
|
||||
*/
|
||||
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
|
||||
#if __REALLY_HAVE_AGP
|
||||
if ( !dev_priv->is_pci )
|
||||
ring_start = dev_priv->cce_ring->offset - dev->agp->base;
|
||||
else
|
||||
#endif
|
||||
ring_start = dev_priv->cce_ring->offset - dev->sg->handle;
|
||||
|
||||
R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
|
||||
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
|
||||
|
||||
/* DL_RPTR_ADDR is a physical address in AGP space. */
|
||||
*dev_priv->ring.head = 0;
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
dev_priv->ring_rptr->offset );
|
||||
SET_RING_HEAD( &dev_priv->ring, 0 );
|
||||
|
||||
if ( !dev_priv->is_pci ) {
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
dev_priv->ring_rptr->offset );
|
||||
} else {
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long tmp_ofs, page_ofs;
|
||||
|
||||
tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
|
||||
page_ofs = tmp_ofs >> PAGE_SHIFT;
|
||||
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual));
|
||||
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual),
|
||||
entry->handle + tmp_ofs );
|
||||
}
|
||||
|
||||
/* Set watermark control */
|
||||
R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
|
||||
|
|
@ -346,6 +378,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
drm_r128_private_t *dev_priv;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
|
||||
if ( dev_priv == NULL )
|
||||
return -ENOMEM;
|
||||
|
|
@ -355,11 +389,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
|
||||
dev_priv->is_pci = init->is_pci;
|
||||
|
||||
/* GH: We don't support PCI cards until PCI GART is implemented.
|
||||
* Fail here so we can remove all checks for PCI cards around
|
||||
* the CCE ring code.
|
||||
*/
|
||||
if ( dev_priv->is_pci ) {
|
||||
if ( dev_priv->is_pci && !dev->sg ) {
|
||||
DRM_DEBUG( "PCI GART memory not allocated!\n" );
|
||||
DRM_ERROR( "PCI GART memory not allocated!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -368,6 +400,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
dev_priv->usec_timeout = init->usec_timeout;
|
||||
if ( dev_priv->usec_timeout < 1 ||
|
||||
dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
|
||||
DRM_DEBUG( "TIMEOUT problem!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -387,6 +420,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
|
||||
( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
|
||||
( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
|
||||
DRM_DEBUG( "Bad cce_mode!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -476,9 +510,24 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
DRM_IOREMAP( dev_priv->cce_ring );
|
||||
DRM_IOREMAP( dev_priv->ring_rptr );
|
||||
DRM_IOREMAP( dev_priv->buffers );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DRM_IOREMAP( dev_priv->cce_ring );
|
||||
DRM_IOREMAP( dev_priv->ring_rptr );
|
||||
DRM_IOREMAP( dev_priv->buffers );
|
||||
} else {
|
||||
dev_priv->cce_ring->handle =
|
||||
(void *)dev_priv->cce_ring->offset;
|
||||
dev_priv->ring_rptr->handle =
|
||||
(void *)dev_priv->ring_rptr->offset;
|
||||
dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
|
||||
}
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
if ( !dev_priv->is_pci )
|
||||
dev_priv->cce_buffers_offset = dev->agp->base;
|
||||
else
|
||||
#endif
|
||||
dev_priv->cce_buffers_offset = dev->sg->handle;
|
||||
|
||||
dev_priv->ring.head = ((__volatile__ u32 *)
|
||||
dev_priv->ring_rptr->handle);
|
||||
|
|
@ -501,6 +550,20 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
R128_WRITE( R128_LAST_DISPATCH_REG,
|
||||
dev_priv->sarea_priv->last_dispatch );
|
||||
|
||||
if ( dev_priv->is_pci ) {
|
||||
dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
|
||||
if ( !dev_priv->phys_pci_gart ) {
|
||||
DRM_DEBUG( "failed to init PCI GART!\n" );
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv),
|
||||
DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
R128_WRITE( R128_PCI_GART_PAGE,
|
||||
virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
|
||||
}
|
||||
|
||||
r128_cce_init_ring_buffer( dev );
|
||||
r128_cce_load_microcode( dev_priv );
|
||||
r128_do_engine_reset( dev );
|
||||
|
|
@ -513,9 +576,11 @@ int r128_do_cleanup_cce( drm_device_t *dev )
|
|||
if ( dev->dev_private ) {
|
||||
drm_r128_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_IOREMAPFREE( dev_priv->cce_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DRM_IOREMAPFREE( dev_priv->cce_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
}
|
||||
|
||||
DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
|
||||
DRM_MEM_DRIVER );
|
||||
|
|
@ -532,6 +597,8 @@ int r128_cce_init( struct inode *inode, struct file *filp,
|
|||
drm_device_t *dev = priv->dev;
|
||||
drm_r128_init_t init;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -665,7 +732,7 @@ int r128_engine_reset( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Fullscreen mode
|
||||
*/
|
||||
|
||||
|
|
@ -724,7 +791,7 @@ int r128_fullscreen( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Freelist management
|
||||
*/
|
||||
#define R128_BUFFER_USED 0xffffffff
|
||||
|
|
@ -829,7 +896,7 @@ void r128_freelist_reset( drm_device_t *dev )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CCE command submission
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,11 @@ typedef struct drm_r128_init {
|
|||
R128_INIT_CCE = 0x01,
|
||||
R128_CLEANUP_CCE = 0x02
|
||||
} func;
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
int sarea_priv_offset;
|
||||
#else
|
||||
unsigned long sarea_priv_offset;
|
||||
#endif
|
||||
int is_pci;
|
||||
int cce_mode;
|
||||
int cce_secure;
|
||||
|
|
@ -189,12 +193,21 @@ typedef struct drm_r128_init {
|
|||
unsigned int depth_offset, depth_pitch;
|
||||
unsigned int span_offset;
|
||||
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
unsigned int fb_offset;
|
||||
unsigned int mmio_offset;
|
||||
unsigned int ring_offset;
|
||||
unsigned int ring_rptr_offset;
|
||||
unsigned int buffers_offset;
|
||||
unsigned int agp_textures_offset;
|
||||
#else
|
||||
unsigned long fb_offset;
|
||||
unsigned long mmio_offset;
|
||||
unsigned long ring_offset;
|
||||
unsigned long ring_rptr_offset;
|
||||
unsigned long buffers_offset;
|
||||
unsigned long agp_textures_offset;
|
||||
#endif
|
||||
} drm_r128_init_t;
|
||||
|
||||
typedef struct drm_r128_cce_stop {
|
||||
|
|
@ -211,8 +224,15 @@ typedef struct drm_r128_fullscreen {
|
|||
|
||||
typedef struct drm_r128_clear {
|
||||
unsigned int flags;
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
int x, y, w, h;
|
||||
#endif
|
||||
unsigned int color;
|
||||
unsigned int colormask;
|
||||
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
|
||||
unsigned int color_mask;
|
||||
unsigned int depth_mask;
|
||||
#endif
|
||||
unsigned int depth;
|
||||
} drm_r128_clear_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,12 +33,13 @@
|
|||
#include "r128.h"
|
||||
#include "drmP.h"
|
||||
#include "r128_drv.h"
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
|
||||
|
||||
#define DRIVER_NAME "r128"
|
||||
#define DRIVER_DESC "ATI Rage 128"
|
||||
#define DRIVER_DATE "20010308"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 1
|
||||
|
|
@ -88,3 +89,4 @@
|
|||
#include "drm_proc.h"
|
||||
#include "drm_vm.h"
|
||||
#include "drm_stub.h"
|
||||
#include "drm_scatter.h"
|
||||
|
|
|
|||
|
|
@ -28,11 +28,15 @@
|
|||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* Kevin E. Martin <martin@valinux.com>
|
||||
* Gareth Hughes <gareth@valinux.com>
|
||||
* Michel Dänzer <daenzerm@student.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef __R128_DRV_H__
|
||||
#define __R128_DRV_H__
|
||||
|
||||
#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head )
|
||||
#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val )
|
||||
|
||||
typedef struct drm_r128_freelist {
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
|
|
@ -67,6 +71,8 @@ typedef struct drm_r128_private {
|
|||
|
||||
int usec_timeout;
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
unsigned long cce_buffers_offset;
|
||||
|
||||
atomic_t idle_count;
|
||||
|
||||
|
|
@ -134,7 +140,7 @@ extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
|
|||
static inline void
|
||||
r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring )
|
||||
{
|
||||
ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32);
|
||||
ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32);
|
||||
if ( ring->space <= 0 )
|
||||
ring->space += ring->size;
|
||||
}
|
||||
|
|
@ -248,6 +254,7 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
|
|||
# define R128_PC_FLUSH_ALL 0x00ff
|
||||
# define R128_PC_BUSY (1 << 31)
|
||||
|
||||
#define R128_PCI_GART_PAGE 0x017c
|
||||
#define R128_PRIM_TEX_CNTL_C 0x1cb0
|
||||
|
||||
#define R128_SCALE_3D_CNTL 0x1a00
|
||||
|
|
@ -365,7 +372,7 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
|
|||
|
||||
#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
|
||||
#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
|
||||
#define R128_MAX_VB_AGE 0xffffffff
|
||||
#define R128_MAX_VB_AGE 0x7fffffff
|
||||
#define R128_MAX_VB_VERTS (0xffff)
|
||||
|
||||
#define R128_RING_HIGH_MARK 128
|
||||
|
|
@ -373,22 +380,53 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp,
|
|||
#define R128_PERFORMANCE_BOXES 0
|
||||
|
||||
|
||||
#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
|
||||
#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
||||
#define R128_ADDR(reg) (R128_BASE( reg ) + reg)
|
||||
|
||||
#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg )
|
||||
#define R128_READ(reg) R128_DEREF( reg )
|
||||
#define R128_WRITE(reg,val) do { R128_DEREF( reg ) = val; } while (0)
|
||||
#ifdef __alpha__
|
||||
#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg)))
|
||||
static inline u32 _R128_READ(u32 *addr)
|
||||
{
|
||||
mb();
|
||||
return *(volatile u32 *)addr;
|
||||
}
|
||||
#define R128_WRITE(reg,val) \
|
||||
do { \
|
||||
wmb(); \
|
||||
R128_DEREF(reg) = val; \
|
||||
} while (0)
|
||||
#else
|
||||
#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) )
|
||||
#define R128_WRITE(reg,val) \
|
||||
do { \
|
||||
R128_DEREF( reg ) = cpu_to_le32( val ); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg )
|
||||
#ifdef __alpha__
|
||||
#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg))
|
||||
static inline u8 _R128_READ8(u8 *addr)
|
||||
{
|
||||
mb();
|
||||
return *(volatile u8 *)addr;
|
||||
}
|
||||
#define R128_WRITE8(reg,val) \
|
||||
do { \
|
||||
wmb(); \
|
||||
R128_DEREF8(reg) = val; \
|
||||
} while (0)
|
||||
#else
|
||||
#define R128_READ8(reg) R128_DEREF8( reg )
|
||||
#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#define R128_WRITE_PLL(addr,val) \
|
||||
do { \
|
||||
R128_WRITE8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \
|
||||
R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
|
||||
#define R128_WRITE_PLL(addr,val) \
|
||||
do { \
|
||||
R128_WRITE8(R128_CLOCK_CNTL_INDEX, \
|
||||
((addr) & 0x1f) | R128_PLL_WR_EN); \
|
||||
R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
|
||||
} while (0)
|
||||
|
||||
extern int R128_READ_PLL(drm_device_t *dev, int addr);
|
||||
|
|
@ -403,7 +441,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
|
|||
(pkt) | ((n) << 16))
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Misc helper macros
|
||||
*/
|
||||
|
||||
|
|
@ -450,7 +488,7 @@ do { \
|
|||
} while (0)
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Ring control
|
||||
*/
|
||||
|
||||
|
|
@ -485,7 +523,7 @@ do { \
|
|||
|
||||
#define ADVANCE_RING() do { \
|
||||
if ( R128_VERBOSE ) { \
|
||||
DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
|
||||
DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
|
||||
write, dev_priv->ring.tail ); \
|
||||
} \
|
||||
if ( R128_BROKEN_CCE && write < 32 ) { \
|
||||
|
|
@ -503,7 +541,7 @@ do { \
|
|||
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
|
||||
(unsigned int)(x), write ); \
|
||||
} \
|
||||
ring[write++] = (x); \
|
||||
ring[write++] = cpu_to_le32( x ); \
|
||||
write &= tail_mask; \
|
||||
} while (0)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/delay.h>
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CCE hardware state programming functions
|
||||
*/
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ static inline void r128_emit_state( drm_r128_private_t *dev_priv )
|
|||
|
||||
|
||||
#if R128_PERFORMANCE_BOXES
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Performance monitoring functions
|
||||
*/
|
||||
|
||||
|
|
@ -340,7 +340,7 @@ static void r128_cce_performance_boxes( drm_r128_private_t *dev_priv )
|
|||
#endif
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CCE command dispatch functions
|
||||
*/
|
||||
|
||||
|
|
@ -660,7 +660,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
|
|||
u32 *data = (u32 *)
|
||||
((char *)dev_priv->buffers->handle
|
||||
+ buf->offset + start);
|
||||
data[dwords++] = R128_CCE_PACKET2;
|
||||
data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
|
||||
}
|
||||
|
||||
buf_priv->dispatched = 1;
|
||||
|
|
@ -704,7 +704,7 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
|
|||
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
|
||||
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
int format = sarea_priv->vc_format;
|
||||
int offset = dev_priv->buffers->offset - dev->agp->base;
|
||||
int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
|
||||
int prim = buf_priv->prim;
|
||||
u32 *data;
|
||||
int dwords;
|
||||
|
|
@ -727,16 +727,21 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
|
|||
data = (u32 *)((char *)dev_priv->buffers->handle
|
||||
+ buf->offset + start);
|
||||
|
||||
data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
|
||||
data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
|
||||
dwords-2 ) );
|
||||
|
||||
data[1] = offset;
|
||||
data[2] = R128_MAX_VB_VERTS;
|
||||
data[3] = format;
|
||||
data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
|
||||
(count << 16));
|
||||
data[1] = cpu_to_le32( offset );
|
||||
data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
|
||||
data[3] = cpu_to_le32( format );
|
||||
data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
|
||||
(count << 16)) );
|
||||
|
||||
if ( count & 0x1 ) {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
data[dwords-1] &= 0x0000ffff;
|
||||
#else
|
||||
data[dwords-1] &= 0xffff0000;
|
||||
#endif
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
@ -842,23 +847,23 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
|
|||
|
||||
data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
|
||||
|
||||
data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
|
||||
data[1] = (R128_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R128_GMC_BRUSH_NONE |
|
||||
(blit->format << 8) |
|
||||
R128_GMC_SRC_DATATYPE_COLOR |
|
||||
R128_ROP3_S |
|
||||
R128_DP_SRC_SOURCE_HOST_DATA |
|
||||
R128_GMC_CLR_CMP_CNTL_DIS |
|
||||
R128_GMC_AUX_CLIP_DIS |
|
||||
R128_GMC_WR_MSK_DIS);
|
||||
data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
|
||||
data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
|
||||
R128_GMC_BRUSH_NONE |
|
||||
(blit->format << 8) |
|
||||
R128_GMC_SRC_DATATYPE_COLOR |
|
||||
R128_ROP3_S |
|
||||
R128_DP_SRC_SOURCE_HOST_DATA |
|
||||
R128_GMC_CLR_CMP_CNTL_DIS |
|
||||
R128_GMC_AUX_CLIP_DIS |
|
||||
R128_GMC_WR_MSK_DIS) );
|
||||
|
||||
data[2] = (blit->pitch << 21) | (blit->offset >> 5);
|
||||
data[3] = 0xffffffff;
|
||||
data[4] = 0xffffffff;
|
||||
data[5] = (blit->y << 16) | blit->x;
|
||||
data[6] = (blit->height << 16) | blit->width;
|
||||
data[7] = dwords;
|
||||
data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
|
||||
data[3] = cpu_to_le32( 0xffffffff );
|
||||
data[4] = cpu_to_le32( 0xffffffff );
|
||||
data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
|
||||
data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
|
||||
data[7] = cpu_to_le32( dwords );
|
||||
|
||||
buf->used = (dwords + 8) * sizeof(u32);
|
||||
|
||||
|
|
@ -879,7 +884,7 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Tiled depth buffer management
|
||||
*
|
||||
* FIXME: These should all set the destination write mask for when we
|
||||
|
|
@ -1203,7 +1208,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Polygon stipple
|
||||
*/
|
||||
|
||||
|
|
@ -1225,7 +1230,7 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* IOCTL functions
|
||||
*/
|
||||
|
||||
|
|
@ -1299,8 +1304,8 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
|
|||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( !dev_priv || dev_priv->is_pci ) {
|
||||
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -1362,8 +1367,8 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
|
|||
|
||||
LOCK_TEST_WITH_RETURN( dev );
|
||||
|
||||
if ( !dev_priv || dev_priv->is_pci ) {
|
||||
DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@
|
|||
/* General customization:
|
||||
*/
|
||||
#define __HAVE_AGP 1
|
||||
#define __MUST_HAVE_AGP 1
|
||||
#define __MUST_HAVE_AGP 0
|
||||
#define __HAVE_MTRR 1
|
||||
#define __HAVE_CTX_BITMAP 1
|
||||
#define __HAVE_SG 1
|
||||
#define __HAVE_PCI_DMA 1
|
||||
|
||||
/* Driver customization:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@
|
|||
|
||||
#define RADEON_FIFO_DEBUG 0
|
||||
|
||||
#if defined(__alpha__)
|
||||
# define PCIGART_ENABLED
|
||||
#else
|
||||
# undef PCIGART_ENABLED
|
||||
#endif
|
||||
|
||||
|
||||
/* CP microcode (from ATI) */
|
||||
static u32 radeon_cp_microcode[][2] = {
|
||||
|
|
@ -318,11 +324,21 @@ static void radeon_status( drm_radeon_private_t *dev_priv )
|
|||
(unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
|
||||
printk( "CP_RB_WTPR = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
|
||||
printk( "AIC_CNTL = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
|
||||
printk( "AIC_STAT = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
|
||||
printk( "AIC_PT_BASE = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
|
||||
printk( "TLB_ADDR = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
|
||||
printk( "TLB_DATA = 0x%08x\n",
|
||||
(unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Engine, FIFO control
|
||||
*/
|
||||
|
||||
|
|
@ -393,7 +409,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CP control, initialization
|
||||
*/
|
||||
|
||||
|
|
@ -401,6 +417,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
|
|||
static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
radeon_do_wait_for_idle( dev_priv );
|
||||
|
||||
|
|
@ -419,6 +436,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
|
|||
*/
|
||||
static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
#if 0
|
||||
u32 tmp;
|
||||
|
||||
|
|
@ -432,6 +450,7 @@ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
|
|||
int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
BEGIN_RING( 6 );
|
||||
|
||||
|
|
@ -449,6 +468,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
|
|||
static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
radeon_do_wait_for_idle( dev_priv );
|
||||
|
||||
|
|
@ -472,6 +492,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
|
|||
static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
u32 cur_read_ptr;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
|
||||
RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
|
||||
|
|
@ -485,6 +506,8 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
|
|||
*/
|
||||
static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
|
||||
{
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
|
||||
|
||||
dev_priv->cp_running = 0;
|
||||
|
|
@ -503,8 +526,13 @@ static int radeon_do_engine_reset( drm_device_t *dev )
|
|||
clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
|
||||
mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
|
||||
|
||||
/* FIXME: remove magic number here and in radeon ddx driver!!! */
|
||||
RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl | 0x003f00000 );
|
||||
RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
|
||||
RADEON_FORCEON_MCLKA |
|
||||
RADEON_FORCEON_MCLKB |
|
||||
RADEON_FORCEON_YCLKA |
|
||||
RADEON_FORCEON_YCLKB |
|
||||
RADEON_FORCEON_MC |
|
||||
RADEON_FORCEON_AIC ) );
|
||||
|
||||
rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
|
||||
|
||||
|
|
@ -546,18 +574,29 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
|
|||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
u32 ring_start, cur_read_ptr;
|
||||
u32 tmp;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
/* Initialize the memory controller */
|
||||
RADEON_WRITE( RADEON_MC_FB_LOCATION,
|
||||
(dev_priv->agp_vm_start - 1) & 0xffff0000 );
|
||||
RADEON_WRITE( RADEON_MC_AGP_LOCATION,
|
||||
(((dev_priv->agp_vm_start - 1 +
|
||||
dev_priv->agp_size) & 0xffff0000) |
|
||||
(dev_priv->agp_vm_start >> 16)) );
|
||||
|
||||
ring_start = (dev_priv->cp_ring->offset
|
||||
- dev->agp->base
|
||||
+ dev_priv->agp_vm_start);
|
||||
if ( !dev_priv->is_pci ) {
|
||||
RADEON_WRITE( RADEON_MC_AGP_LOCATION,
|
||||
(((dev_priv->agp_vm_start - 1 +
|
||||
dev_priv->agp_size) & 0xffff0000) |
|
||||
(dev_priv->agp_vm_start >> 16)) );
|
||||
}
|
||||
|
||||
#if __REALLY_HAVE_AGP
|
||||
if ( !dev_priv->is_pci )
|
||||
ring_start = (dev_priv->cp_ring->offset
|
||||
- dev->agp->base
|
||||
+ dev_priv->agp_vm_start);
|
||||
else
|
||||
#endif
|
||||
ring_start = (dev_priv->cp_ring->offset
|
||||
- dev->sg->handle
|
||||
+ dev_priv->agp_vm_start);
|
||||
|
||||
RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
|
||||
|
||||
|
|
@ -570,17 +609,29 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
|
|||
*dev_priv->ring.head = cur_read_ptr;
|
||||
dev_priv->ring.tail = cur_read_ptr;
|
||||
|
||||
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
|
||||
dev_priv->ring_rptr->offset );
|
||||
} else {
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long tmp_ofs, page_ofs;
|
||||
|
||||
tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
|
||||
page_ofs = tmp_ofs >> PAGE_SHIFT;
|
||||
|
||||
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual));
|
||||
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual),
|
||||
entry->handle + tmp_ofs );
|
||||
}
|
||||
|
||||
/* Set ring buffer size */
|
||||
RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
|
||||
|
||||
radeon_do_wait_for_idle( dev_priv );
|
||||
|
||||
/* Turn off PCI GART */
|
||||
tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN;
|
||||
RADEON_WRITE( RADEON_AIC_CNTL, tmp );
|
||||
|
||||
/* Turn on bus mastering */
|
||||
tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
|
||||
RADEON_WRITE( RADEON_BUS_CNTL, tmp );
|
||||
|
|
@ -596,8 +647,10 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
|
|||
static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv;
|
||||
drm_radeon_depth_clear_t *depth_clear;
|
||||
struct list_head *list;
|
||||
u32 tmp;
|
||||
drm_radeon_depth_clear_t *depth_clear;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
|
||||
if ( dev_priv == NULL )
|
||||
|
|
@ -608,11 +661,19 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
|
||||
dev_priv->is_pci = init->is_pci;
|
||||
|
||||
/* We don't support PCI cards until PCI GART is implemented.
|
||||
* Fail here so we can remove all checks for PCI cards around
|
||||
* the CP ring code.
|
||||
#if !defined(PCIGART_ENABLED)
|
||||
/* PCI support is not 100% working, so we disable it here.
|
||||
*/
|
||||
if ( dev_priv->is_pci ) {
|
||||
DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( dev_priv->is_pci && !dev->sg ) {
|
||||
DRM_ERROR( "PCI GART memory not allocated!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -621,6 +682,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
dev_priv->usec_timeout = init->usec_timeout;
|
||||
if ( dev_priv->usec_timeout < 1 ||
|
||||
dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
|
||||
DRM_DEBUG( "TIMEOUT problem!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -638,6 +700,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
*/
|
||||
if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
|
||||
( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
|
||||
DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
|
|
@ -732,15 +795,45 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
DRM_IOREMAP( dev_priv->cp_ring );
|
||||
DRM_IOREMAP( dev_priv->ring_rptr );
|
||||
DRM_IOREMAP( dev_priv->buffers );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DRM_IOREMAP( dev_priv->cp_ring );
|
||||
DRM_IOREMAP( dev_priv->ring_rptr );
|
||||
DRM_IOREMAP( dev_priv->buffers );
|
||||
} else {
|
||||
dev_priv->cp_ring->handle =
|
||||
(void *)dev_priv->cp_ring->offset;
|
||||
dev_priv->ring_rptr->handle =
|
||||
(void *)dev_priv->ring_rptr->offset;
|
||||
dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
|
||||
|
||||
DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
|
||||
dev_priv->cp_ring->handle );
|
||||
DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
|
||||
dev_priv->ring_rptr->handle );
|
||||
DRM_DEBUG( "dev_priv->buffers->handle %p\n",
|
||||
dev_priv->buffers->handle );
|
||||
}
|
||||
|
||||
|
||||
dev_priv->agp_size = init->agp_size;
|
||||
dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
|
||||
dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
|
||||
- dev->agp->base
|
||||
+ dev_priv->agp_vm_start);
|
||||
#if __REALLY_HAVE_AGP
|
||||
if ( !dev_priv->is_pci )
|
||||
dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
|
||||
- dev->agp->base
|
||||
+ dev_priv->agp_vm_start);
|
||||
else
|
||||
#endif
|
||||
dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
|
||||
- dev->sg->handle
|
||||
+ dev_priv->agp_vm_start);
|
||||
|
||||
DRM_DEBUG( "dev_priv->agp_size %d\n",
|
||||
dev_priv->agp_size );
|
||||
DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n",
|
||||
dev_priv->agp_vm_start );
|
||||
DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n",
|
||||
dev_priv->agp_buffers_offset );
|
||||
|
||||
dev_priv->ring.head = ((__volatile__ u32 *)
|
||||
dev_priv->ring_rptr->handle);
|
||||
|
|
@ -784,6 +877,44 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
RADEON_WRITE( RADEON_LAST_CLEAR_REG,
|
||||
dev_priv->sarea_priv->last_clear );
|
||||
|
||||
if ( dev_priv->is_pci ) {
|
||||
dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
|
||||
if ( !dev_priv->phys_pci_gart ) {
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
DRM(free)( dev_priv, sizeof(*dev_priv),
|
||||
DRM_MEM_DRIVER );
|
||||
dev->dev_private = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Turn on PCI GART
|
||||
*/
|
||||
tmp = RADEON_READ( RADEON_AIC_CNTL )
|
||||
| RADEON_PCIGART_TRANSLATE_EN;
|
||||
RADEON_WRITE( RADEON_AIC_CNTL, tmp );
|
||||
|
||||
/* set PCI GART page-table base address
|
||||
*/
|
||||
RADEON_WRITE( RADEON_AIC_PT_BASE,
|
||||
virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
|
||||
|
||||
/* set address range for PCI address translate
|
||||
*/
|
||||
RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
|
||||
RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
|
||||
+ dev_priv->agp_size - 1);
|
||||
|
||||
/* Turn off AGP aperture -- is this required for PCIGART?
|
||||
*/
|
||||
RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
|
||||
RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
|
||||
} else {
|
||||
/* Turn off PCI GART
|
||||
*/
|
||||
tmp = RADEON_READ( RADEON_AIC_CNTL )
|
||||
& ~RADEON_PCIGART_TRANSLATE_EN;
|
||||
RADEON_WRITE( RADEON_AIC_CNTL, tmp );
|
||||
}
|
||||
|
||||
radeon_cp_load_microcode( dev_priv );
|
||||
radeon_cp_init_ring_buffer( dev );
|
||||
radeon_do_engine_reset( dev );
|
||||
|
|
@ -797,12 +928,16 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
|
||||
int radeon_do_cleanup_cp( drm_device_t *dev )
|
||||
{
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( dev->dev_private ) {
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
DRM_IOREMAPFREE( dev_priv->cp_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
if ( !dev_priv->is_pci ) {
|
||||
DRM_IOREMAPFREE( dev_priv->cp_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
}
|
||||
|
||||
DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
|
||||
DRM_MEM_DRIVER );
|
||||
|
|
@ -953,7 +1088,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Fullscreen mode
|
||||
*/
|
||||
|
||||
|
|
@ -1014,7 +1149,7 @@ int radeon_fullscreen( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Freelist management
|
||||
*/
|
||||
#define RADEON_BUFFER_USED 0xffffffff
|
||||
|
|
@ -1153,7 +1288,7 @@ void radeon_freelist_reset( drm_device_t *dev )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CP command submission
|
||||
*/
|
||||
|
||||
|
|
@ -1170,7 +1305,10 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
|
|||
}
|
||||
|
||||
/* FIXME: This return value is ignored in the BEGIN_RING macro! */
|
||||
#if RADEON_FIFO_DEBUG
|
||||
radeon_status( dev_priv );
|
||||
DRM_ERROR( "failed!\n" );
|
||||
#endif
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,13 @@
|
|||
#include "radeon.h"
|
||||
#include "drmP.h"
|
||||
#include "radeon_drv.h"
|
||||
#include "ati_pcigart.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
|
||||
|
||||
#define DRIVER_NAME "radeon"
|
||||
#define DRIVER_DESC "ATI Radeon"
|
||||
#define DRIVER_DATE "20010402"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 2
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
@ -84,3 +85,4 @@
|
|||
#include "drm_proc.h"
|
||||
#include "drm_vm.h"
|
||||
#include "drm_stub.h"
|
||||
#include "drm_scatter.h"
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ typedef struct drm_radeon_private {
|
|||
|
||||
int agp_size;
|
||||
u32 agp_vm_start;
|
||||
u32 agp_buffers_offset;
|
||||
unsigned long agp_buffers_offset;
|
||||
|
||||
int cp_mode;
|
||||
int cp_running;
|
||||
|
|
@ -83,6 +83,7 @@ typedef struct drm_radeon_private {
|
|||
|
||||
int usec_timeout;
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
|
||||
atomic_t idle_count;
|
||||
|
||||
|
|
@ -180,6 +181,7 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
* for Radeon kernel driver.
|
||||
*/
|
||||
|
||||
#define RADEON_AGP_COMMAND 0x0f60
|
||||
#define RADEON_AUX_SCISSOR_CNTL 0x26f0
|
||||
# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
|
||||
# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
|
||||
|
|
@ -253,6 +255,12 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
#define RADEON_MC_AGP_LOCATION 0x014c
|
||||
#define RADEON_MC_FB_LOCATION 0x0148
|
||||
#define RADEON_MCLK_CNTL 0x0012
|
||||
# define RADEON_FORCEON_MCLKA (1 << 16)
|
||||
# define RADEON_FORCEON_MCLKB (1 << 17)
|
||||
# define RADEON_FORCEON_YCLKA (1 << 18)
|
||||
# define RADEON_FORCEON_YCLKB (1 << 19)
|
||||
# define RADEON_FORCEON_MC (1 << 20)
|
||||
# define RADEON_FORCEON_AIC (1 << 21)
|
||||
|
||||
#define RADEON_PP_BORDER_COLOR_0 0x1d40
|
||||
#define RADEON_PP_BORDER_COLOR_1 0x1d44
|
||||
|
|
@ -433,6 +441,12 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
|
||||
#define RADEON_AIC_CNTL 0x01d0
|
||||
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
|
||||
#define RADEON_AIC_STAT 0x01d4
|
||||
#define RADEON_AIC_PT_BASE 0x01d8
|
||||
#define RADEON_AIC_LO_ADDR 0x01dc
|
||||
#define RADEON_AIC_HI_ADDR 0x01e0
|
||||
#define RADEON_AIC_TLB_ADDR 0x01e4
|
||||
#define RADEON_AIC_TLB_DATA 0x01e8
|
||||
|
||||
/* CP command packets */
|
||||
#define RADEON_CP_PACKET0 0x00000000
|
||||
|
|
@ -509,18 +523,47 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
#define RADEON_RING_HIGH_MARK 128
|
||||
|
||||
|
||||
#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
|
||||
#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
||||
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
|
||||
|
||||
#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg )
|
||||
#ifdef __alpha__
|
||||
#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
|
||||
static inline u32 _RADEON_READ(u32 *addr)
|
||||
{
|
||||
mb();
|
||||
return *(volatile u32 *)addr;
|
||||
}
|
||||
#define RADEON_WRITE(reg,val) \
|
||||
do { \
|
||||
wmb(); \
|
||||
RADEON_DEREF(reg) = val; \
|
||||
} while (0)
|
||||
#else
|
||||
#define RADEON_READ(reg) RADEON_DEREF( reg )
|
||||
#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
|
||||
#endif
|
||||
|
||||
#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg )
|
||||
#ifdef __alpha__
|
||||
#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
|
||||
static inline u8 _RADEON_READ8(u8 *addr)
|
||||
{
|
||||
mb();
|
||||
return *(volatile u8 *)addr;
|
||||
}
|
||||
#define RADEON_WRITE8(reg,val) \
|
||||
do { \
|
||||
wmb(); \
|
||||
RADEON_DEREF8( reg ) = val; \
|
||||
} while (0)
|
||||
#else
|
||||
#define RADEON_READ8(reg) RADEON_DEREF8( reg )
|
||||
#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
|
||||
#endif
|
||||
|
||||
#define RADEON_WRITE_PLL( addr, val ) do { \
|
||||
#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) ); \
|
||||
|
|
@ -529,7 +572,6 @@ extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
|
||||
|
||||
|
||||
|
||||
#define CP_PACKET0( reg, n ) \
|
||||
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
|
||||
#define CP_PACKET0_TABLE( reg, n ) \
|
||||
|
|
@ -542,7 +584,7 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
|
|||
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Engine control helper macros
|
||||
*/
|
||||
|
||||
|
|
@ -591,7 +633,7 @@ extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
|
|||
} while (0)
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Misc helper macros
|
||||
*/
|
||||
|
||||
|
|
@ -648,7 +690,7 @@ do { \
|
|||
} while (0)
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Ring control
|
||||
*/
|
||||
|
||||
|
|
@ -675,7 +717,7 @@ do { \
|
|||
|
||||
#define ADVANCE_RING() do { \
|
||||
if ( RADEON_VERBOSE ) { \
|
||||
DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \
|
||||
DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
|
||||
write, dev_priv->ring.tail ); \
|
||||
} \
|
||||
radeon_flush_write_combine(); \
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include <linux/delay.h>
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CP hardware state programming functions
|
||||
*/
|
||||
|
||||
|
|
@ -48,10 +48,13 @@ static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
|
|||
box->x1, box->y1, box->x2, box->y2 );
|
||||
|
||||
BEGIN_RING( 4 );
|
||||
|
||||
OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
|
||||
OUT_RING( (box->y1 << 16) | box->x1 );
|
||||
|
||||
OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
|
||||
OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
|
||||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +377,7 @@ static inline void radeon_emit_state( drm_radeon_private_t *dev_priv,
|
|||
|
||||
|
||||
#if RADEON_PERFORMANCE_BOXES
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* Performance monitoring functions
|
||||
*/
|
||||
|
||||
|
|
@ -432,7 +435,7 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
|
|||
#endif
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* CP command dispatch functions
|
||||
*/
|
||||
|
||||
|
|
@ -1092,7 +1095,7 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
|
|||
}
|
||||
|
||||
|
||||
/* =============================================================
|
||||
/* ================================================================
|
||||
* IOCTL functions
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -17,4 +17,20 @@ typedef struct {
|
|||
unsigned int left, right;
|
||||
} drm_sis_flip_t;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
int sisp_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
696
linux/sis_drv.c
696
linux/sis_drv.c
|
|
@ -26,669 +26,49 @@
|
|||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include "sis.h"
|
||||
#include "drmP.h"
|
||||
#include "sis_drm.h"
|
||||
#include "sis_drv.h"
|
||||
|
||||
#define SIS_NAME "sis"
|
||||
#define SIS_DESC "SIS 300/630/540"
|
||||
#define SIS_DATE "20000831"
|
||||
#define SIS_MAJOR 1
|
||||
#define SIS_MINOR 0
|
||||
#define SIS_PATCHLEVEL 0
|
||||
#define DRIVER_AUTHOR "SIS"
|
||||
#define DRIVER_NAME "sis"
|
||||
#define DRIVER_DESC "SIS 300/630/540"
|
||||
#define DRIVER_DATE "20010624"
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
static drm_device_t sis_device;
|
||||
drm_ctx_t sis_res_ctx;
|
||||
|
||||
static struct file_operations sis_fops = {
|
||||
#if LINUX_VERSION_CODE >= 0x020400
|
||||
/* This started being used during 2.4.0-test */
|
||||
owner: THIS_MODULE,
|
||||
#endif
|
||||
open: sis_open,
|
||||
flush: drm_flush,
|
||||
release: sis_release,
|
||||
ioctl: sis_ioctl,
|
||||
mmap: drm_mmap,
|
||||
read: drm_read,
|
||||
fasync: drm_fasync,
|
||||
poll: drm_poll,
|
||||
};
|
||||
|
||||
static struct miscdevice sis_misc = {
|
||||
minor: MISC_DYNAMIC_MINOR,
|
||||
name: SIS_NAME,
|
||||
fops: &sis_fops,
|
||||
};
|
||||
|
||||
static drm_ioctl_desc_t sis_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { sis_version, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { sis_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { sis_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { sis_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { sis_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { sis_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { sis_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { sis_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { sis_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { sis_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
|
||||
#endif
|
||||
/* FB Memory Management */
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 },
|
||||
|
||||
/* AGP Memory Management */
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sis_agp_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sis_agp_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sis_agp_free, 1, 1 },
|
||||
|
||||
#if defined(SIS_STEREO)
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 },
|
||||
#endif
|
||||
};
|
||||
#define SIS_IOCTL_COUNT DRM_ARRAY_SIZE(sis_ioctls)
|
||||
|
||||
#ifdef MODULE
|
||||
static char *sis = NULL;
|
||||
#define DRIVER_IOCTLS \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)] = { sis_fb_alloc, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)] = { sis_fb_free, 1, 1 }, \
|
||||
/* AGP Memory Management */ \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)] = { sisp_agp_init, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)] = { sisp_agp_alloc, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)] = { sisp_agp_free, 1, 1 }
|
||||
#if 0 /* these don't appear to be defined */
|
||||
/* SIS Stereo */
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { sis_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP)] = { sis_flip, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)] = { sis_flip_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final, 1, 1 }
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("VA Linux Systems, Inc.");
|
||||
MODULE_DESCRIPTION("sis");
|
||||
MODULE_PARM(sis, "s");
|
||||
#define __HAVE_COUNTERS 5
|
||||
|
||||
#ifndef MODULE
|
||||
/* sis_options is called by the kernel to parse command-line options
|
||||
* passed via the boot-loader (e.g., LILO). It calls the insmod option
|
||||
* routine, drm_parse_drm.
|
||||
*/
|
||||
|
||||
static int __init sis_options(char *str)
|
||||
{
|
||||
drm_parse_options(str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("sis=", sis_options);
|
||||
#endif
|
||||
|
||||
static int sis_setup(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
atomic_set(&dev->ioctl_count, 0);
|
||||
atomic_set(&dev->vma_count, 0);
|
||||
dev->buf_use = 0;
|
||||
atomic_set(&dev->buf_alloc, 0);
|
||||
|
||||
atomic_set(&dev->total_open, 0);
|
||||
atomic_set(&dev->total_close, 0);
|
||||
atomic_set(&dev->total_ioctl, 0);
|
||||
atomic_set(&dev->total_irq, 0);
|
||||
atomic_set(&dev->total_ctx, 0);
|
||||
atomic_set(&dev->total_locks, 0);
|
||||
atomic_set(&dev->total_unlocks, 0);
|
||||
atomic_set(&dev->total_contends, 0);
|
||||
atomic_set(&dev->total_sleeps, 0);
|
||||
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
dev->magiclist[i].head = NULL;
|
||||
dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
dev->vmalist = NULL;
|
||||
dev->lock.hw_lock = NULL;
|
||||
init_waitqueue_head(&dev->lock.lock_queue);
|
||||
dev->queue_count = 0;
|
||||
dev->queue_reserved = 0;
|
||||
dev->queue_slots = 0;
|
||||
dev->queuelist = NULL;
|
||||
dev->irq = 0;
|
||||
dev->context_flag = 0;
|
||||
dev->interrupt_flag = 0;
|
||||
dev->dma = 0;
|
||||
dev->dma_flag = 0;
|
||||
dev->last_context = 0;
|
||||
dev->last_switch = 0;
|
||||
dev->last_checked = 0;
|
||||
init_timer(&dev->timer);
|
||||
init_waitqueue_head(&dev->context_wait);
|
||||
|
||||
dev->ctx_start = 0;
|
||||
dev->lck_start = 0;
|
||||
|
||||
dev->buf_rp = dev->buf;
|
||||
dev->buf_wp = dev->buf;
|
||||
dev->buf_end = dev->buf + DRM_BSZ;
|
||||
dev->buf_async = NULL;
|
||||
init_waitqueue_head(&dev->buf_readers);
|
||||
init_waitqueue_head(&dev->buf_writers);
|
||||
|
||||
sis_res_ctx.handle=-1;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
/* The kernel's context could be created here, but is now created
|
||||
in drm_dma_enqueue. This is more resource-efficient for
|
||||
hardware that does not do DMA, but may mean that
|
||||
drm_select_queue fails between the time the interrupt is
|
||||
initialized and the time the queues are initialized. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int sis_takedown(drm_device_t *dev)
|
||||
{
|
||||
int i;
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_t *map;
|
||||
drm_vma_entry_t *vma, *vma_next;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
#if defined(SIS_STEREO)
|
||||
if (dev->irq) sis_irq_uninstall(dev);
|
||||
#endif
|
||||
|
||||
down(&dev->struct_sem);
|
||||
del_timer(&dev->timer);
|
||||
|
||||
if (dev->devname) {
|
||||
drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
|
||||
dev->devname = NULL;
|
||||
}
|
||||
|
||||
if (dev->unique) {
|
||||
drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
|
||||
dev->unique = NULL;
|
||||
dev->unique_len = 0;
|
||||
}
|
||||
/* Clear pid list */
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
for (pt = dev->magiclist[i].head; pt; pt = next) {
|
||||
next = pt->next;
|
||||
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
|
||||
}
|
||||
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
/* Clear AGP information */
|
||||
if (dev->agp) {
|
||||
drm_agp_mem_t *temp;
|
||||
drm_agp_mem_t *temp_next;
|
||||
|
||||
temp = dev->agp->memory;
|
||||
while(temp != NULL) {
|
||||
temp_next = temp->next;
|
||||
drm_free_agp(temp->memory, temp->pages);
|
||||
drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS);
|
||||
temp = temp_next;
|
||||
}
|
||||
if (dev->agp->acquired) _drm_agp_release();
|
||||
}
|
||||
#endif
|
||||
/* Clear vma list (only built for debugging) */
|
||||
if (dev->vmalist) {
|
||||
for (vma = dev->vmalist; vma; vma = vma_next) {
|
||||
vma_next = vma->next;
|
||||
drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
|
||||
}
|
||||
dev->vmalist = NULL;
|
||||
}
|
||||
|
||||
/* Clear map area and mtrr information */
|
||||
if (dev->maplist) {
|
||||
for (i = 0; i < dev->map_count; i++) {
|
||||
map = dev->maplist[i];
|
||||
switch (map->type) {
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_FRAME_BUFFER:
|
||||
#ifdef CONFIG_MTRR
|
||||
if (map->mtrr >= 0) {
|
||||
int retcode;
|
||||
retcode = mtrr_del(map->mtrr,
|
||||
map->offset,
|
||||
map->size);
|
||||
DRM_DEBUG("mtrr_del = %d\n", retcode);
|
||||
}
|
||||
#endif
|
||||
drm_ioremapfree(map->handle, map->size);
|
||||
break;
|
||||
case _DRM_SHM:
|
||||
drm_free_pages((unsigned long)map->handle,
|
||||
drm_order(map->size)
|
||||
- PAGE_SHIFT,
|
||||
DRM_MEM_SAREA);
|
||||
break;
|
||||
case _DRM_AGP:
|
||||
/* Do nothing here, because this is all
|
||||
handled in the AGP/GART driver. */
|
||||
break;
|
||||
}
|
||||
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
||||
}
|
||||
drm_free(dev->maplist,
|
||||
dev->map_count * sizeof(*dev->maplist),
|
||||
DRM_MEM_MAPS);
|
||||
dev->maplist = NULL;
|
||||
dev->map_count = 0;
|
||||
}
|
||||
|
||||
if (dev->lock.hw_lock) {
|
||||
dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
dev->lock.pid = 0;
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sis_init is called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported). */
|
||||
|
||||
static int sis_init(void)
|
||||
{
|
||||
int retcode;
|
||||
drm_device_t *dev = &sis_device;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
memset((void *)dev, 0, sizeof(*dev));
|
||||
dev->count_lock = SPIN_LOCK_UNLOCKED;
|
||||
sema_init(&dev->struct_sem, 1);
|
||||
|
||||
#ifdef MODULE
|
||||
drm_parse_options(sis);
|
||||
#endif
|
||||
|
||||
if ((retcode = misc_register(&sis_misc))) {
|
||||
DRM_ERROR("Cannot register \"%s\"\n", SIS_NAME);
|
||||
return retcode;
|
||||
}
|
||||
dev->device = MKDEV(MISC_MAJOR, sis_misc.minor);
|
||||
dev->name = SIS_NAME;
|
||||
|
||||
drm_mem_init();
|
||||
drm_proc_init(dev);
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
dev->agp = drm_agp_init();
|
||||
#endif
|
||||
if((retcode = drm_ctxbitmap_init(dev))) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
drm_proc_cleanup();
|
||||
misc_deregister(&sis_misc);
|
||||
sis_takedown(dev);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
|
||||
SIS_NAME,
|
||||
SIS_MAJOR,
|
||||
SIS_MINOR,
|
||||
SIS_PATCHLEVEL,
|
||||
SIS_DATE,
|
||||
sis_misc.minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sis_cleanup is called via cleanup_module at module unload time. */
|
||||
|
||||
static void sis_cleanup(void)
|
||||
{
|
||||
drm_device_t *dev = &sis_device;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
drm_proc_cleanup();
|
||||
if (misc_deregister(&sis_misc)) {
|
||||
DRM_ERROR("Cannot unload module\n");
|
||||
} else {
|
||||
DRM_INFO("Module unloaded\n");
|
||||
}
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
sis_takedown(dev);
|
||||
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
|
||||
if (dev->agp) {
|
||||
drm_agp_uninit();
|
||||
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
|
||||
dev->agp = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(sis_init);
|
||||
module_exit(sis_cleanup);
|
||||
|
||||
|
||||
int sis_version(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_version_t version;
|
||||
int len;
|
||||
|
||||
if (copy_from_user(&version, (drm_version_t *)arg, sizeof(version)))
|
||||
return -EFAULT;
|
||||
|
||||
#define DRM_COPY(name,value) \
|
||||
len = strlen(value); \
|
||||
if (len > name##_len) len = name##_len; \
|
||||
name##_len = strlen(value); \
|
||||
if (len && name) { \
|
||||
if (copy_to_user(name, value, len)) \
|
||||
return -EFAULT; \
|
||||
}
|
||||
|
||||
version.version_major = SIS_MAJOR;
|
||||
version.version_minor = SIS_MINOR;
|
||||
version.version_patchlevel = SIS_PATCHLEVEL;
|
||||
|
||||
DRM_COPY(version.name, SIS_NAME);
|
||||
DRM_COPY(version.date, SIS_DATE);
|
||||
DRM_COPY(version.desc, SIS_DESC);
|
||||
|
||||
if (copy_to_user((drm_version_t *)arg, &version, sizeof(version)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sis_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_device_t *dev = &sis_device;
|
||||
int retcode = 0;
|
||||
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
if (!(retcode = drm_open_helper(inode, filp, dev))) {
|
||||
#if LINUX_VERSION_CODE < 0x020333
|
||||
MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
|
||||
#endif
|
||||
atomic_inc(&dev->total_open);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!dev->open_count++) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return sis_setup(dev);
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
}
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int sis_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
int retcode = 0;
|
||||
|
||||
lock_kernel();
|
||||
dev = priv->dev;
|
||||
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
if (!(retcode = drm_release(inode, filp))) {
|
||||
#if LINUX_VERSION_CODE < 0x020333
|
||||
MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
|
||||
#endif
|
||||
atomic_inc(&dev->total_close);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!--dev->open_count) {
|
||||
if (atomic_read(&dev->ioctl_count) || dev->blocked) {
|
||||
DRM_ERROR("Device busy: %d %d\n",
|
||||
atomic_read(&dev->ioctl_count),
|
||||
dev->blocked);
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return -EBUSY;
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return sis_takedown(dev);
|
||||
}
|
||||
spin_unlock(&dev->count_lock);
|
||||
}
|
||||
|
||||
unlock_kernel();
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/* sis_ioctl is called whenever a process performs an ioctl on /dev/drm. */
|
||||
|
||||
int sis_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
int retcode = 0;
|
||||
drm_ioctl_desc_t *ioctl;
|
||||
drm_ioctl_t *func;
|
||||
|
||||
atomic_inc(&dev->ioctl_count);
|
||||
atomic_inc(&dev->total_ioctl);
|
||||
++priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
|
||||
current->pid, cmd, nr, dev->device, priv->authenticated);
|
||||
|
||||
if (nr >= SIS_IOCTL_COUNT) {
|
||||
retcode = -EINVAL;
|
||||
} else {
|
||||
ioctl = &sis_ioctls[nr];
|
||||
func = ioctl->func;
|
||||
|
||||
if (!func) {
|
||||
DRM_DEBUG("no function\n");
|
||||
retcode = -EINVAL;
|
||||
} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
|
||||
|| (ioctl->auth_needed && !priv->authenticated)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
retcode = (func)(inode, filp, cmd, arg);
|
||||
}
|
||||
}
|
||||
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int sis_lock(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;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
int ret = 0;
|
||||
drm_lock_t lock;
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
cycles_t start;
|
||||
|
||||
dev->lck_start = start = get_cycles();
|
||||
#endif
|
||||
|
||||
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid, dev->lock.hw_lock->lock,
|
||||
lock.flags);
|
||||
|
||||
#if 0
|
||||
/* dev->queue_count == 0 right now for
|
||||
sis. FIXME? */
|
||||
if (lock.context < 0 || lock.context >= dev->queue_count)
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if 0
|
||||
if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
|
||||
!= lock.context) {
|
||||
long j = jiffies - dev->lock.lock_time;
|
||||
|
||||
if (lock.context == sis_res_ctx.handle &&
|
||||
j >= 0 && j < DRM_LOCK_SLICE) {
|
||||
/* Can't take lock if we just had it and
|
||||
there is contention. */
|
||||
DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
|
||||
lock.context, current->pid, j,
|
||||
dev->lock.lock_time, jiffies);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule_timeout(DRM_LOCK_SLICE-j);
|
||||
DRM_DEBUG("jiffies=%d\n", jiffies);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
lock.context)) {
|
||||
dev->lock.pid = current->pid;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc(&dev->total_locks);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
atomic_inc(&dev->total_sleeps);
|
||||
#if 1
|
||||
current->policy |= SCHED_YIELD;
|
||||
#endif
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!ret && dev->last_context != lock.context &&
|
||||
lock.context != sis_res_ctx.handle &&
|
||||
dev->last_context != sis_res_ctx.handle) {
|
||||
add_wait_queue(&dev->context_wait, &entry);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
/* PRE: dev->last_context != lock.context */
|
||||
sis_context_switch(dev, dev->last_context, lock.context);
|
||||
/* POST: we will wait for the context
|
||||
switch and will dispatch on a later call
|
||||
when dev->last_context == lock.context
|
||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
||||
TIME! */
|
||||
current->policy |= SCHED_YIELD;
|
||||
schedule();
|
||||
current->state = TASK_RUNNING;
|
||||
remove_wait_queue(&dev->context_wait, &entry);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
} else if (dev->last_context != lock.context) {
|
||||
DRM_ERROR("Context mismatch: %d %d\n",
|
||||
dev->last_context, lock.context);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
sigemptyset(&dev->sigmask);
|
||||
sigaddset(&dev->sigmask, SIGSTOP);
|
||||
sigaddset(&dev->sigmask, SIGTSTP);
|
||||
sigaddset(&dev->sigmask, SIGTTIN);
|
||||
sigaddset(&dev->sigmask, SIGTTOU);
|
||||
dev->sigdata.context = lock.context;
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
|
||||
|
||||
if (lock.flags & _DRM_LOCK_READY) {
|
||||
/* Wait for space in DMA/FIFO */
|
||||
}
|
||||
if (lock.flags & _DRM_LOCK_QUIESCENT) {
|
||||
/* Make hardware quiescent */
|
||||
#if 0
|
||||
sis_quiescent(dev);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
#if DRM_DMA_HISTOGRAM
|
||||
atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sis_unlock(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_lock_t lock;
|
||||
|
||||
if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG("%d frees lock (%d holds)\n",
|
||||
lock.context,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
atomic_inc(&dev->total_unlocks);
|
||||
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
|
||||
atomic_inc(&dev->total_contends);
|
||||
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
|
||||
/* FIXME: Try to send data to card here */
|
||||
if (!dev->context_flag) {
|
||||
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
unblock_all_signals();
|
||||
return 0;
|
||||
}
|
||||
#include "drm_auth.h"
|
||||
#include "drm_agpsupport.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"
|
||||
|
|
|
|||
|
|
@ -28,53 +28,11 @@
|
|||
#ifndef _SIS_DRV_H_
|
||||
#define _SIS_DRV_H_
|
||||
|
||||
/* sis_drv.c */
|
||||
extern int sis_version(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_open(struct inode *inode, struct file *filp);
|
||||
extern int sis_release(struct inode *inode, struct file *filp);
|
||||
extern int sis_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_irq_install(drm_device_t *dev, int irq);
|
||||
extern int sis_irq_uninstall(drm_device_t *dev);
|
||||
extern int sis_control(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_lock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_unlock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
typedef struct drm_sis_private {
|
||||
drm_map_t *buffers;
|
||||
} drm_sis_private_t;
|
||||
|
||||
/* sis_context.c */
|
||||
|
||||
extern int sis_resctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_addctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_modctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_getctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_switchctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_newctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int sis_rmctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern int sis_context_switch(drm_device_t *dev, int old, int new);
|
||||
extern int sis_context_switch_complete(drm_device_t *dev, int new);
|
||||
|
||||
int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int sis_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
/* Stereo ? - this was never committed */
|
||||
|
||||
int sis_flip(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
|
@ -83,8 +41,5 @@ int sis_flip_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
int sis_flip_final(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
void flip_final(void);
|
||||
|
||||
int sis_init_context(int contexy);
|
||||
int sis_final_context(int context);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@
|
|||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#include "sis.h"
|
||||
#include <linux/sisfb.h>
|
||||
#include "drmP.h"
|
||||
#include "sis_drm.h"
|
||||
#include "sis_ds.h"
|
||||
#include "sis_drv.h"
|
||||
#include "sis_ds.h"
|
||||
|
||||
#define MAX_CONTEXT 100
|
||||
#define VIDEO_TYPE 0
|
||||
|
|
@ -149,7 +151,7 @@ int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
|
||||
static memHeap_t *AgpHeap = NULL;
|
||||
|
||||
int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
int sisp_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_sis_agp_t agp;
|
||||
|
|
@ -164,7 +166,7 @@ int sis_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_sis_mem_t agp;
|
||||
|
|
@ -201,7 +203,7 @@ int sis_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
return retval;
|
||||
}
|
||||
|
||||
int sis_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_sis_mem_t agp;
|
||||
|
|
@ -277,7 +279,9 @@ int sis_final_context(int context)
|
|||
retval = setFirst(set, &item);
|
||||
while(retval){
|
||||
DRM_DEBUG("free video memory 0x%x\n", item);
|
||||
#if 0
|
||||
sis_free(item);
|
||||
#endif
|
||||
retval = setNext(set, &item);
|
||||
}
|
||||
setDestroy(set);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "tdfx"
|
||||
#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
|
||||
#define DRIVER_DATE "20010216"
|
||||
#define DRIVER_DATE "20010624"
|
||||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 0
|
||||
|
|
|
|||
|
|
@ -44,8 +44,27 @@
|
|||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||
#endif
|
||||
|
||||
#define XFREE86_VERSION(major,minor,patch,snap) \
|
||||
((major << 16) | (minor < 8) | patch)
|
||||
|
||||
#ifndef CONFIG_XFREE86_VERSION
|
||||
#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_PROC_DEVICES "/proc/devices"
|
||||
#define DRM_PROC_MISC "/proc/misc"
|
||||
#define DRM_PROC_DRM "/proc/drm"
|
||||
#define DRM_DEV_DRM "/dev/drm"
|
||||
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
||||
#define DRM_DEV_UID 0
|
||||
#define DRM_DEV_GID 0
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_MAJOR 226
|
||||
#define DRM_MAX_MINOR 15
|
||||
#endif
|
||||
#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 */
|
||||
|
|
@ -127,10 +146,11 @@ typedef struct drm_control {
|
|||
} drm_control_t;
|
||||
|
||||
typedef enum drm_map_type {
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3 /* AGP/GART */
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3, /* AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
|
||||
} drm_map_type_t;
|
||||
|
||||
typedef enum drm_map_flags {
|
||||
|
|
@ -239,7 +259,8 @@ typedef struct drm_buf_desc {
|
|||
int high_mark; /* High water mark */
|
||||
enum {
|
||||
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
|
||||
_DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
|
||||
_DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
|
||||
} flags;
|
||||
unsigned long agp_start; /* Start address of where the agp buffers
|
||||
* are in the agp aperture */
|
||||
|
|
@ -345,6 +366,11 @@ typedef struct drm_agp_info {
|
|||
unsigned short id_device;
|
||||
} drm_agp_info_t;
|
||||
|
||||
typedef struct drm_scatter_gather {
|
||||
unsigned long size; /* In bytes -- will round to page boundary */
|
||||
unsigned long handle; /* Used for mapping / unmapping */
|
||||
} drm_scatter_gather_t;
|
||||
|
||||
#define DRM_IOCTL_BASE 'd'
|
||||
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
|
||||
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
|
||||
|
|
@ -400,6 +426,9 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
|
||||
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
|
||||
|
||||
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
|
||||
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
|
||||
|
||||
/* MGA specific ioctls */
|
||||
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
|
||||
|
|
@ -419,6 +448,7 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
|
||||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
|
|
@ -428,15 +458,15 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
|
||||
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -449,9 +479,10 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
|
||||
#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_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_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)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
59
shared/drm.h
59
shared/drm.h
|
|
@ -44,8 +44,27 @@
|
|||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||
#endif
|
||||
|
||||
#define XFREE86_VERSION(major,minor,patch,snap) \
|
||||
((major << 16) | (minor < 8) | patch)
|
||||
|
||||
#ifndef CONFIG_XFREE86_VERSION
|
||||
#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_PROC_DEVICES "/proc/devices"
|
||||
#define DRM_PROC_MISC "/proc/misc"
|
||||
#define DRM_PROC_DRM "/proc/drm"
|
||||
#define DRM_DEV_DRM "/dev/drm"
|
||||
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
||||
#define DRM_DEV_UID 0
|
||||
#define DRM_DEV_GID 0
|
||||
#endif
|
||||
|
||||
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
|
||||
#define DRM_MAJOR 226
|
||||
#define DRM_MAX_MINOR 15
|
||||
#endif
|
||||
#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 */
|
||||
|
|
@ -127,10 +146,11 @@ typedef struct drm_control {
|
|||
} drm_control_t;
|
||||
|
||||
typedef enum drm_map_type {
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3 /* AGP/GART */
|
||||
_DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /* no caching, no core dump */
|
||||
_DRM_SHM = 2, /* shared, cached */
|
||||
_DRM_AGP = 3, /* AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4 /* Scatter/gather memory for PCI DMA */
|
||||
} drm_map_type_t;
|
||||
|
||||
typedef enum drm_map_flags {
|
||||
|
|
@ -239,7 +259,8 @@ typedef struct drm_buf_desc {
|
|||
int high_mark; /* High water mark */
|
||||
enum {
|
||||
_DRM_PAGE_ALIGN = 0x01, /* Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02 /* Buffer is in agp space */
|
||||
_DRM_AGP_BUFFER = 0x02, /* Buffer is in agp space */
|
||||
_DRM_SG_BUFFER = 0x04 /* Scatter/gather memory buffer */
|
||||
} flags;
|
||||
unsigned long agp_start; /* Start address of where the agp buffers
|
||||
* are in the agp aperture */
|
||||
|
|
@ -345,6 +366,11 @@ typedef struct drm_agp_info {
|
|||
unsigned short id_device;
|
||||
} drm_agp_info_t;
|
||||
|
||||
typedef struct drm_scatter_gather {
|
||||
unsigned long size; /* In bytes -- will round to page boundary */
|
||||
unsigned long handle; /* Used for mapping / unmapping */
|
||||
} drm_scatter_gather_t;
|
||||
|
||||
#define DRM_IOCTL_BASE 'd'
|
||||
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
|
||||
#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
|
||||
|
|
@ -400,6 +426,9 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
|
||||
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
|
||||
|
||||
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
|
||||
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
|
||||
|
||||
/* MGA specific ioctls */
|
||||
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x41, drm_lock_t)
|
||||
|
|
@ -419,6 +448,7 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
|
||||
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
|
||||
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
|
||||
|
||||
/* Rage 128 specific ioctls */
|
||||
|
|
@ -428,15 +458,15 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43)
|
||||
#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44)
|
||||
#define DRM_IOCTL_R128_RESET DRM_IO( 0x46)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47)
|
||||
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t)
|
||||
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
|
||||
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
|
||||
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
|
||||
#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
|
||||
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
|
||||
#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t)
|
||||
#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t)
|
||||
|
||||
/* Radeon specific ioctls */
|
||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t)
|
||||
|
|
@ -449,9 +479,10 @@ typedef struct drm_agp_info {
|
|||
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
|
||||
#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_TEXTURE DRM_IOWR(0x4b, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_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)
|
||||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue