merged from trunk

This commit is contained in:
Keith Whitwell 2003-03-28 13:47:41 +00:00
parent 7c9631e592
commit 79db46ccef
87 changed files with 2293 additions and 618 deletions

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/ati_pcigart.h,v 1.1 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drmP.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#ifndef _DRM_P_H_ #ifndef _DRM_P_H_
@ -489,8 +490,10 @@ struct drm_device {
#if __HAVE_VBL_IRQ #if __HAVE_VBL_IRQ
wait_queue_head_t vbl_queue; /* vbl wait channel */ wait_queue_head_t vbl_queue; /* vbl wait channel */
atomic_t vbl_received; atomic_t vbl_received;
#if 0 /* vbl signals are untested, ntested */
struct drm_vbl_sig_list vbl_sig_list; struct drm_vbl_sig_list vbl_sig_list;
DRM_SPINTYPE vbl_lock; DRM_SPINTYPE vbl_lock;
#endif
#endif #endif
cycles_t ctx_start; cycles_t ctx_start;
cycles_t lck_start; cycles_t lck_start;

View file

@ -27,6 +27,7 @@
* Author: * Author:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_agpsupport.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_auth.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_bufs.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_context.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_dma.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"
@ -524,7 +526,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
#endif #endif
#if __HAVE_VBL_IRQ #if __HAVE_VBL_IRQ && 0 /* disabled */
DRM_SPININIT( dev->vbl_lock, "vblsig" ); DRM_SPININIT( dev->vbl_lock, "vblsig" );
TAILQ_INIT( &dev->vbl_sig_list ); TAILQ_INIT( &dev->vbl_sig_list );
#endif #endif
@ -645,6 +647,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
if (flags & _DRM_VBLANK_SIGNAL) { if (flags & _DRM_VBLANK_SIGNAL) {
#if 0 /* disabled */
drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t));
if (vbl_sig == NULL) if (vbl_sig == NULL)
return ENOMEM; return ENOMEM;
@ -660,6 +663,8 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
DRM_SPINUNLOCK(&dev->vbl_lock); DRM_SPINUNLOCK(&dev->vbl_lock);
ret = 0; ret = 0;
#endif
ret = EINVAL;
} else { } else {
ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); ret = DRM(vblank_wait)(dev, &vblwait.request.sequence);
@ -674,6 +679,11 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
return ret; return ret;
} }
void DRM(vbl_send_signals)(drm_device_t *dev)
{
}
#if 0 /* disabled */
void DRM(vbl_send_signals)( drm_device_t *dev ) void DRM(vbl_send_signals)( drm_device_t *dev )
{ {
drm_vbl_sig_t *vbl_sig; drm_vbl_sig_t *vbl_sig;
@ -692,13 +702,14 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
psignal(p, vbl_sig->signo); psignal(p, vbl_sig->signo);
TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
DRM_FREE(vbl_sig); DRM_FREE(vbl_sig,sizeof(*vbl_sig));
} }
vbl_sig = next; vbl_sig = next;
} }
DRM_SPINUNLOCK(&dev->vbl_lock); DRM_SPINUNLOCK(&dev->vbl_lock);
} }
#endif
#endif /* __HAVE_VBL_IRQ */ #endif /* __HAVE_VBL_IRQ */

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_drawable.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_drv.h,v 1.12 2003/03/09 02:08:28 anholt Exp $
*/ */
/* /*
@ -223,23 +225,18 @@ const char *DRM(find_description)(int vendor, int device);
#ifdef __FreeBSD__ #ifdef __FreeBSD__
static struct cdevsw DRM(cdevsw) = { static struct cdevsw DRM(cdevsw) = {
/* open */ DRM( open ), .d_open = DRM( open ),
/* close */ DRM( close ), .d_close = DRM( close ),
/* read */ DRM( read ), .d_read = DRM( read ),
/* write */ DRM( write ), .d_write = DRM( write ),
/* ioctl */ DRM( ioctl ), .d_ioctl = DRM( ioctl ),
/* poll */ DRM( poll ), .d_poll = DRM( poll ),
/* mmap */ DRM( mmap ), .d_mmap = DRM( mmap ),
/* strategy */ nostrategy, .d_name = DRIVER_NAME,
/* name */ DRIVER_NAME, .d_maj = CDEV_MAJOR,
/* maj */ CDEV_MAJOR, .d_flags = D_TTY | D_TRACKCLOSE,
/* dump */ nodump, #if __FreeBSD_version < 500000
/* psize */ nopsize, .d_bmaj = -1
/* flags */ D_TTY | D_TRACKCLOSE,
#if __FreeBSD_version >= 500000
/* kqfilter */ 0
#else
/* bmaj */ -1
#endif #endif
}; };

View file

@ -28,6 +28,8 @@
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Daryll Strauss <daryll@valinux.com> * Daryll Strauss <daryll@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_fops.h,v 1.5 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_ioctl.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_lock.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_memory.h,v 1.7 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"
@ -106,7 +108,8 @@ void DRM(mem_uninit)(void)
#ifdef __FreeBSD__ #ifdef __FreeBSD__
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */
static int DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1, static int
DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
int arg2, struct sysctl_req *req) int arg2, struct sysctl_req *req)
{ {
drm_mem_stats_t *pt; drm_mem_stats_t *pt;

View file

@ -1,3 +1,6 @@
/*
* $FreeBSD: src/sys/dev/drm/drm_os_freebsd.h,v 1.8 2003/03/09 02:08:28 anholt Exp $
*/
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/malloc.h> #include <sys/malloc.h>
@ -45,7 +48,11 @@
#define __REALLY_HAVE_AGP __HAVE_AGP #define __REALLY_HAVE_AGP __HAVE_AGP
#endif #endif
#ifdef __i386__
#define __REALLY_HAVE_MTRR (__HAVE_MTRR) #define __REALLY_HAVE_MTRR (__HAVE_MTRR)
#else
#define __REALLY_HAVE_MTRR 0
#endif
#define __REALLY_HAVE_SG (__HAVE_SG) #define __REALLY_HAVE_SG (__HAVE_SG)
#if __REALLY_HAVE_AGP #if __REALLY_HAVE_AGP
@ -88,7 +95,7 @@
#define DRM_STRUCTPROC struct proc #define DRM_STRUCTPROC struct proc
#define DRM_SPINTYPE struct simplelock #define DRM_SPINTYPE struct simplelock
#define DRM_SPININIT(l,name) simple_lock_init(&l) #define DRM_SPININIT(l,name) simple_lock_init(&l)
#define DRM_SPINUNINIT(l,name) #define DRM_SPINUNINIT(l)
#define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINLOCK(l) simple_lock(l)
#define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_SPINUNLOCK(u) simple_unlock(u);
#define DRM_CURRENTPID curproc->p_pid #define DRM_CURRENTPID curproc->p_pid
@ -102,7 +109,7 @@
#define DRM_IRQ_ARGS void *arg #define DRM_IRQ_ARGS void *arg
#define DRM_DEVICE drm_device_t *dev = kdev->si_drv1 #define DRM_DEVICE drm_device_t *dev = kdev->si_drv1
#define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT )
#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) #define DRM_FREE(pt,size) free( pt, DRM(M_DRM) )
#define DRM_VTOPHYS(addr) vtophys(addr) #define DRM_VTOPHYS(addr) vtophys(addr)
/* Read/write from bus space, with byteswapping to le if necessary */ /* Read/write from bus space, with byteswapping to le if necessary */
@ -211,10 +218,9 @@ typedef struct drm_chipinfo
#define cpu_to_le32(x) (x) /* FIXME */ #define cpu_to_le32(x) (x) /* FIXME */
typedef u_int32_t dma_addr_t; typedef unsigned long dma_addr_t;
typedef u_int32_t atomic_t; typedef u_int32_t atomic_t;
typedef u_int32_t cycles_t; typedef u_int32_t cycles_t;
typedef u_int32_t spinlock_t;
typedef u_int32_t u32; typedef u_int32_t u32;
typedef u_int16_t u16; typedef u_int16_t u16;
typedef u_int8_t u8; typedef u_int8_t u8;
@ -230,7 +236,7 @@ typedef u_int8_t u8;
#if __FreeBSD_version < 500000 #if __FreeBSD_version < 500000
/* The extra atomic functions from 5.0 haven't been merged to 4.x */ /* The extra atomic functions from 5.0 haven't been merged to 4.x */
static __inline int static __inline int
atomic_cmpset_int(int *dst, int old, int new) atomic_cmpset_int(volatile int *dst, int old, int new)
{ {
int s = splhigh(); int s = splhigh();
if (*dst==old) { if (*dst==old) {

View file

@ -89,7 +89,7 @@ MALLOC_DECLARE(DRM(M_DRM));
extern const int DRM(M_DRM) = M_DEVBUF; extern const int DRM(M_DRM) = M_DEVBUF;
#endif /* __NetBSD_Version__ */ #endif /* __NetBSD_Version__ */
#define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT )
#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) #define DRM_FREE(pt,size) free( pt, DRM(M_DRM) )
#define DRM_VTOPHYS(addr) vtophys(addr) #define DRM_VTOPHYS(addr) vtophys(addr)
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) #define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
@ -183,7 +183,6 @@ typedef struct drm_chipinfo
typedef u_int32_t dma_addr_t; typedef u_int32_t dma_addr_t;
typedef volatile long atomic_t; typedef volatile long atomic_t;
typedef u_int32_t cycles_t; typedef u_int32_t cycles_t;
typedef u_int32_t spinlock_t;
typedef u_int32_t u32; typedef u_int32_t u32;
typedef u_int16_t u16; typedef u_int16_t u16;
typedef u_int8_t u8; typedef u_int8_t u8;

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_scatter.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -1,5 +1,5 @@
/* /*
* $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#ifdef __FreeBSD__ #ifdef __FreeBSD__

View file

@ -1,5 +1,11 @@
/*
* $FreeBSD: src/sys/dev/drm/drm_vm.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && __FreeBSD_version >= 500102
static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr,
int prot)
#elif defined(__FreeBSD__)
static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
@ -17,10 +23,18 @@ static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
physical = dma->pagelist[page]; physical = dma->pagelist[page];
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = physical;
return 0;
#else
return atop(physical); return atop(physical);
#endif
} }
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && __FreeBSD_version >= 500102
int DRM(mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr,
int prot)
#elif defined(__FreeBSD__)
int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot)
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
@ -44,7 +58,11 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
if (dev->dma if (dev->dma
&& offset >= 0 && offset >= 0
&& offset < ptoa(dev->dma->page_count)) && offset < ptoa(dev->dma->page_count))
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
return DRM(dma_mmap)(kdev, offset, paddr, prot);
#else
return DRM(dma_mmap)(kdev, offset, prot); return DRM(dma_mmap)(kdev, offset, prot);
#endif
/* A sequential search of a linked list is /* A sequential search of a linked list is
fine here because: 1) there will only be fine here because: 1) there will only be
@ -73,10 +91,20 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
case _DRM_FRAME_BUFFER: case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS: case _DRM_REGISTERS:
case _DRM_AGP: case _DRM_AGP:
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = offset;
return 0;
#else
return atop(offset); return atop(offset);
#endif
case _DRM_SCATTER_GATHER: case _DRM_SCATTER_GATHER:
case _DRM_SHM: case _DRM_SHM:
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = vtophys(offset);
return 0;
#else
return atop(vtophys(offset)); return atop(vtophys(offset));
#endif
default: default:
return -1; /* This should never happen. */ return -1; /* This should never happen. */
} }

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "mga.h" #include "mga.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "r128.h" #include "r128.h"

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $
*/ */
#include "radeon.h" #include "radeon.h"
@ -37,39 +39,41 @@
#endif #endif
drm_chipinfo_t DRM(devicelist)[] = { drm_chipinfo_t DRM(devicelist)[] = {
{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"}, {0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"},
{0x1002, 0x4336, 1, "ATI Radeon Mobility"}, {0x1002, 0x4336, 1, "ATI Radeon Mobility U1"},
{0x1002, 0x4337, 1, "ATI Radeon IGP 340"}, {0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"},
{0x1002, 0x4964, 1, "ATI Radeon Id 9000"}, {0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"},
{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"}, {0x1002, 0x4966, 1, "ATI Radeon If R250 9000"},
{0x1002, 0x4966, 1, "ATI Radeon If 9000"}, {0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"},
{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"}, {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"},
{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"}, {0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"},
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"}, {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"},
{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"}, {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"},
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"}, {0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"},
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"}, {0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"},
{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"}, {0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"},
{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"}, {0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"},
{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"}, {0x1002, 0x5144, 1, "ATI Radeon QD R100"},
{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"}, {0x1002, 0x5145, 1, "ATI Radeon QE R100"},
{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"}, {0x1002, 0x5146, 1, "ATI Radeon QF R100"},
{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"}, {0x1002, 0x5147, 1, "ATI Radeon QG R100"},
{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"}, {0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"},
{0x1002, 0x5147, 1, "ATI Radeon QG R100 (AGP)"},
{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00 (AGP)"},
{0x1002, 0x5149, 1, "ATI Radeon QI R200"}, {0x1002, 0x5149, 1, "ATI Radeon QI R200"},
{0x1002, 0x514A, 1, "ATI Radeon QJ R200"}, {0x1002, 0x514A, 1, "ATI Radeon QJ R200"},
{0x1002, 0x514B, 1, "ATI Radeon QK R200"}, {0x1002, 0x514B, 1, "ATI Radeon QK R200"},
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"}, {0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"},
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"}, {0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"},
{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"}, {0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"},
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"}, {0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"},
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"}, {0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"},
{0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"},
{0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"},
{0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"},
{0x1002, 0x5168, 1, "ATI Radeon Qh R200"}, {0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
{0x1002, 0x5169, 1, "ATI Radeon Qi R200"}, {0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
{0x1002, 0x516A, 1, "ATI Radeon Qj R200"}, {0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
{0x1002, 0x516B, 1, "ATI Radeon Qk R200"}, {0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
{0x1002, 0x516C, 1, "ATI Radeon Ql R200"},
{0, 0, 0, NULL} {0, 0, 0, NULL}
}; };

View file

@ -28,6 +28,8 @@
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Daryll Strauss <daryll@valinux.com> * Daryll Strauss <daryll@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "tdfx.h" #include "tdfx.h"

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/ati_pcigart.h,v 1.1 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -30,6 +30,7 @@
* Acknowledgements: * Acknowledgements:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg. * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
* *
* $FreeBSD: src/sys/dev/drm/drm.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#ifndef _DRM_H_ #ifndef _DRM_H_

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drmP.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#ifndef _DRM_P_H_ #ifndef _DRM_P_H_
@ -489,8 +490,10 @@ struct drm_device {
#if __HAVE_VBL_IRQ #if __HAVE_VBL_IRQ
wait_queue_head_t vbl_queue; /* vbl wait channel */ wait_queue_head_t vbl_queue; /* vbl wait channel */
atomic_t vbl_received; atomic_t vbl_received;
#if 0 /* vbl signals are untested, ntested */
struct drm_vbl_sig_list vbl_sig_list; struct drm_vbl_sig_list vbl_sig_list;
DRM_SPINTYPE vbl_lock; DRM_SPINTYPE vbl_lock;
#endif
#endif #endif
cycles_t ctx_start; cycles_t ctx_start;
cycles_t lck_start; cycles_t lck_start;

View file

@ -27,6 +27,7 @@
* Author: * Author:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_agpsupport.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_auth.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_bufs.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,7 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
* $FreeBSD: src/sys/dev/drm/drm_context.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_dma.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"
@ -524,7 +526,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev); TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
#endif #endif
#if __HAVE_VBL_IRQ #if __HAVE_VBL_IRQ && 0 /* disabled */
DRM_SPININIT( dev->vbl_lock, "vblsig" ); DRM_SPININIT( dev->vbl_lock, "vblsig" );
TAILQ_INIT( &dev->vbl_sig_list ); TAILQ_INIT( &dev->vbl_sig_list );
#endif #endif
@ -645,6 +647,7 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK; flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
if (flags & _DRM_VBLANK_SIGNAL) { if (flags & _DRM_VBLANK_SIGNAL) {
#if 0 /* disabled */
drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t)); drm_vbl_sig_t *vbl_sig = DRM_MALLOC(sizeof(drm_vbl_sig_t));
if (vbl_sig == NULL) if (vbl_sig == NULL)
return ENOMEM; return ENOMEM;
@ -660,6 +663,8 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link); TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
DRM_SPINUNLOCK(&dev->vbl_lock); DRM_SPINUNLOCK(&dev->vbl_lock);
ret = 0; ret = 0;
#endif
ret = EINVAL;
} else { } else {
ret = DRM(vblank_wait)(dev, &vblwait.request.sequence); ret = DRM(vblank_wait)(dev, &vblwait.request.sequence);
@ -674,6 +679,11 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
return ret; return ret;
} }
void DRM(vbl_send_signals)(drm_device_t *dev)
{
}
#if 0 /* disabled */
void DRM(vbl_send_signals)( drm_device_t *dev ) void DRM(vbl_send_signals)( drm_device_t *dev )
{ {
drm_vbl_sig_t *vbl_sig; drm_vbl_sig_t *vbl_sig;
@ -692,13 +702,14 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
psignal(p, vbl_sig->signo); psignal(p, vbl_sig->signo);
TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link); TAILQ_REMOVE(&dev->vbl_sig_list, vbl_sig, link);
DRM_FREE(vbl_sig); DRM_FREE(vbl_sig,sizeof(*vbl_sig));
} }
vbl_sig = next; vbl_sig = next;
} }
DRM_SPINUNLOCK(&dev->vbl_lock); DRM_SPINUNLOCK(&dev->vbl_lock);
} }
#endif
#endif /* __HAVE_VBL_IRQ */ #endif /* __HAVE_VBL_IRQ */

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_drawable.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_drv.h,v 1.12 2003/03/09 02:08:28 anholt Exp $
*/ */
/* /*
@ -223,23 +225,18 @@ const char *DRM(find_description)(int vendor, int device);
#ifdef __FreeBSD__ #ifdef __FreeBSD__
static struct cdevsw DRM(cdevsw) = { static struct cdevsw DRM(cdevsw) = {
/* open */ DRM( open ), .d_open = DRM( open ),
/* close */ DRM( close ), .d_close = DRM( close ),
/* read */ DRM( read ), .d_read = DRM( read ),
/* write */ DRM( write ), .d_write = DRM( write ),
/* ioctl */ DRM( ioctl ), .d_ioctl = DRM( ioctl ),
/* poll */ DRM( poll ), .d_poll = DRM( poll ),
/* mmap */ DRM( mmap ), .d_mmap = DRM( mmap ),
/* strategy */ nostrategy, .d_name = DRIVER_NAME,
/* name */ DRIVER_NAME, .d_maj = CDEV_MAJOR,
/* maj */ CDEV_MAJOR, .d_flags = D_TTY | D_TRACKCLOSE,
/* dump */ nodump, #if __FreeBSD_version < 500000
/* psize */ nopsize, .d_bmaj = -1
/* flags */ D_TTY | D_TRACKCLOSE,
#if __FreeBSD_version >= 500000
/* kqfilter */ 0
#else
/* bmaj */ -1
#endif #endif
}; };

View file

@ -28,6 +28,8 @@
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Daryll Strauss <daryll@valinux.com> * Daryll Strauss <daryll@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_fops.h,v 1.5 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_init.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_ioctl.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_lists.h,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_lock.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_memory.h,v 1.7 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"
@ -106,7 +108,8 @@ void DRM(mem_uninit)(void)
#ifdef __FreeBSD__ #ifdef __FreeBSD__
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */ /* drm_mem_info is called whenever a process reads /dev/drm/mem. */
static int DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1, static int
DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
int arg2, struct sysctl_req *req) int arg2, struct sysctl_req *req)
{ {
drm_mem_stats_t *pt; drm_mem_stats_t *pt;

View file

@ -1,3 +1,6 @@
/*
* $FreeBSD: src/sys/dev/drm/drm_os_freebsd.h,v 1.8 2003/03/09 02:08:28 anholt Exp $
*/
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/malloc.h> #include <sys/malloc.h>
@ -45,7 +48,11 @@
#define __REALLY_HAVE_AGP __HAVE_AGP #define __REALLY_HAVE_AGP __HAVE_AGP
#endif #endif
#ifdef __i386__
#define __REALLY_HAVE_MTRR (__HAVE_MTRR) #define __REALLY_HAVE_MTRR (__HAVE_MTRR)
#else
#define __REALLY_HAVE_MTRR 0
#endif
#define __REALLY_HAVE_SG (__HAVE_SG) #define __REALLY_HAVE_SG (__HAVE_SG)
#if __REALLY_HAVE_AGP #if __REALLY_HAVE_AGP
@ -88,7 +95,7 @@
#define DRM_STRUCTPROC struct proc #define DRM_STRUCTPROC struct proc
#define DRM_SPINTYPE struct simplelock #define DRM_SPINTYPE struct simplelock
#define DRM_SPININIT(l,name) simple_lock_init(&l) #define DRM_SPININIT(l,name) simple_lock_init(&l)
#define DRM_SPINUNINIT(l,name) #define DRM_SPINUNINIT(l)
#define DRM_SPINLOCK(l) simple_lock(l) #define DRM_SPINLOCK(l) simple_lock(l)
#define DRM_SPINUNLOCK(u) simple_unlock(u); #define DRM_SPINUNLOCK(u) simple_unlock(u);
#define DRM_CURRENTPID curproc->p_pid #define DRM_CURRENTPID curproc->p_pid
@ -102,7 +109,7 @@
#define DRM_IRQ_ARGS void *arg #define DRM_IRQ_ARGS void *arg
#define DRM_DEVICE drm_device_t *dev = kdev->si_drv1 #define DRM_DEVICE drm_device_t *dev = kdev->si_drv1
#define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT )
#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) #define DRM_FREE(pt,size) free( pt, DRM(M_DRM) )
#define DRM_VTOPHYS(addr) vtophys(addr) #define DRM_VTOPHYS(addr) vtophys(addr)
/* Read/write from bus space, with byteswapping to le if necessary */ /* Read/write from bus space, with byteswapping to le if necessary */
@ -211,10 +218,9 @@ typedef struct drm_chipinfo
#define cpu_to_le32(x) (x) /* FIXME */ #define cpu_to_le32(x) (x) /* FIXME */
typedef u_int32_t dma_addr_t; typedef unsigned long dma_addr_t;
typedef u_int32_t atomic_t; typedef u_int32_t atomic_t;
typedef u_int32_t cycles_t; typedef u_int32_t cycles_t;
typedef u_int32_t spinlock_t;
typedef u_int32_t u32; typedef u_int32_t u32;
typedef u_int16_t u16; typedef u_int16_t u16;
typedef u_int8_t u8; typedef u_int8_t u8;
@ -230,7 +236,7 @@ typedef u_int8_t u8;
#if __FreeBSD_version < 500000 #if __FreeBSD_version < 500000
/* The extra atomic functions from 5.0 haven't been merged to 4.x */ /* The extra atomic functions from 5.0 haven't been merged to 4.x */
static __inline int static __inline int
atomic_cmpset_int(int *dst, int old, int new) atomic_cmpset_int(volatile int *dst, int old, int new)
{ {
int s = splhigh(); int s = splhigh();
if (*dst==old) { if (*dst==old) {

View file

@ -89,7 +89,7 @@ MALLOC_DECLARE(DRM(M_DRM));
extern const int DRM(M_DRM) = M_DEVBUF; extern const int DRM(M_DRM) = M_DEVBUF;
#endif /* __NetBSD_Version__ */ #endif /* __NetBSD_Version__ */
#define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT ) #define DRM_MALLOC(size) malloc( size, DRM(M_DRM), M_NOWAIT )
#define DRM_FREE(pt) free( pt, DRM(M_DRM) ) #define DRM_FREE(pt,size) free( pt, DRM(M_DRM) )
#define DRM_VTOPHYS(addr) vtophys(addr) #define DRM_VTOPHYS(addr) vtophys(addr)
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) ) #define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
@ -183,7 +183,6 @@ typedef struct drm_chipinfo
typedef u_int32_t dma_addr_t; typedef u_int32_t dma_addr_t;
typedef volatile long atomic_t; typedef volatile long atomic_t;
typedef u_int32_t cycles_t; typedef u_int32_t cycles_t;
typedef u_int32_t spinlock_t;
typedef u_int32_t u32; typedef u_int32_t u32;
typedef u_int16_t u16; typedef u_int16_t u16;
typedef u_int8_t u8; typedef u_int8_t u8;

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/drm_scatter.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "drmP.h" #include "drmP.h"

View file

@ -1,5 +1,5 @@
/* /*
* $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.1 2002/04/27 20:47:57 anholt Exp $ * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.2 2003/03/09 02:08:28 anholt Exp $
*/ */
#ifdef __FreeBSD__ #ifdef __FreeBSD__

View file

@ -1,5 +1,11 @@
/*
* $FreeBSD: src/sys/dev/drm/drm_vm.h,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && __FreeBSD_version >= 500102
static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr,
int prot)
#elif defined(__FreeBSD__)
static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) static int DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot) static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
@ -17,10 +23,18 @@ static paddr_t DRM(dma_mmap)(dev_t kdev, vm_offset_t offset, int prot)
physical = dma->pagelist[page]; physical = dma->pagelist[page];
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical); DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", (long)offset, page, physical);
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = physical;
return 0;
#else
return atop(physical); return atop(physical);
#endif
} }
#ifdef __FreeBSD__ #if defined(__FreeBSD__) && __FreeBSD_version >= 500102
int DRM(mmap)(dev_t kdev, vm_offset_t offset, vm_offset_t *paddr,
int prot)
#elif defined(__FreeBSD__)
int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot) int DRM(mmap)(dev_t kdev, vm_offset_t offset, int prot)
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot) paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
@ -44,7 +58,11 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
if (dev->dma if (dev->dma
&& offset >= 0 && offset >= 0
&& offset < ptoa(dev->dma->page_count)) && offset < ptoa(dev->dma->page_count))
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
return DRM(dma_mmap)(kdev, offset, paddr, prot);
#else
return DRM(dma_mmap)(kdev, offset, prot); return DRM(dma_mmap)(kdev, offset, prot);
#endif
/* A sequential search of a linked list is /* A sequential search of a linked list is
fine here because: 1) there will only be fine here because: 1) there will only be
@ -73,10 +91,20 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
case _DRM_FRAME_BUFFER: case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS: case _DRM_REGISTERS:
case _DRM_AGP: case _DRM_AGP:
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = offset;
return 0;
#else
return atop(offset); return atop(offset);
#endif
case _DRM_SCATTER_GATHER: case _DRM_SCATTER_GATHER:
case _DRM_SHM: case _DRM_SHM:
#if defined(__FreeBSD__) && __FreeBSD_version >= 500102
*paddr = vtophys(offset);
return 0;
#else
return atop(vtophys(offset)); return atop(vtophys(offset));
#endif
default: default:
return -1; /* This should never happen. */ return -1; /* This should never happen. */
} }

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/mga_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "mga.h" #include "mga.h"

View file

@ -27,6 +27,8 @@
* Authors: * Authors:
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/r128_drv.c,v 1.4 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "r128.h" #include "r128.h"

View file

@ -25,6 +25,8 @@
* *
* Authors: * Authors:
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/radeon_drv.c,v 1.5 2003/03/11 01:38:17 anholt Exp $
*/ */
#include "radeon.h" #include "radeon.h"
@ -37,39 +39,41 @@
#endif #endif
drm_chipinfo_t DRM(devicelist)[] = { drm_chipinfo_t DRM(devicelist)[] = {
{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"}, {0x1002, 0x4242, 1, "ATI Radeon BB R200 AIW 8500DV"},
{0x1002, 0x4336, 1, "ATI Radeon Mobility"}, {0x1002, 0x4336, 1, "ATI Radeon Mobility U1"},
{0x1002, 0x4337, 1, "ATI Radeon IGP 340"}, {0x1002, 0x4964, 1, "ATI Radeon Id R250 9000"},
{0x1002, 0x4964, 1, "ATI Radeon Id 9000"}, {0x1002, 0x4965, 1, "ATI Radeon Ie R250 9000"},
{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"}, {0x1002, 0x4966, 1, "ATI Radeon If R250 9000"},
{0x1002, 0x4966, 1, "ATI Radeon If 9000"}, {0x1002, 0x4967, 1, "ATI Radeon Ig R250 9000"},
{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"}, {0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7500 M7"},
{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"}, {0x1002, 0x4C58, 1, "ATI Radeon LX RV200 Mobility FireGL 7800 M7"},
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"}, {0x1002, 0x4C59, 1, "ATI Radeon LY Mobility M6"},
{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"}, {0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility M6"},
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"}, {0x1002, 0x4C64, 1, "ATI Radeon Ld R250 Mobility 9000 M9"},
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"}, {0x1002, 0x4C65, 1, "ATI Radeon Le R250 Mobility 9000 M9"},
{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"}, {0x1002, 0x4C66, 1, "ATI Radeon Lf R250 Mobility 9000 M9"},
{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"}, {0x1002, 0x4C67, 1, "ATI Radeon Lg R250 Mobility 9000 M9"},
{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"}, {0x1002, 0x5144, 1, "ATI Radeon QD R100"},
{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"}, {0x1002, 0x5145, 1, "ATI Radeon QE R100"},
{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"}, {0x1002, 0x5146, 1, "ATI Radeon QF R100"},
{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"}, {0x1002, 0x5147, 1, "ATI Radeon QG R100"},
{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"}, {0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00"},
{0x1002, 0x5147, 1, "ATI Radeon QG R100 (AGP)"},
{0x1002, 0x5148, 1, "ATI Radeon QH FireGL 8x00 (AGP)"},
{0x1002, 0x5149, 1, "ATI Radeon QI R200"}, {0x1002, 0x5149, 1, "ATI Radeon QI R200"},
{0x1002, 0x514A, 1, "ATI Radeon QJ R200"}, {0x1002, 0x514A, 1, "ATI Radeon QJ R200"},
{0x1002, 0x514B, 1, "ATI Radeon QK R200"}, {0x1002, 0x514B, 1, "ATI Radeon QK R200"},
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"}, {0x1002, 0x514C, 1, "ATI Radeon QL R200 8500 LE"},
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"}, {0x1002, 0x514D, 1, "ATI Radeon QM R200 9100"},
{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"}, {0x1002, 0x514E, 1, "ATI Radeon QN R200 8500 LE"},
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"}, {0x1002, 0x514F, 1, "ATI Radeon QO R200 8500 LE"},
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"}, {0x1002, 0x5157, 1, "ATI Radeon QW RV200 7500"},
{0x1002, 0x5158, 1, "ATI Radeon QX RV200 7500"},
{0x1002, 0x5159, 1, "ATI Radeon QY RV100 VE"},
{0x1002, 0x515A, 1, "ATI Radeon QZ RV100 VE"},
{0x1002, 0x5168, 1, "ATI Radeon Qh R200"}, {0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
{0x1002, 0x5169, 1, "ATI Radeon Qi R200"}, {0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
{0x1002, 0x516A, 1, "ATI Radeon Qj R200"}, {0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
{0x1002, 0x516B, 1, "ATI Radeon Qk R200"}, {0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
{0x1002, 0x516C, 1, "ATI Radeon Ql R200"},
{0, 0, 0, NULL} {0, 0, 0, NULL}
}; };

View file

@ -28,6 +28,8 @@
* Rickard E. (Rik) Faith <faith@valinux.com> * Rickard E. (Rik) Faith <faith@valinux.com>
* Daryll Strauss <daryll@valinux.com> * Daryll Strauss <daryll@valinux.com>
* Gareth Hughes <gareth@valinux.com> * Gareth Hughes <gareth@valinux.com>
*
* $FreeBSD: src/sys/dev/drm/tdfx_drv.c,v 1.3 2003/03/09 02:08:28 anholt Exp $
*/ */
#include "tdfx.h" #include "tdfx.h"

View file

@ -27,7 +27,7 @@
* Authors: Rickard E. (Rik) Faith <faith@valinux.com> * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com> * Kevin E. Martin <martin@valinux.com>
* *
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.28 2002/10/16 01:26:49 dawes Exp $ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.31 2003/02/04 03:01:59 dawes Exp $
* *
*/ */

View file

@ -3,15 +3,15 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
O_TARGET := drm.o O_TARGET := drm.o
list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o
gamma-objs := gamma_drv.o gamma_dma.o gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o
i810-objs := i810_drv.o i810_dma.o i810-objs := i810_drv.o i810_dma.o
i830-objs := i830_drv.o i830_dma.o i830-objs := i830_drv.o i830_dma.o i830_irq.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o
ffb-objs := ffb_drv.o ffb_context.o ffb-objs := ffb_drv.o ffb_context.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o obj-$(CONFIG_DRM_GAMMA) += gamma.o

View file

@ -166,6 +166,12 @@
#define pte_unmap(pte) #define pte_unmap(pte)
#endif #endif
#ifndef list_for_each_safe
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr) static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{ {

View file

@ -268,7 +268,7 @@ drm_agp_head_t *DRM(agp_init)(void)
head->page_mask = head->agp_info.page_mask; head->page_mask = head->agp_info.page_mask;
#endif #endif
DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
head->agp_info.version.major, head->agp_info.version.major,
head->agp_info.version.minor, head->agp_info.version.minor,
head->agp_info.aper_base, head->agp_info.aper_base,

View file

@ -720,7 +720,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
list_del( (struct list_head *) vbl_sig ); list_del( (struct list_head *) vbl_sig );
DRM_FREE( vbl_sig ); DRM_FREE( vbl_sig, sizeof(*vbl_sig) );
dev->vbl_pending--; dev->vbl_pending--;
} }

View file

@ -766,9 +766,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
* Begin inline drm_release * Begin inline drm_release
*/ */
printk( "%s: pid = %d, device = 0x%x, open_count = %d\n", DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
__FUNCTION__, current->pid, (long)dev->device, dev->open_count );
current->pid, dev->device, dev->open_count );
printk( "%s: curently hw_lock %p is_held %d lock.filp %p filp %p\n", printk( "%s: curently hw_lock %p is_held %d lock.filp %p filp %p\n",
__FUNCTION__, __FUNCTION__,
@ -909,8 +908,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
++priv->ioctl_count; ++priv->ioctl_count;
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
current->pid, cmd, nr, dev->device, priv->authenticated ); current->pid, cmd, nr, (long)dev->device,
priv->authenticated );
if ( nr >= DRIVER_IOCTL_COUNT ) { if ( nr >= DRIVER_IOCTL_COUNT ) {
retcode = -EINVAL; retcode = -EINVAL;

View file

@ -92,6 +92,11 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
int DRM(flush)(struct file *filp) int DRM(flush)(struct file *filp)
{ {
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)dev->device, dev->open_count);
return 0; return 0;
} }
@ -101,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on)
drm_device_t *dev = priv->dev; drm_device_t *dev = priv->dev;
int retcode; int retcode;
DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
retcode = fasync_helper(fd, filp, on, &dev->buf_async); retcode = fasync_helper(fd, filp, on, &dev->buf_async);
if (retcode < 0) return retcode; if (retcode < 0) return retcode;
return 0; return 0;

View file

@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
return -EFAULT; return -EFAULT;
#ifdef __alpha__
{
int domain = p.busnum >> 8;
p.busnum &= 0xff;
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
dev;
dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) {
struct pci_controller *hose = dev->sysdata;
if (hose->index == domain) {
p.busnum += hose->bus->number;
break;
}
}
}
#endif
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
if (!dev) { if (!dev) {
DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
do { do {
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
int b, d, f; int domain, b, d, f;
char *p; char *p;
for(p = dev->unique; p && *p && *p != ':'; p++); for(p = dev->unique; p && *p && *p != ':'; p++);
@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
f = (int)simple_strtoul(p+1, &p, 10); f = (int)simple_strtoul(p+1, &p, 10);
if (*p) break; if (*p) break;
domain = b >> 8;
b &= 0xff;
#ifdef __alpha__
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
pci_dev;
pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) {
struct pci_controller *hose = pci_dev->sysdata;
if (hose->index == domain) {
b += hose->bus->number;
break;
}
}
#endif
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
if (pci_dev) { if (pci_dev) {
dev->pdev = pci_dev; dev->pdev = pci_dev;

View file

@ -43,7 +43,7 @@
/* malloc/free without the overhead of DRM(alloc) */ /* malloc/free without the overhead of DRM(alloc) */
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
#define DRM_FREE(x) kfree(x) #define DRM_FREE(x,size) kfree(x)
#define DRM_GETSAREA() \ #define DRM_GETSAREA() \
do { \ do { \

View file

@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
*eof = 0; *eof = 0;
if (dev->unique) { if (dev->unique) {
DRM_PROC_PRINT("%s 0x%x %s\n", DRM_PROC_PRINT("%s 0x%lx %s\n",
dev->name, dev->device, dev->unique); dev->name, (long)dev->device, dev->unique);
} else { } else {
DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
} }
if (len > request + offset) return request; if (len > request + offset) return request;

View file

@ -53,30 +53,10 @@
#define I810_BUF_UNMAPPED 0 #define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1 #define I810_BUF_MAPPED 1
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
#define down_write down
#define BEGIN_LP_RING(n) do { \ #define up_write up
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ #endif
if (dev_priv->ring.space < n*4) \
i810_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \
dev_priv->ring.tail = outring; \
I810_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
static inline void i810_print_status_page(drm_device_t *dev) static inline void i810_print_status_page(drm_device_t *dev)
{ {
@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write( &current->mm->mmap_sem ); down_write( &current->mm->mmap_sem );
#endif
old_fops = filp->f_op; old_fops = filp->f_op;
filp->f_op = &i810_buffer_fops; filp->f_op = &i810_buffer_fops;
dev_priv->mmap_buffer = buf; dev_priv->mmap_buffer = buf;
@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
filp->f_op = old_fops; filp->f_op = old_fops;
if ((unsigned long)buf_priv->virtual > -1024UL) { if ((unsigned long)buf_priv->virtual > -1024UL) {
/* Real error */ /* Real error */
DRM_DEBUG("mmap error\n"); DRM_ERROR("mmap error\n");
retcode = (signed int)buf_priv->virtual; retcode = (signed int)buf_priv->virtual;
buf_priv->virtual = 0; buf_priv->virtual = 0;
} }
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write( &current->mm->mmap_sem ); up_write( &current->mm->mmap_sem );
#endif
return retcode; return retcode;
} }
@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf)
if(buf_priv->currently_mapped != I810_BUF_MAPPED) if(buf_priv->currently_mapped != I810_BUF_MAPPED)
return -EINVAL; return -EINVAL;
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
#endif
retcode = DO_MUNMAP(current->mm, retcode = DO_MUNMAP(current->mm,
(unsigned long)buf_priv->virtual, (unsigned long)buf_priv->virtual,
(size_t) buf->total); (size_t) buf->total);
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
#endif
buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->currently_mapped = I810_BUF_UNMAPPED;
buf_priv->virtual = 0; buf_priv->virtual = 0;
@ -256,7 +223,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
retcode = i810_map_buffer(buf, filp); retcode = i810_map_buffer(buf, filp);
if(retcode) { if(retcode) {
i810_freelist_put(dev, buf); i810_freelist_put(dev, buf);
DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
return retcode; return retcode;
} }
buf->filp = filp; buf->filp = filp;
@ -320,7 +287,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
end = jiffies + (HZ*3); end = jiffies + (HZ*3);
iters++; iters++;
if((signed)(end - jiffies) <= 0) { if(time_before(end, jiffies)) {
DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("space: %d wanted %d\n", ring->space, n);
DRM_ERROR("lockup\n"); DRM_ERROR("lockup\n");
goto out_wait_ring; goto out_wait_ring;

View file

@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
#define I810_READ16(reg) I810_DEREF16(reg) #define I810_READ16(reg) I810_DEREF16(reg)
#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
#define I810_VERBOSE 0
#define RING_LOCALS unsigned int outring, ringmask; \
volatile char *virt;
#define BEGIN_LP_RING(n) do { \
if (I810_VERBOSE) \
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i810_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
dev_priv->ring.tail = outring; \
I810_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23))
#define BR00_BITBLT_CLIENT 0x40000000 #define BR00_BITBLT_CLIENT 0x40000000
#define BR00_OP_COLOR_BLT 0x10000000 #define BR00_OP_COLOR_BLT 0x10000000

View file

@ -38,6 +38,7 @@
#include "i830_drm.h" #include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */
#include <linux/delay.h> #include <linux/delay.h>
#ifdef DO_MUNMAP_4_ARGS #ifdef DO_MUNMAP_4_ARGS
@ -53,8 +54,6 @@
#define I830_BUF_UNMAPPED 0 #define I830_BUF_UNMAPPED 0
#define I830_BUF_MAPPED 1 #define I830_BUF_MAPPED 1
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
#define down_write down #define down_write down
#define up_write up #define up_write up
@ -67,32 +66,6 @@
#define UnlockPage(page) unlock_page(page) #define UnlockPage(page) unlock_page(page)
#endif #endif
#define I830_VERBOSE 0
#define BEGIN_LP_RING(n) do { \
if (I830_VERBOSE) \
printk("BEGIN_LP_RING(%d) in %s\n", \
n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i830_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
I830_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
static inline void i830_print_status_page(drm_device_t *dev) static inline void i830_print_status_page(drm_device_t *dev)
{ {
@ -251,7 +224,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
buf = i830_freelist_get(dev); buf = i830_freelist_get(dev);
if (!buf) { if (!buf) {
retcode = -ENOMEM; retcode = -ENOMEM;
DRM_ERROR("retcode=%d\n", retcode); DRM_DEBUG("retcode=%d\n", retcode);
return retcode; return retcode;
} }
@ -291,6 +264,15 @@ static int i830_dma_cleanup(drm_device_t *dev)
/* Need to rewrite hardware status page */ /* Need to rewrite hardware status page */
I830_WRITE(0x02080, 0x1ffff000); I830_WRITE(0x02080, 0x1ffff000);
} }
/* Disable interrupts here because after dev_private
* is freed, it's too late.
*/
if (dev->irq) {
I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
}
DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM(free)(dev->dev_private, sizeof(drm_i830_private_t),
DRM_MEM_DRIVER); DRM_MEM_DRIVER);
dev->dev_private = NULL; dev->dev_private = NULL;
@ -304,7 +286,7 @@ static int i830_dma_cleanup(drm_device_t *dev)
return 0; return 0;
} }
static int i830_wait_ring(drm_device_t *dev, int n) int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_ring_buffer_t *ring = &(dev_priv->ring); drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
@ -330,6 +312,7 @@ static int i830_wait_ring(drm_device_t *dev, int n)
goto out_wait_ring; goto out_wait_ring;
} }
udelay(1); udelay(1);
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
} }
out_wait_ring: out_wait_ring:
@ -345,6 +328,9 @@ static void i830_kernel_lost_context(drm_device_t *dev)
ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
ring->space = ring->head - (ring->tail+8); ring->space = ring->head - (ring->tail+8);
if (ring->space < 0) ring->space += ring->Size; if (ring->space < 0) ring->space += ring->Size;
if (ring->head == ring->tail)
dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
} }
static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
@ -459,6 +445,8 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->back_pitch = init->back_pitch; dev_priv->back_pitch = init->back_pitch;
dev_priv->depth_pitch = init->depth_pitch; dev_priv->depth_pitch = init->depth_pitch;
dev_priv->do_boxes = 0;
dev_priv->use_mi_batchbuffer_start = 0;
/* Program Hardware Status Page */ /* Program Hardware Status Page */
dev_priv->hw_status_page = dev_priv->hw_status_page =
@ -473,7 +461,7 @@ static int i830_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
I830_WRITE(0x02080, dev_priv->dma_status_page); I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
DRM_DEBUG("Enabled hardware status page\n"); DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */ /* Now we need to init our freelist */
@ -534,11 +522,7 @@ static void i830EmitContextVerified( drm_device_t *dev,
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 ); BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
OUT_RING( GFX_OP_STIPPLE );
OUT_RING( 0 );
for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -576,22 +560,25 @@ static void i830EmitContextVerified( drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
static void i830EmitTexVerified( drm_device_t *dev, static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code )
volatile unsigned int *code )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0; int i, j = 0;
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
(code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) ==
(STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
OUT_RING( GFX_OP_MAP_INFO ); OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
OUT_RING( code[I830_TEXREG_MI1] ); OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
OUT_RING( code[I830_TEXREG_MI2] ); OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
OUT_RING( code[I830_TEXREG_MI3] ); OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
OUT_RING( code[I830_TEXREG_MI4] ); OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
OUT_RING( code[I830_TEXREG_MI5] ); OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -604,10 +591,13 @@ static void i830EmitTexVerified( drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
else
printk("rejected packet %x\n", code[0]);
}
static void i830EmitTexBlendVerified( drm_device_t *dev, static void i830EmitTexBlendVerified( drm_device_t *dev,
volatile unsigned int *code, unsigned int *code,
volatile unsigned int num) unsigned int num)
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0; int i, j = 0;
@ -617,7 +607,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev,
if (!num) if (!num)
return; return;
BEGIN_LP_RING( num ); BEGIN_LP_RING( num + 1 );
for ( i = 0 ; i < num ; i++ ) { for ( i = 0 ; i < num ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -640,6 +630,8 @@ static void i830EmitTexPalette( drm_device_t *dev,
int i; int i;
RING_LOCALS; RING_LOCALS;
return;
BEGIN_LP_RING( 258 ); BEGIN_LP_RING( 258 );
if(is_shared == 1) { if(is_shared == 1) {
@ -653,42 +645,41 @@ static void i830EmitTexPalette( drm_device_t *dev,
OUT_RING(palette[i]); OUT_RING(palette[i]);
} }
OUT_RING(0); OUT_RING(0);
/* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
*/
} }
/* Need to do some additional checking when setting the dest buffer. /* Need to do some additional checking when setting the dest buffer.
*/ */
static void i830EmitDestVerified( drm_device_t *dev, static void i830EmitDestVerified( drm_device_t *dev,
volatile unsigned int *code ) unsigned int *code )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
tmp = code[I830_DESTREG_CBUFADDR]; tmp = code[I830_DESTREG_CBUFADDR];
if (tmp == dev_priv->front_di1) { if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
/* Don't use fence when front buffer rendering */ if (((int)outring) & 8) {
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING(0);
OUT_RING( BUF_3D_ID_COLOR_BACK | OUT_RING(0);
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); }
OUT_RING( tmp );
OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_DEPTH |
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
OUT_RING( dev_priv->zi1 );
} else if(tmp == dev_priv->back_di1) {
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_COLOR_BACK | OUT_RING( BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
BUF_3D_USE_FENCE); BUF_3D_USE_FENCE);
OUT_RING( tmp ); OUT_RING( tmp );
OUT_RING( 0 );
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
OUT_RING( dev_priv->zi1 ); OUT_RING( dev_priv->zi1 );
OUT_RING( 0 );
} else { } else {
DRM_ERROR("bad di1 %x (allow %x or %x)\n", DRM_ERROR("bad di1 %x (allow %x or %x)\n",
tmp, dev_priv->front_di1, dev_priv->back_di1); tmp, dev_priv->front_di1, dev_priv->back_di1);
@ -716,21 +707,35 @@ static void i830EmitDestVerified( drm_device_t *dev,
OUT_RING( 0 ); OUT_RING( 0 );
} }
OUT_RING( code[I830_DESTREG_SENABLE] );
OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( GFX_OP_SCISSOR_RECT );
OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR1] );
OUT_RING( code[I830_DESTREG_SR2] ); OUT_RING( code[I830_DESTREG_SR2] );
OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
static void i830EmitStippleVerified( drm_device_t *dev,
unsigned int *code )
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
BEGIN_LP_RING( 2 );
OUT_RING( GFX_OP_STIPPLE );
OUT_RING( code[1] );
ADVANCE_LP_RING();
}
static void i830EmitState( drm_device_t *dev ) static void i830EmitState( drm_device_t *dev )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty; unsigned int dirty = sarea_priv->dirty;
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
if (dirty & I830_UPLOAD_BUFFERS) { if (dirty & I830_UPLOAD_BUFFERS) {
i830EmitDestVerified( dev, sarea_priv->BufferState ); i830EmitDestVerified( dev, sarea_priv->BufferState );
sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
@ -774,7 +779,144 @@ static void i830EmitState( drm_device_t *dev )
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
} }
/* 1.3:
*/
#if 0
if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {
i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
} }
if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {
i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
}
#endif
}
/* 1.3:
*/
if (dirty & I830_UPLOAD_STIPPLE) {
i830EmitStippleVerified( dev,
sarea_priv->StippleState);
sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
}
if (dirty & I830_UPLOAD_TEX2) {
i830EmitTexVerified( dev, sarea_priv->TexState2 );
sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
}
if (dirty & I830_UPLOAD_TEX3) {
i830EmitTexVerified( dev, sarea_priv->TexState3 );
sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
}
if (dirty & I830_UPLOAD_TEXBLEND2) {
i830EmitTexBlendVerified(
dev,
sarea_priv->TexBlendState2,
sarea_priv->TexBlendStateWordsUsed2);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
}
if (dirty & I830_UPLOAD_TEXBLEND3) {
i830EmitTexBlendVerified(
dev,
sarea_priv->TexBlendState3,
sarea_priv->TexBlendStateWordsUsed3);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
}
}
/* ================================================================
* Performance monitoring functions
*/
static void i830_fill_box( drm_device_t *dev,
int x, int y, int w, int h,
int r, int g, int b )
{
drm_i830_private_t *dev_priv = dev->dev_private;
u32 color;
unsigned int BR13, CMD;
RING_LOCALS;
BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
x += dev_priv->sarea_priv->boxes[0].x1;
y += dev_priv->sarea_priv->boxes[0].y1;
if (dev_priv->cpp == 4) {
BR13 |= (1<<25);
CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
} else {
color = (((r & 0xf8) << 8) |
((g & 0xfc) << 3) |
((b & 0xf8) >> 3));
}
BEGIN_LP_RING( 6 );
OUT_RING( CMD );
OUT_RING( BR13 );
OUT_RING( (y << 16) | x );
OUT_RING( ((y+h) << 16) | (x+w) );
if ( dev_priv->current_page == 1 ) {
OUT_RING( dev_priv->front_offset );
} else {
OUT_RING( dev_priv->back_offset );
}
OUT_RING( color );
ADVANCE_LP_RING();
}
static void i830_cp_performance_boxes( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
/* Purple box for page flipping
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP )
i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
/* Red box if we have to wait for idle at any point
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT )
i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
/* Blue box: lost context?
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT )
i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
/* Yellow box for texture swaps
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD )
i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
/* Green box if hardware never idles (as far as we can tell)
*/
if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) )
i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
/* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
*/
if (dev_priv->dma_used) {
int bar = dev_priv->dma_used / 10240;
if (bar > 100) bar = 100;
if (bar < 1) bar = 1;
i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
dev_priv->dma_used = 0;
}
dev_priv->sarea_priv->perf_boxes = 0;
} }
static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
@ -792,6 +934,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
unsigned int BR13, CMD, D_CMD; unsigned int BR13, CMD, D_CMD;
RING_LOCALS; RING_LOCALS;
if ( dev_priv->current_page == 1 ) {
unsigned int tmp = flags;
flags &= ~(I830_FRONT | I830_BACK);
if ( tmp & I830_FRONT ) flags |= I830_BACK;
if ( tmp & I830_BACK ) flags |= I830_FRONT;
}
i830_kernel_lost_context(dev); i830_kernel_lost_context(dev);
switch(cpp) { switch(cpp) {
@ -871,13 +1022,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
drm_clip_rect_t *pbox = sarea_priv->boxes; drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch; int pitch = dev_priv->pitch;
int cpp = dev_priv->cpp; int cpp = dev_priv->cpp;
int ofs = dev_priv->back_offset;
int i; int i;
unsigned int CMD, BR13; unsigned int CMD, BR13;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG("swapbuffers\n"); DRM_DEBUG("swapbuffers\n");
i830_kernel_lost_context(dev);
if (dev_priv->do_boxes)
i830_cp_performance_boxes( dev );
switch(cpp) { switch(cpp) {
case 2: case 2:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
@ -894,7 +1049,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
break; break;
} }
i830_kernel_lost_context(dev);
if (nbox > I830_NR_SAREA_CLIPRECTS) if (nbox > I830_NR_SAREA_CLIPRECTS)
nbox = I830_NR_SAREA_CLIPRECTS; nbox = I830_NR_SAREA_CLIPRECTS;
@ -914,23 +1068,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
BEGIN_LP_RING( 8 ); BEGIN_LP_RING( 8 );
OUT_RING( CMD ); OUT_RING( CMD );
OUT_RING( BR13 ); OUT_RING( BR13 );
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
OUT_RING( (pbox->y2 << 16) | pbox->x2 );
OUT_RING( (pbox->y1 << 16) | if (dev_priv->current_page == 0)
pbox->x1 );
OUT_RING( (pbox->y2 << 16) |
pbox->x2 );
OUT_RING( dev_priv->front_offset ); OUT_RING( dev_priv->front_offset );
OUT_RING( (pbox->y1 << 16) | else
pbox->x1 ); OUT_RING( dev_priv->back_offset );
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
OUT_RING( BR13 & 0xffff ); OUT_RING( BR13 & 0xffff );
OUT_RING( ofs );
if (dev_priv->current_page == 0)
OUT_RING( dev_priv->back_offset );
else
OUT_RING( dev_priv->front_offset );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
} }
static void i830_dma_dispatch_flip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
__FUNCTION__,
dev_priv->current_page,
dev_priv->sarea_priv->pf_current_page);
i830_kernel_lost_context(dev);
if (dev_priv->do_boxes) {
dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
i830_cp_performance_boxes( dev );
}
BEGIN_LP_RING( 2 );
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
OUT_RING( 0 );
ADVANCE_LP_RING();
BEGIN_LP_RING( 6 );
OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );
OUT_RING( 0 );
if ( dev_priv->current_page == 0 ) {
OUT_RING( dev_priv->back_offset );
dev_priv->current_page = 1;
} else {
OUT_RING( dev_priv->front_offset );
dev_priv->current_page = 0;
}
OUT_RING(0);
ADVANCE_LP_RING();
BEGIN_LP_RING( 2 );
OUT_RING( MI_WAIT_FOR_EVENT |
MI_WAIT_FOR_PLANE_A_FLIP );
OUT_RING( 0 );
ADVANCE_LP_RING();
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
static void i830_dma_dispatch_vertex(drm_device_t *dev, static void i830_dma_dispatch_vertex(drm_device_t *dev,
drm_buf_t *buf, drm_buf_t *buf,
@ -983,8 +1186,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
sarea_priv->vertex_prim | sarea_priv->vertex_prim |
((used/4)-2)); ((used/4)-2));
if (dev_priv->use_mi_batchbuffer_start) {
vp[used/4] = MI_BATCH_BUFFER_END; vp[used/4] = MI_BATCH_BUFFER_END;
used += 4; used += 4;
}
if (used & 4) { if (used & 4) {
vp[used/4] = 0; vp[used/4] = 0;
@ -1007,10 +1212,20 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2); BEGIN_LP_RING(2);
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
OUT_RING( start | MI_BATCH_NON_SECURE ); OUT_RING( start | MI_BATCH_NON_SECURE );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
}
else {
BEGIN_LP_RING(4);
OUT_RING( MI_BATCH_BUFFER );
OUT_RING( start | MI_BATCH_NON_SECURE );
OUT_RING( start + used - 4 );
OUT_RING( 0 );
ADVANCE_LP_RING();
}
} while (++i < nbox); } while (++i < nbox);
} }
@ -1049,7 +1264,7 @@ void i830_dma_quiescent(drm_device_t *dev)
OUT_RING( 0 ); OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
i830_wait_ring( dev, dev_priv->ring.Size - 8 ); i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
} }
static int i830_flush_queue(drm_device_t *dev) static int i830_flush_queue(drm_device_t *dev)
@ -1066,7 +1281,7 @@ static int i830_flush_queue(drm_device_t *dev)
OUT_RING( 0 ); OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
i830_wait_ring( dev, dev_priv->ring.Size - 8 ); i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
for (i = 0; i < dma->buf_count; i++) { for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[ i ]; drm_buf_t *buf = dma->buflist[ i ];
@ -1208,6 +1423,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/* Not sure why this isn't set all the time:
*/
static void i830_do_init_pageflip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
int i830_do_cleanup_pageflip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if (dev_priv->current_page != 0)
i830_dma_dispatch_flip( dev );
dev_priv->page_flipping = 0;
return 0;
}
int i830_flip_bufs(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_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("i830_flip_buf called without lock held\n");
return -EINVAL;
}
if (!dev_priv->page_flipping)
i830_do_init_pageflip( dev );
i830_dma_dispatch_flip( dev );
return 0;
}
int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@ -1271,3 +1533,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
{ {
return 0; return 0;
} }
int i830_getparam( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_getparam_t param;
int value;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_getparam_t *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
case I830_PARAM_IRQ_ACTIVE:
value = dev->irq ? 1 : 0;
break;
default:
return -EINVAL;
}
if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
DRM_ERROR( "copy_to_user\n" );
return -EFAULT;
}
return 0;
}
int i830_setparam( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_setparam_t param;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_setparam_t *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
dev_priv->use_mi_batchbuffer_start = param.value;
break;
default:
return -EINVAL;
}
return 0;
}

View file

@ -3,6 +3,9 @@
/* WARNING: These defines must be the same as what the Xserver uses. /* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver. * if you change them, you must change the defines in the Xserver.
*
* KW: Actually, you can't ever change them because doing so would
* break backwards compatibility.
*/ */
#ifndef _I830_DEFINES_ #ifndef _I830_DEFINES_
@ -18,14 +21,12 @@
#define I830_NR_TEX_REGIONS 64 #define I830_NR_TEX_REGIONS 64
#define I830_LOG_MIN_TEX_REGION_SIZE 16 #define I830_LOG_MIN_TEX_REGION_SIZE 16
/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ /* KW: These aren't correct but someone set them to two and then
#if !defined(I830_ENABLE_4_TEXTURES) * released the module. Now we can't change them as doing so would
* break backwards compatibility.
*/
#define I830_TEXTURE_COUNT 2 #define I830_TEXTURE_COUNT 2
#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ #define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT
#else /* defined(I830_ENABLE_4_TEXTURES) */
#define I830_TEXTURE_COUNT 4
#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */
#endif /* I830_ENABLE_4_TEXTURES */
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
@ -57,6 +58,7 @@
#define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEXBLEND_MASK 0xf00000
#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
#define I830_UPLOAD_STIPPLE 0x8000000
/* Indices into buf.Setup where various bits of state are mirrored per /* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit, * context and per buffer. These can be fired at the card as a unit,
@ -73,7 +75,6 @@
*/ */
#define I830_DESTREG_CBUFADDR 0 #define I830_DESTREG_CBUFADDR 0
/* Invarient */
#define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DBUFADDR 1
#define I830_DESTREG_DV0 2 #define I830_DESTREG_DV0 2
#define I830_DESTREG_DV1 3 #define I830_DESTREG_DV1 3
@ -109,6 +110,13 @@
#define I830_CTXREG_MCSB1 16 #define I830_CTXREG_MCSB1 16
#define I830_CTX_SETUP_SIZE 17 #define I830_CTX_SETUP_SIZE 17
/* 1.3: Stipple state
*/
#define I830_STPREG_ST0 0
#define I830_STPREG_ST1 1
#define I830_STP_SETUP_SIZE 2
/* Texture state (per tex unit) /* Texture state (per tex unit)
*/ */
@ -124,6 +132,18 @@
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
#define I830_TEX_SETUP_SIZE 10 #define I830_TEX_SETUP_SIZE 10
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
#define I830_TEXREG_TM0S0 1
#define I830_TEXREG_TM0S1 2
#define I830_TEXREG_TM0S2 3
#define I830_TEXREG_TM0S3 4
#define I830_TEXREG_TM0S4 5
#define I830_TEXREG_NOP0 6 /* noop */
#define I830_TEXREG_NOP1 7 /* noop */
#define I830_TEXREG_NOP2 8 /* noop */
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
#define __I830_TEX_SETUP_SIZE 10
#define I830_FRONT 0x1 #define I830_FRONT 0x1
#define I830_BACK 0x2 #define I830_BACK 0x2
#define I830_DEPTH 0x4 #define I830_DEPTH 0x4
@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea {
int ctxOwner; /* last context to upload state */ int ctxOwner; /* last context to upload state */
int vertex_prim; int vertex_prim;
int pf_enabled; /* is pageflipping allowed? */
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
/* Here's the state for texunits 2,3:
*/
unsigned int TexState2[I830_TEX_SETUP_SIZE];
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
unsigned int TexBlendStateWordsUsed2;
unsigned int TexState3[I830_TEX_SETUP_SIZE];
unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
unsigned int TexBlendStateWordsUsed3;
unsigned int StippleState[I830_STP_SETUP_SIZE];
} drm_i830_sarea_t; } drm_i830_sarea_t;
/* Flags for perf_boxes
*/
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
#define I830_BOX_FLIP 0x2 /* populated by kernel */
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
/* I830 specific ioctls /* I830 specific ioctls
* The device specific ioctl range is 0x40 to 0x79. * The device specific ioctl range is 0x40 to 0x79.
*/ */
@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea {
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) #define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) #define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) #define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49)
#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t)
#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t)
#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t)
#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t)
typedef struct _drm_i830_clear { typedef struct _drm_i830_clear {
int clear_color; int clear_color;
@ -248,4 +300,36 @@ typedef struct drm_i830_dma {
int granted; int granted;
} drm_i830_dma_t; } drm_i830_dma_t;
/* 1.3: Userspace can request & wait on irq's:
*/
typedef struct drm_i830_irq_emit {
int *irq_seq;
} drm_i830_irq_emit_t;
typedef struct drm_i830_irq_wait {
int irq_seq;
} drm_i830_irq_wait_t;
/* 1.3: New ioctl to query kernel params:
*/
#define I830_PARAM_IRQ_ACTIVE 1
typedef struct drm_i830_getparam {
int param;
int *value;
} drm_i830_getparam_t;
/* 1.3: New ioctl to set kernel params:
*/
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
typedef struct drm_i830_setparam {
int param;
int value;
} drm_i830_setparam_t;
#endif /* _I830_DRM_H_ */ #endif /* _I830_DRM_H_ */

View file

@ -78,6 +78,19 @@ typedef struct drm_i830_private {
int back_pitch; int back_pitch;
int depth_pitch; int depth_pitch;
unsigned int cpp; unsigned int cpp;
int do_boxes;
int dma_used;
int current_page;
int page_flipping;
wait_queue_head_t irq_queue;
atomic_t irq_received;
atomic_t irq_emitted;
int use_mi_batchbuffer_start;
} drm_i830_private_t; } drm_i830_private_t;
/* i830_dma.c */ /* i830_dma.c */
@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
extern int i830_clear_bufs(struct inode *inode, struct file *filp, extern int i830_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern int i830_flip_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i830_getparam( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_setparam( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* i830_irq.c */
extern int i830_irq_emit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_irq_wait( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_wait_irq(drm_device_t *dev, int irq_nr);
extern int i830_emit_irq(drm_device_t *dev);
#define I830_BASE(reg) ((unsigned long) \ #define I830_BASE(reg) ((unsigned long) \
dev_priv->mmio_map->handle) dev_priv->mmio_map->handle)
@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define I830_READ16(reg) I830_DEREF16(reg) #define I830_READ16(reg) I830_DEREF16(reg)
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
#define I830_VERBOSE 0
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
volatile char *virt;
#define BEGIN_LP_RING(n) do { \
if (I830_VERBOSE) \
printk("BEGIN_LP_RING(%d) in %s\n", \
n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i830_wait_ring(dev, n*4, __FUNCTION__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define OUT_RING(n) do { \
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outcount++; \
outring += 4; \
outring &= ringmask; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
dev_priv->ring.space -= outcount * 4; \
I830_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
#define CMD_REPORT_HEAD (7<<23) #define CMD_REPORT_HEAD (7<<23)
#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
#define LOAD_TEXTURE_MAP0 (1<<11)
#define INST_PARSER_CLIENT 0x00000000 #define INST_PARSER_CLIENT 0x00000000
#define INST_OP_FLUSH 0x02000000 #define INST_OP_FLUSH 0x02000000
#define INST_FLUSH_MAP_CACHE 0x00000001 #define INST_FLUSH_MAP_CACHE 0x00000001
@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_MASK_R 0x020a8
#define I830REG_INT_ENABLE_R 0x020a0 #define I830REG_INT_ENABLE_R 0x020a0
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
#define LP_RING 0x2030 #define LP_RING 0x2030
#define HP_RING 0x2040 #define HP_RING 0x2040
#define RING_TAIL 0x00 #define RING_TAIL 0x00
@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
#define ASYNC_FLIP (1<<22)
#define CMD_3D (0x3<<29) #define CMD_3D (0x3<<29)
#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) #define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE (1)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
#endif #endif

178
linux-core/i830_irq.c Normal file
View file

@ -0,0 +1,178 @@
/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
*
* Copyright 2002 Tungsten Graphics, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Keith Whitwell <keith@tungstengraphics.com>
*
*/
#define __NO_VERSION__
#include "i830.h"
#include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
void DRM(dma_service)(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
u16 temp;
temp = I830_READ16(I830REG_INT_IDENTITY_R);
printk("%s: %x\n", __FUNCTION__, temp);
if(temp == 0)
return;
I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
if (temp & 2) {
atomic_inc(&dev_priv->irq_received);
wake_up_interruptible(&dev_priv->irq_queue);
}
}
int i830_emit_irq(drm_device_t *dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG("%s\n", __FUNCTION__);
atomic_inc(&dev_priv->irq_emitted);
BEGIN_LP_RING(2);
OUT_RING( 0 );
OUT_RING( GFX_OP_USER_INTERRUPT );
ADVANCE_LP_RING();
return atomic_read(&dev_priv->irq_emitted);
}
int i830_wait_irq(drm_device_t *dev, int irq_nr)
{
drm_i830_private_t *dev_priv =
(drm_i830_private_t *)dev->dev_private;
DECLARE_WAITQUEUE(entry, current);
unsigned long end = jiffies + HZ*3;
int ret = 0;
DRM_DEBUG("%s\n", __FUNCTION__);
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
return 0;
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
add_wait_queue(&dev_priv->irq_queue, &entry);
for (;;) {
current->state = TASK_INTERRUPTIBLE;
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
break;
if((signed)(end - jiffies) <= 0) {
DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
I830_READ16( I830REG_INT_IDENTITY_R ),
I830_READ16( I830REG_INT_MASK_R ),
I830_READ16( I830REG_INT_ENABLE_R ),
I830_READ16( I830REG_HWSTAM ));
ret = -EBUSY; /* Lockup? Missed irq? */
break;
}
schedule_timeout(HZ*3);
if (signal_pending(current)) {
ret = -EINTR;
break;
}
}
current->state = TASK_RUNNING;
remove_wait_queue(&dev_priv->irq_queue, &entry);
return ret;
}
/* Needs the lock as it touches the ring.
*/
int i830_irq_emit( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_emit_t emit;
int result;
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("i830_irq_emit called without lock held\n");
return -EINVAL;
}
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) ))
return -EFAULT;
result = i830_emit_irq( dev );
if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
DRM_ERROR( "copy_to_user\n" );
return -EFAULT;
}
return 0;
}
/* Doesn't need the hardware lock.
*/
int i830_irq_wait( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_wait_t irqwait;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg,
sizeof(irqwait) ))
return -EFAULT;
return i830_wait_irq( dev, irqwait.irq_seq );
}

View file

@ -3,15 +3,15 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
O_TARGET := drm.o O_TARGET := drm.o
list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o ffb.o radeon.o list-multi := gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o
gamma-objs := gamma_drv.o gamma_dma.o gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128-objs := r128_drv.o r128_cce.o r128_irq.o r128_state.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga-objs := mga_drv.o mga_dma.o mga_irq.o mga_state.o mga_warp.o
i810-objs := i810_drv.o i810_dma.o i810-objs := i810_drv.o i810_dma.o
i830-objs := i830_drv.o i830_dma.o i830-objs := i830_drv.o i830_dma.o i830_irq.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon-objs := radeon_drv.o radeon_cp.o radeon_irq.o radeon_mem.o radeon_state.o
ffb-objs := ffb_drv.o ffb_context.o ffb-objs := ffb_drv.o ffb_context.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o obj-$(CONFIG_DRM_GAMMA) += gamma.o

View file

@ -32,6 +32,8 @@
# make TREE=/usr/my-kernel-tree/include # make TREE=/usr/my-kernel-tree/include
# #
SHELL=/bin/sh
.SUFFIXES: .SUFFIXES:
# *** Setup # *** Setup
@ -44,7 +46,8 @@ LIBS =
DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \ DRMTEMPLATES = drm_auth.h drm_bufs.h drm_context.h drm_dma.h drm_drawable.h \
drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \ drm_drv.h drm_fops.h drm_init.h drm_ioctl.h drm_lists.h \
drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h drm_lock.h drm_memory.h drm_proc.h drm_stub.h drm_vm.h
DRMHEADERS = drm.h drmP.h drm_sarea.h DRMSHARED = drm_sarea.h
DRMHEADERS = drm.h drmP.h $(DRMSHARED)
GAMMAOBJS = gamma_drv.o gamma_dma.o GAMMAOBJS = gamma_drv.o gamma_dma.o
GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
@ -54,10 +57,14 @@ TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES)
R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o R128OBJS = r128_drv.o r128_cce.o r128_state.o r128_irq.o
R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
R128SHARED = r128.h r128_drv.h r128_drm.h r128_cce.c r128_state.c r128_irq.c
RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o RADEONOBJS = radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
radeon_irq.o
RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \ RADEONHEADERS = radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
$(DRMTEMPLATES) $(DRMTEMPLATES)
RADEONSHARED = radeon.h radeon_drv.h radeon_drm.h radeon_cp.c radeon_irq.c \
radeon_mem.c radeon_state.c
INC = /usr/include INC = /usr/include
@ -160,11 +167,13 @@ endif
MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o MGAOBJS = mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES) MGAHEADERS = mga.h mga_drv.h mga_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
MGASHARED = mga.h mga_dma.c mga_drm.h mga_drv.h mga_state.c \
mga_ucode.h mga_warp.c
I810OBJS = i810_drv.o i810_dma.o I810OBJS = i810_drv.o i810_dma.o
I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES) I810HEADERS = i810.h i810_drv.h i810_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
I830OBJS = i830_drv.o i830_dma.o I830OBJS = i830_drv.o i830_dma.o i830_irq.o
I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES) I830HEADERS = i830.h i830_drv.h i830_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
endif endif
@ -172,6 +181,10 @@ endif
ifeq ($(MACHINE),alpha) ifeq ($(MACHINE),alpha)
MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6 MODCFLAGS+= -ffixed-8 -mno-fp-regs -mcpu=ev56 -Wa,-mev6
endif endif
ifeq ($(MACHINE),x86_64)
MODCFLAGS+= -mcmodel=kernel
endif
MODS += sis.o MODS += sis.o
@ -208,6 +221,15 @@ endif
# **** End of configuration # **** End of configuration
# Link in shared headers if needed
SHAREDSRC = $(DRMSHARED) $(MGASHARED) $(R128SHARED) $(RADEONSHARED)
SHAREDDIR = ../../../shared/drm/kernel
$(SHAREDSRC):
@if [ ! -r $@ ]; then (rm -f $@; set -x; ln -s $(SHAREDDIR)/$@ .); fi
dristat: dristat.c dristat: dristat.c
$(CC) $(PRGCFLAGS) $< -o $@ $(CC) $(PRGCFLAGS) $< -o $@
@ -280,3 +302,7 @@ endif
clean cleandir:: clean cleandir::
rm -f *.o *.a *~ core rm -f *.o *.a *~ core
@for i in $(SHAREDSRC); do \
if [ -L $$i ]; then (set -x; rm -f $$i); fi; \
done

View file

@ -166,6 +166,12 @@
#define pte_unmap(pte) #define pte_unmap(pte)
#endif #endif
#ifndef list_for_each_safe
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr) static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{ {

View file

@ -268,7 +268,7 @@ drm_agp_head_t *DRM(agp_init)(void)
head->page_mask = head->agp_info.page_mask; head->page_mask = head->agp_info.page_mask;
#endif #endif
DRM_DEBUG("AGP %d.%d, aperture @ 0x%08lx %ZuMB\n", DRM_INFO("AGP %d.%d aperture @ 0x%08lx %ZuMB\n",
head->agp_info.version.major, head->agp_info.version.major,
head->agp_info.version.minor, head->agp_info.version.minor,
head->agp_info.aper_base, head->agp_info.aper_base,

View file

@ -720,7 +720,7 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
list_del( (struct list_head *) vbl_sig ); list_del( (struct list_head *) vbl_sig );
DRM_FREE( vbl_sig ); DRM_FREE( vbl_sig, sizeof(*vbl_sig) );
dev->vbl_pending--; dev->vbl_pending--;
} }

View file

@ -766,9 +766,8 @@ int DRM(release)( struct inode *inode, struct file *filp )
* Begin inline drm_release * Begin inline drm_release
*/ */
printk( "%s: pid = %d, device = 0x%x, open_count = %d\n", DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
__FUNCTION__, current->pid, (long)dev->device, dev->open_count );
current->pid, dev->device, dev->open_count );
printk( "%s: curently hw_lock %p is_held %d lock.filp %p filp %p\n", printk( "%s: curently hw_lock %p is_held %d lock.filp %p filp %p\n",
__FUNCTION__, __FUNCTION__,
@ -909,8 +908,9 @@ int DRM(ioctl)( struct inode *inode, struct file *filp,
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] ); atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
++priv->ioctl_count; ++priv->ioctl_count;
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n", DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
current->pid, cmd, nr, dev->device, priv->authenticated ); current->pid, cmd, nr, (long)dev->device,
priv->authenticated );
if ( nr >= DRIVER_IOCTL_COUNT ) { if ( nr >= DRIVER_IOCTL_COUNT ) {
retcode = -EINVAL; retcode = -EINVAL;

View file

@ -92,6 +92,11 @@ int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
int DRM(flush)(struct file *filp) int DRM(flush)(struct file *filp)
{ {
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)dev->device, dev->open_count);
return 0; return 0;
} }
@ -101,7 +106,7 @@ int DRM(fasync)(int fd, struct file *filp, int on)
drm_device_t *dev = priv->dev; drm_device_t *dev = priv->dev;
int retcode; int retcode;
DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device); DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)dev->device);
retcode = fasync_helper(fd, filp, on, &dev->buf_async); retcode = fasync_helper(fd, filp, on, &dev->buf_async);
if (retcode < 0) return retcode; if (retcode < 0) return retcode;
return 0; return 0;

View file

@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp,
if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
return -EFAULT; return -EFAULT;
#ifdef __alpha__
{
int domain = p.busnum >> 8;
p.busnum &= 0xff;
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
dev;
dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) {
struct pci_controller *hose = dev->sysdata;
if (hose->index == domain) {
p.busnum += hose->bus->number;
break;
}
}
}
#endif
dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
if (!dev) { if (!dev) {
DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", DRM_ERROR("pci_find_slot failed for %d:%d:%d\n",
@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
do { do {
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
int b, d, f; int domain, b, d, f;
char *p; char *p;
for(p = dev->unique; p && *p && *p != ':'; p++); for(p = dev->unique; p && *p && *p != ':'; p++);
@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
f = (int)simple_strtoul(p+1, &p, 10); f = (int)simple_strtoul(p+1, &p, 10);
if (*p) break; if (*p) break;
domain = b >> 8;
b &= 0xff;
#ifdef __alpha__
/*
* Find the hose the device is on (the domain number is the
* hose index) and offset the bus by the root bus of that
* hose.
*/
for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL);
pci_dev;
pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) {
struct pci_controller *hose = pci_dev->sysdata;
if (hose->index == domain) {
b += hose->bus->number;
break;
}
}
#endif
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
if (pci_dev) { if (pci_dev) {
dev->pdev = pci_dev; dev->pdev = pci_dev;

View file

@ -43,7 +43,7 @@
/* malloc/free without the overhead of DRM(alloc) */ /* malloc/free without the overhead of DRM(alloc) */
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL) #define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
#define DRM_FREE(x) kfree(x) #define DRM_FREE(x,size) kfree(x)
#define DRM_GETSAREA() \ #define DRM_GETSAREA() \
do { \ do { \

View file

@ -148,10 +148,10 @@ static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
*eof = 0; *eof = 0;
if (dev->unique) { if (dev->unique) {
DRM_PROC_PRINT("%s 0x%x %s\n", DRM_PROC_PRINT("%s 0x%lx %s\n",
dev->name, dev->device, dev->unique); dev->name, (long)dev->device, dev->unique);
} else { } else {
DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device); DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
} }
if (len > request + offset) return request; if (len > request + offset) return request;

View file

@ -524,11 +524,11 @@ static int gamma_dma_send_buffers(struct file *filp,
} }
} }
if (retcode) { if (retcode) {
DRM_ERROR("ctx%d w%d p%d c%d i%d l%d pid:%d\n", DRM_ERROR("ctx%d w%d p%d c%ld i%d l%d pid:%d\n",
d->context, d->context,
last_buf->waiting, last_buf->waiting,
last_buf->pending, last_buf->pending,
DRM_WAITCOUNT(dev, d->context), (long)DRM_WAITCOUNT(dev, d->context),
last_buf->idx, last_buf->idx,
last_buf->list, last_buf->list,
current->pid); current->pid);
@ -593,7 +593,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init )
drm_buf_t *buf; drm_buf_t *buf;
int i; int i;
struct list_head *list; struct list_head *list;
unsigned int *pgt; unsigned long *pgt;
DRM_DEBUG( "%s\n", __FUNCTION__ ); DRM_DEBUG( "%s\n", __FUNCTION__ );
@ -646,7 +646,7 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init )
for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) { for (i = 0; i < GLINT_DRI_BUF_COUNT; i++) {
buf = dma->buflist[i]; buf = dma->buflist[i];
*pgt = (unsigned int)buf->address + 0x07; *pgt = (unsigned long)buf->address + 0x07;
pgt++; pgt++;
} }

View file

@ -53,30 +53,10 @@
#define I810_BUF_UNMAPPED 0 #define I810_BUF_UNMAPPED 0
#define I810_BUF_MAPPED 1 #define I810_BUF_MAPPED 1
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
#define down_write down
#define BEGIN_LP_RING(n) do { \ #define up_write up
if (0) DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \ #endif
if (dev_priv->ring.space < n*4) \
i810_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (0) DRM_DEBUG("ADVANCE_LP_RING\n"); \
dev_priv->ring.tail = outring; \
I810_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (0) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
static inline void i810_print_status_page(drm_device_t *dev) static inline void i810_print_status_page(drm_device_t *dev)
{ {
@ -185,11 +165,7 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write( &current->mm->mmap_sem ); down_write( &current->mm->mmap_sem );
#endif
old_fops = filp->f_op; old_fops = filp->f_op;
filp->f_op = &i810_buffer_fops; filp->f_op = &i810_buffer_fops;
dev_priv->mmap_buffer = buf; dev_priv->mmap_buffer = buf;
@ -201,15 +177,12 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
filp->f_op = old_fops; filp->f_op = old_fops;
if ((unsigned long)buf_priv->virtual > -1024UL) { if ((unsigned long)buf_priv->virtual > -1024UL) {
/* Real error */ /* Real error */
DRM_DEBUG("mmap error\n"); DRM_ERROR("mmap error\n");
retcode = (signed int)buf_priv->virtual; retcode = (signed int)buf_priv->virtual;
buf_priv->virtual = 0; buf_priv->virtual = 0;
} }
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write( &current->mm->mmap_sem ); up_write( &current->mm->mmap_sem );
#endif
return retcode; return retcode;
} }
@ -220,19 +193,13 @@ static int i810_unmap_buffer(drm_buf_t *buf)
if(buf_priv->currently_mapped != I810_BUF_MAPPED) if(buf_priv->currently_mapped != I810_BUF_MAPPED)
return -EINVAL; return -EINVAL;
#if LINUX_VERSION_CODE <= 0x020402
down( &current->mm->mmap_sem );
#else
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
#endif
retcode = DO_MUNMAP(current->mm, retcode = DO_MUNMAP(current->mm,
(unsigned long)buf_priv->virtual, (unsigned long)buf_priv->virtual,
(size_t) buf->total); (size_t) buf->total);
#if LINUX_VERSION_CODE <= 0x020402
up( &current->mm->mmap_sem );
#else
up_write(&current->mm->mmap_sem); up_write(&current->mm->mmap_sem);
#endif
buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->currently_mapped = I810_BUF_UNMAPPED;
buf_priv->virtual = 0; buf_priv->virtual = 0;
@ -256,7 +223,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
retcode = i810_map_buffer(buf, filp); retcode = i810_map_buffer(buf, filp);
if(retcode) { if(retcode) {
i810_freelist_put(dev, buf); i810_freelist_put(dev, buf);
DRM_DEBUG("mapbuf failed, retcode %d\n", retcode); DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
return retcode; return retcode;
} }
buf->filp = filp; buf->filp = filp;
@ -320,7 +287,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
end = jiffies + (HZ*3); end = jiffies + (HZ*3);
iters++; iters++;
if((signed)(end - jiffies) <= 0) { if(time_before(end, jiffies)) {
DRM_ERROR("space: %d wanted %d\n", ring->space, n); DRM_ERROR("space: %d wanted %d\n", ring->space, n);
DRM_ERROR("lockup\n"); DRM_ERROR("lockup\n");
goto out_wait_ring; goto out_wait_ring;

View file

@ -136,6 +136,33 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
#define I810_READ16(reg) I810_DEREF16(reg) #define I810_READ16(reg) I810_DEREF16(reg)
#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0) #define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
#define I810_VERBOSE 0
#define RING_LOCALS unsigned int outring, ringmask; \
volatile char *virt;
#define BEGIN_LP_RING(n) do { \
if (I810_VERBOSE) \
DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i810_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
dev_priv->ring.tail = outring; \
I810_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
@ -198,6 +225,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) #define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) #define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23))
#define BR00_BITBLT_CLIENT 0x40000000 #define BR00_BITBLT_CLIENT 0x40000000
#define BR00_OP_COLOR_BLT 0x10000000 #define BR00_OP_COLOR_BLT 0x10000000

View file

@ -45,11 +45,21 @@
#define DRIVER_NAME "i830" #define DRIVER_NAME "i830"
#define DRIVER_DESC "Intel 830M" #define DRIVER_DESC "Intel 830M"
#define DRIVER_DATE "20020828" #define DRIVER_DATE "20021108"
/* Interface history:
*
* 1.1: Original.
* 1.2: ?
* 1.3: New irq emit/wait ioctls.
* New pageflip ioctl.
* New getparam ioctl.
* State for texunits 3&4 in sarea.
* New (alternative) layout for texture state.
*/
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 2 #define DRIVER_MINOR 3
#define DRIVER_PATCHLEVEL 1 #define DRIVER_PATCHLEVEL 2
#define DRIVER_IOCTLS \ #define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)] = { i830_dma_init, 1, 1 }, \
@ -60,7 +70,12 @@
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)] = { i830_swap_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)] = { i830_copybuf, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_FLIP)] = { i830_flip_bufs, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_EMIT)] = { i830_irq_emit, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_IRQ_WAIT)] = { i830_irq_wait, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_GETPARAM)] = { i830_getparam, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_I830_SETPARAM)] = { i830_setparam, 1, 0 }
#define __HAVE_COUNTERS 4 #define __HAVE_COUNTERS 4
#define __HAVE_COUNTER6 _DRM_STAT_IRQ #define __HAVE_COUNTER6 _DRM_STAT_IRQ
@ -87,10 +102,49 @@
i830_dma_quiescent( dev ); \ i830_dma_quiescent( dev ); \
} while (0) } while (0)
/* Don't need an irq any more. The template code will make sure that
* a noop stub is generated for compatibility. /* Driver will work either way: IRQ's save cpu time when waiting for
* the card, but are subject to subtle interactions between bios,
* hardware and the driver.
*/ */
#define USE_IRQS 0
#if USE_IRQS
#define __HAVE_DMA_IRQ 1
#define __HAVE_SHARED_IRQ 1
#define DRIVER_PREINSTALL() do { \
drm_i830_private_t *dev_priv = \
(drm_i830_private_t *)dev->dev_private; \
\
I830_WRITE16( I830REG_HWSTAM, 0xffff ); \
I830_WRITE16( I830REG_INT_MASK_R, 0x0 ); \
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 ); \
} while (0)
#define DRIVER_POSTINSTALL() do { \
drm_i830_private_t *dev_priv = \
(drm_i830_private_t *)dev->dev_private; \
I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 ); \
atomic_set(&dev_priv->irq_received, 0); \
atomic_set(&dev_priv->irq_emitted, 0); \
init_waitqueue_head(&dev_priv->irq_queue); \
} while (0)
/* This gets called too late to be useful: dev_priv has already been
* freed.
*/
#define DRIVER_UNINSTALL() do { \
} while (0)
#else
#define __HAVE_DMA_IRQ 0 #define __HAVE_DMA_IRQ 0
#endif
/* Buffer customization: /* Buffer customization:
*/ */

View file

@ -38,6 +38,7 @@
#include "i830_drm.h" #include "i830_drm.h"
#include "i830_drv.h" #include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */ #include <linux/interrupt.h> /* For task queue support */
#include <linux/pagemap.h> /* For FASTCALL on unlock_page() */
#include <linux/delay.h> #include <linux/delay.h>
#ifdef DO_MUNMAP_4_ARGS #ifdef DO_MUNMAP_4_ARGS
@ -53,8 +54,6 @@
#define I830_BUF_UNMAPPED 0 #define I830_BUF_UNMAPPED 0
#define I830_BUF_MAPPED 1 #define I830_BUF_MAPPED 1
#define RING_LOCALS unsigned int outring, ringmask; volatile char *virt;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,2)
#define down_write down #define down_write down
#define up_write up #define up_write up
@ -67,32 +66,6 @@
#define UnlockPage(page) unlock_page(page) #define UnlockPage(page) unlock_page(page)
#endif #endif
#define I830_VERBOSE 0
#define BEGIN_LP_RING(n) do { \
if (I830_VERBOSE) \
printk("BEGIN_LP_RING(%d) in %s\n", \
n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i830_wait_ring(dev, n*4); \
dev_priv->ring.space -= n*4; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
I830_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
#define OUT_RING(n) do { \
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
} while (0)
static inline void i830_print_status_page(drm_device_t *dev) static inline void i830_print_status_page(drm_device_t *dev)
{ {
@ -251,7 +224,7 @@ static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d,
buf = i830_freelist_get(dev); buf = i830_freelist_get(dev);
if (!buf) { if (!buf) {
retcode = -ENOMEM; retcode = -ENOMEM;
DRM_ERROR("retcode=%d\n", retcode); DRM_DEBUG("retcode=%d\n", retcode);
return retcode; return retcode;
} }
@ -291,6 +264,15 @@ static int i830_dma_cleanup(drm_device_t *dev)
/* Need to rewrite hardware status page */ /* Need to rewrite hardware status page */
I830_WRITE(0x02080, 0x1ffff000); I830_WRITE(0x02080, 0x1ffff000);
} }
/* Disable interrupts here because after dev_private
* is freed, it's too late.
*/
if (dev->irq) {
I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
}
DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), DRM(free)(dev->dev_private, sizeof(drm_i830_private_t),
DRM_MEM_DRIVER); DRM_MEM_DRIVER);
dev->dev_private = NULL; dev->dev_private = NULL;
@ -304,7 +286,7 @@ static int i830_dma_cleanup(drm_device_t *dev)
return 0; return 0;
} }
static int i830_wait_ring(drm_device_t *dev, int n) int i830_wait_ring(drm_device_t *dev, int n, const char *caller)
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_ring_buffer_t *ring = &(dev_priv->ring); drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
@ -330,6 +312,7 @@ static int i830_wait_ring(drm_device_t *dev, int n)
goto out_wait_ring; goto out_wait_ring;
} }
udelay(1); udelay(1);
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
} }
out_wait_ring: out_wait_ring:
@ -345,6 +328,9 @@ static void i830_kernel_lost_context(drm_device_t *dev)
ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR; ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
ring->space = ring->head - (ring->tail+8); ring->space = ring->head - (ring->tail+8);
if (ring->space < 0) ring->space += ring->Size; if (ring->space < 0) ring->space += ring->Size;
if (ring->head == ring->tail)
dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
} }
static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv) static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
@ -459,6 +445,8 @@ static int i830_dma_initialize(drm_device_t *dev,
dev_priv->back_pitch = init->back_pitch; dev_priv->back_pitch = init->back_pitch;
dev_priv->depth_pitch = init->depth_pitch; dev_priv->depth_pitch = init->depth_pitch;
dev_priv->do_boxes = 0;
dev_priv->use_mi_batchbuffer_start = 0;
/* Program Hardware Status Page */ /* Program Hardware Status Page */
dev_priv->hw_status_page = dev_priv->hw_status_page =
@ -473,7 +461,7 @@ static int i830_dma_initialize(drm_device_t *dev,
memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE); memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page); DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
I830_WRITE(0x02080, dev_priv->dma_status_page); I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
DRM_DEBUG("Enabled hardware status page\n"); DRM_DEBUG("Enabled hardware status page\n");
/* Now we need to init our freelist */ /* Now we need to init our freelist */
@ -534,11 +522,7 @@ static void i830EmitContextVerified( drm_device_t *dev,
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 2 ); BEGIN_LP_RING( I830_CTX_SETUP_SIZE + 4 );
OUT_RING( GFX_OP_STIPPLE );
OUT_RING( 0 );
for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) { for ( i = 0 ; i < I830_CTXREG_BLENDCOLR0 ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -576,22 +560,25 @@ static void i830EmitContextVerified( drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
static void i830EmitTexVerified( drm_device_t *dev, static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code )
volatile unsigned int *code )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0; int i, j = 0;
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
(code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) ==
(STATE3D_LOAD_STATE_IMMEDIATE_2|4)) {
BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
OUT_RING( GFX_OP_MAP_INFO ); OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */
OUT_RING( code[I830_TEXREG_MI1] ); OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */
OUT_RING( code[I830_TEXREG_MI2] ); OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */
OUT_RING( code[I830_TEXREG_MI3] ); OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */
OUT_RING( code[I830_TEXREG_MI4] ); OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */
OUT_RING( code[I830_TEXREG_MI5] ); OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */
for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -604,10 +591,13 @@ static void i830EmitTexVerified( drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
else
printk("rejected packet %x\n", code[0]);
}
static void i830EmitTexBlendVerified( drm_device_t *dev, static void i830EmitTexBlendVerified( drm_device_t *dev,
volatile unsigned int *code, unsigned int *code,
volatile unsigned int num) unsigned int num)
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
int i, j = 0; int i, j = 0;
@ -617,7 +607,7 @@ static void i830EmitTexBlendVerified( drm_device_t *dev,
if (!num) if (!num)
return; return;
BEGIN_LP_RING( num ); BEGIN_LP_RING( num + 1 );
for ( i = 0 ; i < num ; i++ ) { for ( i = 0 ; i < num ; i++ ) {
tmp = code[i]; tmp = code[i];
@ -640,6 +630,8 @@ static void i830EmitTexPalette( drm_device_t *dev,
int i; int i;
RING_LOCALS; RING_LOCALS;
return;
BEGIN_LP_RING( 258 ); BEGIN_LP_RING( 258 );
if(is_shared == 1) { if(is_shared == 1) {
@ -653,42 +645,41 @@ static void i830EmitTexPalette( drm_device_t *dev,
OUT_RING(palette[i]); OUT_RING(palette[i]);
} }
OUT_RING(0); OUT_RING(0);
/* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
*/
} }
/* Need to do some additional checking when setting the dest buffer. /* Need to do some additional checking when setting the dest buffer.
*/ */
static void i830EmitDestVerified( drm_device_t *dev, static void i830EmitDestVerified( drm_device_t *dev,
volatile unsigned int *code ) unsigned int *code )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
unsigned int tmp; unsigned int tmp;
RING_LOCALS; RING_LOCALS;
BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 );
tmp = code[I830_DESTREG_CBUFADDR]; tmp = code[I830_DESTREG_CBUFADDR];
if (tmp == dev_priv->front_di1) { if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
/* Don't use fence when front buffer rendering */ if (((int)outring) & 8) {
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING(0);
OUT_RING( BUF_3D_ID_COLOR_BACK | OUT_RING(0);
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); }
OUT_RING( tmp );
OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_DEPTH |
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
OUT_RING( dev_priv->zi1 );
} else if(tmp == dev_priv->back_di1) {
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_COLOR_BACK | OUT_RING( BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
BUF_3D_USE_FENCE); BUF_3D_USE_FENCE);
OUT_RING( tmp ); OUT_RING( tmp );
OUT_RING( 0 );
OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( CMD_OP_DESTBUFFER_INFO );
OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
OUT_RING( dev_priv->zi1 ); OUT_RING( dev_priv->zi1 );
OUT_RING( 0 );
} else { } else {
DRM_ERROR("bad di1 %x (allow %x or %x)\n", DRM_ERROR("bad di1 %x (allow %x or %x)\n",
tmp, dev_priv->front_di1, dev_priv->back_di1); tmp, dev_priv->front_di1, dev_priv->back_di1);
@ -716,21 +707,35 @@ static void i830EmitDestVerified( drm_device_t *dev,
OUT_RING( 0 ); OUT_RING( 0 );
} }
OUT_RING( code[I830_DESTREG_SENABLE] );
OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( GFX_OP_SCISSOR_RECT );
OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR1] );
OUT_RING( code[I830_DESTREG_SR2] ); OUT_RING( code[I830_DESTREG_SR2] );
OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
static void i830EmitStippleVerified( drm_device_t *dev,
unsigned int *code )
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
BEGIN_LP_RING( 2 );
OUT_RING( GFX_OP_STIPPLE );
OUT_RING( code[1] );
ADVANCE_LP_RING();
}
static void i830EmitState( drm_device_t *dev ) static void i830EmitState( drm_device_t *dev )
{ {
drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_private_t *dev_priv = dev->dev_private;
drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty; unsigned int dirty = sarea_priv->dirty;
DRM_DEBUG("%s %x\n", __FUNCTION__, dirty);
if (dirty & I830_UPLOAD_BUFFERS) { if (dirty & I830_UPLOAD_BUFFERS) {
i830EmitDestVerified( dev, sarea_priv->BufferState ); i830EmitDestVerified( dev, sarea_priv->BufferState );
sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
@ -774,7 +779,144 @@ static void i830EmitState( drm_device_t *dev )
i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
} }
/* 1.3:
*/
#if 0
if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {
i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
} }
if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {
i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);
sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
}
#endif
}
/* 1.3:
*/
if (dirty & I830_UPLOAD_STIPPLE) {
i830EmitStippleVerified( dev,
sarea_priv->StippleState);
sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
}
if (dirty & I830_UPLOAD_TEX2) {
i830EmitTexVerified( dev, sarea_priv->TexState2 );
sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
}
if (dirty & I830_UPLOAD_TEX3) {
i830EmitTexVerified( dev, sarea_priv->TexState3 );
sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
}
if (dirty & I830_UPLOAD_TEXBLEND2) {
i830EmitTexBlendVerified(
dev,
sarea_priv->TexBlendState2,
sarea_priv->TexBlendStateWordsUsed2);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
}
if (dirty & I830_UPLOAD_TEXBLEND3) {
i830EmitTexBlendVerified(
dev,
sarea_priv->TexBlendState3,
sarea_priv->TexBlendStateWordsUsed3);
sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
}
}
/* ================================================================
* Performance monitoring functions
*/
static void i830_fill_box( drm_device_t *dev,
int x, int y, int w, int h,
int r, int g, int b )
{
drm_i830_private_t *dev_priv = dev->dev_private;
u32 color;
unsigned int BR13, CMD;
RING_LOCALS;
BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24);
CMD = XY_COLOR_BLT_CMD;
x += dev_priv->sarea_priv->boxes[0].x1;
y += dev_priv->sarea_priv->boxes[0].y1;
if (dev_priv->cpp == 4) {
BR13 |= (1<<25);
CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
} else {
color = (((r & 0xf8) << 8) |
((g & 0xfc) << 3) |
((b & 0xf8) >> 3));
}
BEGIN_LP_RING( 6 );
OUT_RING( CMD );
OUT_RING( BR13 );
OUT_RING( (y << 16) | x );
OUT_RING( ((y+h) << 16) | (x+w) );
if ( dev_priv->current_page == 1 ) {
OUT_RING( dev_priv->front_offset );
} else {
OUT_RING( dev_priv->back_offset );
}
OUT_RING( color );
ADVANCE_LP_RING();
}
static void i830_cp_performance_boxes( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
/* Purple box for page flipping
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP )
i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 );
/* Red box if we have to wait for idle at any point
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT )
i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 );
/* Blue box: lost context?
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT )
i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 );
/* Yellow box for texture swaps
*/
if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD )
i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 );
/* Green box if hardware never idles (as far as we can tell)
*/
if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) )
i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 );
/* Draw bars indicating number of buffers allocated
* (not a great measure, easily confused)
*/
if (dev_priv->dma_used) {
int bar = dev_priv->dma_used / 10240;
if (bar > 100) bar = 100;
if (bar < 1) bar = 1;
i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 );
dev_priv->dma_used = 0;
}
dev_priv->sarea_priv->perf_boxes = 0;
} }
static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
@ -792,6 +934,15 @@ static void i830_dma_dispatch_clear( drm_device_t *dev, int flags,
unsigned int BR13, CMD, D_CMD; unsigned int BR13, CMD, D_CMD;
RING_LOCALS; RING_LOCALS;
if ( dev_priv->current_page == 1 ) {
unsigned int tmp = flags;
flags &= ~(I830_FRONT | I830_BACK);
if ( tmp & I830_FRONT ) flags |= I830_BACK;
if ( tmp & I830_BACK ) flags |= I830_FRONT;
}
i830_kernel_lost_context(dev); i830_kernel_lost_context(dev);
switch(cpp) { switch(cpp) {
@ -871,13 +1022,17 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
drm_clip_rect_t *pbox = sarea_priv->boxes; drm_clip_rect_t *pbox = sarea_priv->boxes;
int pitch = dev_priv->pitch; int pitch = dev_priv->pitch;
int cpp = dev_priv->cpp; int cpp = dev_priv->cpp;
int ofs = dev_priv->back_offset;
int i; int i;
unsigned int CMD, BR13; unsigned int CMD, BR13;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG("swapbuffers\n"); DRM_DEBUG("swapbuffers\n");
i830_kernel_lost_context(dev);
if (dev_priv->do_boxes)
i830_cp_performance_boxes( dev );
switch(cpp) { switch(cpp) {
case 2: case 2:
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
@ -894,7 +1049,6 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
break; break;
} }
i830_kernel_lost_context(dev);
if (nbox > I830_NR_SAREA_CLIPRECTS) if (nbox > I830_NR_SAREA_CLIPRECTS)
nbox = I830_NR_SAREA_CLIPRECTS; nbox = I830_NR_SAREA_CLIPRECTS;
@ -914,23 +1068,72 @@ static void i830_dma_dispatch_swap( drm_device_t *dev )
BEGIN_LP_RING( 8 ); BEGIN_LP_RING( 8 );
OUT_RING( CMD ); OUT_RING( CMD );
OUT_RING( BR13 ); OUT_RING( BR13 );
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
OUT_RING( (pbox->y2 << 16) | pbox->x2 );
OUT_RING( (pbox->y1 << 16) | if (dev_priv->current_page == 0)
pbox->x1 );
OUT_RING( (pbox->y2 << 16) |
pbox->x2 );
OUT_RING( dev_priv->front_offset ); OUT_RING( dev_priv->front_offset );
OUT_RING( (pbox->y1 << 16) | else
pbox->x1 ); OUT_RING( dev_priv->back_offset );
OUT_RING( (pbox->y1 << 16) | pbox->x1 );
OUT_RING( BR13 & 0xffff ); OUT_RING( BR13 & 0xffff );
OUT_RING( ofs );
if (dev_priv->current_page == 0)
OUT_RING( dev_priv->back_offset );
else
OUT_RING( dev_priv->front_offset );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
} }
static void i830_dma_dispatch_flip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n",
__FUNCTION__,
dev_priv->current_page,
dev_priv->sarea_priv->pf_current_page);
i830_kernel_lost_context(dev);
if (dev_priv->do_boxes) {
dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
i830_cp_performance_boxes( dev );
}
BEGIN_LP_RING( 2 );
OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
OUT_RING( 0 );
ADVANCE_LP_RING();
BEGIN_LP_RING( 6 );
OUT_RING( CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP );
OUT_RING( 0 );
if ( dev_priv->current_page == 0 ) {
OUT_RING( dev_priv->back_offset );
dev_priv->current_page = 1;
} else {
OUT_RING( dev_priv->front_offset );
dev_priv->current_page = 0;
}
OUT_RING(0);
ADVANCE_LP_RING();
BEGIN_LP_RING( 2 );
OUT_RING( MI_WAIT_FOR_EVENT |
MI_WAIT_FOR_PLANE_A_FLIP );
OUT_RING( 0 );
ADVANCE_LP_RING();
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
static void i830_dma_dispatch_vertex(drm_device_t *dev, static void i830_dma_dispatch_vertex(drm_device_t *dev,
drm_buf_t *buf, drm_buf_t *buf,
@ -983,8 +1186,10 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
sarea_priv->vertex_prim | sarea_priv->vertex_prim |
((used/4)-2)); ((used/4)-2));
if (dev_priv->use_mi_batchbuffer_start) {
vp[used/4] = MI_BATCH_BUFFER_END; vp[used/4] = MI_BATCH_BUFFER_END;
used += 4; used += 4;
}
if (used & 4) { if (used & 4) {
vp[used/4] = 0; vp[used/4] = 0;
@ -1007,10 +1212,20 @@ static void i830_dma_dispatch_vertex(drm_device_t *dev,
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2); BEGIN_LP_RING(2);
OUT_RING( MI_BATCH_BUFFER_START | (2<<6) ); OUT_RING( MI_BATCH_BUFFER_START | (2<<6) );
OUT_RING( start | MI_BATCH_NON_SECURE ); OUT_RING( start | MI_BATCH_NON_SECURE );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
}
else {
BEGIN_LP_RING(4);
OUT_RING( MI_BATCH_BUFFER );
OUT_RING( start | MI_BATCH_NON_SECURE );
OUT_RING( start + used - 4 );
OUT_RING( 0 );
ADVANCE_LP_RING();
}
} while (++i < nbox); } while (++i < nbox);
} }
@ -1049,7 +1264,7 @@ void i830_dma_quiescent(drm_device_t *dev)
OUT_RING( 0 ); OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
i830_wait_ring( dev, dev_priv->ring.Size - 8 ); i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
} }
static int i830_flush_queue(drm_device_t *dev) static int i830_flush_queue(drm_device_t *dev)
@ -1066,7 +1281,7 @@ static int i830_flush_queue(drm_device_t *dev)
OUT_RING( 0 ); OUT_RING( 0 );
ADVANCE_LP_RING(); ADVANCE_LP_RING();
i830_wait_ring( dev, dev_priv->ring.Size - 8 ); i830_wait_ring( dev, dev_priv->ring.Size - 8, __FUNCTION__ );
for (i = 0; i < dma->buf_count; i++) { for (i = 0; i < dma->buf_count; i++) {
drm_buf_t *buf = dma->buflist[ i ]; drm_buf_t *buf = dma->buflist[ i ];
@ -1208,6 +1423,53 @@ int i830_swap_bufs(struct inode *inode, struct file *filp,
return 0; return 0;
} }
/* Not sure why this isn't set all the time:
*/
static void i830_do_init_pageflip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
dev_priv->page_flipping = 1;
dev_priv->current_page = 0;
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
}
int i830_do_cleanup_pageflip( drm_device_t *dev )
{
drm_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if (dev_priv->current_page != 0)
i830_dma_dispatch_flip( dev );
dev_priv->page_flipping = 0;
return 0;
}
int i830_flip_bufs(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_i830_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("%s\n", __FUNCTION__);
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("i830_flip_buf called without lock held\n");
return -EINVAL;
}
if (!dev_priv->page_flipping)
i830_do_init_pageflip( dev );
i830_dma_dispatch_flip( dev );
return 0;
}
int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd, int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@ -1271,3 +1533,66 @@ int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
{ {
return 0; return 0;
} }
int i830_getparam( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_getparam_t param;
int value;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_getparam_t *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
case I830_PARAM_IRQ_ACTIVE:
value = dev->irq ? 1 : 0;
break;
default:
return -EINVAL;
}
if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
DRM_ERROR( "copy_to_user\n" );
return -EFAULT;
}
return 0;
}
int i830_setparam( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_setparam_t param;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user(&param, (drm_i830_setparam_t *)arg, sizeof(param) ))
return -EFAULT;
switch( param.param ) {
case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
dev_priv->use_mi_batchbuffer_start = param.value;
break;
default:
return -EINVAL;
}
return 0;
}

View file

@ -3,6 +3,9 @@
/* WARNING: These defines must be the same as what the Xserver uses. /* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver. * if you change them, you must change the defines in the Xserver.
*
* KW: Actually, you can't ever change them because doing so would
* break backwards compatibility.
*/ */
#ifndef _I830_DEFINES_ #ifndef _I830_DEFINES_
@ -18,14 +21,12 @@
#define I830_NR_TEX_REGIONS 64 #define I830_NR_TEX_REGIONS 64
#define I830_LOG_MIN_TEX_REGION_SIZE 16 #define I830_LOG_MIN_TEX_REGION_SIZE 16
/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ /* KW: These aren't correct but someone set them to two and then
#if !defined(I830_ENABLE_4_TEXTURES) * released the module. Now we can't change them as doing so would
* break backwards compatibility.
*/
#define I830_TEXTURE_COUNT 2 #define I830_TEXTURE_COUNT 2
#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ #define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT
#else /* defined(I830_ENABLE_4_TEXTURES) */
#define I830_TEXTURE_COUNT 4
#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */
#endif /* I830_ENABLE_4_TEXTURES */
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
@ -57,6 +58,7 @@
#define I830_UPLOAD_TEXBLEND_MASK 0xf00000 #define I830_UPLOAD_TEXBLEND_MASK 0xf00000
#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) #define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 #define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
#define I830_UPLOAD_STIPPLE 0x8000000
/* Indices into buf.Setup where various bits of state are mirrored per /* Indices into buf.Setup where various bits of state are mirrored per
* context and per buffer. These can be fired at the card as a unit, * context and per buffer. These can be fired at the card as a unit,
@ -73,7 +75,6 @@
*/ */
#define I830_DESTREG_CBUFADDR 0 #define I830_DESTREG_CBUFADDR 0
/* Invarient */
#define I830_DESTREG_DBUFADDR 1 #define I830_DESTREG_DBUFADDR 1
#define I830_DESTREG_DV0 2 #define I830_DESTREG_DV0 2
#define I830_DESTREG_DV1 3 #define I830_DESTREG_DV1 3
@ -109,6 +110,13 @@
#define I830_CTXREG_MCSB1 16 #define I830_CTXREG_MCSB1 16
#define I830_CTX_SETUP_SIZE 17 #define I830_CTX_SETUP_SIZE 17
/* 1.3: Stipple state
*/
#define I830_STPREG_ST0 0
#define I830_STPREG_ST1 1
#define I830_STP_SETUP_SIZE 2
/* Texture state (per tex unit) /* Texture state (per tex unit)
*/ */
@ -124,6 +132,18 @@
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ #define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
#define I830_TEX_SETUP_SIZE 10 #define I830_TEX_SETUP_SIZE 10
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
#define I830_TEXREG_TM0S0 1
#define I830_TEXREG_TM0S1 2
#define I830_TEXREG_TM0S2 3
#define I830_TEXREG_TM0S3 4
#define I830_TEXREG_TM0S4 5
#define I830_TEXREG_NOP0 6 /* noop */
#define I830_TEXREG_NOP1 7 /* noop */
#define I830_TEXREG_NOP2 8 /* noop */
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
#define __I830_TEX_SETUP_SIZE 10
#define I830_FRONT 0x1 #define I830_FRONT 0x1
#define I830_BACK 0x2 #define I830_BACK 0x2
#define I830_DEPTH 0x4 #define I830_DEPTH 0x4
@ -199,8 +219,35 @@ typedef struct _drm_i830_sarea {
int ctxOwner; /* last context to upload state */ int ctxOwner; /* last context to upload state */
int vertex_prim; int vertex_prim;
int pf_enabled; /* is pageflipping allowed? */
int pf_active;
int pf_current_page; /* which buffer is being displayed? */
int perf_boxes; /* performance boxes to be displayed */
/* Here's the state for texunits 2,3:
*/
unsigned int TexState2[I830_TEX_SETUP_SIZE];
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
unsigned int TexBlendStateWordsUsed2;
unsigned int TexState3[I830_TEX_SETUP_SIZE];
unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
unsigned int TexBlendStateWordsUsed3;
unsigned int StippleState[I830_STP_SETUP_SIZE];
} drm_i830_sarea_t; } drm_i830_sarea_t;
/* Flags for perf_boxes
*/
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
#define I830_BOX_FLIP 0x2 /* populated by kernel */
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
/* I830 specific ioctls /* I830 specific ioctls
* The device specific ioctl range is 0x40 to 0x79. * The device specific ioctl range is 0x40 to 0x79.
*/ */
@ -213,6 +260,11 @@ typedef struct _drm_i830_sarea {
#define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46) #define DRM_IOCTL_I830_SWAP DRM_IO ( 0x46)
#define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t) #define DRM_IOCTL_I830_COPY DRM_IOW( 0x47, drm_i830_copy_t)
#define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48) #define DRM_IOCTL_I830_DOCOPY DRM_IO ( 0x48)
#define DRM_IOCTL_I830_FLIP DRM_IO ( 0x49)
#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(0x4a, drm_i830_irq_emit_t)
#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( 0x4b, drm_i830_irq_wait_t)
#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(0x4c, drm_i830_getparam_t)
#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(0x4d, drm_i830_setparam_t)
typedef struct _drm_i830_clear { typedef struct _drm_i830_clear {
int clear_color; int clear_color;
@ -248,4 +300,36 @@ typedef struct drm_i830_dma {
int granted; int granted;
} drm_i830_dma_t; } drm_i830_dma_t;
/* 1.3: Userspace can request & wait on irq's:
*/
typedef struct drm_i830_irq_emit {
int *irq_seq;
} drm_i830_irq_emit_t;
typedef struct drm_i830_irq_wait {
int irq_seq;
} drm_i830_irq_wait_t;
/* 1.3: New ioctl to query kernel params:
*/
#define I830_PARAM_IRQ_ACTIVE 1
typedef struct drm_i830_getparam {
int param;
int *value;
} drm_i830_getparam_t;
/* 1.3: New ioctl to set kernel params:
*/
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
typedef struct drm_i830_setparam {
int param;
int value;
} drm_i830_setparam_t;
#endif /* _I830_DRM_H_ */ #endif /* _I830_DRM_H_ */

View file

@ -78,6 +78,19 @@ typedef struct drm_i830_private {
int back_pitch; int back_pitch;
int depth_pitch; int depth_pitch;
unsigned int cpp; unsigned int cpp;
int do_boxes;
int dma_used;
int current_page;
int page_flipping;
wait_queue_head_t irq_queue;
atomic_t irq_received;
atomic_t irq_emitted;
int use_mi_batchbuffer_start;
} drm_i830_private_t; } drm_i830_private_t;
/* i830_dma.c */ /* i830_dma.c */
@ -108,6 +121,23 @@ extern int i830_swap_bufs(struct inode *inode, struct file *filp,
extern int i830_clear_bufs(struct inode *inode, struct file *filp, extern int i830_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
extern int i830_flip_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i830_getparam( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_setparam( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* i830_irq.c */
extern int i830_irq_emit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_irq_wait( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int i830_wait_irq(drm_device_t *dev, int irq_nr);
extern int i830_emit_irq(drm_device_t *dev);
#define I830_BASE(reg) ((unsigned long) \ #define I830_BASE(reg) ((unsigned long) \
dev_priv->mmio_map->handle) dev_priv->mmio_map->handle)
@ -119,12 +149,53 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define I830_READ16(reg) I830_DEREF16(reg) #define I830_READ16(reg) I830_DEREF16(reg)
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0) #define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
#define I830_VERBOSE 0
#define RING_LOCALS unsigned int outring, ringmask, outcount; \
volatile char *virt;
#define BEGIN_LP_RING(n) do { \
if (I830_VERBOSE) \
printk("BEGIN_LP_RING(%d) in %s\n", \
n, __FUNCTION__); \
if (dev_priv->ring.space < n*4) \
i830_wait_ring(dev, n*4, __FUNCTION__); \
outcount = 0; \
outring = dev_priv->ring.tail; \
ringmask = dev_priv->ring.tail_mask; \
virt = dev_priv->ring.virtual_start; \
} while (0)
#define OUT_RING(n) do { \
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outcount++; \
outring += 4; \
outring &= ringmask; \
} while (0)
#define ADVANCE_LP_RING() do { \
if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
dev_priv->ring.space -= outcount * 4; \
I830_WRITE(LP_RING + RING_TAIL, outring); \
} while(0)
extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
#define CMD_REPORT_HEAD (7<<23) #define CMD_REPORT_HEAD (7<<23)
#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1) #define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) #define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
#define LOAD_TEXTURE_MAP0 (1<<11)
#define INST_PARSER_CLIENT 0x00000000 #define INST_PARSER_CLIENT 0x00000000
#define INST_OP_FLUSH 0x02000000 #define INST_OP_FLUSH 0x02000000
#define INST_FLUSH_MAP_CACHE 0x00000001 #define INST_FLUSH_MAP_CACHE 0x00000001
@ -140,6 +211,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define I830REG_INT_MASK_R 0x020a8 #define I830REG_INT_MASK_R 0x020a8
#define I830REG_INT_ENABLE_R 0x020a0 #define I830REG_INT_ENABLE_R 0x020a0
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
#define LP_RING 0x2030 #define LP_RING 0x2030
#define HP_RING 0x2040 #define HP_RING 0x2040
#define RING_TAIL 0x00 #define RING_TAIL 0x00
@ -182,6 +256,9 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1) #define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
#define ASYNC_FLIP (1<<22)
#define CMD_3D (0x3<<29) #define CMD_3D (0x3<<29)
#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16)) #define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) #define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
@ -213,6 +290,11 @@ extern int i830_clear_bufs(struct inode *inode, struct file *filp,
#define MI_BATCH_BUFFER_END (0xA<<23) #define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE (1)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
#endif #endif

178
linux/i830_irq.c Normal file
View file

@ -0,0 +1,178 @@
/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
*
* Copyright 2002 Tungsten Graphics, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors: Keith Whitwell <keith@tungstengraphics.com>
*
*/
#define __NO_VERSION__
#include "i830.h"
#include "drmP.h"
#include "drm.h"
#include "i830_drm.h"
#include "i830_drv.h"
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
void DRM(dma_service)(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
u16 temp;
temp = I830_READ16(I830REG_INT_IDENTITY_R);
printk("%s: %x\n", __FUNCTION__, temp);
if(temp == 0)
return;
I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
if (temp & 2) {
atomic_inc(&dev_priv->irq_received);
wake_up_interruptible(&dev_priv->irq_queue);
}
}
int i830_emit_irq(drm_device_t *dev)
{
drm_i830_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
DRM_DEBUG("%s\n", __FUNCTION__);
atomic_inc(&dev_priv->irq_emitted);
BEGIN_LP_RING(2);
OUT_RING( 0 );
OUT_RING( GFX_OP_USER_INTERRUPT );
ADVANCE_LP_RING();
return atomic_read(&dev_priv->irq_emitted);
}
int i830_wait_irq(drm_device_t *dev, int irq_nr)
{
drm_i830_private_t *dev_priv =
(drm_i830_private_t *)dev->dev_private;
DECLARE_WAITQUEUE(entry, current);
unsigned long end = jiffies + HZ*3;
int ret = 0;
DRM_DEBUG("%s\n", __FUNCTION__);
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
return 0;
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
add_wait_queue(&dev_priv->irq_queue, &entry);
for (;;) {
current->state = TASK_INTERRUPTIBLE;
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
break;
if((signed)(end - jiffies) <= 0) {
DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
I830_READ16( I830REG_INT_IDENTITY_R ),
I830_READ16( I830REG_INT_MASK_R ),
I830_READ16( I830REG_INT_ENABLE_R ),
I830_READ16( I830REG_HWSTAM ));
ret = -EBUSY; /* Lockup? Missed irq? */
break;
}
schedule_timeout(HZ*3);
if (signal_pending(current)) {
ret = -EINTR;
break;
}
}
current->state = TASK_RUNNING;
remove_wait_queue(&dev_priv->irq_queue, &entry);
return ret;
}
/* Needs the lock as it touches the ring.
*/
int i830_irq_emit( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_emit_t emit;
int result;
if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("i830_irq_emit called without lock held\n");
return -EINVAL;
}
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user( &emit, (drm_i830_irq_emit_t *)arg, sizeof(emit) ))
return -EFAULT;
result = i830_emit_irq( dev );
if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
DRM_ERROR( "copy_to_user\n" );
return -EFAULT;
}
return 0;
}
/* Doesn't need the hardware lock.
*/
int i830_irq_wait( 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_i830_private_t *dev_priv = dev->dev_private;
drm_i830_irq_wait_t irqwait;
if ( !dev_priv ) {
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
return -EINVAL;
}
if (copy_from_user( &irqwait, (drm_i830_irq_wait_t *)arg,
sizeof(irqwait) ))
return -EFAULT;
return i830_wait_irq( dev, irqwait.irq_seq );
}

View file

@ -24,7 +24,7 @@
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.2 2001/12/19 21:25:59 dawes Exp $ */ /* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis.h,v 1.3 2002/10/30 12:52:38 alanh Exp $ */
#ifndef __SIS_H__ #ifndef __SIS_H__
#define __SIS_H__ #define __SIS_H__

View file

@ -183,10 +183,10 @@ int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
if(block){ if(block){
/* TODO */ /* TODO */
agp.offset = block->ofs; agp.offset = block->ofs;
agp.free = (unsigned int)block; agp.free = (unsigned long)block;
if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){ if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){
DRM_DEBUG("adding to allocation set fails\n"); DRM_DEBUG("adding to allocation set fails\n");
mmFreeMem((PMemBlock)agp.free); mmFreeMem((PMemBlock)(unsigned long)agp.free);
retval = -1; retval = -1;
} }
} }
@ -219,7 +219,7 @@ int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
return -1; return -1;
} }
mmFreeMem((PMemBlock)agp.free); mmFreeMem((PMemBlock)(unsigned long)agp.free);
if(!del_alloc_set(agp.context, AGP_TYPE, agp.free)) if(!del_alloc_set(agp.context, AGP_TYPE, agp.free))
retval = -1; retval = -1;
@ -289,7 +289,7 @@ int sis_final_context(int context)
retval = setFirst(set, &item); retval = setFirst(set, &item);
while(retval){ while(retval){
DRM_DEBUG("free agp memory 0x%x\n", item); DRM_DEBUG("free agp memory 0x%x\n", item);
mmFreeMem((PMemBlock)item); mmFreeMem((PMemBlock)(unsigned long)item);
retval = setNext(set, &item); retval = setNext(set, &item);
} }
setDestroy(set); setDestroy(set);

View file

@ -897,7 +897,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
int count, x, y; int count, x, y;
u32 *buffer; u32 *buffer;
u8 *mask; u8 *mask;
int i; int i, buffer_size, mask_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
@ -909,25 +909,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
buffer = DRM_MALLOC( depth->n * sizeof(u32) ); buffer_size = depth->n * sizeof(u32);
buffer = DRM_MALLOC( buffer_size );
if ( buffer == NULL ) if ( buffer == NULL )
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
if ( DRM_COPY_FROM_USER( buffer, depth->buffer, if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
depth->n * sizeof(u32) ) ) { DRM_FREE( buffer, buffer_size);
DRM_FREE( buffer );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
mask_size = depth->n * sizeof(u8);
if ( depth->mask ) { if ( depth->mask ) {
mask = DRM_MALLOC( depth->n * sizeof(u8) ); mask = DRM_MALLOC( mask_size );
if ( mask == NULL ) { if ( mask == NULL ) {
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( mask, depth->mask, if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
depth->n * sizeof(u8) ) ) { DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer ); DRM_FREE( mask, mask_size );
DRM_FREE( mask );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -954,7 +954,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
} }
} }
DRM_FREE( mask ); DRM_FREE( mask, mask_size );
} else { } else {
for ( i = 0 ; i < count ; i++, x++ ) { for ( i = 0 ; i < count ; i++, x++ ) {
BEGIN_RING( 6 ); BEGIN_RING( 6 );
@ -978,7 +978,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
} }
} }
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return 0; return 0;
} }
@ -990,60 +990,62 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
int count, *x, *y; int count, *x, *y;
u32 *buffer; u32 *buffer;
u8 *mask; u8 *mask;
int i; int i, xbuf_size, ybuf_size, buffer_size, mask_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
count = depth->n; count = depth->n;
x = DRM_MALLOC( count * sizeof(*x) ); xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
x = DRM_MALLOC( xbuf_size );
if ( x == NULL ) { if ( x == NULL ) {
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
y = DRM_MALLOC( count * sizeof(*y) ); y = DRM_MALLOC( ybuf_size );
if ( y == NULL ) { if ( y == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
buffer = DRM_MALLOC( depth->n * sizeof(u32) ); buffer_size = depth->n * sizeof(u32);
buffer = DRM_MALLOC( buffer_size );
if ( buffer == NULL ) { if ( buffer == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( buffer, depth->buffer, if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
depth->n * sizeof(u32) ) ) { DRM_FREE( x, xbuf_size );
DRM_FREE( x ); DRM_FREE( y, ybuf_size );
DRM_FREE( y ); DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( depth->mask ) { if ( depth->mask ) {
mask = DRM_MALLOC( depth->n * sizeof(u8) ); mask_size = depth->n * sizeof(u8);
mask = DRM_MALLOC( mask_size );
if ( mask == NULL ) { if ( mask == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( mask, depth->mask, if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
depth->n * sizeof(u8) ) ) { DRM_FREE( x, xbuf_size );
DRM_FREE( x ); DRM_FREE( y, ybuf_size );
DRM_FREE( y ); DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer ); DRM_FREE( mask, mask_size );
DRM_FREE( mask );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -1070,7 +1072,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
} }
} }
DRM_FREE( mask ); DRM_FREE( mask, mask_size );
} else { } else {
for ( i = 0 ; i < count ; i++ ) { for ( i = 0 ; i < count ; i++ ) {
BEGIN_RING( 6 ); BEGIN_RING( 6 );
@ -1094,9 +1096,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
} }
} }
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return 0; return 0;
} }
@ -1147,7 +1149,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
{ {
drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y; int count, *x, *y;
int i; int i, xbuf_size, ybuf_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ ); DRM_DEBUG( "%s\n", __FUNCTION__ );
@ -1156,23 +1158,25 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
count = dev_priv->depth_pitch; count = dev_priv->depth_pitch;
} }
x = DRM_MALLOC( count * sizeof(*x) ); xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
x = DRM_MALLOC( xbuf_size );
if ( x == NULL ) { if ( x == NULL ) {
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
y = DRM_MALLOC( count * sizeof(*y) ); y = DRM_MALLOC( ybuf_size );
if ( y == NULL ) { if ( y == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -1200,8 +1204,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
ADVANCE_RING(); ADVANCE_RING();
} }
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return 0; return 0;
} }

View file

@ -118,7 +118,7 @@ static void free_block( struct mem_block *p )
p->size += q->size; p->size += q->size;
p->next = q->next; p->next = q->next;
p->next->prev = p; p->next->prev = p;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
if (p->prev->filp == 0) { if (p->prev->filp == 0) {
@ -126,7 +126,7 @@ static void free_block( struct mem_block *p )
q->size += p->size; q->size += p->size;
q->next = p->next; q->next = p->next;
q->next->prev = q; q->next->prev = q;
DRM_FREE(p); DRM_FREE(p, sizeof(*q));
} }
} }
@ -141,7 +141,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
*heap = DRM_MALLOC(sizeof(**heap)); *heap = DRM_MALLOC(sizeof(**heap));
if (!*heap) { if (!*heap) {
DRM_FREE( blocks ); DRM_FREE( blocks, sizeof(*blocks) );
return -ENOMEM; return -ENOMEM;
} }
@ -180,7 +180,7 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
p->size += q->size; p->size += q->size;
p->next = q->next; p->next = q->next;
p->next->prev = p; p->next->prev = p;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
} }
} }
@ -197,10 +197,10 @@ void radeon_mem_takedown( struct mem_block **heap )
for (p = (*heap)->next ; p != *heap ; ) { for (p = (*heap)->next ; p != *heap ; ) {
struct mem_block *q = p; struct mem_block *q = p;
p = p->next; p = p->next;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
DRM_FREE( *heap ); DRM_FREE( *heap, sizeof(**heap) );
*heap = 0; *heap = 0;
} }

View file

@ -897,7 +897,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
int count, x, y; int count, x, y;
u32 *buffer; u32 *buffer;
u8 *mask; u8 *mask;
int i; int i, buffer_size, mask_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
@ -909,25 +909,25 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
buffer = DRM_MALLOC( depth->n * sizeof(u32) ); buffer_size = depth->n * sizeof(u32);
buffer = DRM_MALLOC( buffer_size );
if ( buffer == NULL ) if ( buffer == NULL )
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
if ( DRM_COPY_FROM_USER( buffer, depth->buffer, if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
depth->n * sizeof(u32) ) ) { DRM_FREE( buffer, buffer_size);
DRM_FREE( buffer );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
mask_size = depth->n * sizeof(u8);
if ( depth->mask ) { if ( depth->mask ) {
mask = DRM_MALLOC( depth->n * sizeof(u8) ); mask = DRM_MALLOC( mask_size );
if ( mask == NULL ) { if ( mask == NULL ) {
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( mask, depth->mask, if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
depth->n * sizeof(u8) ) ) { DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer ); DRM_FREE( mask, mask_size );
DRM_FREE( mask );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -954,7 +954,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
} }
} }
DRM_FREE( mask ); DRM_FREE( mask, mask_size );
} else { } else {
for ( i = 0 ; i < count ; i++, x++ ) { for ( i = 0 ; i < count ; i++, x++ ) {
BEGIN_RING( 6 ); BEGIN_RING( 6 );
@ -978,7 +978,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
} }
} }
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return 0; return 0;
} }
@ -990,60 +990,62 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
int count, *x, *y; int count, *x, *y;
u32 *buffer; u32 *buffer;
u8 *mask; u8 *mask;
int i; int i, xbuf_size, ybuf_size, buffer_size, mask_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "\n" ); DRM_DEBUG( "\n" );
count = depth->n; count = depth->n;
x = DRM_MALLOC( count * sizeof(*x) ); xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
x = DRM_MALLOC( xbuf_size );
if ( x == NULL ) { if ( x == NULL ) {
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
y = DRM_MALLOC( count * sizeof(*y) ); y = DRM_MALLOC( ybuf_size );
if ( y == NULL ) { if ( y == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( y, depth->y, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
buffer = DRM_MALLOC( depth->n * sizeof(u32) ); buffer_size = depth->n * sizeof(u32);
buffer = DRM_MALLOC( buffer_size );
if ( buffer == NULL ) { if ( buffer == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( buffer, depth->buffer, if ( DRM_COPY_FROM_USER( buffer, depth->buffer, buffer_size ) ) {
depth->n * sizeof(u32) ) ) { DRM_FREE( x, xbuf_size );
DRM_FREE( x ); DRM_FREE( y, ybuf_size );
DRM_FREE( y ); DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( depth->mask ) { if ( depth->mask ) {
mask = DRM_MALLOC( depth->n * sizeof(u8) ); mask_size = depth->n * sizeof(u8);
mask = DRM_MALLOC( mask_size );
if ( mask == NULL ) { if ( mask == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( mask, depth->mask, if ( DRM_COPY_FROM_USER( mask, depth->mask, mask_size ) ) {
depth->n * sizeof(u8) ) ) { DRM_FREE( x, xbuf_size );
DRM_FREE( x ); DRM_FREE( y, ybuf_size );
DRM_FREE( y ); DRM_FREE( buffer, buffer_size );
DRM_FREE( buffer ); DRM_FREE( mask, mask_size );
DRM_FREE( mask );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -1070,7 +1072,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
} }
} }
DRM_FREE( mask ); DRM_FREE( mask, mask_size );
} else { } else {
for ( i = 0 ; i < count ; i++ ) { for ( i = 0 ; i < count ; i++ ) {
BEGIN_RING( 6 ); BEGIN_RING( 6 );
@ -1094,9 +1096,9 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
} }
} }
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
DRM_FREE( buffer ); DRM_FREE( buffer, buffer_size );
return 0; return 0;
} }
@ -1147,7 +1149,7 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
{ {
drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y; int count, *x, *y;
int i; int i, xbuf_size, ybuf_size;
RING_LOCALS; RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ ); DRM_DEBUG( "%s\n", __FUNCTION__ );
@ -1156,23 +1158,25 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
count = dev_priv->depth_pitch; count = dev_priv->depth_pitch;
} }
x = DRM_MALLOC( count * sizeof(*x) ); xbuf_size = count * sizeof(*x);
ybuf_size = count * sizeof(*y);
x = DRM_MALLOC( xbuf_size );
if ( x == NULL ) { if ( x == NULL ) {
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
y = DRM_MALLOC( count * sizeof(*y) ); y = DRM_MALLOC( ybuf_size );
if ( y == NULL ) { if ( y == NULL ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
return DRM_ERR(ENOMEM); return DRM_ERR(ENOMEM);
} }
if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( x, depth->x, xbuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) { if ( DRM_COPY_FROM_USER( y, depth->y, ybuf_size ) ) {
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
@ -1200,8 +1204,8 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
ADVANCE_RING(); ADVANCE_RING();
} }
DRM_FREE( x ); DRM_FREE( x, xbuf_size );
DRM_FREE( y ); DRM_FREE( y, ybuf_size );
return 0; return 0;
} }

View file

@ -118,7 +118,7 @@ static void free_block( struct mem_block *p )
p->size += q->size; p->size += q->size;
p->next = q->next; p->next = q->next;
p->next->prev = p; p->next->prev = p;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
if (p->prev->filp == 0) { if (p->prev->filp == 0) {
@ -126,7 +126,7 @@ static void free_block( struct mem_block *p )
q->size += p->size; q->size += p->size;
q->next = p->next; q->next = p->next;
q->next->prev = q; q->next->prev = q;
DRM_FREE(p); DRM_FREE(p, sizeof(*q));
} }
} }
@ -141,7 +141,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
*heap = DRM_MALLOC(sizeof(**heap)); *heap = DRM_MALLOC(sizeof(**heap));
if (!*heap) { if (!*heap) {
DRM_FREE( blocks ); DRM_FREE( blocks, sizeof(*blocks) );
return -ENOMEM; return -ENOMEM;
} }
@ -180,7 +180,7 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
p->size += q->size; p->size += q->size;
p->next = q->next; p->next = q->next;
p->next->prev = p; p->next->prev = p;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
} }
} }
@ -197,10 +197,10 @@ void radeon_mem_takedown( struct mem_block **heap )
for (p = (*heap)->next ; p != *heap ; ) { for (p = (*heap)->next ; p != *heap ; ) {
struct mem_block *q = p; struct mem_block *q = p;
p = p->next; p = p->next;
DRM_FREE(q); DRM_FREE(q, sizeof(*q));
} }
DRM_FREE( *heap ); DRM_FREE( *heap, sizeof(**heap) );
*heap = 0; *heap = 0;
} }