Merge from bsd-4-0-0-branch.
parent
a64472d184
commit
cfa778af9c
|
@ -1,6 +1,6 @@
|
||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
# i810, i830 & sis are not complete
|
# i810, i830 & sis are not complete
|
||||||
SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis
|
SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
|
@ -42,25 +42,6 @@
|
||||||
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
|
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
|
||||||
# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
|
# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
|
||||||
|
|
||||||
static unsigned long DRM(ati_alloc_pcigart_table)( void )
|
|
||||||
{
|
|
||||||
unsigned long address;
|
|
||||||
|
|
||||||
DRM_DEBUG( "\n" );
|
|
||||||
|
|
||||||
address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK );
|
|
||||||
|
|
||||||
DRM_DEBUG( "returning 0x%08lx\n", address );
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|
||||||
{
|
|
||||||
DRM_DEBUG( "\n" );
|
|
||||||
|
|
||||||
free( (void *)address, DRM(M_DRM));
|
|
||||||
}
|
|
||||||
|
|
||||||
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
unsigned long *addr,
|
unsigned long *addr,
|
||||||
dma_addr_t *bus_addr)
|
dma_addr_t *bus_addr)
|
||||||
|
@ -76,23 +57,15 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
address = DRM(ati_alloc_pcigart_table)();
|
address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE,
|
||||||
|
DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0);
|
||||||
if ( !address ) {
|
if ( !address ) {
|
||||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME non-vtophys==bustophys-arches */
|
/* XXX: we need to busdma this */
|
||||||
bus_address = vtophys( address );
|
bus_address = vtophys( address );
|
||||||
/*pci_map_single(dev->pdev, (void *)address,
|
|
||||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
|
||||||
PCI_DMA_TODEVICE);*/
|
|
||||||
/* if (bus_address == 0) {
|
|
||||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
|
||||||
DRM(ati_free_pcigart_table)( (unsigned long)address );
|
|
||||||
address = 0;
|
|
||||||
goto done;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pci_gart = (u32 *)address;
|
pci_gart = (u32 *)address;
|
||||||
|
|
||||||
|
@ -102,16 +75,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||||
|
|
||||||
for ( i = 0 ; i < pages ; i++ ) {
|
for ( i = 0 ; i < pages ; i++ ) {
|
||||||
/* we need to support large memory configurations */
|
|
||||||
/* FIXME non-vtophys==vtobus-arches */
|
|
||||||
entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) );
|
entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) );
|
||||||
/* if (entry->busaddr[i] == 0) {
|
|
||||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
|
||||||
DRM(ati_pcigart_cleanup)( dev, (unsigned long)address, bus_address );
|
|
||||||
address = 0;
|
|
||||||
bus_address = 0;
|
|
||||||
goto done;
|
|
||||||
}*/
|
|
||||||
page_base = (u32) entry->busaddr[i];
|
page_base = (u32) entry->busaddr[i];
|
||||||
|
|
||||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||||
|
@ -122,8 +86,6 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
DRM_READMEMORYBARRIER();
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
*addr = address;
|
*addr = address;
|
||||||
*bus_addr = bus_address;
|
*bus_addr = bus_address;
|
||||||
|
@ -142,9 +104,8 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( addr ) {
|
#if __FreeBSD_version > 500000
|
||||||
DRM(ati_free_pcigart_table)( addr );
|
contigfree( (void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM)); /* Not available on 4.x */
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,15 +121,15 @@ typedef struct drm_file drm_file_t;
|
||||||
|
|
||||||
/* Mapping helper macros */
|
/* Mapping helper macros */
|
||||||
#define DRM_IOREMAP(map) \
|
#define DRM_IOREMAP(map) \
|
||||||
(map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
|
(map)->handle = DRM(ioremap)( dev, map )
|
||||||
|
|
||||||
#define DRM_IOREMAP_NOCACHE(map) \
|
#define DRM_IOREMAP_NOCACHE(map) \
|
||||||
(map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size)
|
(map)->handle = DRM(ioremap_nocache)( dev, map )
|
||||||
|
|
||||||
#define DRM_IOREMAPFREE(map) \
|
#define DRM_IOREMAPFREE(map) \
|
||||||
do { \
|
do { \
|
||||||
if ( (map)->handle && (map)->size ) \
|
if ( (map)->handle && (map)->size ) \
|
||||||
DRM(ioremapfree)( (map)->handle, (map)->size ); \
|
DRM(ioremapfree)( map ); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Internal types and structures */
|
/* Internal types and structures */
|
||||||
|
@ -377,7 +377,6 @@ typedef struct drm_sg_mem {
|
||||||
unsigned long handle;
|
unsigned long handle;
|
||||||
void *virtual;
|
void *virtual;
|
||||||
int pages;
|
int pages;
|
||||||
struct page **pagelist;
|
|
||||||
dma_addr_t *busaddr;
|
dma_addr_t *busaddr;
|
||||||
} drm_sg_mem_t;
|
} drm_sg_mem_t;
|
||||||
|
|
||||||
|
@ -386,10 +385,23 @@ typedef struct drm_sigdata {
|
||||||
drm_hw_lock_t *lock;
|
drm_hw_lock_t *lock;
|
||||||
} drm_sigdata_t;
|
} drm_sigdata_t;
|
||||||
|
|
||||||
|
typedef struct drm_local_map {
|
||||||
|
unsigned long offset; /* Physical address (0 for SAREA)*/
|
||||||
|
unsigned long size; /* Physical size (bytes) */
|
||||||
|
drm_map_type_t type; /* Type of memory mapped */
|
||||||
|
drm_map_flags_t flags; /* Flags */
|
||||||
|
void *handle; /* User-space: "Handle" to pass to mmap */
|
||||||
|
/* Kernel-space: kernel-virtual address */
|
||||||
|
int mtrr; /* MTRR slot used */
|
||||||
|
/* Private data */
|
||||||
|
bus_space_tag_t iot;
|
||||||
|
bus_space_handle_t ioh;
|
||||||
|
} drm_local_map_t;
|
||||||
|
|
||||||
typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t;
|
typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t;
|
||||||
typedef struct drm_map_list_entry {
|
typedef struct drm_map_list_entry {
|
||||||
TAILQ_ENTRY(drm_map_list_entry) link;
|
TAILQ_ENTRY(drm_map_list_entry) link;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
} drm_map_list_entry_t;
|
} drm_map_list_entry_t;
|
||||||
|
|
||||||
TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
|
TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
|
||||||
|
@ -440,7 +452,7 @@ struct drm_device {
|
||||||
drm_map_list_t *maplist; /* Linked list of regions */
|
drm_map_list_t *maplist; /* Linked list of regions */
|
||||||
int map_count; /* Number of mappable regions */
|
int map_count; /* Number of mappable regions */
|
||||||
|
|
||||||
drm_map_t **context_sareas;
|
drm_local_map_t **context_sareas;
|
||||||
int max_context;
|
int max_context;
|
||||||
|
|
||||||
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
||||||
|
@ -454,9 +466,9 @@ struct drm_device {
|
||||||
drm_device_dma_t *dma; /* Optional pointer for DMA support */
|
drm_device_dma_t *dma; /* Optional pointer for DMA support */
|
||||||
|
|
||||||
/* Context support */
|
/* Context support */
|
||||||
#ifdef __FreeBSD__
|
|
||||||
int irq; /* Interrupt used by board */
|
int irq; /* Interrupt used by board */
|
||||||
int irqrid; /* Interrupt used by board */
|
int irqrid; /* Interrupt used by board */
|
||||||
|
#ifdef __FreeBSD__
|
||||||
struct resource *irqr; /* Resource for interrupt used by board */
|
struct resource *irqr; /* Resource for interrupt used by board */
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
struct pci_attach_args pa;
|
struct pci_attach_args pa;
|
||||||
|
@ -530,15 +542,16 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s);
|
||||||
|
|
||||||
/* Memory management support (drm_memory.h) */
|
/* Memory management support (drm_memory.h) */
|
||||||
extern void DRM(mem_init)(void);
|
extern void DRM(mem_init)(void);
|
||||||
|
extern void DRM(mem_uninit)(void);
|
||||||
extern void *DRM(alloc)(size_t size, int area);
|
extern void *DRM(alloc)(size_t size, int area);
|
||||||
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
|
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
|
||||||
int area);
|
int area);
|
||||||
extern char *DRM(strdup)(const char *s, int area);
|
extern char *DRM(strdup)(const char *s, int area);
|
||||||
extern void DRM(strfree)(char *s, int area);
|
extern void DRM(strfree)(char *s, int area);
|
||||||
extern void DRM(free)(void *pt, size_t size, int area);
|
extern void DRM(free)(void *pt, size_t size, int area);
|
||||||
extern void *DRM(ioremap)(unsigned long offset, unsigned long size);
|
extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map);
|
||||||
extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size);
|
extern void *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map);
|
||||||
extern void DRM(ioremapfree)(void *pt, unsigned long size);
|
extern void DRM(ioremapfree)(drm_local_map_t *map);
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
|
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
|
||||||
|
|
|
@ -37,7 +37,8 @@ int DRM(agp_info)(DRM_IOCTL_ARGS)
|
||||||
struct agp_info *kern;
|
struct agp_info *kern;
|
||||||
drm_agp_info_t info;
|
drm_agp_info_t info;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
kern = &dev->agp->info;
|
kern = &dev->agp->info;
|
||||||
agp_get_info(dev->agp->agpdev, kern);
|
agp_get_info(dev->agp->agpdev, kern);
|
||||||
|
@ -60,9 +61,11 @@ int DRM(agp_acquire)(DRM_IOCTL_ARGS)
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
if (!dev->agp || dev->agp->acquired) return EINVAL;
|
if (!dev->agp || dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
retcode = agp_acquire(dev->agp->agpdev);
|
retcode = agp_acquire(dev->agp->agpdev);
|
||||||
if (retcode) return retcode;
|
if (retcode)
|
||||||
|
return retcode;
|
||||||
dev->agp->acquired = 1;
|
dev->agp->acquired = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +96,8 @@ int DRM(agp_enable)(DRM_IOCTL_ARGS)
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_agp_mode_t mode;
|
drm_agp_mode_t mode;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
mode = *(drm_agp_mode_t *) data;
|
mode = *(drm_agp_mode_t *) data;
|
||||||
|
|
||||||
|
@ -114,7 +118,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS)
|
||||||
u_int32_t type;
|
u_int32_t type;
|
||||||
struct agp_memory_info info;
|
struct agp_memory_info info;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
request = *(drm_agp_buffer_t *) data;
|
request = *(drm_agp_buffer_t *) data;
|
||||||
|
|
||||||
|
@ -136,7 +141,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS)
|
||||||
entry->pages = pages;
|
entry->pages = pages;
|
||||||
entry->prev = NULL;
|
entry->prev = NULL;
|
||||||
entry->next = dev->agp->memory;
|
entry->next = dev->agp->memory;
|
||||||
if (dev->agp->memory) dev->agp->memory->prev = entry;
|
if (dev->agp->memory)
|
||||||
|
dev->agp->memory->prev = entry;
|
||||||
dev->agp->memory = entry;
|
dev->agp->memory = entry;
|
||||||
|
|
||||||
agp_memory_info(dev->agp->agpdev, entry->handle, &info);
|
agp_memory_info(dev->agp->agpdev, entry->handle, &info);
|
||||||
|
@ -166,7 +172,8 @@ int DRM(agp_unbind)(DRM_IOCTL_ARGS)
|
||||||
drm_agp_mem_t *entry;
|
drm_agp_mem_t *entry;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
request = *(drm_agp_binding_t *) data;
|
request = *(drm_agp_binding_t *) data;
|
||||||
if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
|
if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -209,15 +216,20 @@ int DRM(agp_free)(DRM_IOCTL_ARGS)
|
||||||
drm_agp_buffer_t request;
|
drm_agp_buffer_t request;
|
||||||
drm_agp_mem_t *entry;
|
drm_agp_mem_t *entry;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
request = *(drm_agp_buffer_t *) data;
|
request = *(drm_agp_buffer_t *) data;
|
||||||
if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle)))
|
if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (entry->bound) DRM(unbind_agp)(entry->handle);
|
if (entry->bound)
|
||||||
|
DRM(unbind_agp)(entry->handle);
|
||||||
|
|
||||||
if (entry->prev) entry->prev->next = entry->next;
|
if (entry->prev)
|
||||||
else dev->agp->memory = entry->next;
|
entry->prev->next = entry->next;
|
||||||
if (entry->next) entry->next->prev = entry->prev;
|
else
|
||||||
|
dev->agp->memory = entry->next;
|
||||||
|
if (entry->next)
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
DRM(free_agp)(entry->handle, entry->pages);
|
DRM(free_agp)(entry->handle, entry->pages);
|
||||||
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -116,25 +116,20 @@ int DRM(getmagic)(DRM_IOCTL_ARGS)
|
||||||
{
|
{
|
||||||
static drm_magic_t sequence = 0;
|
static drm_magic_t sequence = 0;
|
||||||
drm_auth_t auth;
|
drm_auth_t auth;
|
||||||
static DRM_SPINTYPE lock;
|
|
||||||
static int first = 1;
|
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
DRM_PRIV;
|
DRM_PRIV;
|
||||||
|
|
||||||
if (first) {
|
|
||||||
DRM_SPININIT(lock, "drm getmagic");
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find unique magic */
|
/* Find unique magic */
|
||||||
if (priv->magic) {
|
if (priv->magic) {
|
||||||
auth.magic = priv->magic;
|
auth.magic = priv->magic;
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
DRM_SPINLOCK(&lock);
|
int old = sequence;
|
||||||
if (!sequence) ++sequence; /* reserve 0 */
|
|
||||||
auth.magic = sequence++;
|
auth.magic = old+1;
|
||||||
DRM_SPINUNLOCK(&lock);
|
|
||||||
|
if (!atomic_cmpset_int(&sequence, old, auth.magic))
|
||||||
|
continue;
|
||||||
} while (DRM(find_file)(dev, auth.magic));
|
} while (DRM(find_file)(dev, auth.magic));
|
||||||
priv->magic = auth.magic;
|
priv->magic = auth.magic;
|
||||||
DRM(add_magic)(dev, priv, auth.magic);
|
DRM(add_magic)(dev, priv, auth.magic);
|
||||||
|
|
|
@ -69,18 +69,26 @@ int DRM(order)( unsigned long size )
|
||||||
int DRM(addmap)( DRM_IOCTL_ARGS )
|
int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t *map;
|
drm_map_t request;
|
||||||
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
|
|
||||||
if (!(dev->flags & (FREAD|FWRITE)))
|
if (!(dev->flags & (FREAD|FWRITE)))
|
||||||
return DRM_ERR(EACCES); /* Require read/write */
|
return DRM_ERR(EACCES); /* Require read/write */
|
||||||
|
|
||||||
map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) );
|
||||||
|
|
||||||
|
map = (drm_local_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
|
||||||
if ( !map )
|
if ( !map )
|
||||||
return DRM_ERR(ENOMEM);
|
return DRM_ERR(ENOMEM);
|
||||||
|
|
||||||
*map = *(drm_map_t *)data;
|
map->offset = request.offset;
|
||||||
|
map->size = request.size;
|
||||||
|
map->type = request.type;
|
||||||
|
map->flags = request.flags;
|
||||||
|
map->mtrr = -1;
|
||||||
|
map->handle = 0;
|
||||||
|
|
||||||
/* Only allow shared memory to be removable since we only keep enough
|
/* Only allow shared memory to be removable since we only keep enough
|
||||||
* book keeping information about shared memory to allow for removal
|
* book keeping information about shared memory to allow for removal
|
||||||
* when processes fork.
|
* when processes fork.
|
||||||
|
@ -95,22 +103,14 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
map->mtrr = -1;
|
|
||||||
map->handle = 0;
|
|
||||||
|
|
||||||
switch ( map->type ) {
|
switch ( map->type ) {
|
||||||
case _DRM_REGISTERS:
|
case _DRM_REGISTERS:
|
||||||
case _DRM_FRAME_BUFFER:
|
case _DRM_FRAME_BUFFER:
|
||||||
#if !defined(__sparc__) && !defined(__alpha__)
|
if ( map->offset + map->size < map->offset ) {
|
||||||
if ( map->offset + map->size < map->offset
|
|
||||||
) {
|
|
||||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef __alpha__
|
|
||||||
map->offset += dev->hose->mem_space->start;
|
|
||||||
#endif
|
|
||||||
#if __REALLY_HAVE_MTRR
|
#if __REALLY_HAVE_MTRR
|
||||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||||
|
@ -130,14 +130,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
mtrrmap.base = map->offset;
|
mtrrmap.base = map->offset;
|
||||||
mtrrmap.len = map->size;
|
mtrrmap.len = map->size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = MTRR_PRIVATE | MTRR_VALID;
|
mtrrmap.flags = MTRR_VALID;
|
||||||
mtrrmap.owner = p->p_pid;
|
map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL );
|
||||||
/* USER? KERNEL? XXX */
|
|
||||||
map->mtrr = mtrr_get( &mtrrmap, &one, p, MTRR_GETSET_KERNEL );
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* __REALLY_HAVE_MTRR */
|
#endif /* __REALLY_HAVE_MTRR */
|
||||||
map->handle = DRM(ioremap)( map->offset, map->size );
|
DRM_IOREMAP(map);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
|
@ -155,9 +153,6 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
break;
|
break;
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
case _DRM_AGP:
|
case _DRM_AGP:
|
||||||
#ifdef __alpha__
|
|
||||||
map->offset += dev->hose->mem_space->start;
|
|
||||||
#endif
|
|
||||||
map->offset += dev->agp->base;
|
map->offset += dev->agp->base;
|
||||||
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
||||||
break;
|
break;
|
||||||
|
@ -187,11 +182,19 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
TAILQ_INSERT_TAIL(dev->maplist, list, link);
|
TAILQ_INSERT_TAIL(dev->maplist, list, link);
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
|
|
||||||
*(drm_map_t *)data = *map;
|
request.offset = map->offset;
|
||||||
|
request.size = map->size;
|
||||||
|
request.type = map->type;
|
||||||
|
request.flags = map->flags;
|
||||||
|
request.mtrr = map->mtrr;
|
||||||
|
request.handle = map->handle;
|
||||||
|
|
||||||
if ( map->type != _DRM_SHM ) {
|
if ( request.type != _DRM_SHM ) {
|
||||||
((drm_map_t *)data)->handle = (void *)map->offset;
|
request.handle = (void *)request.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, request, sizeof(drm_map_t) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +207,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_t request;
|
drm_map_t request;
|
||||||
int found_maps = 0;
|
int found_maps = 0;
|
||||||
|
|
||||||
|
@ -257,7 +260,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRM(ioremapfree)(map->handle, map->size);
|
DRM(ioremapfree)( map );
|
||||||
break;
|
break;
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
DRM(free)( map->handle, map->size, DRM_MEM_SAREA );
|
DRM(free)( map->handle, map->size, DRM_MEM_SAREA );
|
||||||
|
@ -1018,6 +1021,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS )
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
struct vnode *vn;
|
struct vnode *vn;
|
||||||
|
struct vmspace *vms = p->p_vmspace;
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
drm_buf_map_t request;
|
drm_buf_map_t request;
|
||||||
|
@ -1043,7 +1047,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS )
|
||||||
if ( request.count >= dma->buf_count ) {
|
if ( request.count >= dma->buf_count ) {
|
||||||
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
||||||
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
||||||
drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
||||||
|
|
||||||
if ( !map ) {
|
if ( !map ) {
|
||||||
retcode = EINVAL;
|
retcode = EINVAL;
|
||||||
|
|
|
@ -69,7 +69,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
||||||
if((bit+1) > dev->max_context) {
|
if((bit+1) > dev->max_context) {
|
||||||
dev->max_context = (bit+1);
|
dev->max_context = (bit+1);
|
||||||
if(dev->context_sareas) {
|
if(dev->context_sareas) {
|
||||||
drm_map_t **ctx_sareas;
|
drm_local_map_t **ctx_sareas;
|
||||||
|
|
||||||
ctx_sareas = DRM(realloc)(dev->context_sareas,
|
ctx_sareas = DRM(realloc)(dev->context_sareas,
|
||||||
(dev->max_context - 1) *
|
(dev->max_context - 1) *
|
||||||
|
@ -149,7 +149,7 @@ int DRM(getsareactx)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_ctx_priv_map_t request;
|
drm_ctx_priv_map_t request;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||||
sizeof(request) );
|
sizeof(request) );
|
||||||
|
@ -174,7 +174,7 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_ctx_priv_map_t request;
|
drm_ctx_priv_map_t request;
|
||||||
drm_map_t *map = NULL;
|
drm_local_map_t *map = NULL;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||||
|
@ -183,24 +183,20 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS )
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
TAILQ_FOREACH(list, dev->maplist, link) {
|
TAILQ_FOREACH(list, dev->maplist, link) {
|
||||||
map=list->map;
|
map=list->map;
|
||||||
if(map->handle == request.handle)
|
if(map->handle == request.handle) {
|
||||||
goto found;
|
if (dev->max_context < 0)
|
||||||
|
goto bad;
|
||||||
|
if (request.ctx_id >= (unsigned) dev->max_context)
|
||||||
|
goto bad;
|
||||||
|
dev->context_sareas[request.ctx_id] = map;
|
||||||
|
DRM_UNLOCK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
|
|
||||||
found:
|
|
||||||
map = list->map;
|
|
||||||
if (!map) goto bad;
|
|
||||||
if (dev->max_context < 0)
|
|
||||||
goto bad;
|
|
||||||
if (request.ctx_id >= (unsigned) dev->max_context)
|
|
||||||
goto bad;
|
|
||||||
dev->context_sareas[request.ctx_id] = map;
|
|
||||||
DRM_UNLOCK;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
|
|
|
@ -534,9 +534,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
||||||
|
|
||||||
/* Install handler */
|
/* Install handler */
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid,
|
dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid,
|
||||||
0, ~0, 1, RF_SHAREABLE);
|
0, ~0, 1, RF_SHAREABLE);
|
||||||
if (!dev->irqr) {
|
if (!dev->irqr) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
if (pci_intr_map(&dev->pa, &dev->ih) != 0) {
|
||||||
|
#endif
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
dev->irq = 0;
|
dev->irq = 0;
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
|
@ -544,11 +548,24 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#if __FreeBSD_version < 500000
|
||||||
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
|
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
|
||||||
DRM(dma_service), dev, &dev->irqh);
|
DRM(dma_service), dev, &dev->irqh);
|
||||||
|
#else
|
||||||
|
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE,
|
||||||
|
DRM(dma_service), dev, &dev->irqh);
|
||||||
|
#endif
|
||||||
if ( retcode ) {
|
if ( retcode ) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY,
|
||||||
|
(int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev);
|
||||||
|
if ( !dev->irqh ) {
|
||||||
|
#endif
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
|
bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
|
||||||
|
#endif
|
||||||
dev->irq = 0;
|
dev->irq = 0;
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
|
@ -580,9 +597,13 @@ int DRM(irq_uninstall)( drm_device_t *dev )
|
||||||
|
|
||||||
DRM(driver_irq_uninstall)( dev );
|
DRM(driver_irq_uninstall)( dev );
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
||||||
bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
|
bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,16 +125,10 @@
|
||||||
#define DRIVER_NUM_CARDS 1
|
#define DRIVER_NUM_CARDS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static int DRM(init)(device_t nbdev);
|
static int DRM(init)(device_t nbdev);
|
||||||
static void DRM(cleanup)(device_t nbdev);
|
static void DRM(cleanup)(device_t nbdev);
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static int DRM(init)(drm_device_t *);
|
|
||||||
static void DRM(cleanup)(drm_device_t *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#define CDEV_MAJOR 145
|
|
||||||
#define DRIVER_SOFTC(unit) \
|
#define DRIVER_SOFTC(unit) \
|
||||||
((drm_device_t *) devclass_get_softc(DRM(devclass), unit))
|
((drm_device_t *) devclass_get_softc(DRM(devclass), unit))
|
||||||
|
|
||||||
|
@ -147,9 +141,8 @@ MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1);
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
#define CDEV_MAJOR 90
|
|
||||||
#define DRIVER_SOFTC(unit) \
|
#define DRIVER_SOFTC(unit) \
|
||||||
((drm_device_t *) device_lookup(&DRM(_cd), unit))
|
((drm_device_t *) device_lookup(&DRM(cd), unit))
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
static drm_ioctl_desc_t DRM(ioctls)[] = {
|
static drm_ioctl_desc_t DRM(ioctls)[] = {
|
||||||
|
@ -229,6 +222,27 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
||||||
const char *DRM(find_description)(int vendor, int device);
|
const char *DRM(find_description)(int vendor, int device);
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
static struct cdevsw DRM(cdevsw) = {
|
||||||
|
/* open */ DRM( open ),
|
||||||
|
/* close */ DRM( close ),
|
||||||
|
/* read */ DRM( read ),
|
||||||
|
/* write */ DRM( write ),
|
||||||
|
/* ioctl */ DRM( ioctl ),
|
||||||
|
/* poll */ DRM( poll ),
|
||||||
|
/* mmap */ DRM( mmap ),
|
||||||
|
/* strategy */ nostrategy,
|
||||||
|
/* name */ DRIVER_NAME,
|
||||||
|
/* maj */ CDEV_MAJOR,
|
||||||
|
/* dump */ nodump,
|
||||||
|
/* psize */ nopsize,
|
||||||
|
/* flags */ D_TTY | D_TRACKCLOSE,
|
||||||
|
#if __FreeBSD_version >= 500000
|
||||||
|
/* kqfilter */ 0
|
||||||
|
#else
|
||||||
|
/* bmaj */ -1
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static int DRM(probe)(device_t dev)
|
static int DRM(probe)(device_t dev)
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
|
@ -271,57 +285,108 @@ static driver_t DRM(driver) = {
|
||||||
sizeof(drm_device_t),
|
sizeof(drm_device_t),
|
||||||
};
|
};
|
||||||
|
|
||||||
static devclass_t DRM( devclass);
|
static devclass_t DRM(devclass);
|
||||||
|
|
||||||
static struct cdevsw DRM( cdevsw) = {
|
|
||||||
/* open */ DRM( open ),
|
|
||||||
/* close */ DRM( close ),
|
|
||||||
/* read */ DRM( read ),
|
|
||||||
/* write */ DRM( write ),
|
|
||||||
/* ioctl */ DRM( ioctl ),
|
|
||||||
/* poll */ DRM( poll ),
|
|
||||||
/* mmap */ DRM( mmap ),
|
|
||||||
/* strategy */ nostrategy,
|
|
||||||
/* name */ DRIVER_NAME,
|
|
||||||
/* maj */ CDEV_MAJOR,
|
|
||||||
/* dump */ nodump,
|
|
||||||
/* psize */ nopsize,
|
|
||||||
/* flags */ D_TTY | D_TRACKCLOSE,
|
|
||||||
#if __FreeBSD_version >= 500000
|
|
||||||
/* kqfilter */ 0
|
|
||||||
#else
|
|
||||||
/* bmaj */ -1
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
int DRM(probe)(struct device *parent, struct cfdata *match, void *aux);
|
|
||||||
void DRM(attach)(struct device *parent, struct device *self, void *aux);
|
|
||||||
int DRM(detach)(struct device *self, int flags);
|
|
||||||
int DRM(activate)(struct device *self, enum devact act);
|
|
||||||
|
|
||||||
struct cfattach DRM(_ca) = {
|
static struct cdevsw DRM(cdevsw) = {
|
||||||
sizeof(drm_device_t), DRM(probe),
|
DRM(open),
|
||||||
DRM(attach), DRM(detach), DRM(activate) };
|
DRM(close),
|
||||||
|
DRM(read),
|
||||||
int DRM(probe)(struct device *parent, struct cfdata *match, void *aux)
|
DRM(write),
|
||||||
|
DRM(ioctl),
|
||||||
|
nostop,
|
||||||
|
notty,
|
||||||
|
DRM(poll),
|
||||||
|
DRM(mmap),
|
||||||
|
nokqfilter,
|
||||||
|
D_TTY
|
||||||
|
};
|
||||||
|
|
||||||
|
int DRM(refcnt) = 0;
|
||||||
|
#if __NetBSD_Version__ >= 106080000
|
||||||
|
MOD_DEV( DRIVER_NAME, DRIVER_NAME, NULL, -1, &DRM(cdevsw), CDEV_MAJOR);
|
||||||
|
#else
|
||||||
|
MOD_DEV( DRIVER_NAME, LM_DT_CHAR, CDEV_MAJOR, &DRM(cdevsw) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver);
|
||||||
|
static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd);
|
||||||
|
|
||||||
|
int DRM(modprobe)();
|
||||||
|
int DRM(probe)(struct pci_attach_args *pa);
|
||||||
|
void DRM(attach)(struct pci_attach_args *pa, dev_t kdev);
|
||||||
|
|
||||||
|
int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver) {
|
||||||
|
DISPATCH(lkmtp, cmd, ver, DRM(lkmhandle), DRM(lkmhandle), DRM(lkmhandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd)
|
||||||
|
{
|
||||||
|
int j, error = 0;
|
||||||
|
#if defined(__NetBSD__) && (__NetBSD_Version__ > 106080000)
|
||||||
|
struct lkm_dev *args = lkmtp->private.lkm_dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(cmd) {
|
||||||
|
case LKM_E_LOAD:
|
||||||
|
if (lkmexists(lkmtp))
|
||||||
|
return EEXIST;
|
||||||
|
|
||||||
|
if(DRM(modprobe)())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case LKM_E_UNLOAD:
|
||||||
|
if (DRM(refcnt) > 0)
|
||||||
|
return (EBUSY);
|
||||||
|
break;
|
||||||
|
case LKM_E_STAT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error = EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DRM(modprobe)() {
|
||||||
|
struct pci_attach_args pa;
|
||||||
|
int error = 0;
|
||||||
|
if((error = pci_find_device(&pa, DRM(probe))) != 0)
|
||||||
|
DRM(attach)(&pa, 0);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DRM(probe)(struct pci_attach_args *pa)
|
||||||
{
|
{
|
||||||
struct pci_attach_args *pa = aux;
|
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
|
||||||
desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
|
desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
|
||||||
if (desc != NULL)
|
if (desc != NULL) {
|
||||||
return 10;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRM(attach)(struct device *parent, struct device *self, void *aux)
|
void DRM(attach)(struct pci_attach_args *pa, dev_t kdev)
|
||||||
{
|
{
|
||||||
struct pci_attach_args *pa = aux;
|
int i;
|
||||||
drm_device_t *dev = (drm_device_t *)self;
|
drm_device_t *dev;
|
||||||
|
|
||||||
memcpy(&dev->pa, aux, sizeof(dev->pa));
|
config_makeroom(kdev, &DRM(cd));
|
||||||
|
DRM(cd).cd_devs[(kdev)] = DRM(alloc)(sizeof(drm_device_t),
|
||||||
|
DRM_MEM_DRIVER);
|
||||||
|
dev = DRIVER_SOFTC(kdev);
|
||||||
|
|
||||||
|
memset(dev, 0, sizeof(drm_device_t));
|
||||||
|
memcpy(&dev->pa, pa, sizeof(dev->pa));
|
||||||
|
|
||||||
DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)));
|
DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)));
|
||||||
DRM(init)(dev);
|
DRM(init)(dev);
|
||||||
}
|
}
|
||||||
|
@ -345,8 +410,7 @@ int DRM(activate)(struct device *self, enum devact act)
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif /* __NetBSD__ */
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *DRM(find_description)(int vendor, int device) {
|
const char *DRM(find_description)(int vendor, int device) {
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
|
@ -487,7 +551,7 @@ static int DRM(setup)( drm_device_t *dev )
|
||||||
static int DRM(takedown)( drm_device_t *dev )
|
static int DRM(takedown)( drm_device_t *dev )
|
||||||
{
|
{
|
||||||
drm_magic_entry_t *pt, *next;
|
drm_magic_entry_t *pt, *next;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
drm_vma_entry_t *vma, *vma_next;
|
drm_vma_entry_t *vma, *vma_next;
|
||||||
int i;
|
int i;
|
||||||
|
@ -581,15 +645,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
||||||
mtrrmap.len = map->size;
|
mtrrmap.len = map->size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = 0;
|
mtrrmap.flags = 0;
|
||||||
/*mtrrmap.owner = p->p_pid;*/
|
|
||||||
/* XXX: Use curproc here? */
|
|
||||||
retcode = mtrr_set( &mtrrmap, &one,
|
retcode = mtrr_set( &mtrrmap, &one,
|
||||||
DRM_CURPROC, MTRR_GETSET_KERNEL);
|
DRM_CURPROC, MTRR_GETSET_KERNEL);
|
||||||
#endif
|
#endif
|
||||||
DRM_DEBUG( "mtrr_del=%d\n", retcode );
|
DRM_DEBUG( "mtrr_del=%d\n", retcode );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRM(ioremapfree)( map->handle, map->size );
|
DRM(ioremapfree)( map );
|
||||||
break;
|
break;
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
DRM(free)(map->handle,
|
DRM(free)(map->handle,
|
||||||
|
@ -658,15 +720,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
||||||
* linux/init/main.c (this is not currently supported).
|
* linux/init/main.c (this is not currently supported).
|
||||||
* bsd: drm_init is called via the attach function per device.
|
* bsd: drm_init is called via the attach function per device.
|
||||||
*/
|
*/
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static int DRM(init)( device_t nbdev )
|
static int DRM(init)( device_t nbdev )
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static int DRM(init)( drm_device_t *dev )
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int unit;
|
int unit;
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
drm_device_t *dev;
|
drm_device_t *dev;
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
drm_device_t *dev = nbdev;
|
||||||
#endif
|
#endif
|
||||||
#if __HAVE_CTX_BITMAP
|
#if __HAVE_CTX_BITMAP
|
||||||
int retcode;
|
int retcode;
|
||||||
|
@ -724,7 +784,6 @@ static int DRM(init)( drm_device_t *dev )
|
||||||
struct mtrr mtrrmap;
|
struct mtrr mtrrmap;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
mtrrmap.base = dev->agp->info.ai_aperture_base;
|
mtrrmap.base = dev->agp->info.ai_aperture_base;
|
||||||
/* Might need a multiplier here XXX */
|
|
||||||
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = MTRR_VALID;
|
mtrrmap.flags = MTRR_VALID;
|
||||||
|
@ -763,21 +822,16 @@ static int DRM(init)( drm_device_t *dev )
|
||||||
* bsd: drm_cleanup is called per device at module unload time.
|
* bsd: drm_cleanup is called per device at module unload time.
|
||||||
* FIXME: NetBSD
|
* FIXME: NetBSD
|
||||||
*/
|
*/
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static void DRM(cleanup)(device_t nbdev)
|
static void DRM(cleanup)(device_t nbdev)
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static void DRM(cleanup)(drm_device_t *dev)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifdef __FreeBSD__
|
|
||||||
drm_device_t *dev;
|
drm_device_t *dev;
|
||||||
#endif
|
|
||||||
#if __REALLY_HAVE_MTRR
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
|
#if __REALLY_HAVE_MTRR
|
||||||
struct mtrr mtrrmap;
|
struct mtrr mtrrmap;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
#endif /* __NetBSD__ */
|
|
||||||
#endif /* __REALLY_HAVE_MTRR */
|
#endif /* __REALLY_HAVE_MTRR */
|
||||||
|
dev = nbdev;
|
||||||
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
DRM_DEBUG( "\n" );
|
DRM_DEBUG( "\n" );
|
||||||
|
|
||||||
|
@ -799,7 +853,7 @@ static void DRM(cleanup)(drm_device_t *dev)
|
||||||
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
||||||
mtrrmap.type = 0;
|
mtrrmap.type = 0;
|
||||||
mtrrmap.flags = 0;
|
mtrrmap.flags = 0;
|
||||||
retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
|
mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -814,6 +868,8 @@ static void DRM(cleanup)(drm_device_t *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRIVER_POSTCLEANUP();
|
DRIVER_POSTCLEANUP();
|
||||||
|
DRM(mem_uninit)();
|
||||||
|
DRM_SPINUNINIT(dev->count_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,7 +982,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
||||||
}
|
}
|
||||||
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
||||||
DRM_KERNEL_CONTEXT ) ) {
|
DRM_KERNEL_CONTEXT ) ) {
|
||||||
dev->lock.pid = p->p_pid;
|
dev->lock.pid = DRM_CURRENTPID;
|
||||||
dev->lock.lock_time = jiffies;
|
dev->lock.lock_time = jiffies;
|
||||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||||
break; /* Got lock */
|
break; /* Got lock */
|
||||||
|
@ -1043,7 +1099,6 @@ int DRM(ioctl)( DRM_IOCTL_ARGS )
|
||||||
*(int *) data = fgetown(dev->buf_sigio);
|
*(int *) data = fgetown(dev->buf_sigio);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
|
@ -1056,6 +1111,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS )
|
||||||
*(int *)data = dev->buf_pgid;
|
*(int *)data = dev->buf_pgid;
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
}
|
||||||
|
|
||||||
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
||||||
retcode = EINVAL;
|
retcode = EINVAL;
|
||||||
|
|
|
@ -100,7 +100,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p,
|
||||||
the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
|
the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
|
||||||
DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
|
DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
|
||||||
|
|
||||||
ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag)
|
int DRM(read)(dev_t kdev, struct uio *uio, int ioflag)
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
int left;
|
int left;
|
||||||
|
@ -182,8 +182,8 @@ int DRM(write_string)(drm_device_t *dev, const char *s)
|
||||||
selwakeup(&dev->buf_sel);
|
selwakeup(&dev->buf_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio);
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio);
|
||||||
if (dev->buf_sigio) {
|
if (dev->buf_sigio) {
|
||||||
DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid);
|
DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid);
|
||||||
#if __FreeBSD_version >= 500000
|
#if __FreeBSD_version >= 500000
|
||||||
|
@ -200,6 +200,7 @@ int DRM(write_string)(drm_device_t *dev, const char *s)
|
||||||
gsignal(dev->buf_pgid, SIGIO);
|
gsignal(dev->buf_pgid, SIGIO);
|
||||||
else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL)
|
else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL)
|
||||||
psignal(p, SIGIO);
|
psignal(p, SIGIO);
|
||||||
|
}
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
DRM_DEBUG("waking\n");
|
DRM_DEBUG("waking\n");
|
||||||
wakeup(&dev->buf_rp);
|
wakeup(&dev->buf_rp);
|
||||||
|
|
|
@ -136,7 +136,7 @@ int DRM(getmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t map;
|
drm_map_t map;
|
||||||
drm_map_t *mapinlist;
|
drm_local_map_t *mapinlist;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
int idx;
|
int idx;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -47,14 +47,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
|
|
||||||
char failed;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
||||||
else new = context | _DRM_LOCK_HELD;
|
else new = context | _DRM_LOCK_HELD;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
||||||
if (old & _DRM_LOCK_HELD) {
|
if (old & _DRM_LOCK_HELD) {
|
||||||
if (context != DRM_KERNEL_CONTEXT) {
|
if (context != DRM_KERNEL_CONTEXT) {
|
||||||
|
@ -77,14 +75,13 @@ int DRM(lock_transfer)(drm_device_t *dev,
|
||||||
__volatile__ unsigned int *lock, unsigned int context)
|
__volatile__ unsigned int *lock, unsigned int context)
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
char failed;
|
|
||||||
|
|
||||||
dev->lock.pid = 0;
|
dev->lock.pid = 0;
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
new = context | _DRM_LOCK_HELD;
|
new = context | _DRM_LOCK_HELD;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,14 +90,13 @@ int DRM(lock_free)(drm_device_t *dev,
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
pid_t pid = dev->lock.pid;
|
pid_t pid = dev->lock.pid;
|
||||||
char failed;
|
|
||||||
|
|
||||||
dev->lock.pid = 0;
|
dev->lock.pid = 0;
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
new = 0;
|
new = 0;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
||||||
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
|
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
|
||||||
context,
|
context,
|
||||||
|
@ -224,8 +220,6 @@ int DRM(notifier)(void *priv)
|
||||||
{
|
{
|
||||||
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
char failed;
|
|
||||||
|
|
||||||
|
|
||||||
/* Allow signal delivery if lock isn't held */
|
/* Allow signal delivery if lock isn't held */
|
||||||
if (!_DRM_LOCK_IS_HELD(s->lock->lock)
|
if (!_DRM_LOCK_IS_HELD(s->lock->lock)
|
||||||
|
@ -236,8 +230,8 @@ int DRM(notifier)(void *priv)
|
||||||
do {
|
do {
|
||||||
old = s->lock->lock;
|
old = s->lock->lock;
|
||||||
new = old | _DRM_LOCK_CONT;
|
new = old | _DRM_LOCK_CONT;
|
||||||
_DRM_CAS(&s->lock->lock, old, new, failed);
|
} while (!atomic_cmpset_int(&s->lock->lock, old, new));
|
||||||
} while (failed);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
#define malloctype DRM(M_DRM)
|
#define malloctype DRM(M_DRM)
|
||||||
/* The macros confliced in the MALLOC_DEFINE */
|
/* The macros conflicted in the MALLOC_DEFINE */
|
||||||
|
|
||||||
MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
|
MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
|
||||||
|
|
||||||
|
@ -81,6 +81,10 @@ void DRM(mem_init)(void)
|
||||||
{
|
{
|
||||||
drm_mem_stats_t *mem;
|
drm_mem_stats_t *mem;
|
||||||
|
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
malloc_type_attach(DRM(M_DRM));
|
||||||
|
#endif
|
||||||
|
|
||||||
DRM_SPININIT(DRM(mem_lock), "drm memory");
|
DRM_SPININIT(DRM(mem_lock), "drm memory");
|
||||||
|
|
||||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||||
|
@ -95,9 +99,15 @@ void DRM(mem_init)(void)
|
||||||
DRM(ram_used) = 0;
|
DRM(ram_used) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRM(mem_uninit)(void)
|
||||||
|
{
|
||||||
|
DRM_SPINUNINIT(DRM(mem_lock));
|
||||||
|
}
|
||||||
|
|
||||||
#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_SYSCTL_HANDLER_ARGS
|
static int DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
|
||||||
|
int arg2, struct sysctl_req *req)
|
||||||
{
|
{
|
||||||
drm_mem_stats_t *pt;
|
drm_mem_stats_t *pt;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
@ -112,7 +122,7 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
|
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
|
||||||
"locked", 0, 0, 0, DRM(ram_used));
|
"locked", 0, 0, 0, DRM(ram_used));
|
||||||
DRM_SYSCTL_PRINT("\n");
|
DRM_SYSCTL_PRINT("\n");
|
||||||
for (pt = DRM(mem_stats); pt->name; pt++) {
|
for (pt = stats; pt->name; pt++) {
|
||||||
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
||||||
pt->name,
|
pt->name,
|
||||||
pt->succeed_count,
|
pt->succeed_count,
|
||||||
|
@ -132,13 +142,22 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
|
int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
drm_mem_stats_t *stats;
|
||||||
|
|
||||||
|
stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT);
|
||||||
|
if (stats == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
ret = DRM(_mem_info)(oidp, arg1, arg2, req);
|
bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats)));
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
|
||||||
|
ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req);
|
||||||
|
|
||||||
|
free(stats, DRM(M_DRM));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
void *DRM(alloc)(size_t size, int area)
|
void *DRM(alloc)(size_t size, int area)
|
||||||
{
|
{
|
||||||
|
@ -149,11 +168,7 @@ void *DRM(alloc)(size_t size, int area)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
|
if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) {
|
|
||||||
#endif
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[area].fail_count;
|
++DRM(mem_stats)[area].fail_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
@ -203,13 +218,10 @@ void DRM(free)(void *pt, size_t size, int area)
|
||||||
int alloc_count;
|
int alloc_count;
|
||||||
int free_count;
|
int free_count;
|
||||||
|
|
||||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
if (!pt)
|
||||||
|
DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||||
else
|
else
|
||||||
#ifdef __FreeBSD__
|
free(pt, DRM(M_DRM));
|
||||||
free(pt, DRM(M_DRM));
|
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
free(pt, M_DEVBUF);
|
|
||||||
#endif
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
DRM(mem_stats)[area].bytes_freed += size;
|
DRM(mem_stats)[area].bytes_freed += size;
|
||||||
free_count = ++DRM(mem_stats)[area].free_count;
|
free_count = ++DRM(mem_stats)[area].free_count;
|
||||||
|
@ -221,25 +233,36 @@ void DRM(free)(void *pt, size_t size, int area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DRM(ioremap)(unsigned long offset, unsigned long size)
|
void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map )
|
||||||
{
|
{
|
||||||
void *pt;
|
void *pt;
|
||||||
|
|
||||||
if (!size) {
|
if (!map->size) {
|
||||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||||
"Mapping 0 bytes at 0x%08lx\n", offset);
|
"Mapping 0 bytes at 0x%08lx\n", map->offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
map->iot = dev->pa.pa_memt;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(pt = pmap_mapdev(offset, size))) {
|
#ifdef __FreeBSD__
|
||||||
|
if (!(pt = pmap_mapdev(map->offset, map->size))) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
if (bus_space_map(map->iot, map->offset, map->size,
|
||||||
|
BUS_SPACE_MAP_LINEAR, &map->ioh)) {
|
||||||
|
#endif
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
pt = bus_space_vaddr(map->iot, map->ioh);
|
||||||
|
#endif
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
@ -271,19 +294,23 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void DRM(ioremapfree)(void *pt, unsigned long size)
|
void DRM(ioremapfree)(drm_local_map_t *map)
|
||||||
{
|
{
|
||||||
int alloc_count;
|
int alloc_count;
|
||||||
int free_count;
|
int free_count;
|
||||||
|
|
||||||
if (!pt)
|
if (map->handle == NULL)
|
||||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||||
"Attempt to free NULL pointer\n");
|
"Attempt to free NULL pointer\n");
|
||||||
else
|
else
|
||||||
pmap_unmapdev((vm_offset_t) pt, size);
|
#ifdef __FreeBSD__
|
||||||
|
pmap_unmapdev((vm_offset_t) map->handle, map->size);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
bus_space_unmap(map->iot, map->ioh, map->size);
|
||||||
|
#endif
|
||||||
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size;
|
||||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#define DRM_STRUCTPROC struct thread
|
#define DRM_STRUCTPROC struct thread
|
||||||
#define DRM_SPINTYPE struct mtx
|
#define DRM_SPINTYPE struct mtx
|
||||||
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
||||||
|
#define DRM_SPINUNINIT(l) mtx_destroy(&l)
|
||||||
#define DRM_SPINLOCK(l) mtx_lock(l)
|
#define DRM_SPINLOCK(l) mtx_lock(l)
|
||||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
||||||
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
||||||
|
@ -87,6 +88,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_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,10 +104,18 @@
|
||||||
#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) free( pt, DRM(M_DRM) )
|
||||||
#define DRM_VTOPHYS(addr) vtophys(addr)
|
#define DRM_VTOPHYS(addr) vtophys(addr)
|
||||||
#define DRM_READ8(addr) *((volatile char *)(addr))
|
|
||||||
#define DRM_READ32(addr) *((volatile long *)(addr))
|
/* Read/write from bus space, with byteswapping to le if necessary */
|
||||||
#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val)
|
#define DRM_READ8(map, offset) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val)
|
#define DRM_READ32(map, offset) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset))
|
||||||
|
#define DRM_WRITE8(map, offset, val) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val
|
||||||
|
#define DRM_WRITE32(map, offset, val) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
|
||||||
|
/*
|
||||||
|
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
|
||||||
|
#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) )
|
||||||
|
#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
*/
|
||||||
#define DRM_AGP_FIND_DEVICE() agp_find_device()
|
#define DRM_AGP_FIND_DEVICE() agp_find_device()
|
||||||
#define DRM_ERR(v) v
|
#define DRM_ERR(v) v
|
||||||
|
|
||||||
|
@ -130,7 +140,7 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
drm_map_list_entry_t *listentry; \
|
drm_map_list_entry_t *listentry; \
|
||||||
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
||||||
drm_map_t *map = listentry->map; \
|
drm_local_map_t *map = listentry->map; \
|
||||||
if (map->type == _DRM_SHM && \
|
if (map->type == _DRM_SHM && \
|
||||||
map->flags & _DRM_CONTAINS_LOCK) { \
|
map->flags & _DRM_CONTAINS_LOCK) { \
|
||||||
dev_priv->sarea = map; \
|
dev_priv->sarea = map; \
|
||||||
|
@ -166,7 +176,7 @@ while (!condition) { \
|
||||||
copyin(user, kern, size)
|
copyin(user, kern, size)
|
||||||
/* Macros for userspace access with checking readability once */
|
/* Macros for userspace access with checking readability once */
|
||||||
/* FIXME: can't find equivalent functionality for nocheck yet.
|
/* FIXME: can't find equivalent functionality for nocheck yet.
|
||||||
* It's be slower than linux, but should be correct.
|
* It'll be slower than linux, but should be correct.
|
||||||
*/
|
*/
|
||||||
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
||||||
(!useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
(!useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
||||||
|
@ -175,20 +185,13 @@ while (!condition) { \
|
||||||
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
||||||
((val) = fuword(uaddr), 0)
|
((val) = fuword(uaddr), 0)
|
||||||
|
|
||||||
/* From machine/bus_at386.h on i386 */
|
#define DRM_WRITEMEMORYBARRIER( map ) \
|
||||||
#define DRM_READMEMORYBARRIER() \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
|
||||||
do { \
|
#define DRM_READMEMORYBARRIER( map ) \
|
||||||
__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DRM_WRITEMEMORYBARRIER() \
|
|
||||||
do { \
|
|
||||||
__asm __volatile("" : : : "memory"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define PAGE_ALIGN(addr) round_page(addr)
|
#define PAGE_ALIGN(addr) round_page(addr)
|
||||||
|
|
||||||
#ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */
|
#ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */
|
||||||
#define M_WAITOK 0
|
#define M_WAITOK 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -206,7 +209,7 @@ typedef struct drm_chipinfo
|
||||||
char *name;
|
char *name;
|
||||||
} drm_chipinfo_t;
|
} drm_chipinfo_t;
|
||||||
|
|
||||||
#define cpu_to_le32(x) (x)
|
#define cpu_to_le32(x) (x) /* FIXME */
|
||||||
|
|
||||||
typedef u_int32_t dma_addr_t;
|
typedef u_int32_t dma_addr_t;
|
||||||
typedef u_int32_t atomic_t;
|
typedef u_int32_t atomic_t;
|
||||||
|
@ -223,6 +226,23 @@ typedef u_int8_t u8;
|
||||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
||||||
|
|
||||||
/* Fake this */
|
/* Fake this */
|
||||||
|
|
||||||
|
#if __FreeBSD_version < 500000
|
||||||
|
/* The extra atomic functions from 5.0 haven't been merged to 4.x */
|
||||||
|
static __inline int
|
||||||
|
atomic_cmpset_int(int *dst, int old, int new)
|
||||||
|
{
|
||||||
|
int s = splhigh();
|
||||||
|
if (*dst==old) {
|
||||||
|
*dst = new;
|
||||||
|
splx(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static __inline atomic_t
|
static __inline atomic_t
|
||||||
test_and_set_bit(int b, volatile void *p)
|
test_and_set_bit(int b, volatile void *p)
|
||||||
{
|
{
|
||||||
|
@ -284,20 +304,6 @@ find_first_zero_bit(volatile void *p, int max)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
|
|
||||||
#define _DRM_CAS(lock,old,new,__ret) \
|
|
||||||
do { \
|
|
||||||
int __dummy; /* Can't mark eax as clobbered */ \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
"lock ; cmpxchg %4,%1\n\t" \
|
|
||||||
"setnz %0" \
|
|
||||||
: "=d" (__ret), \
|
|
||||||
"=m" (__drm_dummy_lock(lock)), \
|
|
||||||
"=a" (__dummy) \
|
|
||||||
: "2" (old), \
|
|
||||||
"r" (new)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Redefinitions to make templating easy */
|
/* Redefinitions to make templating easy */
|
||||||
#define wait_queue_head_t atomic_t
|
#define wait_queue_head_t atomic_t
|
||||||
#define agp_memory void
|
#define agp_memory void
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <uvm/uvm.h>
|
#include <uvm/uvm.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include <sys/lkm.h>
|
||||||
/* For TIOCSPGRP/TIOCGPGRP */
|
/* For TIOCSPGRP/TIOCGPGRP */
|
||||||
#include <sys/ttycom.h>
|
#include <sys/ttycom.h>
|
||||||
|
|
||||||
|
@ -31,11 +32,9 @@
|
||||||
#include <dev/pci/pcireg.h>
|
#include <dev/pci/pcireg.h>
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
|
|
||||||
#include "drmvar.h"
|
|
||||||
|
|
||||||
#define __REALLY_HAVE_AGP __HAVE_AGP
|
#define __REALLY_HAVE_AGP __HAVE_AGP
|
||||||
|
|
||||||
#define __REALLY_HAVE_MTRR 0
|
#define __REALLY_HAVE_MTRR 1
|
||||||
#define __REALLY_HAVE_SG 0
|
#define __REALLY_HAVE_SG 0
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
|
@ -43,8 +42,7 @@
|
||||||
#include <sys/agpio.h>
|
#include <sys/agpio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define device_t struct device *
|
#include <opt_drm.h>
|
||||||
extern struct cfdriver DRM(_cd);
|
|
||||||
|
|
||||||
#if DRM_DEBUG
|
#if DRM_DEBUG
|
||||||
#undef DRM_DEBUG_CODE
|
#undef DRM_DEBUG_CODE
|
||||||
|
@ -52,36 +50,54 @@ extern struct cfdriver DRM(_cd);
|
||||||
#endif
|
#endif
|
||||||
#undef DRM_DEBUG
|
#undef DRM_DEBUG
|
||||||
|
|
||||||
|
#if DRM_LINUX
|
||||||
|
#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef drm_device_t *device_t;
|
||||||
|
|
||||||
|
extern struct cfdriver DRM(cd);
|
||||||
|
|
||||||
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
|
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
|
||||||
|
|
||||||
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
||||||
#define DRM_DEV_UID 0
|
#define DRM_DEV_UID 0
|
||||||
#define DRM_DEV_GID 0
|
#define DRM_DEV_GID 0
|
||||||
#define CDEV_MAJOR 90
|
#define CDEV_MAJOR 34
|
||||||
|
|
||||||
#define DRM_CURPROC curproc
|
#define DRM_CURPROC curproc
|
||||||
#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_SPINLOCK(l) simple_lock(l)
|
#define DRM_SPINUNINIT(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
|
||||||
|
|
||||||
#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p
|
#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p
|
||||||
#define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL)
|
#define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL)
|
||||||
#define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
|
#define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
|
||||||
#define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag)
|
#define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag)
|
||||||
#define DRM_TASKQUEUE_ARGS void *dev, int pending
|
#define DRM_TASKQUEUE_ARGS void *dev, int pending
|
||||||
#define DRM_IRQ_ARGS void *device
|
#define DRM_IRQ_ARGS void *arg
|
||||||
#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev))
|
#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev))
|
||||||
|
/* XXX Not sure if this is the 'right' version.. */
|
||||||
|
#if __NetBSD_Version__ >= 106140000
|
||||||
|
MALLOC_DECLARE(DRM(M_DRM));
|
||||||
|
#else
|
||||||
|
/* XXX Make sure this works */
|
||||||
|
extern const int DRM(M_DRM) = M_DEVBUF;
|
||||||
|
#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) free( pt, DRM(M_DRM) )
|
||||||
#define DRM_VTOPHYS(addr) vtophys(addr)
|
#define DRM_VTOPHYS(addr) vtophys(addr)
|
||||||
#define DRM_READ8(addr) *((volatile char *)(addr))
|
|
||||||
#define DRM_READ32(addr) *((volatile long *)(addr))
|
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
|
||||||
#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val)
|
#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) )
|
||||||
#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val)
|
#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
#define DRM_AGP_FIND_DEVICE()
|
#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
|
||||||
|
#define DRM_AGP_FIND_DEVICE() agp_find_device(0)
|
||||||
|
|
||||||
#define DRM_PRIV \
|
#define DRM_PRIV \
|
||||||
drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
|
drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
|
||||||
|
@ -104,7 +120,7 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
drm_map_list_entry_t *listentry; \
|
drm_map_list_entry_t *listentry; \
|
||||||
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
||||||
drm_map_t *map = listentry->map; \
|
drm_local_map_t *map = listentry->map; \
|
||||||
if (map->type == _DRM_SHM && \
|
if (map->type == _DRM_SHM && \
|
||||||
map->flags & _DRM_CONTAINS_LOCK) { \
|
map->flags & _DRM_CONTAINS_LOCK) { \
|
||||||
dev_priv->sarea = map; \
|
dev_priv->sarea = map; \
|
||||||
|
@ -113,7 +129,15 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define return DRM_ERR(v) return v;
|
#define DRM_HZ hz
|
||||||
|
|
||||||
|
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
|
||||||
|
while (!condition) { \
|
||||||
|
ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \
|
||||||
|
if ( ret ) \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
#define DRM_ERR(v) v
|
#define DRM_ERR(v) v
|
||||||
|
|
||||||
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
|
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
|
||||||
|
@ -124,21 +148,25 @@ do { \
|
||||||
copyout(arg2, arg1, arg3)
|
copyout(arg2, arg1, arg3)
|
||||||
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
|
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
|
||||||
copyin(arg2, arg1, arg3)
|
copyin(arg2, arg1, arg3)
|
||||||
|
/* Macros for userspace access with checking readability once */
|
||||||
|
/* FIXME: can't find equivalent functionality for nocheck yet.
|
||||||
|
* It'll be slower than linux, but should be correct.
|
||||||
|
*/
|
||||||
|
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
||||||
|
(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
||||||
|
#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
|
||||||
|
copyin(arg2, arg1, arg3)
|
||||||
|
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
||||||
|
((val) = fuword(uaddr), 0)
|
||||||
|
|
||||||
#define DRM_READMEMORYBARRIER \
|
#define DRM_WRITEMEMORYBARRIER( map ) \
|
||||||
{ \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
|
||||||
int xchangeDummy; \
|
#define DRM_READMEMORYBARRIER( map ) \
|
||||||
DRM_DEBUG("%s\n", __FUNCTION__); \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
|
||||||
__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \
|
|
||||||
__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \
|
|
||||||
" movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \
|
|
||||||
" pop %%eax" : /* no outputs */ : /* no inputs */ ); \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER
|
#define DRM_WAKEUP(w) wakeup((void *)w)
|
||||||
|
|
||||||
#define DRM_WAKEUP(w) wakeup(w)
|
|
||||||
#define DRM_WAKEUP_INT(w) wakeup(w)
|
#define DRM_WAKEUP_INT(w) wakeup(w)
|
||||||
|
#define DRM_INIT_WAITQUEUE( queue ) do {} while (0)
|
||||||
|
|
||||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||||
|
|
||||||
|
@ -150,8 +178,10 @@ typedef struct drm_chipinfo
|
||||||
char *name;
|
char *name;
|
||||||
} drm_chipinfo_t;
|
} drm_chipinfo_t;
|
||||||
|
|
||||||
|
#define cpu_to_le32(x) (x) /* FIXME */
|
||||||
|
|
||||||
typedef u_int32_t dma_addr_t;
|
typedef u_int32_t dma_addr_t;
|
||||||
typedef volatile u_int32_t 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 spinlock_t;
|
||||||
typedef u_int32_t u32;
|
typedef u_int32_t u32;
|
||||||
|
@ -160,20 +190,35 @@ typedef u_int8_t u8;
|
||||||
typedef dev_type_ioctl(d_ioctl_t);
|
typedef dev_type_ioctl(d_ioctl_t);
|
||||||
typedef vaddr_t vm_offset_t;
|
typedef vaddr_t vm_offset_t;
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
#define atomic_set(p, v) (*(p) = (v))
|
#define atomic_set(p, v) (*(p) = (v))
|
||||||
#define atomic_read(p) (*(p))
|
#define atomic_read(p) (*(p))
|
||||||
#define atomic_inc(p) atomic_add_int(p, 1)
|
#define atomic_inc(p) (*(p) += 1)
|
||||||
#define atomic_dec(p) atomic_subtract_int(p, 1)
|
#define atomic_dec(p) (*(p) -= 1)
|
||||||
#define atomic_add(n, p) atomic_add_int(p, n)
|
#define atomic_add(n, p) (*(p) += (n))
|
||||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
#define atomic_sub(n, p) (*(p) -= (n))
|
||||||
|
|
||||||
/* FIXME: Is NetBSD's kernel non-reentrant? */
|
/* FIXME */
|
||||||
#define atomic_add_int(p, v) *(p) += v
|
#define atomic_add_int(p, v) *(p) += v
|
||||||
#define atomic_subtract_int(p, v) *(p) -= v
|
#define atomic_subtract_int(p, v) *(p) -= v
|
||||||
#define atomic_set_int(p, bits) *(p) |= (bits)
|
#define atomic_set_int(p, bits) *(p) |= (bits)
|
||||||
#define atomic_clear_int(p, bits) *(p) &= ~(bits)
|
#define atomic_clear_int(p, bits) *(p) &= ~(bits)
|
||||||
|
|
||||||
/* Fake this */
|
/* Fake this */
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
atomic_cmpset_int(__volatile__ int *dst, int old, int new)
|
||||||
|
{
|
||||||
|
int s = splhigh();
|
||||||
|
if (*dst==old) {
|
||||||
|
*dst = new;
|
||||||
|
splx(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static __inline atomic_t
|
static __inline atomic_t
|
||||||
test_and_set_bit(int b, atomic_t *p)
|
test_and_set_bit(int b, atomic_t *p)
|
||||||
{
|
{
|
||||||
|
@ -223,20 +268,6 @@ find_first_zero_bit(atomic_t *p, int max)
|
||||||
#define spldrm() spltty()
|
#define spldrm() spltty()
|
||||||
#define jiffies hardclock_ticks
|
#define jiffies hardclock_ticks
|
||||||
|
|
||||||
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
|
|
||||||
#define _DRM_CAS(lock,old,new,__ret) \
|
|
||||||
do { \
|
|
||||||
int __dummy; /* Can't mark eax as clobbered */ \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
"lock ; cmpxchg %4,%1\n\t" \
|
|
||||||
"setnz %0" \
|
|
||||||
: "=d" (__ret), \
|
|
||||||
"=m" (__drm_dummy_lock(lock)), \
|
|
||||||
"=a" (__dummy) \
|
|
||||||
: "2" (old), \
|
|
||||||
"r" (new)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Redefinitions to make templating easy */
|
/* Redefinitions to make templating easy */
|
||||||
#define wait_queue_head_t atomic_t
|
#define wait_queue_head_t atomic_t
|
||||||
#define agp_memory void
|
#define agp_memory void
|
||||||
|
@ -257,7 +288,7 @@ do { \
|
||||||
#define DRM_DEBUG(fmt, arg...) \
|
#define DRM_DEBUG(fmt, arg...) \
|
||||||
do { \
|
do { \
|
||||||
if (DRM(flags) & DRM_FLAG_DEBUG) \
|
if (DRM(flags) & DRM_FLAG_DEBUG) \
|
||||||
printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \
|
printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
||||||
|
|
|
@ -40,9 +40,6 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry )
|
||||||
DRM(free)( entry->busaddr,
|
DRM(free)( entry->busaddr,
|
||||||
entry->pages * sizeof(*entry->busaddr),
|
entry->pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -73,21 +70,10 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
|
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
|
||||||
|
|
||||||
entry->pages = pages;
|
entry->pages = pages;
|
||||||
entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
if ( !entry->pagelist ) {
|
|
||||||
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero(entry->pagelist, pages * sizeof(*entry->pagelist));
|
|
||||||
|
|
||||||
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
if ( !entry->busaddr ) {
|
if ( !entry->busaddr ) {
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -100,9 +86,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
DRM(free)( entry->busaddr,
|
DRM(free)( entry->busaddr,
|
||||||
entry->pages * sizeof(*entry->busaddr),
|
entry->pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -124,46 +107,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
|
|
||||||
dev->sg = entry;
|
dev->sg = entry;
|
||||||
|
|
||||||
#if DEBUG_SCATTER
|
|
||||||
/* Verify that each page points to its virtual address, and vice
|
|
||||||
* versa.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < pages ; i++ ) {
|
|
||||||
unsigned long *tmp;
|
|
||||||
|
|
||||||
tmp = page_address( entry->pagelist[i] );
|
|
||||||
for ( j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++ ) {
|
|
||||||
*tmp = 0xcafebabe;
|
|
||||||
}
|
|
||||||
tmp = (unsigned long *)((u8 *)entry->virtual +
|
|
||||||
(PAGE_SIZE * i));
|
|
||||||
for( j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++ ) {
|
|
||||||
if ( *tmp != 0xcafebabe && error == 0 ) {
|
|
||||||
error = 1;
|
|
||||||
DRM_ERROR( "Scatter allocation error, "
|
|
||||||
"pagelist does not match "
|
|
||||||
"virtual mapping\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp = page_address( entry->pagelist[i] );
|
|
||||||
for(j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++) {
|
|
||||||
*tmp = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error == 0)
|
|
||||||
DRM_ERROR( "Scatter allocation matches pagelist\n" );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DRM(sg_cleanup)( entry );
|
DRM(sg_cleanup)( entry );
|
||||||
|
|
|
@ -125,7 +125,7 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
|
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
{
|
{
|
||||||
drm_device_t *dev = arg1;
|
drm_device_t *dev = arg1;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *listentry;
|
drm_map_list_entry_t *listentry;
|
||||||
const char *types[] = { "FB", "REG", "SHM" };
|
const char *types[] = { "FB", "REG", "SHM" };
|
||||||
const char *type;
|
const char *type;
|
||||||
|
@ -203,7 +203,7 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
q->read_queue ? 'r':'-',
|
q->read_queue ? 'r':'-',
|
||||||
q->write_queue ? 'w':'-',
|
q->write_queue ? 'w':'-',
|
||||||
q->flush_queue ? 'f':'-',
|
q->flush_queue ? 'f':'-',
|
||||||
DRM_BUFCOUNT(&q->waitlist),
|
(int)DRM_BUFCOUNT(&q->waitlist),
|
||||||
atomic_read(&q->total_flushed),
|
atomic_read(&q->total_flushed),
|
||||||
atomic_read(&q->total_queued),
|
atomic_read(&q->total_queued),
|
||||||
atomic_read(&q->total_locks));
|
atomic_read(&q->total_locks));
|
||||||
|
|
|
@ -27,7 +27,7 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t *map = NULL;
|
drm_local_map_t *map = NULL;
|
||||||
drm_map_list_entry_t *listentry=NULL;
|
drm_map_list_entry_t *listentry=NULL;
|
||||||
drm_file_t *priv;
|
drm_file_t *priv;
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "mga.h"
|
#include "mga.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -63,4 +61,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_vm.h"
|
#include "drm_vm.h"
|
||||||
#include "drm_sysctl.h"
|
#include "drm_sysctl.h"
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
|
DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(mga, DV_TTY, NULL);
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "r128.h"
|
#include "r128.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -83,4 +80,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_scatter.h"
|
#include "drm_scatter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
|
DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(r128, DV_TTY, NULL);
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -38,21 +36,40 @@
|
||||||
#include "ati_pcigart.h"
|
#include "ati_pcigart.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
|
|
||||||
* Please report to eta@lclark.edu inaccuracies or if a chip you have works that is marked unsupported here.
|
|
||||||
*/
|
|
||||||
drm_chipinfo_t DRM(devicelist)[] = {
|
drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
|
{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"},
|
||||||
|
{0x1002, 0x4336, 1, "ATI Radeon Mobility"},
|
||||||
|
{0x1002, 0x4337, 1, "ATI Radeon IGP 340"},
|
||||||
|
{0x1002, 0x4964, 1, "ATI Radeon Id 9000"},
|
||||||
|
{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"},
|
||||||
|
{0x1002, 0x4966, 1, "ATI Radeon If 9000"},
|
||||||
|
{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"},
|
||||||
|
{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"},
|
||||||
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
|
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
|
||||||
|
{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"},
|
||||||
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
|
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
|
||||||
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
|
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
|
||||||
{0x1002, 0x5144, 1, "ATI Radeon QD (AGP)"},
|
{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5145, 1, "ATI Radeon QE (AGP)"},
|
{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5146, 1, "ATI Radeon QF (AGP)"},
|
{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5147, 1, "ATI Radeon QG (AGP)"},
|
{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"},
|
||||||
|
{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"},
|
||||||
|
{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"},
|
||||||
|
{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"},
|
||||||
|
{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, 0x514A, 1, "ATI Radeon QJ R200"},
|
||||||
|
{0x1002, 0x514B, 1, "ATI Radeon QK R200"},
|
||||||
|
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
|
||||||
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
|
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
|
||||||
|
{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"},
|
||||||
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
|
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
|
||||||
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
|
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
|
||||||
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
|
{0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
|
||||||
|
{0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
|
||||||
|
{0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
|
||||||
|
{0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
|
||||||
{0, 0, 0, NULL}
|
{0, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,4 +91,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_scatter.h"
|
#include "drm_scatter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
|
DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(radeon, DV_TTY, NULL);
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "tdfx.h"
|
#include "tdfx.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
|
@ -96,4 +93,6 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
|
DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(tdfx, DV_TTY, NULL);
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
# i810, i830 & sis are not complete
|
# i810, i830 & sis are not complete
|
||||||
SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis
|
SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
# i810, i830 & sis are not complete
|
# i810, i830 & sis are not complete
|
||||||
SUBDIR = gamma mga r128 radeon tdfx # i810 i830 sis
|
SUBDIR = mga r128 radeon tdfx # i810 i830 sis gamma
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
|
|
@ -42,25 +42,6 @@
|
||||||
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
|
# define ATI_MAX_PCIGART_PAGES 8192 /* 32 MB aperture, 4K pages */
|
||||||
# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
|
# define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
|
||||||
|
|
||||||
static unsigned long DRM(ati_alloc_pcigart_table)( void )
|
|
||||||
{
|
|
||||||
unsigned long address;
|
|
||||||
|
|
||||||
DRM_DEBUG( "\n" );
|
|
||||||
|
|
||||||
address = (unsigned long) malloc( (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM), M_WAITOK );
|
|
||||||
|
|
||||||
DRM_DEBUG( "returning 0x%08lx\n", address );
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|
||||||
{
|
|
||||||
DRM_DEBUG( "\n" );
|
|
||||||
|
|
||||||
free( (void *)address, DRM(M_DRM));
|
|
||||||
}
|
|
||||||
|
|
||||||
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
unsigned long *addr,
|
unsigned long *addr,
|
||||||
dma_addr_t *bus_addr)
|
dma_addr_t *bus_addr)
|
||||||
|
@ -76,23 +57,15 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
address = DRM(ati_alloc_pcigart_table)();
|
address = (long)contigmalloc((1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE,
|
||||||
|
DRM(M_DRM), M_WAITOK, 0ul, 0xfffffffful, PAGE_SIZE, 0);
|
||||||
if ( !address ) {
|
if ( !address ) {
|
||||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME non-vtophys==bustophys-arches */
|
/* XXX: we need to busdma this */
|
||||||
bus_address = vtophys( address );
|
bus_address = vtophys( address );
|
||||||
/*pci_map_single(dev->pdev, (void *)address,
|
|
||||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
|
||||||
PCI_DMA_TODEVICE);*/
|
|
||||||
/* if (bus_address == 0) {
|
|
||||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
|
||||||
DRM(ati_free_pcigart_table)( (unsigned long)address );
|
|
||||||
address = 0;
|
|
||||||
goto done;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
pci_gart = (u32 *)address;
|
pci_gart = (u32 *)address;
|
||||||
|
|
||||||
|
@ -102,16 +75,7 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
bzero( pci_gart, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||||
|
|
||||||
for ( i = 0 ; i < pages ; i++ ) {
|
for ( i = 0 ; i < pages ; i++ ) {
|
||||||
/* we need to support large memory configurations */
|
|
||||||
/* FIXME non-vtophys==vtobus-arches */
|
|
||||||
entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) );
|
entry->busaddr[i] = vtophys( entry->handle + (i*PAGE_SIZE) );
|
||||||
/* if (entry->busaddr[i] == 0) {
|
|
||||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
|
||||||
DRM(ati_pcigart_cleanup)( dev, (unsigned long)address, bus_address );
|
|
||||||
address = 0;
|
|
||||||
bus_address = 0;
|
|
||||||
goto done;
|
|
||||||
}*/
|
|
||||||
page_base = (u32) entry->busaddr[i];
|
page_base = (u32) entry->busaddr[i];
|
||||||
|
|
||||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||||
|
@ -122,8 +86,6 @@ int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
DRM_READMEMORYBARRIER();
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
*addr = address;
|
*addr = address;
|
||||||
*bus_addr = bus_address;
|
*bus_addr = bus_address;
|
||||||
|
@ -142,9 +104,8 @@ int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( addr ) {
|
#if __FreeBSD_version > 500000
|
||||||
DRM(ati_free_pcigart_table)( addr );
|
contigfree( (void *)addr, (1 << ATI_PCIGART_TABLE_ORDER) * PAGE_SIZE, DRM(M_DRM)); /* Not available on 4.x */
|
||||||
}
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
33
bsd/drmP.h
33
bsd/drmP.h
|
@ -121,15 +121,15 @@ typedef struct drm_file drm_file_t;
|
||||||
|
|
||||||
/* Mapping helper macros */
|
/* Mapping helper macros */
|
||||||
#define DRM_IOREMAP(map) \
|
#define DRM_IOREMAP(map) \
|
||||||
(map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
|
(map)->handle = DRM(ioremap)( dev, map )
|
||||||
|
|
||||||
#define DRM_IOREMAP_NOCACHE(map) \
|
#define DRM_IOREMAP_NOCACHE(map) \
|
||||||
(map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size)
|
(map)->handle = DRM(ioremap_nocache)( dev, map )
|
||||||
|
|
||||||
#define DRM_IOREMAPFREE(map) \
|
#define DRM_IOREMAPFREE(map) \
|
||||||
do { \
|
do { \
|
||||||
if ( (map)->handle && (map)->size ) \
|
if ( (map)->handle && (map)->size ) \
|
||||||
DRM(ioremapfree)( (map)->handle, (map)->size ); \
|
DRM(ioremapfree)( map ); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Internal types and structures */
|
/* Internal types and structures */
|
||||||
|
@ -377,7 +377,6 @@ typedef struct drm_sg_mem {
|
||||||
unsigned long handle;
|
unsigned long handle;
|
||||||
void *virtual;
|
void *virtual;
|
||||||
int pages;
|
int pages;
|
||||||
struct page **pagelist;
|
|
||||||
dma_addr_t *busaddr;
|
dma_addr_t *busaddr;
|
||||||
} drm_sg_mem_t;
|
} drm_sg_mem_t;
|
||||||
|
|
||||||
|
@ -386,10 +385,23 @@ typedef struct drm_sigdata {
|
||||||
drm_hw_lock_t *lock;
|
drm_hw_lock_t *lock;
|
||||||
} drm_sigdata_t;
|
} drm_sigdata_t;
|
||||||
|
|
||||||
|
typedef struct drm_local_map {
|
||||||
|
unsigned long offset; /* Physical address (0 for SAREA)*/
|
||||||
|
unsigned long size; /* Physical size (bytes) */
|
||||||
|
drm_map_type_t type; /* Type of memory mapped */
|
||||||
|
drm_map_flags_t flags; /* Flags */
|
||||||
|
void *handle; /* User-space: "Handle" to pass to mmap */
|
||||||
|
/* Kernel-space: kernel-virtual address */
|
||||||
|
int mtrr; /* MTRR slot used */
|
||||||
|
/* Private data */
|
||||||
|
bus_space_tag_t iot;
|
||||||
|
bus_space_handle_t ioh;
|
||||||
|
} drm_local_map_t;
|
||||||
|
|
||||||
typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t;
|
typedef TAILQ_HEAD(drm_map_list, drm_map_list_entry) drm_map_list_t;
|
||||||
typedef struct drm_map_list_entry {
|
typedef struct drm_map_list_entry {
|
||||||
TAILQ_ENTRY(drm_map_list_entry) link;
|
TAILQ_ENTRY(drm_map_list_entry) link;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
} drm_map_list_entry_t;
|
} drm_map_list_entry_t;
|
||||||
|
|
||||||
TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
|
TAILQ_HEAD(drm_vbl_sig_list, drm_vbl_sig);
|
||||||
|
@ -440,7 +452,7 @@ struct drm_device {
|
||||||
drm_map_list_t *maplist; /* Linked list of regions */
|
drm_map_list_t *maplist; /* Linked list of regions */
|
||||||
int map_count; /* Number of mappable regions */
|
int map_count; /* Number of mappable regions */
|
||||||
|
|
||||||
drm_map_t **context_sareas;
|
drm_local_map_t **context_sareas;
|
||||||
int max_context;
|
int max_context;
|
||||||
|
|
||||||
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
|
||||||
|
@ -454,9 +466,9 @@ struct drm_device {
|
||||||
drm_device_dma_t *dma; /* Optional pointer for DMA support */
|
drm_device_dma_t *dma; /* Optional pointer for DMA support */
|
||||||
|
|
||||||
/* Context support */
|
/* Context support */
|
||||||
#ifdef __FreeBSD__
|
|
||||||
int irq; /* Interrupt used by board */
|
int irq; /* Interrupt used by board */
|
||||||
int irqrid; /* Interrupt used by board */
|
int irqrid; /* Interrupt used by board */
|
||||||
|
#ifdef __FreeBSD__
|
||||||
struct resource *irqr; /* Resource for interrupt used by board */
|
struct resource *irqr; /* Resource for interrupt used by board */
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
struct pci_attach_args pa;
|
struct pci_attach_args pa;
|
||||||
|
@ -530,15 +542,16 @@ extern int DRM(write_string)(drm_device_t *dev, const char *s);
|
||||||
|
|
||||||
/* Memory management support (drm_memory.h) */
|
/* Memory management support (drm_memory.h) */
|
||||||
extern void DRM(mem_init)(void);
|
extern void DRM(mem_init)(void);
|
||||||
|
extern void DRM(mem_uninit)(void);
|
||||||
extern void *DRM(alloc)(size_t size, int area);
|
extern void *DRM(alloc)(size_t size, int area);
|
||||||
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
|
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
|
||||||
int area);
|
int area);
|
||||||
extern char *DRM(strdup)(const char *s, int area);
|
extern char *DRM(strdup)(const char *s, int area);
|
||||||
extern void DRM(strfree)(char *s, int area);
|
extern void DRM(strfree)(char *s, int area);
|
||||||
extern void DRM(free)(void *pt, size_t size, int area);
|
extern void DRM(free)(void *pt, size_t size, int area);
|
||||||
extern void *DRM(ioremap)(unsigned long offset, unsigned long size);
|
extern void *DRM(ioremap)(drm_device_t *dev, drm_local_map_t *map);
|
||||||
extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size);
|
extern void *DRM(ioremap_nocache)(drm_device_t *dev, drm_local_map_t *map);
|
||||||
extern void DRM(ioremapfree)(void *pt, unsigned long size);
|
extern void DRM(ioremapfree)(drm_local_map_t *map);
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
|
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
|
||||||
|
|
|
@ -37,7 +37,8 @@ int DRM(agp_info)(DRM_IOCTL_ARGS)
|
||||||
struct agp_info *kern;
|
struct agp_info *kern;
|
||||||
drm_agp_info_t info;
|
drm_agp_info_t info;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
kern = &dev->agp->info;
|
kern = &dev->agp->info;
|
||||||
agp_get_info(dev->agp->agpdev, kern);
|
agp_get_info(dev->agp->agpdev, kern);
|
||||||
|
@ -60,9 +61,11 @@ int DRM(agp_acquire)(DRM_IOCTL_ARGS)
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
if (!dev->agp || dev->agp->acquired) return EINVAL;
|
if (!dev->agp || dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
retcode = agp_acquire(dev->agp->agpdev);
|
retcode = agp_acquire(dev->agp->agpdev);
|
||||||
if (retcode) return retcode;
|
if (retcode)
|
||||||
|
return retcode;
|
||||||
dev->agp->acquired = 1;
|
dev->agp->acquired = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +96,8 @@ int DRM(agp_enable)(DRM_IOCTL_ARGS)
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_agp_mode_t mode;
|
drm_agp_mode_t mode;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
mode = *(drm_agp_mode_t *) data;
|
mode = *(drm_agp_mode_t *) data;
|
||||||
|
|
||||||
|
@ -114,7 +118,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS)
|
||||||
u_int32_t type;
|
u_int32_t type;
|
||||||
struct agp_memory_info info;
|
struct agp_memory_info info;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
request = *(drm_agp_buffer_t *) data;
|
request = *(drm_agp_buffer_t *) data;
|
||||||
|
|
||||||
|
@ -136,7 +141,8 @@ int DRM(agp_alloc)(DRM_IOCTL_ARGS)
|
||||||
entry->pages = pages;
|
entry->pages = pages;
|
||||||
entry->prev = NULL;
|
entry->prev = NULL;
|
||||||
entry->next = dev->agp->memory;
|
entry->next = dev->agp->memory;
|
||||||
if (dev->agp->memory) dev->agp->memory->prev = entry;
|
if (dev->agp->memory)
|
||||||
|
dev->agp->memory->prev = entry;
|
||||||
dev->agp->memory = entry;
|
dev->agp->memory = entry;
|
||||||
|
|
||||||
agp_memory_info(dev->agp->agpdev, entry->handle, &info);
|
agp_memory_info(dev->agp->agpdev, entry->handle, &info);
|
||||||
|
@ -166,7 +172,8 @@ int DRM(agp_unbind)(DRM_IOCTL_ARGS)
|
||||||
drm_agp_mem_t *entry;
|
drm_agp_mem_t *entry;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
request = *(drm_agp_binding_t *) data;
|
request = *(drm_agp_binding_t *) data;
|
||||||
if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
|
if (!(entry = DRM(agp_lookup_entry)(dev, (void *) request.handle)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -209,15 +216,20 @@ int DRM(agp_free)(DRM_IOCTL_ARGS)
|
||||||
drm_agp_buffer_t request;
|
drm_agp_buffer_t request;
|
||||||
drm_agp_mem_t *entry;
|
drm_agp_mem_t *entry;
|
||||||
|
|
||||||
if (!dev->agp || !dev->agp->acquired) return EINVAL;
|
if (!dev->agp || !dev->agp->acquired)
|
||||||
|
return EINVAL;
|
||||||
request = *(drm_agp_buffer_t *) data;
|
request = *(drm_agp_buffer_t *) data;
|
||||||
if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle)))
|
if (!(entry = DRM(agp_lookup_entry)(dev, (void*) request.handle)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (entry->bound) DRM(unbind_agp)(entry->handle);
|
if (entry->bound)
|
||||||
|
DRM(unbind_agp)(entry->handle);
|
||||||
|
|
||||||
if (entry->prev) entry->prev->next = entry->next;
|
if (entry->prev)
|
||||||
else dev->agp->memory = entry->next;
|
entry->prev->next = entry->next;
|
||||||
if (entry->next) entry->next->prev = entry->prev;
|
else
|
||||||
|
dev->agp->memory = entry->next;
|
||||||
|
if (entry->next)
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
DRM(free_agp)(entry->handle, entry->pages);
|
DRM(free_agp)(entry->handle, entry->pages);
|
||||||
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -116,25 +116,20 @@ int DRM(getmagic)(DRM_IOCTL_ARGS)
|
||||||
{
|
{
|
||||||
static drm_magic_t sequence = 0;
|
static drm_magic_t sequence = 0;
|
||||||
drm_auth_t auth;
|
drm_auth_t auth;
|
||||||
static DRM_SPINTYPE lock;
|
|
||||||
static int first = 1;
|
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
DRM_PRIV;
|
DRM_PRIV;
|
||||||
|
|
||||||
if (first) {
|
|
||||||
DRM_SPININIT(lock, "drm getmagic");
|
|
||||||
first = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find unique magic */
|
/* Find unique magic */
|
||||||
if (priv->magic) {
|
if (priv->magic) {
|
||||||
auth.magic = priv->magic;
|
auth.magic = priv->magic;
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
DRM_SPINLOCK(&lock);
|
int old = sequence;
|
||||||
if (!sequence) ++sequence; /* reserve 0 */
|
|
||||||
auth.magic = sequence++;
|
auth.magic = old+1;
|
||||||
DRM_SPINUNLOCK(&lock);
|
|
||||||
|
if (!atomic_cmpset_int(&sequence, old, auth.magic))
|
||||||
|
continue;
|
||||||
} while (DRM(find_file)(dev, auth.magic));
|
} while (DRM(find_file)(dev, auth.magic));
|
||||||
priv->magic = auth.magic;
|
priv->magic = auth.magic;
|
||||||
DRM(add_magic)(dev, priv, auth.magic);
|
DRM(add_magic)(dev, priv, auth.magic);
|
||||||
|
|
|
@ -69,18 +69,26 @@ int DRM(order)( unsigned long size )
|
||||||
int DRM(addmap)( DRM_IOCTL_ARGS )
|
int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t *map;
|
drm_map_t request;
|
||||||
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
|
|
||||||
if (!(dev->flags & (FREAD|FWRITE)))
|
if (!(dev->flags & (FREAD|FWRITE)))
|
||||||
return DRM_ERR(EACCES); /* Require read/write */
|
return DRM_ERR(EACCES); /* Require read/write */
|
||||||
|
|
||||||
map = (drm_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_map_t *)data, sizeof(drm_map_t) );
|
||||||
|
|
||||||
|
map = (drm_local_map_t *) DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
|
||||||
if ( !map )
|
if ( !map )
|
||||||
return DRM_ERR(ENOMEM);
|
return DRM_ERR(ENOMEM);
|
||||||
|
|
||||||
*map = *(drm_map_t *)data;
|
map->offset = request.offset;
|
||||||
|
map->size = request.size;
|
||||||
|
map->type = request.type;
|
||||||
|
map->flags = request.flags;
|
||||||
|
map->mtrr = -1;
|
||||||
|
map->handle = 0;
|
||||||
|
|
||||||
/* Only allow shared memory to be removable since we only keep enough
|
/* Only allow shared memory to be removable since we only keep enough
|
||||||
* book keeping information about shared memory to allow for removal
|
* book keeping information about shared memory to allow for removal
|
||||||
* when processes fork.
|
* when processes fork.
|
||||||
|
@ -95,22 +103,14 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
map->mtrr = -1;
|
|
||||||
map->handle = 0;
|
|
||||||
|
|
||||||
switch ( map->type ) {
|
switch ( map->type ) {
|
||||||
case _DRM_REGISTERS:
|
case _DRM_REGISTERS:
|
||||||
case _DRM_FRAME_BUFFER:
|
case _DRM_FRAME_BUFFER:
|
||||||
#if !defined(__sparc__) && !defined(__alpha__)
|
if ( map->offset + map->size < map->offset ) {
|
||||||
if ( map->offset + map->size < map->offset
|
|
||||||
) {
|
|
||||||
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef __alpha__
|
|
||||||
map->offset += dev->hose->mem_space->start;
|
|
||||||
#endif
|
|
||||||
#if __REALLY_HAVE_MTRR
|
#if __REALLY_HAVE_MTRR
|
||||||
if ( map->type == _DRM_FRAME_BUFFER ||
|
if ( map->type == _DRM_FRAME_BUFFER ||
|
||||||
(map->flags & _DRM_WRITE_COMBINING) ) {
|
(map->flags & _DRM_WRITE_COMBINING) ) {
|
||||||
|
@ -130,14 +130,12 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
mtrrmap.base = map->offset;
|
mtrrmap.base = map->offset;
|
||||||
mtrrmap.len = map->size;
|
mtrrmap.len = map->size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = MTRR_PRIVATE | MTRR_VALID;
|
mtrrmap.flags = MTRR_VALID;
|
||||||
mtrrmap.owner = p->p_pid;
|
map->mtrr = mtrr_set( &mtrrmap, &one, p, MTRR_GETSET_KERNEL );
|
||||||
/* USER? KERNEL? XXX */
|
|
||||||
map->mtrr = mtrr_get( &mtrrmap, &one, p, MTRR_GETSET_KERNEL );
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* __REALLY_HAVE_MTRR */
|
#endif /* __REALLY_HAVE_MTRR */
|
||||||
map->handle = DRM(ioremap)( map->offset, map->size );
|
DRM_IOREMAP(map);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
|
@ -155,9 +153,6 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
break;
|
break;
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
case _DRM_AGP:
|
case _DRM_AGP:
|
||||||
#ifdef __alpha__
|
|
||||||
map->offset += dev->hose->mem_space->start;
|
|
||||||
#endif
|
|
||||||
map->offset += dev->agp->base;
|
map->offset += dev->agp->base;
|
||||||
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
map->mtrr = dev->agp->agp_mtrr; /* for getmap */
|
||||||
break;
|
break;
|
||||||
|
@ -187,11 +182,19 @@ int DRM(addmap)( DRM_IOCTL_ARGS )
|
||||||
TAILQ_INSERT_TAIL(dev->maplist, list, link);
|
TAILQ_INSERT_TAIL(dev->maplist, list, link);
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
|
|
||||||
*(drm_map_t *)data = *map;
|
request.offset = map->offset;
|
||||||
|
request.size = map->size;
|
||||||
|
request.type = map->type;
|
||||||
|
request.flags = map->flags;
|
||||||
|
request.mtrr = map->mtrr;
|
||||||
|
request.handle = map->handle;
|
||||||
|
|
||||||
if ( map->type != _DRM_SHM ) {
|
if ( request.type != _DRM_SHM ) {
|
||||||
((drm_map_t *)data)->handle = (void *)map->offset;
|
request.handle = (void *)request.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DRM_COPY_TO_USER_IOCTL( (drm_map_t *)data, request, sizeof(drm_map_t) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +207,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_t request;
|
drm_map_t request;
|
||||||
int found_maps = 0;
|
int found_maps = 0;
|
||||||
|
|
||||||
|
@ -257,7 +260,7 @@ int DRM(rmmap)( DRM_IOCTL_ARGS )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRM(ioremapfree)(map->handle, map->size);
|
DRM(ioremapfree)( map );
|
||||||
break;
|
break;
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
DRM(free)( map->handle, map->size, DRM_MEM_SAREA );
|
DRM(free)( map->handle, map->size, DRM_MEM_SAREA );
|
||||||
|
@ -1018,6 +1021,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS )
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
struct vnode *vn;
|
struct vnode *vn;
|
||||||
|
struct vmspace *vms = p->p_vmspace;
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
drm_buf_map_t request;
|
drm_buf_map_t request;
|
||||||
|
@ -1043,7 +1047,7 @@ int DRM(mapbufs)( DRM_IOCTL_ARGS )
|
||||||
if ( request.count >= dma->buf_count ) {
|
if ( request.count >= dma->buf_count ) {
|
||||||
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
|
||||||
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
(__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
|
||||||
drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
drm_local_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
|
||||||
|
|
||||||
if ( !map ) {
|
if ( !map ) {
|
||||||
retcode = EINVAL;
|
retcode = EINVAL;
|
||||||
|
|
|
@ -69,7 +69,7 @@ int DRM(ctxbitmap_next)( drm_device_t *dev )
|
||||||
if((bit+1) > dev->max_context) {
|
if((bit+1) > dev->max_context) {
|
||||||
dev->max_context = (bit+1);
|
dev->max_context = (bit+1);
|
||||||
if(dev->context_sareas) {
|
if(dev->context_sareas) {
|
||||||
drm_map_t **ctx_sareas;
|
drm_local_map_t **ctx_sareas;
|
||||||
|
|
||||||
ctx_sareas = DRM(realloc)(dev->context_sareas,
|
ctx_sareas = DRM(realloc)(dev->context_sareas,
|
||||||
(dev->max_context - 1) *
|
(dev->max_context - 1) *
|
||||||
|
@ -149,7 +149,7 @@ int DRM(getsareactx)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_ctx_priv_map_t request;
|
drm_ctx_priv_map_t request;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||||
sizeof(request) );
|
sizeof(request) );
|
||||||
|
@ -174,7 +174,7 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_ctx_priv_map_t request;
|
drm_ctx_priv_map_t request;
|
||||||
drm_map_t *map = NULL;
|
drm_local_map_t *map = NULL;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
|
||||||
|
@ -183,24 +183,20 @@ int DRM(setsareactx)( DRM_IOCTL_ARGS )
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
TAILQ_FOREACH(list, dev->maplist, link) {
|
TAILQ_FOREACH(list, dev->maplist, link) {
|
||||||
map=list->map;
|
map=list->map;
|
||||||
if(map->handle == request.handle)
|
if(map->handle == request.handle) {
|
||||||
goto found;
|
if (dev->max_context < 0)
|
||||||
|
goto bad;
|
||||||
|
if (request.ctx_id >= (unsigned) dev->max_context)
|
||||||
|
goto bad;
|
||||||
|
dev->context_sareas[request.ctx_id] = map;
|
||||||
|
DRM_UNLOCK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
return DRM_ERR(EINVAL);
|
return DRM_ERR(EINVAL);
|
||||||
|
|
||||||
found:
|
|
||||||
map = list->map;
|
|
||||||
if (!map) goto bad;
|
|
||||||
if (dev->max_context < 0)
|
|
||||||
goto bad;
|
|
||||||
if (request.ctx_id >= (unsigned) dev->max_context)
|
|
||||||
goto bad;
|
|
||||||
dev->context_sareas[request.ctx_id] = map;
|
|
||||||
DRM_UNLOCK;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
|
|
|
@ -534,9 +534,13 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
||||||
|
|
||||||
/* Install handler */
|
/* Install handler */
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid,
|
dev->irqr = bus_alloc_resource(dev->device, SYS_RES_IRQ, &dev->irqrid,
|
||||||
0, ~0, 1, RF_SHAREABLE);
|
0, ~0, 1, RF_SHAREABLE);
|
||||||
if (!dev->irqr) {
|
if (!dev->irqr) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
if (pci_intr_map(&dev->pa, &dev->ih) != 0) {
|
||||||
|
#endif
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
dev->irq = 0;
|
dev->irq = 0;
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
|
@ -544,11 +548,24 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#if __FreeBSD_version < 500000
|
||||||
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
|
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY,
|
||||||
DRM(dma_service), dev, &dev->irqh);
|
DRM(dma_service), dev, &dev->irqh);
|
||||||
|
#else
|
||||||
|
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE,
|
||||||
|
DRM(dma_service), dev, &dev->irqh);
|
||||||
|
#endif
|
||||||
if ( retcode ) {
|
if ( retcode ) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
dev->irqh = pci_intr_establish(&dev->pa.pa_pc, dev->ih, IPL_TTY,
|
||||||
|
(int (*)(DRM_IRQ_ARGS))DRM(dma_service), dev);
|
||||||
|
if ( !dev->irqh ) {
|
||||||
|
#endif
|
||||||
DRM_LOCK;
|
DRM_LOCK;
|
||||||
|
#ifdef __FreeBSD__
|
||||||
bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
|
bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
|
||||||
|
#endif
|
||||||
dev->irq = 0;
|
dev->irq = 0;
|
||||||
dev->irqrid = 0;
|
dev->irqrid = 0;
|
||||||
DRM_UNLOCK;
|
DRM_UNLOCK;
|
||||||
|
@ -580,9 +597,13 @@ int DRM(irq_uninstall)( drm_device_t *dev )
|
||||||
|
|
||||||
DRM(driver_irq_uninstall)( dev );
|
DRM(driver_irq_uninstall)( dev );
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
|
||||||
bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
|
bus_release_resource(dev->device, SYS_RES_IRQ, irqrid, dev->irqr);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
196
bsd/drm_drv.h
196
bsd/drm_drv.h
|
@ -125,16 +125,10 @@
|
||||||
#define DRIVER_NUM_CARDS 1
|
#define DRIVER_NUM_CARDS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static int DRM(init)(device_t nbdev);
|
static int DRM(init)(device_t nbdev);
|
||||||
static void DRM(cleanup)(device_t nbdev);
|
static void DRM(cleanup)(device_t nbdev);
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static int DRM(init)(drm_device_t *);
|
|
||||||
static void DRM(cleanup)(drm_device_t *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#define CDEV_MAJOR 145
|
|
||||||
#define DRIVER_SOFTC(unit) \
|
#define DRIVER_SOFTC(unit) \
|
||||||
((drm_device_t *) devclass_get_softc(DRM(devclass), unit))
|
((drm_device_t *) devclass_get_softc(DRM(devclass), unit))
|
||||||
|
|
||||||
|
@ -147,9 +141,8 @@ MODULE_DEPEND(DRIVER_NAME, linux, 1, 1, 1);
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
#define CDEV_MAJOR 90
|
|
||||||
#define DRIVER_SOFTC(unit) \
|
#define DRIVER_SOFTC(unit) \
|
||||||
((drm_device_t *) device_lookup(&DRM(_cd), unit))
|
((drm_device_t *) device_lookup(&DRM(cd), unit))
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
static drm_ioctl_desc_t DRM(ioctls)[] = {
|
static drm_ioctl_desc_t DRM(ioctls)[] = {
|
||||||
|
@ -229,6 +222,27 @@ static drm_ioctl_desc_t DRM(ioctls)[] = {
|
||||||
const char *DRM(find_description)(int vendor, int device);
|
const char *DRM(find_description)(int vendor, int device);
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
static struct cdevsw DRM(cdevsw) = {
|
||||||
|
/* open */ DRM( open ),
|
||||||
|
/* close */ DRM( close ),
|
||||||
|
/* read */ DRM( read ),
|
||||||
|
/* write */ DRM( write ),
|
||||||
|
/* ioctl */ DRM( ioctl ),
|
||||||
|
/* poll */ DRM( poll ),
|
||||||
|
/* mmap */ DRM( mmap ),
|
||||||
|
/* strategy */ nostrategy,
|
||||||
|
/* name */ DRIVER_NAME,
|
||||||
|
/* maj */ CDEV_MAJOR,
|
||||||
|
/* dump */ nodump,
|
||||||
|
/* psize */ nopsize,
|
||||||
|
/* flags */ D_TTY | D_TRACKCLOSE,
|
||||||
|
#if __FreeBSD_version >= 500000
|
||||||
|
/* kqfilter */ 0
|
||||||
|
#else
|
||||||
|
/* bmaj */ -1
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static int DRM(probe)(device_t dev)
|
static int DRM(probe)(device_t dev)
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
|
@ -271,57 +285,108 @@ static driver_t DRM(driver) = {
|
||||||
sizeof(drm_device_t),
|
sizeof(drm_device_t),
|
||||||
};
|
};
|
||||||
|
|
||||||
static devclass_t DRM( devclass);
|
static devclass_t DRM(devclass);
|
||||||
|
|
||||||
static struct cdevsw DRM( cdevsw) = {
|
|
||||||
/* open */ DRM( open ),
|
|
||||||
/* close */ DRM( close ),
|
|
||||||
/* read */ DRM( read ),
|
|
||||||
/* write */ DRM( write ),
|
|
||||||
/* ioctl */ DRM( ioctl ),
|
|
||||||
/* poll */ DRM( poll ),
|
|
||||||
/* mmap */ DRM( mmap ),
|
|
||||||
/* strategy */ nostrategy,
|
|
||||||
/* name */ DRIVER_NAME,
|
|
||||||
/* maj */ CDEV_MAJOR,
|
|
||||||
/* dump */ nodump,
|
|
||||||
/* psize */ nopsize,
|
|
||||||
/* flags */ D_TTY | D_TRACKCLOSE,
|
|
||||||
#if __FreeBSD_version >= 500000
|
|
||||||
/* kqfilter */ 0
|
|
||||||
#else
|
|
||||||
/* bmaj */ -1
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#elif defined(__NetBSD__)
|
#elif defined(__NetBSD__)
|
||||||
int DRM(probe)(struct device *parent, struct cfdata *match, void *aux);
|
|
||||||
void DRM(attach)(struct device *parent, struct device *self, void *aux);
|
|
||||||
int DRM(detach)(struct device *self, int flags);
|
|
||||||
int DRM(activate)(struct device *self, enum devact act);
|
|
||||||
|
|
||||||
struct cfattach DRM(_ca) = {
|
static struct cdevsw DRM(cdevsw) = {
|
||||||
sizeof(drm_device_t), DRM(probe),
|
DRM(open),
|
||||||
DRM(attach), DRM(detach), DRM(activate) };
|
DRM(close),
|
||||||
|
DRM(read),
|
||||||
int DRM(probe)(struct device *parent, struct cfdata *match, void *aux)
|
DRM(write),
|
||||||
|
DRM(ioctl),
|
||||||
|
nostop,
|
||||||
|
notty,
|
||||||
|
DRM(poll),
|
||||||
|
DRM(mmap),
|
||||||
|
nokqfilter,
|
||||||
|
D_TTY
|
||||||
|
};
|
||||||
|
|
||||||
|
int DRM(refcnt) = 0;
|
||||||
|
#if __NetBSD_Version__ >= 106080000
|
||||||
|
MOD_DEV( DRIVER_NAME, DRIVER_NAME, NULL, -1, &DRM(cdevsw), CDEV_MAJOR);
|
||||||
|
#else
|
||||||
|
MOD_DEV( DRIVER_NAME, LM_DT_CHAR, CDEV_MAJOR, &DRM(cdevsw) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver);
|
||||||
|
static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd);
|
||||||
|
|
||||||
|
int DRM(modprobe)();
|
||||||
|
int DRM(probe)(struct pci_attach_args *pa);
|
||||||
|
void DRM(attach)(struct pci_attach_args *pa, dev_t kdev);
|
||||||
|
|
||||||
|
int DRM(lkmentry)(struct lkm_table *lkmtp, int cmd, int ver) {
|
||||||
|
DISPATCH(lkmtp, cmd, ver, DRM(lkmhandle), DRM(lkmhandle), DRM(lkmhandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DRM(lkmhandle)(struct lkm_table *lkmtp, int cmd)
|
||||||
|
{
|
||||||
|
int j, error = 0;
|
||||||
|
#if defined(__NetBSD__) && (__NetBSD_Version__ > 106080000)
|
||||||
|
struct lkm_dev *args = lkmtp->private.lkm_dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(cmd) {
|
||||||
|
case LKM_E_LOAD:
|
||||||
|
if (lkmexists(lkmtp))
|
||||||
|
return EEXIST;
|
||||||
|
|
||||||
|
if(DRM(modprobe)())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case LKM_E_UNLOAD:
|
||||||
|
if (DRM(refcnt) > 0)
|
||||||
|
return (EBUSY);
|
||||||
|
break;
|
||||||
|
case LKM_E_STAT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error = EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DRM(modprobe)() {
|
||||||
|
struct pci_attach_args pa;
|
||||||
|
int error = 0;
|
||||||
|
if((error = pci_find_device(&pa, DRM(probe))) != 0)
|
||||||
|
DRM(attach)(&pa, 0);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DRM(probe)(struct pci_attach_args *pa)
|
||||||
{
|
{
|
||||||
struct pci_attach_args *pa = aux;
|
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
|
||||||
desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
|
desc = DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
|
||||||
if (desc != NULL)
|
if (desc != NULL) {
|
||||||
return 10;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DRM(attach)(struct device *parent, struct device *self, void *aux)
|
void DRM(attach)(struct pci_attach_args *pa, dev_t kdev)
|
||||||
{
|
{
|
||||||
struct pci_attach_args *pa = aux;
|
int i;
|
||||||
drm_device_t *dev = (drm_device_t *)self;
|
drm_device_t *dev;
|
||||||
|
|
||||||
memcpy(&dev->pa, aux, sizeof(dev->pa));
|
config_makeroom(kdev, &DRM(cd));
|
||||||
|
DRM(cd).cd_devs[(kdev)] = DRM(alloc)(sizeof(drm_device_t),
|
||||||
|
DRM_MEM_DRIVER);
|
||||||
|
dev = DRIVER_SOFTC(kdev);
|
||||||
|
|
||||||
|
memset(dev, 0, sizeof(drm_device_t));
|
||||||
|
memcpy(&dev->pa, pa, sizeof(dev->pa));
|
||||||
|
|
||||||
DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)));
|
DRM_INFO("%s", DRM(find_description)(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id)));
|
||||||
DRM(init)(dev);
|
DRM(init)(dev);
|
||||||
}
|
}
|
||||||
|
@ -345,8 +410,7 @@ int DRM(activate)(struct device *self, enum devact act)
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif /* __NetBSD__ */
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *DRM(find_description)(int vendor, int device) {
|
const char *DRM(find_description)(int vendor, int device) {
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
|
@ -487,7 +551,7 @@ static int DRM(setup)( drm_device_t *dev )
|
||||||
static int DRM(takedown)( drm_device_t *dev )
|
static int DRM(takedown)( drm_device_t *dev )
|
||||||
{
|
{
|
||||||
drm_magic_entry_t *pt, *next;
|
drm_magic_entry_t *pt, *next;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
drm_vma_entry_t *vma, *vma_next;
|
drm_vma_entry_t *vma, *vma_next;
|
||||||
int i;
|
int i;
|
||||||
|
@ -581,15 +645,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
||||||
mtrrmap.len = map->size;
|
mtrrmap.len = map->size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = 0;
|
mtrrmap.flags = 0;
|
||||||
/*mtrrmap.owner = p->p_pid;*/
|
|
||||||
/* XXX: Use curproc here? */
|
|
||||||
retcode = mtrr_set( &mtrrmap, &one,
|
retcode = mtrr_set( &mtrrmap, &one,
|
||||||
DRM_CURPROC, MTRR_GETSET_KERNEL);
|
DRM_CURPROC, MTRR_GETSET_KERNEL);
|
||||||
#endif
|
#endif
|
||||||
DRM_DEBUG( "mtrr_del=%d\n", retcode );
|
DRM_DEBUG( "mtrr_del=%d\n", retcode );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRM(ioremapfree)( map->handle, map->size );
|
DRM(ioremapfree)( map );
|
||||||
break;
|
break;
|
||||||
case _DRM_SHM:
|
case _DRM_SHM:
|
||||||
DRM(free)(map->handle,
|
DRM(free)(map->handle,
|
||||||
|
@ -658,15 +720,13 @@ static int DRM(takedown)( drm_device_t *dev )
|
||||||
* linux/init/main.c (this is not currently supported).
|
* linux/init/main.c (this is not currently supported).
|
||||||
* bsd: drm_init is called via the attach function per device.
|
* bsd: drm_init is called via the attach function per device.
|
||||||
*/
|
*/
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static int DRM(init)( device_t nbdev )
|
static int DRM(init)( device_t nbdev )
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static int DRM(init)( drm_device_t *dev )
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int unit;
|
int unit;
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
drm_device_t *dev;
|
drm_device_t *dev;
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
drm_device_t *dev = nbdev;
|
||||||
#endif
|
#endif
|
||||||
#if __HAVE_CTX_BITMAP
|
#if __HAVE_CTX_BITMAP
|
||||||
int retcode;
|
int retcode;
|
||||||
|
@ -724,7 +784,6 @@ static int DRM(init)( drm_device_t *dev )
|
||||||
struct mtrr mtrrmap;
|
struct mtrr mtrrmap;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
mtrrmap.base = dev->agp->info.ai_aperture_base;
|
mtrrmap.base = dev->agp->info.ai_aperture_base;
|
||||||
/* Might need a multiplier here XXX */
|
|
||||||
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
||||||
mtrrmap.type = MTRR_TYPE_WC;
|
mtrrmap.type = MTRR_TYPE_WC;
|
||||||
mtrrmap.flags = MTRR_VALID;
|
mtrrmap.flags = MTRR_VALID;
|
||||||
|
@ -763,21 +822,16 @@ static int DRM(init)( drm_device_t *dev )
|
||||||
* bsd: drm_cleanup is called per device at module unload time.
|
* bsd: drm_cleanup is called per device at module unload time.
|
||||||
* FIXME: NetBSD
|
* FIXME: NetBSD
|
||||||
*/
|
*/
|
||||||
#ifdef __FreeBSD__
|
|
||||||
static void DRM(cleanup)(device_t nbdev)
|
static void DRM(cleanup)(device_t nbdev)
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
static void DRM(cleanup)(drm_device_t *dev)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#ifdef __FreeBSD__
|
|
||||||
drm_device_t *dev;
|
drm_device_t *dev;
|
||||||
#endif
|
|
||||||
#if __REALLY_HAVE_MTRR
|
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
|
#if __REALLY_HAVE_MTRR
|
||||||
struct mtrr mtrrmap;
|
struct mtrr mtrrmap;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
#endif /* __NetBSD__ */
|
|
||||||
#endif /* __REALLY_HAVE_MTRR */
|
#endif /* __REALLY_HAVE_MTRR */
|
||||||
|
dev = nbdev;
|
||||||
|
#endif /* __NetBSD__ */
|
||||||
|
|
||||||
DRM_DEBUG( "\n" );
|
DRM_DEBUG( "\n" );
|
||||||
|
|
||||||
|
@ -799,7 +853,7 @@ static void DRM(cleanup)(drm_device_t *dev)
|
||||||
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
mtrrmap.len = dev->agp->info.ai_aperture_size;
|
||||||
mtrrmap.type = 0;
|
mtrrmap.type = 0;
|
||||||
mtrrmap.flags = 0;
|
mtrrmap.flags = 0;
|
||||||
retval = mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
|
mtrr_set( &mtrrmap, &one, NULL, MTRR_GETSET_KERNEL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -814,6 +868,8 @@ static void DRM(cleanup)(drm_device_t *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DRIVER_POSTCLEANUP();
|
DRIVER_POSTCLEANUP();
|
||||||
|
DRM(mem_uninit)();
|
||||||
|
DRM_SPINUNINIT(dev->count_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -926,7 +982,7 @@ int DRM(close)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p)
|
||||||
}
|
}
|
||||||
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
|
||||||
DRM_KERNEL_CONTEXT ) ) {
|
DRM_KERNEL_CONTEXT ) ) {
|
||||||
dev->lock.pid = p->p_pid;
|
dev->lock.pid = DRM_CURRENTPID;
|
||||||
dev->lock.lock_time = jiffies;
|
dev->lock.lock_time = jiffies;
|
||||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||||
break; /* Got lock */
|
break; /* Got lock */
|
||||||
|
@ -1043,7 +1099,6 @@ int DRM(ioctl)( DRM_IOCTL_ARGS )
|
||||||
*(int *) data = fgetown(dev->buf_sigio);
|
*(int *) data = fgetown(dev->buf_sigio);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
#ifdef __NetBSD__
|
#ifdef __NetBSD__
|
||||||
case TIOCSPGRP:
|
case TIOCSPGRP:
|
||||||
|
@ -1056,6 +1111,7 @@ int DRM(ioctl)( DRM_IOCTL_ARGS )
|
||||||
*(int *)data = dev->buf_pgid;
|
*(int *)data = dev->buf_pgid;
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
|
}
|
||||||
|
|
||||||
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
if ( nr >= DRIVER_IOCTL_COUNT ) {
|
||||||
retcode = EINVAL;
|
retcode = EINVAL;
|
||||||
|
|
|
@ -100,7 +100,7 @@ int DRM(open_helper)(dev_t kdev, int flags, int fmt, DRM_STRUCTPROC *p,
|
||||||
the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
|
the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
|
||||||
DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
|
DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
|
||||||
|
|
||||||
ssize_t DRM(read)(dev_t kdev, struct uio *uio, int ioflag)
|
int DRM(read)(dev_t kdev, struct uio *uio, int ioflag)
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
int left;
|
int left;
|
||||||
|
@ -182,8 +182,8 @@ int DRM(write_string)(drm_device_t *dev, const char *s)
|
||||||
selwakeup(&dev->buf_sel);
|
selwakeup(&dev->buf_sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio);
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
DRM_DEBUG("dev->buf_sigio=%p\n", dev->buf_sigio);
|
||||||
if (dev->buf_sigio) {
|
if (dev->buf_sigio) {
|
||||||
DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid);
|
DRM_DEBUG("dev->buf_sigio->sio_pgid=%d\n", dev->buf_sigio->sio_pgid);
|
||||||
#if __FreeBSD_version >= 500000
|
#if __FreeBSD_version >= 500000
|
||||||
|
@ -200,6 +200,7 @@ int DRM(write_string)(drm_device_t *dev, const char *s)
|
||||||
gsignal(dev->buf_pgid, SIGIO);
|
gsignal(dev->buf_pgid, SIGIO);
|
||||||
else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL)
|
else if(dev->buf_pgid && (p = pfind(-dev->buf_pgid)) != NULL)
|
||||||
psignal(p, SIGIO);
|
psignal(p, SIGIO);
|
||||||
|
}
|
||||||
#endif /* __NetBSD__ */
|
#endif /* __NetBSD__ */
|
||||||
DRM_DEBUG("waking\n");
|
DRM_DEBUG("waking\n");
|
||||||
wakeup(&dev->buf_rp);
|
wakeup(&dev->buf_rp);
|
||||||
|
|
|
@ -136,7 +136,7 @@ int DRM(getmap)( DRM_IOCTL_ARGS )
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t map;
|
drm_map_t map;
|
||||||
drm_map_t *mapinlist;
|
drm_local_map_t *mapinlist;
|
||||||
drm_map_list_entry_t *list;
|
drm_map_list_entry_t *list;
|
||||||
int idx;
|
int idx;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
|
@ -43,7 +43,7 @@ int DRM(waitlist_create)(drm_waitlist_t *bl, int count)
|
||||||
|
|
||||||
if(!bl->bufs) return DRM_ERR(ENOMEM);
|
if(!bl->bufs) return DRM_ERR(ENOMEM);
|
||||||
|
|
||||||
memset(bl->bufs, 0, sizeof(*bl->bufs));
|
bzero(bl->bufs, sizeof(*bl->bufs));
|
||||||
|
|
||||||
bl->count = count;
|
bl->count = count;
|
||||||
bl->rp = bl->bufs;
|
bl->rp = bl->bufs;
|
||||||
|
@ -66,6 +66,8 @@ int DRM(waitlist_destroy)(drm_waitlist_t *bl)
|
||||||
bl->rp = NULL;
|
bl->rp = NULL;
|
||||||
bl->wp = NULL;
|
bl->wp = NULL;
|
||||||
bl->end = NULL;
|
bl->end = NULL;
|
||||||
|
DRM_SPINUNINIT( bl->write_lock );
|
||||||
|
DRM_SPINUNINIT( bl->read_lock );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +139,7 @@ int DRM(freelist_destroy)(drm_freelist_t *bl)
|
||||||
{
|
{
|
||||||
atomic_set(&bl->count, 0);
|
atomic_set(&bl->count, 0);
|
||||||
bl->next = NULL;
|
bl->next = NULL;
|
||||||
|
DRM_SPINUNINIT( bl->lock );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +178,7 @@ int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
|
||||||
/* Check for high water mark */
|
/* Check for high water mark */
|
||||||
if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
|
if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
|
||||||
atomic_set(&bl->wfh, 0);
|
atomic_set(&bl->wfh, 0);
|
||||||
DRM_WAKEUP_INT(&bl->waiting);
|
DRM_WAKEUP_INT((void *)&bl->waiting);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -222,7 +225,7 @@ drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!atomic_read(&bl->wfh)
|
if (!atomic_read(&bl->wfh)
|
||||||
&& (buf = DRM(freelist_try(bl)))) break;
|
&& (buf = DRM(freelist_try(bl)))) break;
|
||||||
error = tsleep(&bl->waiting, PZERO|PCATCH,
|
error = tsleep((void *)&bl->waiting, PZERO|PCATCH,
|
||||||
"drmfg", 0);
|
"drmfg", 0);
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,14 +47,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
|
|
||||||
char failed;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
||||||
else new = context | _DRM_LOCK_HELD;
|
else new = context | _DRM_LOCK_HELD;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
||||||
if (old & _DRM_LOCK_HELD) {
|
if (old & _DRM_LOCK_HELD) {
|
||||||
if (context != DRM_KERNEL_CONTEXT) {
|
if (context != DRM_KERNEL_CONTEXT) {
|
||||||
|
@ -77,14 +75,13 @@ int DRM(lock_transfer)(drm_device_t *dev,
|
||||||
__volatile__ unsigned int *lock, unsigned int context)
|
__volatile__ unsigned int *lock, unsigned int context)
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
char failed;
|
|
||||||
|
|
||||||
dev->lock.pid = 0;
|
dev->lock.pid = 0;
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
new = context | _DRM_LOCK_HELD;
|
new = context | _DRM_LOCK_HELD;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,14 +90,13 @@ int DRM(lock_free)(drm_device_t *dev,
|
||||||
{
|
{
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
pid_t pid = dev->lock.pid;
|
pid_t pid = dev->lock.pid;
|
||||||
char failed;
|
|
||||||
|
|
||||||
dev->lock.pid = 0;
|
dev->lock.pid = 0;
|
||||||
do {
|
do {
|
||||||
old = *lock;
|
old = *lock;
|
||||||
new = 0;
|
new = 0;
|
||||||
_DRM_CAS(lock, old, new, failed);
|
} while (!atomic_cmpset_int(lock, old, new));
|
||||||
} while (failed);
|
|
||||||
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
||||||
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
|
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
|
||||||
context,
|
context,
|
||||||
|
@ -224,8 +220,6 @@ int DRM(notifier)(void *priv)
|
||||||
{
|
{
|
||||||
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
||||||
unsigned int old, new;
|
unsigned int old, new;
|
||||||
char failed;
|
|
||||||
|
|
||||||
|
|
||||||
/* Allow signal delivery if lock isn't held */
|
/* Allow signal delivery if lock isn't held */
|
||||||
if (!_DRM_LOCK_IS_HELD(s->lock->lock)
|
if (!_DRM_LOCK_IS_HELD(s->lock->lock)
|
||||||
|
@ -236,8 +230,8 @@ int DRM(notifier)(void *priv)
|
||||||
do {
|
do {
|
||||||
old = s->lock->lock;
|
old = s->lock->lock;
|
||||||
new = old | _DRM_LOCK_CONT;
|
new = old | _DRM_LOCK_CONT;
|
||||||
_DRM_CAS(&s->lock->lock, old, new, failed);
|
} while (!atomic_cmpset_int(&s->lock->lock, old, new));
|
||||||
} while (failed);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
|
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
#define malloctype DRM(M_DRM)
|
#define malloctype DRM(M_DRM)
|
||||||
/* The macros confliced in the MALLOC_DEFINE */
|
/* The macros conflicted in the MALLOC_DEFINE */
|
||||||
|
|
||||||
MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
|
MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
|
||||||
|
|
||||||
|
@ -81,6 +81,10 @@ void DRM(mem_init)(void)
|
||||||
{
|
{
|
||||||
drm_mem_stats_t *mem;
|
drm_mem_stats_t *mem;
|
||||||
|
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
malloc_type_attach(DRM(M_DRM));
|
||||||
|
#endif
|
||||||
|
|
||||||
DRM_SPININIT(DRM(mem_lock), "drm memory");
|
DRM_SPININIT(DRM(mem_lock), "drm memory");
|
||||||
|
|
||||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||||
|
@ -95,9 +99,15 @@ void DRM(mem_init)(void)
|
||||||
DRM(ram_used) = 0;
|
DRM(ram_used) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DRM(mem_uninit)(void)
|
||||||
|
{
|
||||||
|
DRM_SPINUNINIT(DRM(mem_lock));
|
||||||
|
}
|
||||||
|
|
||||||
#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_SYSCTL_HANDLER_ARGS
|
static int DRM(_mem_info)(drm_mem_stats_t *stats, struct sysctl_oid *oidp, void *arg1,
|
||||||
|
int arg2, struct sysctl_req *req)
|
||||||
{
|
{
|
||||||
drm_mem_stats_t *pt;
|
drm_mem_stats_t *pt;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
@ -112,7 +122,7 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
|
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
|
||||||
"locked", 0, 0, 0, DRM(ram_used));
|
"locked", 0, 0, 0, DRM(ram_used));
|
||||||
DRM_SYSCTL_PRINT("\n");
|
DRM_SYSCTL_PRINT("\n");
|
||||||
for (pt = DRM(mem_stats); pt->name; pt++) {
|
for (pt = stats; pt->name; pt++) {
|
||||||
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
|
||||||
pt->name,
|
pt->name,
|
||||||
pt->succeed_count,
|
pt->succeed_count,
|
||||||
|
@ -132,13 +142,22 @@ static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
|
int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
drm_mem_stats_t *stats;
|
||||||
|
|
||||||
|
stats = malloc(sizeof(DRM(mem_stats)), DRM(M_DRM), M_NOWAIT);
|
||||||
|
if (stats == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
ret = DRM(_mem_info)(oidp, arg1, arg2, req);
|
bcopy(DRM(mem_stats), stats, sizeof(DRM(mem_stats)));
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
|
||||||
|
ret = DRM(_mem_info)(stats, oidp, arg1, arg2, req);
|
||||||
|
|
||||||
|
free(stats, DRM(M_DRM));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
void *DRM(alloc)(size_t size, int area)
|
void *DRM(alloc)(size_t size, int area)
|
||||||
{
|
{
|
||||||
|
@ -149,11 +168,7 @@ void *DRM(alloc)(size_t size, int area)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
|
if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
if (!(pt = malloc(size, M_DEVBUF, M_NOWAIT))) {
|
|
||||||
#endif
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[area].fail_count;
|
++DRM(mem_stats)[area].fail_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
@ -203,13 +218,10 @@ void DRM(free)(void *pt, size_t size, int area)
|
||||||
int alloc_count;
|
int alloc_count;
|
||||||
int free_count;
|
int free_count;
|
||||||
|
|
||||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
if (!pt)
|
||||||
|
DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||||
else
|
else
|
||||||
#ifdef __FreeBSD__
|
free(pt, DRM(M_DRM));
|
||||||
free(pt, DRM(M_DRM));
|
|
||||||
#elif defined(__NetBSD__)
|
|
||||||
free(pt, M_DEVBUF);
|
|
||||||
#endif
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
DRM(mem_stats)[area].bytes_freed += size;
|
DRM(mem_stats)[area].bytes_freed += size;
|
||||||
free_count = ++DRM(mem_stats)[area].free_count;
|
free_count = ++DRM(mem_stats)[area].free_count;
|
||||||
|
@ -221,25 +233,36 @@ void DRM(free)(void *pt, size_t size, int area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DRM(ioremap)(unsigned long offset, unsigned long size)
|
void *DRM(ioremap)( drm_device_t *dev, drm_local_map_t *map )
|
||||||
{
|
{
|
||||||
void *pt;
|
void *pt;
|
||||||
|
|
||||||
if (!size) {
|
if (!map->size) {
|
||||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||||
"Mapping 0 bytes at 0x%08lx\n", offset);
|
"Mapping 0 bytes at 0x%08lx\n", map->offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
map->iot = dev->pa.pa_memt;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(pt = pmap_mapdev(offset, size))) {
|
#ifdef __FreeBSD__
|
||||||
|
if (!(pt = pmap_mapdev(map->offset, map->size))) {
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
if (bus_space_map(map->iot, map->offset, map->size,
|
||||||
|
BUS_SPACE_MAP_LINEAR, &map->ioh)) {
|
||||||
|
#endif
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
pt = bus_space_vaddr(map->iot, map->ioh);
|
||||||
|
#endif
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
|
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += map->size;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
@ -271,19 +294,23 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void DRM(ioremapfree)(void *pt, unsigned long size)
|
void DRM(ioremapfree)(drm_local_map_t *map)
|
||||||
{
|
{
|
||||||
int alloc_count;
|
int alloc_count;
|
||||||
int free_count;
|
int free_count;
|
||||||
|
|
||||||
if (!pt)
|
if (map->handle == NULL)
|
||||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||||
"Attempt to free NULL pointer\n");
|
"Attempt to free NULL pointer\n");
|
||||||
else
|
else
|
||||||
pmap_unmapdev((vm_offset_t) pt, size);
|
#ifdef __FreeBSD__
|
||||||
|
pmap_unmapdev((vm_offset_t) map->handle, map->size);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
bus_space_unmap(map->iot, map->ioh, map->size);
|
||||||
|
#endif
|
||||||
|
|
||||||
DRM_SPINLOCK(&DRM(mem_lock));
|
DRM_SPINLOCK(&DRM(mem_lock));
|
||||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += map->size;
|
||||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||||
DRM_SPINUNLOCK(&DRM(mem_lock));
|
DRM_SPINUNLOCK(&DRM(mem_lock));
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
#define DRM_STRUCTPROC struct thread
|
#define DRM_STRUCTPROC struct thread
|
||||||
#define DRM_SPINTYPE struct mtx
|
#define DRM_SPINTYPE struct mtx
|
||||||
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
#define DRM_SPININIT(l,name) mtx_init(&l, name, NULL, MTX_DEF)
|
||||||
|
#define DRM_SPINUNINIT(l) mtx_destroy(&l)
|
||||||
#define DRM_SPINLOCK(l) mtx_lock(l)
|
#define DRM_SPINLOCK(l) mtx_lock(l)
|
||||||
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
#define DRM_SPINUNLOCK(u) mtx_unlock(u);
|
||||||
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
#define DRM_CURRENTPID curthread->td_proc->p_pid
|
||||||
|
@ -87,6 +88,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_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,10 +104,18 @@
|
||||||
#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) free( pt, DRM(M_DRM) )
|
||||||
#define DRM_VTOPHYS(addr) vtophys(addr)
|
#define DRM_VTOPHYS(addr) vtophys(addr)
|
||||||
#define DRM_READ8(addr) *((volatile char *)(addr))
|
|
||||||
#define DRM_READ32(addr) *((volatile long *)(addr))
|
/* Read/write from bus space, with byteswapping to le if necessary */
|
||||||
#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val)
|
#define DRM_READ8(map, offset) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val)
|
#define DRM_READ32(map, offset) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset))
|
||||||
|
#define DRM_WRITE8(map, offset, val) *(volatile u_int8_t *) (((unsigned long)(map)->handle) + (offset)) = val
|
||||||
|
#define DRM_WRITE32(map, offset, val) *(volatile u_int32_t *)(((unsigned long)(map)->handle) + (offset)) = val
|
||||||
|
/*
|
||||||
|
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
|
||||||
|
#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) )
|
||||||
|
#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
*/
|
||||||
#define DRM_AGP_FIND_DEVICE() agp_find_device()
|
#define DRM_AGP_FIND_DEVICE() agp_find_device()
|
||||||
#define DRM_ERR(v) v
|
#define DRM_ERR(v) v
|
||||||
|
|
||||||
|
@ -130,7 +140,7 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
drm_map_list_entry_t *listentry; \
|
drm_map_list_entry_t *listentry; \
|
||||||
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
||||||
drm_map_t *map = listentry->map; \
|
drm_local_map_t *map = listentry->map; \
|
||||||
if (map->type == _DRM_SHM && \
|
if (map->type == _DRM_SHM && \
|
||||||
map->flags & _DRM_CONTAINS_LOCK) { \
|
map->flags & _DRM_CONTAINS_LOCK) { \
|
||||||
dev_priv->sarea = map; \
|
dev_priv->sarea = map; \
|
||||||
|
@ -166,7 +176,7 @@ while (!condition) { \
|
||||||
copyin(user, kern, size)
|
copyin(user, kern, size)
|
||||||
/* Macros for userspace access with checking readability once */
|
/* Macros for userspace access with checking readability once */
|
||||||
/* FIXME: can't find equivalent functionality for nocheck yet.
|
/* FIXME: can't find equivalent functionality for nocheck yet.
|
||||||
* It's be slower than linux, but should be correct.
|
* It'll be slower than linux, but should be correct.
|
||||||
*/
|
*/
|
||||||
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
||||||
(!useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
(!useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
||||||
|
@ -175,20 +185,13 @@ while (!condition) { \
|
||||||
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
||||||
((val) = fuword(uaddr), 0)
|
((val) = fuword(uaddr), 0)
|
||||||
|
|
||||||
/* From machine/bus_at386.h on i386 */
|
#define DRM_WRITEMEMORYBARRIER( map ) \
|
||||||
#define DRM_READMEMORYBARRIER() \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
|
||||||
do { \
|
#define DRM_READMEMORYBARRIER( map ) \
|
||||||
__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory"); \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DRM_WRITEMEMORYBARRIER() \
|
|
||||||
do { \
|
|
||||||
__asm __volatile("" : : : "memory"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define PAGE_ALIGN(addr) round_page(addr)
|
#define PAGE_ALIGN(addr) round_page(addr)
|
||||||
|
|
||||||
#ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */
|
#ifndef M_WAITOK /* M_WAITOK (=0) name removed in -current */
|
||||||
#define M_WAITOK 0
|
#define M_WAITOK 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -206,7 +209,7 @@ typedef struct drm_chipinfo
|
||||||
char *name;
|
char *name;
|
||||||
} drm_chipinfo_t;
|
} drm_chipinfo_t;
|
||||||
|
|
||||||
#define cpu_to_le32(x) (x)
|
#define cpu_to_le32(x) (x) /* FIXME */
|
||||||
|
|
||||||
typedef u_int32_t dma_addr_t;
|
typedef u_int32_t dma_addr_t;
|
||||||
typedef u_int32_t atomic_t;
|
typedef u_int32_t atomic_t;
|
||||||
|
@ -223,6 +226,23 @@ typedef u_int8_t u8;
|
||||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
||||||
|
|
||||||
/* Fake this */
|
/* Fake this */
|
||||||
|
|
||||||
|
#if __FreeBSD_version < 500000
|
||||||
|
/* The extra atomic functions from 5.0 haven't been merged to 4.x */
|
||||||
|
static __inline int
|
||||||
|
atomic_cmpset_int(int *dst, int old, int new)
|
||||||
|
{
|
||||||
|
int s = splhigh();
|
||||||
|
if (*dst==old) {
|
||||||
|
*dst = new;
|
||||||
|
splx(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static __inline atomic_t
|
static __inline atomic_t
|
||||||
test_and_set_bit(int b, volatile void *p)
|
test_and_set_bit(int b, volatile void *p)
|
||||||
{
|
{
|
||||||
|
@ -284,20 +304,6 @@ find_first_zero_bit(volatile void *p, int max)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
|
|
||||||
#define _DRM_CAS(lock,old,new,__ret) \
|
|
||||||
do { \
|
|
||||||
int __dummy; /* Can't mark eax as clobbered */ \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
"lock ; cmpxchg %4,%1\n\t" \
|
|
||||||
"setnz %0" \
|
|
||||||
: "=d" (__ret), \
|
|
||||||
"=m" (__drm_dummy_lock(lock)), \
|
|
||||||
"=a" (__dummy) \
|
|
||||||
: "2" (old), \
|
|
||||||
"r" (new)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Redefinitions to make templating easy */
|
/* Redefinitions to make templating easy */
|
||||||
#define wait_queue_head_t atomic_t
|
#define wait_queue_head_t atomic_t
|
||||||
#define agp_memory void
|
#define agp_memory void
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <uvm/uvm.h>
|
#include <uvm/uvm.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include <sys/lkm.h>
|
||||||
/* For TIOCSPGRP/TIOCGPGRP */
|
/* For TIOCSPGRP/TIOCGPGRP */
|
||||||
#include <sys/ttycom.h>
|
#include <sys/ttycom.h>
|
||||||
|
|
||||||
|
@ -31,11 +32,9 @@
|
||||||
#include <dev/pci/pcireg.h>
|
#include <dev/pci/pcireg.h>
|
||||||
#include <dev/pci/pcivar.h>
|
#include <dev/pci/pcivar.h>
|
||||||
|
|
||||||
#include "drmvar.h"
|
|
||||||
|
|
||||||
#define __REALLY_HAVE_AGP __HAVE_AGP
|
#define __REALLY_HAVE_AGP __HAVE_AGP
|
||||||
|
|
||||||
#define __REALLY_HAVE_MTRR 0
|
#define __REALLY_HAVE_MTRR 1
|
||||||
#define __REALLY_HAVE_SG 0
|
#define __REALLY_HAVE_SG 0
|
||||||
|
|
||||||
#if __REALLY_HAVE_AGP
|
#if __REALLY_HAVE_AGP
|
||||||
|
@ -43,8 +42,7 @@
|
||||||
#include <sys/agpio.h>
|
#include <sys/agpio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define device_t struct device *
|
#include <opt_drm.h>
|
||||||
extern struct cfdriver DRM(_cd);
|
|
||||||
|
|
||||||
#if DRM_DEBUG
|
#if DRM_DEBUG
|
||||||
#undef DRM_DEBUG_CODE
|
#undef DRM_DEBUG_CODE
|
||||||
|
@ -52,36 +50,54 @@ extern struct cfdriver DRM(_cd);
|
||||||
#endif
|
#endif
|
||||||
#undef DRM_DEBUG
|
#undef DRM_DEBUG
|
||||||
|
|
||||||
|
#if DRM_LINUX
|
||||||
|
#undef DRM_LINUX /* FIXME: Linux compat has not been ported yet */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef drm_device_t *device_t;
|
||||||
|
|
||||||
|
extern struct cfdriver DRM(cd);
|
||||||
|
|
||||||
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
|
#define DRM_TIME_SLICE (hz/20) /* Time slice for GLXContexts */
|
||||||
|
|
||||||
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
|
||||||
#define DRM_DEV_UID 0
|
#define DRM_DEV_UID 0
|
||||||
#define DRM_DEV_GID 0
|
#define DRM_DEV_GID 0
|
||||||
#define CDEV_MAJOR 90
|
#define CDEV_MAJOR 34
|
||||||
|
|
||||||
#define DRM_CURPROC curproc
|
#define DRM_CURPROC curproc
|
||||||
#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_SPINLOCK(l) simple_lock(l)
|
#define DRM_SPINUNINIT(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
|
||||||
|
|
||||||
#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p
|
#define DRM_IOCTL_ARGS dev_t kdev, u_long cmd, caddr_t data, int flags, DRM_STRUCTPROC *p
|
||||||
#define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL)
|
#define DRM_LOCK lockmgr(&dev->dev_lock, LK_EXCLUSIVE, NULL)
|
||||||
#define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
|
#define DRM_UNLOCK lockmgr(&dev->dev_lock, LK_RELEASE, NULL)
|
||||||
#define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag)
|
#define DRM_SUSER(p) suser(p->p_ucred, &p->p_acflag)
|
||||||
#define DRM_TASKQUEUE_ARGS void *dev, int pending
|
#define DRM_TASKQUEUE_ARGS void *dev, int pending
|
||||||
#define DRM_IRQ_ARGS void *device
|
#define DRM_IRQ_ARGS void *arg
|
||||||
#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(_cd), minor(kdev))
|
#define DRM_DEVICE drm_device_t *dev = device_lookup(&DRM(cd), minor(kdev))
|
||||||
|
/* XXX Not sure if this is the 'right' version.. */
|
||||||
|
#if __NetBSD_Version__ >= 106140000
|
||||||
|
MALLOC_DECLARE(DRM(M_DRM));
|
||||||
|
#else
|
||||||
|
/* XXX Make sure this works */
|
||||||
|
extern const int DRM(M_DRM) = M_DEVBUF;
|
||||||
|
#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) free( pt, DRM(M_DRM) )
|
||||||
#define DRM_VTOPHYS(addr) vtophys(addr)
|
#define DRM_VTOPHYS(addr) vtophys(addr)
|
||||||
#define DRM_READ8(addr) *((volatile char *)(addr))
|
|
||||||
#define DRM_READ32(addr) *((volatile long *)(addr))
|
#define DRM_READ8(map, offset) bus_space_read_1( (map)->iot, (map)->ioh, (offset) )
|
||||||
#define DRM_WRITE8(addr, val) *((volatile char *)(addr)) = (val)
|
#define DRM_READ32(map, offset) bus_space_read_4( (map)->iot, (map)->ioh, (offset) )
|
||||||
#define DRM_WRITE32(addr, val) *((volatile long *)(addr)) = (val)
|
#define DRM_WRITE8(map, offset, val) bus_space_write_1( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
#define DRM_AGP_FIND_DEVICE()
|
#define DRM_WRITE32(map, offset, val) bus_space_write_4( (map)->iot, (map)->ioh, (offset), (val) )
|
||||||
|
|
||||||
|
#define DRM_AGP_FIND_DEVICE() agp_find_device(0)
|
||||||
|
|
||||||
#define DRM_PRIV \
|
#define DRM_PRIV \
|
||||||
drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
|
drm_file_t *priv = (drm_file_t *) DRM(find_file_by_proc)(dev, p); \
|
||||||
|
@ -104,7 +120,7 @@ do { \
|
||||||
do { \
|
do { \
|
||||||
drm_map_list_entry_t *listentry; \
|
drm_map_list_entry_t *listentry; \
|
||||||
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
TAILQ_FOREACH(listentry, dev->maplist, link) { \
|
||||||
drm_map_t *map = listentry->map; \
|
drm_local_map_t *map = listentry->map; \
|
||||||
if (map->type == _DRM_SHM && \
|
if (map->type == _DRM_SHM && \
|
||||||
map->flags & _DRM_CONTAINS_LOCK) { \
|
map->flags & _DRM_CONTAINS_LOCK) { \
|
||||||
dev_priv->sarea = map; \
|
dev_priv->sarea = map; \
|
||||||
|
@ -113,7 +129,15 @@ do { \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define return DRM_ERR(v) return v;
|
#define DRM_HZ hz
|
||||||
|
|
||||||
|
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
|
||||||
|
while (!condition) { \
|
||||||
|
ret = tsleep( (void *)&(queue), PZERO | PCATCH, "drmwtq", (timeout) ); \
|
||||||
|
if ( ret ) \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
#define DRM_ERR(v) v
|
#define DRM_ERR(v) v
|
||||||
|
|
||||||
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
|
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
|
||||||
|
@ -124,21 +148,25 @@ do { \
|
||||||
copyout(arg2, arg1, arg3)
|
copyout(arg2, arg1, arg3)
|
||||||
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
|
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
|
||||||
copyin(arg2, arg1, arg3)
|
copyin(arg2, arg1, arg3)
|
||||||
|
/* Macros for userspace access with checking readability once */
|
||||||
|
/* FIXME: can't find equivalent functionality for nocheck yet.
|
||||||
|
* It'll be slower than linux, but should be correct.
|
||||||
|
*/
|
||||||
|
#define DRM_VERIFYAREA_READ( uaddr, size ) \
|
||||||
|
(!uvm_useracc((caddr_t)uaddr, size, VM_PROT_READ))
|
||||||
|
#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
|
||||||
|
copyin(arg2, arg1, arg3)
|
||||||
|
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
|
||||||
|
((val) = fuword(uaddr), 0)
|
||||||
|
|
||||||
#define DRM_READMEMORYBARRIER \
|
#define DRM_WRITEMEMORYBARRIER( map ) \
|
||||||
{ \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, 0);
|
||||||
int xchangeDummy; \
|
#define DRM_READMEMORYBARRIER( map ) \
|
||||||
DRM_DEBUG("%s\n", __FUNCTION__); \
|
bus_space_barrier((map)->iot, (map)->ioh, 0, (map)->size, BUS_SPACE_BARRIER_READ);
|
||||||
__asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy)); \
|
|
||||||
__asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;" \
|
|
||||||
" movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;" \
|
|
||||||
" pop %%eax" : /* no outputs */ : /* no inputs */ ); \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
#define DRM_WRITEMEMORYBARRIER DRM_READMEMORYBARRIER
|
#define DRM_WAKEUP(w) wakeup((void *)w)
|
||||||
|
|
||||||
#define DRM_WAKEUP(w) wakeup(w)
|
|
||||||
#define DRM_WAKEUP_INT(w) wakeup(w)
|
#define DRM_WAKEUP_INT(w) wakeup(w)
|
||||||
|
#define DRM_INIT_WAITQUEUE( queue ) do {} while (0)
|
||||||
|
|
||||||
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
|
||||||
|
|
||||||
|
@ -150,8 +178,10 @@ typedef struct drm_chipinfo
|
||||||
char *name;
|
char *name;
|
||||||
} drm_chipinfo_t;
|
} drm_chipinfo_t;
|
||||||
|
|
||||||
|
#define cpu_to_le32(x) (x) /* FIXME */
|
||||||
|
|
||||||
typedef u_int32_t dma_addr_t;
|
typedef u_int32_t dma_addr_t;
|
||||||
typedef volatile u_int32_t 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 spinlock_t;
|
||||||
typedef u_int32_t u32;
|
typedef u_int32_t u32;
|
||||||
|
@ -160,20 +190,35 @@ typedef u_int8_t u8;
|
||||||
typedef dev_type_ioctl(d_ioctl_t);
|
typedef dev_type_ioctl(d_ioctl_t);
|
||||||
typedef vaddr_t vm_offset_t;
|
typedef vaddr_t vm_offset_t;
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
#define atomic_set(p, v) (*(p) = (v))
|
#define atomic_set(p, v) (*(p) = (v))
|
||||||
#define atomic_read(p) (*(p))
|
#define atomic_read(p) (*(p))
|
||||||
#define atomic_inc(p) atomic_add_int(p, 1)
|
#define atomic_inc(p) (*(p) += 1)
|
||||||
#define atomic_dec(p) atomic_subtract_int(p, 1)
|
#define atomic_dec(p) (*(p) -= 1)
|
||||||
#define atomic_add(n, p) atomic_add_int(p, n)
|
#define atomic_add(n, p) (*(p) += (n))
|
||||||
#define atomic_sub(n, p) atomic_subtract_int(p, n)
|
#define atomic_sub(n, p) (*(p) -= (n))
|
||||||
|
|
||||||
/* FIXME: Is NetBSD's kernel non-reentrant? */
|
/* FIXME */
|
||||||
#define atomic_add_int(p, v) *(p) += v
|
#define atomic_add_int(p, v) *(p) += v
|
||||||
#define atomic_subtract_int(p, v) *(p) -= v
|
#define atomic_subtract_int(p, v) *(p) -= v
|
||||||
#define atomic_set_int(p, bits) *(p) |= (bits)
|
#define atomic_set_int(p, bits) *(p) |= (bits)
|
||||||
#define atomic_clear_int(p, bits) *(p) &= ~(bits)
|
#define atomic_clear_int(p, bits) *(p) &= ~(bits)
|
||||||
|
|
||||||
/* Fake this */
|
/* Fake this */
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
atomic_cmpset_int(__volatile__ int *dst, int old, int new)
|
||||||
|
{
|
||||||
|
int s = splhigh();
|
||||||
|
if (*dst==old) {
|
||||||
|
*dst = new;
|
||||||
|
splx(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
splx(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static __inline atomic_t
|
static __inline atomic_t
|
||||||
test_and_set_bit(int b, atomic_t *p)
|
test_and_set_bit(int b, atomic_t *p)
|
||||||
{
|
{
|
||||||
|
@ -223,20 +268,6 @@ find_first_zero_bit(atomic_t *p, int max)
|
||||||
#define spldrm() spltty()
|
#define spldrm() spltty()
|
||||||
#define jiffies hardclock_ticks
|
#define jiffies hardclock_ticks
|
||||||
|
|
||||||
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
|
|
||||||
#define _DRM_CAS(lock,old,new,__ret) \
|
|
||||||
do { \
|
|
||||||
int __dummy; /* Can't mark eax as clobbered */ \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
"lock ; cmpxchg %4,%1\n\t" \
|
|
||||||
"setnz %0" \
|
|
||||||
: "=d" (__ret), \
|
|
||||||
"=m" (__drm_dummy_lock(lock)), \
|
|
||||||
"=a" (__dummy) \
|
|
||||||
: "2" (old), \
|
|
||||||
"r" (new)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Redefinitions to make templating easy */
|
/* Redefinitions to make templating easy */
|
||||||
#define wait_queue_head_t atomic_t
|
#define wait_queue_head_t atomic_t
|
||||||
#define agp_memory void
|
#define agp_memory void
|
||||||
|
@ -257,7 +288,7 @@ do { \
|
||||||
#define DRM_DEBUG(fmt, arg...) \
|
#define DRM_DEBUG(fmt, arg...) \
|
||||||
do { \
|
do { \
|
||||||
if (DRM(flags) & DRM_FLAG_DEBUG) \
|
if (DRM(flags) & DRM_FLAG_DEBUG) \
|
||||||
printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__,## arg); \
|
printf("[" DRM_NAME ":%s] " fmt , __FUNCTION__ ,## arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
#define DRM_DEBUG(fmt, arg...) do { } while (0)
|
||||||
|
|
|
@ -40,9 +40,6 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry )
|
||||||
DRM(free)( entry->busaddr,
|
DRM(free)( entry->busaddr,
|
||||||
entry->pages * sizeof(*entry->busaddr),
|
entry->pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -73,21 +70,10 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
|
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
|
||||||
|
|
||||||
entry->pages = pages;
|
entry->pages = pages;
|
||||||
entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
if ( !entry->pagelist ) {
|
|
||||||
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero(entry->pagelist, pages * sizeof(*entry->pagelist));
|
|
||||||
|
|
||||||
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
if ( !entry->busaddr ) {
|
if ( !entry->busaddr ) {
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -100,9 +86,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
DRM(free)( entry->busaddr,
|
DRM(free)( entry->busaddr,
|
||||||
entry->pages * sizeof(*entry->busaddr),
|
entry->pages * sizeof(*entry->busaddr),
|
||||||
DRM_MEM_PAGES );
|
DRM_MEM_PAGES );
|
||||||
DRM(free)( entry->pagelist,
|
|
||||||
entry->pages * sizeof(*entry->pagelist),
|
|
||||||
DRM_MEM_PAGES );
|
|
||||||
DRM(free)( entry,
|
DRM(free)( entry,
|
||||||
sizeof(*entry),
|
sizeof(*entry),
|
||||||
DRM_MEM_SGLISTS );
|
DRM_MEM_SGLISTS );
|
||||||
|
@ -124,46 +107,6 @@ int DRM(sg_alloc)( DRM_IOCTL_ARGS )
|
||||||
|
|
||||||
dev->sg = entry;
|
dev->sg = entry;
|
||||||
|
|
||||||
#if DEBUG_SCATTER
|
|
||||||
/* Verify that each page points to its virtual address, and vice
|
|
||||||
* versa.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < pages ; i++ ) {
|
|
||||||
unsigned long *tmp;
|
|
||||||
|
|
||||||
tmp = page_address( entry->pagelist[i] );
|
|
||||||
for ( j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++ ) {
|
|
||||||
*tmp = 0xcafebabe;
|
|
||||||
}
|
|
||||||
tmp = (unsigned long *)((u8 *)entry->virtual +
|
|
||||||
(PAGE_SIZE * i));
|
|
||||||
for( j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++ ) {
|
|
||||||
if ( *tmp != 0xcafebabe && error == 0 ) {
|
|
||||||
error = 1;
|
|
||||||
DRM_ERROR( "Scatter allocation error, "
|
|
||||||
"pagelist does not match "
|
|
||||||
"virtual mapping\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp = page_address( entry->pagelist[i] );
|
|
||||||
for(j = 0 ;
|
|
||||||
j < PAGE_SIZE / sizeof(unsigned long) ;
|
|
||||||
j++, tmp++) {
|
|
||||||
*tmp = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error == 0)
|
|
||||||
DRM_ERROR( "Scatter allocation matches pagelist\n" );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DRM(sg_cleanup)( entry );
|
DRM(sg_cleanup)( entry );
|
||||||
|
|
|
@ -125,7 +125,7 @@ static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
|
static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
{
|
{
|
||||||
drm_device_t *dev = arg1;
|
drm_device_t *dev = arg1;
|
||||||
drm_map_t *map;
|
drm_local_map_t *map;
|
||||||
drm_map_list_entry_t *listentry;
|
drm_map_list_entry_t *listentry;
|
||||||
const char *types[] = { "FB", "REG", "SHM" };
|
const char *types[] = { "FB", "REG", "SHM" };
|
||||||
const char *type;
|
const char *type;
|
||||||
|
@ -203,7 +203,7 @@ static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
|
||||||
q->read_queue ? 'r':'-',
|
q->read_queue ? 'r':'-',
|
||||||
q->write_queue ? 'w':'-',
|
q->write_queue ? 'w':'-',
|
||||||
q->flush_queue ? 'f':'-',
|
q->flush_queue ? 'f':'-',
|
||||||
DRM_BUFCOUNT(&q->waitlist),
|
(int)DRM_BUFCOUNT(&q->waitlist),
|
||||||
atomic_read(&q->total_flushed),
|
atomic_read(&q->total_flushed),
|
||||||
atomic_read(&q->total_queued),
|
atomic_read(&q->total_queued),
|
||||||
atomic_read(&q->total_locks));
|
atomic_read(&q->total_locks));
|
||||||
|
|
|
@ -27,7 +27,7 @@ paddr_t DRM(mmap)(dev_t kdev, off_t offset, int prot)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_map_t *map = NULL;
|
drm_local_map_t *map = NULL;
|
||||||
drm_map_list_entry_t *listentry=NULL;
|
drm_map_list_entry_t *listentry=NULL;
|
||||||
drm_file_t *priv;
|
drm_file_t *priv;
|
||||||
|
|
||||||
|
|
71
bsd/gamma.h
71
bsd/gamma.h
|
@ -1,71 +0,0 @@
|
||||||
/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
|
|
||||||
* Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com
|
|
||||||
*
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GAMMA_H__
|
|
||||||
#define __GAMMA_H__
|
|
||||||
|
|
||||||
/* This remains constant for all DRM template files.
|
|
||||||
*/
|
|
||||||
#define DRM(x) gamma_##x
|
|
||||||
|
|
||||||
/* General customization:
|
|
||||||
*/
|
|
||||||
#define __HAVE_MTRR 1
|
|
||||||
|
|
||||||
/* DMA customization:
|
|
||||||
*/
|
|
||||||
#define __HAVE_DMA 1
|
|
||||||
#define __HAVE_OLD_DMA 1
|
|
||||||
#define __HAVE_PCI_DMA 1
|
|
||||||
|
|
||||||
#define __HAVE_MULTIPLE_DMA_QUEUES 1
|
|
||||||
#define __HAVE_DMA_WAITQUEUE 1
|
|
||||||
|
|
||||||
#define __HAVE_DMA_WAITLIST 1
|
|
||||||
#define __HAVE_DMA_FREELIST 1
|
|
||||||
|
|
||||||
#define __HAVE_DMA_FLUSH 1
|
|
||||||
#define __HAVE_DMA_SCHEDULE 1
|
|
||||||
|
|
||||||
#define __HAVE_DMA_READY 1
|
|
||||||
#define DRIVER_DMA_READY() do { \
|
|
||||||
gamma_dma_ready(dev); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define __HAVE_DMA_QUIESCENT 1
|
|
||||||
#define DRIVER_DMA_QUIESCENT() do { \
|
|
||||||
/* FIXME ! */ \
|
|
||||||
gamma_dma_quiescent_dual(dev); \
|
|
||||||
return 0; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define __HAVE_DMA_IRQ 1
|
|
||||||
#define __HAVE_DMA_IRQ_BH 1
|
|
||||||
|
|
||||||
#endif /* __GAMMA_H__ */
|
|
|
@ -1,23 +0,0 @@
|
||||||
# $FreeBSD$
|
|
||||||
|
|
||||||
.PATH: ${.CURDIR}/..
|
|
||||||
KMOD = gamma
|
|
||||||
NOMAN= YES
|
|
||||||
SRCS = gamma_drv.c gamma_dma.c
|
|
||||||
SRCS += device_if.h bus_if.h pci_if.h opt_drm.h
|
|
||||||
CFLAGS += ${DEBUG_FLAGS} -I. -I..
|
|
||||||
|
|
||||||
.if defined(DRM_DEBUG)
|
|
||||||
DRM_DEBUG_OPT= "\#define DRM_DEBUG 1"
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if !defined(DRM_NOLINUX)
|
|
||||||
DRM_LINUX_OPT= "\#define DRM_LINUX 1"
|
|
||||||
.endif
|
|
||||||
|
|
||||||
opt_drm.h:
|
|
||||||
touch opt_drm.h
|
|
||||||
echo $(DRM_DEBUG_OPT) >> opt_drm.h
|
|
||||||
echo $(DRM_LINUX_OPT) >> opt_drm.h
|
|
||||||
|
|
||||||
.include <bsd.kmod.mk>
|
|
611
bsd/gamma_dma.c
611
bsd/gamma_dma.c
|
@ -1,611 +0,0 @@
|
||||||
/* gamma_dma.c -- DMA support for GMX 2000 -*- linux-c -*-
|
|
||||||
* Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
|
|
||||||
*
|
|
||||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "gamma.h"
|
|
||||||
#include "drmP.h"
|
|
||||||
#include "drm.h"
|
|
||||||
#include "gamma_drm.h"
|
|
||||||
#include "gamma_drv.h"
|
|
||||||
|
|
||||||
|
|
||||||
static __inline__ void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
|
|
||||||
unsigned long length)
|
|
||||||
{
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
GAMMA_WRITE(GAMMA_DMAADDRESS, DRM_VTOPHYS((void *)address));
|
|
||||||
while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
|
|
||||||
;
|
|
||||||
GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gamma_dma_quiescent_single(drm_device_t *dev)
|
|
||||||
{
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
while (GAMMA_READ(GAMMA_DMACOUNT))
|
|
||||||
;
|
|
||||||
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
|
|
||||||
;
|
|
||||||
|
|
||||||
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
|
|
||||||
GAMMA_WRITE(GAMMA_SYNC, 0);
|
|
||||||
|
|
||||||
do {
|
|
||||||
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
|
|
||||||
;
|
|
||||||
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gamma_dma_quiescent_dual(drm_device_t *dev)
|
|
||||||
{
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
while (GAMMA_READ(GAMMA_DMACOUNT))
|
|
||||||
;
|
|
||||||
while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
|
|
||||||
;
|
|
||||||
|
|
||||||
GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
|
|
||||||
|
|
||||||
GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
|
|
||||||
GAMMA_WRITE(GAMMA_SYNC, 0);
|
|
||||||
|
|
||||||
/* Read from first MX */
|
|
||||||
do {
|
|
||||||
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
|
|
||||||
;
|
|
||||||
} while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
|
|
||||||
|
|
||||||
/* Read from second MX */
|
|
||||||
do {
|
|
||||||
while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
|
|
||||||
;
|
|
||||||
} while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gamma_dma_ready(drm_device_t *dev)
|
|
||||||
{
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
while (GAMMA_READ(GAMMA_DMACOUNT))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ int gamma_dma_is_ready(drm_device_t *dev)
|
|
||||||
{
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
return !GAMMA_READ(GAMMA_DMACOUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gamma_dma_service( DRM_IRQ_ARGS)
|
|
||||||
{
|
|
||||||
drm_device_t *dev = (drm_device_t *)arg;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
|
|
||||||
atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
|
|
||||||
GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
|
|
||||||
GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
|
|
||||||
GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001);
|
|
||||||
if (gamma_dma_is_ready(dev)) {
|
|
||||||
/* Free previous buffer */
|
|
||||||
if (test_and_set_bit(0, &dev->dma_flag)) return;
|
|
||||||
if (dma->this_buffer) {
|
|
||||||
gamma_free_buffer(dev, dma->this_buffer);
|
|
||||||
dma->this_buffer = NULL;
|
|
||||||
}
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
|
|
||||||
taskqueue_enqueue(taskqueue_swi, &dev->task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only called by gamma_dma_schedule. */
|
|
||||||
static int gamma_do_dma(drm_device_t *dev, int locked)
|
|
||||||
{
|
|
||||||
unsigned long address;
|
|
||||||
unsigned long length;
|
|
||||||
drm_buf_t *buf;
|
|
||||||
int retcode = 0;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
cycles_t dma_start, dma_stop;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (test_and_set_bit(0, &dev->dma_flag)) return DRM_ERR( EBUSY );
|
|
||||||
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
dma_start = get_cycles();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!dma->next_buffer) {
|
|
||||||
DRM_ERROR("No next_buffer\n");
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
return DRM_ERR( EINVAL );
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = dma->next_buffer;
|
|
||||||
address = (unsigned long)buf->address;
|
|
||||||
length = buf->used;
|
|
||||||
|
|
||||||
DRM_DEBUG("context %d, buffer %d (%ld bytes)\n",
|
|
||||||
buf->context, buf->idx, length);
|
|
||||||
|
|
||||||
if (buf->list == DRM_LIST_RECLAIM) {
|
|
||||||
gamma_clear_next_buffer(dev);
|
|
||||||
gamma_free_buffer(dev, buf);
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
return DRM_ERR( EINVAL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!length) {
|
|
||||||
DRM_ERROR("0 length buffer\n");
|
|
||||||
gamma_clear_next_buffer(dev);
|
|
||||||
gamma_free_buffer(dev, buf);
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gamma_dma_is_ready(dev)) {
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
return DRM_ERR( EBUSY );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->while_locked) {
|
|
||||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
|
||||||
DRM_ERROR("Dispatching buffer %d from pid %d"
|
|
||||||
" \"while locked\", but no lock held\n",
|
|
||||||
buf->idx, buf->pid);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!locked && !gamma_lock_take(&dev->lock.hw_lock->lock,
|
|
||||||
DRM_KERNEL_CONTEXT)) {
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
return DRM_ERR( EBUSY );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->last_context != buf->context
|
|
||||||
&& !(dev->queuelist[buf->context]->flags
|
|
||||||
& _DRM_CONTEXT_PRESERVED)) {
|
|
||||||
/* PRE: dev->last_context != buf->context */
|
|
||||||
if (DRM(context_switch)(dev, dev->last_context,
|
|
||||||
buf->context)) {
|
|
||||||
DRM(clear_next_buffer)(dev);
|
|
||||||
DRM(free_buffer)(dev, buf);
|
|
||||||
}
|
|
||||||
retcode = EBUSY;
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
/* POST: we will wait for the context
|
|
||||||
switch and will dispatch on a later call
|
|
||||||
when dev->last_context == buf->context.
|
|
||||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
|
||||||
TIME! */
|
|
||||||
}
|
|
||||||
|
|
||||||
gamma_clear_next_buffer(dev);
|
|
||||||
buf->pending = 1;
|
|
||||||
buf->waiting = 0;
|
|
||||||
buf->list = DRM_LIST_PEND;
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
buf->time_dispatched = get_cycles();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gamma_dma_dispatch(dev, address, length);
|
|
||||||
gamma_free_buffer(dev, dma->this_buffer);
|
|
||||||
dma->this_buffer = buf;
|
|
||||||
|
|
||||||
atomic_inc(&dev->counts[7]); /* _DRM_STAT_DMA */
|
|
||||||
atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
|
|
||||||
|
|
||||||
if (!buf->while_locked && !dev->context_flag && !locked) {
|
|
||||||
if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
|
|
||||||
DRM_KERNEL_CONTEXT)) {
|
|
||||||
DRM_ERROR("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cleanup:
|
|
||||||
|
|
||||||
clear_bit(0, &dev->dma_flag);
|
|
||||||
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
dma_stop = get_cycles();
|
|
||||||
atomic_inc(&dev->histo.dma[gamma_histogram_slot(dma_stop - dma_start)]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return DRM_ERR( retcode );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gamma_dma_timer_bh(unsigned long dev)
|
|
||||||
{
|
|
||||||
gamma_dma_schedule((drm_device_t *)dev, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gamma_dma_immediate_bh(DRM_TASKQUEUE_ARGS)
|
|
||||||
{
|
|
||||||
gamma_dma_schedule(arg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int gamma_dma_schedule(drm_device_t *dev, int locked)
|
|
||||||
{
|
|
||||||
int next;
|
|
||||||
drm_queue_t *q;
|
|
||||||
drm_buf_t *buf;
|
|
||||||
int retcode = 0;
|
|
||||||
int processed = 0;
|
|
||||||
int missed;
|
|
||||||
int expire = 20;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
cycles_t schedule_start;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (test_and_set_bit(0, &dev->interrupt_flag)) {
|
|
||||||
/* Not reentrant */
|
|
||||||
atomic_inc(&dev->counts[10]); /* _DRM_STAT_MISSED */
|
|
||||||
return DRM_ERR( EBUSY );
|
|
||||||
}
|
|
||||||
missed = atomic_read(&dev->counts[10]);
|
|
||||||
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
schedule_start = get_cycles();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
again:
|
|
||||||
if (dev->context_flag) {
|
|
||||||
clear_bit(0, &dev->interrupt_flag);
|
|
||||||
return DRM_ERR( EBUSY );
|
|
||||||
}
|
|
||||||
if (dma->next_buffer) {
|
|
||||||
/* Unsent buffer that was previously
|
|
||||||
selected, but that couldn't be sent
|
|
||||||
because the lock could not be obtained
|
|
||||||
or the DMA engine wasn't ready. Try
|
|
||||||
again. */
|
|
||||||
if (!(retcode = gamma_do_dma(dev, locked))) ++processed;
|
|
||||||
} else {
|
|
||||||
do {
|
|
||||||
next = gamma_select_queue(dev, gamma_dma_timer_bh);
|
|
||||||
if (next >= 0) {
|
|
||||||
q = dev->queuelist[next];
|
|
||||||
buf = gamma_waitlist_get(&q->waitlist);
|
|
||||||
dma->next_buffer = buf;
|
|
||||||
dma->next_queue = q;
|
|
||||||
if (buf && buf->list == DRM_LIST_RECLAIM) {
|
|
||||||
gamma_clear_next_buffer(dev);
|
|
||||||
gamma_free_buffer(dev, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (next >= 0 && !dma->next_buffer);
|
|
||||||
if (dma->next_buffer) {
|
|
||||||
if (!(retcode = gamma_do_dma(dev, locked))) {
|
|
||||||
++processed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (--expire) {
|
|
||||||
if (missed != atomic_read(&dev->counts[10])) {
|
|
||||||
if (gamma_dma_is_ready(dev)) goto again;
|
|
||||||
}
|
|
||||||
if (processed && gamma_dma_is_ready(dev)) {
|
|
||||||
processed = 0;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_bit(0, &dev->interrupt_flag);
|
|
||||||
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles()
|
|
||||||
- schedule_start)]);
|
|
||||||
#endif
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
|
|
||||||
{
|
|
||||||
unsigned long address;
|
|
||||||
unsigned long length;
|
|
||||||
int must_free = 0;
|
|
||||||
int retcode = 0;
|
|
||||||
int i;
|
|
||||||
int idx;
|
|
||||||
drm_buf_t *buf;
|
|
||||||
drm_buf_t *last_buf = NULL;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
static int never;
|
|
||||||
|
|
||||||
/* Turn off interrupt handling */
|
|
||||||
while (test_and_set_bit(0, &dev->interrupt_flag)) {
|
|
||||||
retcode = tsleep(&never, PZERO|PCATCH, "gamp1", 1);
|
|
||||||
if (retcode)
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) {
|
|
||||||
while (!gamma_lock_take(&dev->lock.hw_lock->lock,
|
|
||||||
DRM_KERNEL_CONTEXT)) {
|
|
||||||
retcode = tsleep(&never, PZERO|PCATCH, "gamp2", 1);
|
|
||||||
if (retcode)
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
++must_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < d->send_count; i++) {
|
|
||||||
idx = d->send_indices[i];
|
|
||||||
if (idx < 0 || idx >= dma->buf_count) {
|
|
||||||
DRM_ERROR("Index %d (of %d max)\n",
|
|
||||||
d->send_indices[i], dma->buf_count - 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
buf = dma->buflist[ idx ];
|
|
||||||
if (buf->pid != DRM_CURRENTPID) {
|
|
||||||
DRM_ERROR("Process %d using buffer owned by %d\n",
|
|
||||||
DRM_CURRENTPID, buf->pid);
|
|
||||||
retcode = EINVAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (buf->list != DRM_LIST_NONE) {
|
|
||||||
DRM_ERROR("Process %d using %d's buffer on list %d\n",
|
|
||||||
DRM_CURRENTPID, buf->pid, buf->list);
|
|
||||||
retcode = EINVAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
/* This isn't a race condition on
|
|
||||||
buf->list, since our concern is the
|
|
||||||
buffer reclaim during the time the
|
|
||||||
process closes the /dev/drm? handle, so
|
|
||||||
it can't also be doing DMA. */
|
|
||||||
buf->list = DRM_LIST_PRIO;
|
|
||||||
buf->used = d->send_sizes[i];
|
|
||||||
buf->context = d->context;
|
|
||||||
buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED;
|
|
||||||
address = (unsigned long)buf->address;
|
|
||||||
length = buf->used;
|
|
||||||
if (!length) {
|
|
||||||
DRM_ERROR("0 length buffer\n");
|
|
||||||
}
|
|
||||||
if (buf->pending) {
|
|
||||||
DRM_ERROR("Sending pending buffer:"
|
|
||||||
" buffer %d, offset %d\n",
|
|
||||||
d->send_indices[i], i);
|
|
||||||
retcode = EINVAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (buf->waiting) {
|
|
||||||
DRM_ERROR("Sending waiting buffer:"
|
|
||||||
" buffer %d, offset %d\n",
|
|
||||||
d->send_indices[i], i);
|
|
||||||
retcode = EINVAL;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
buf->pending = 1;
|
|
||||||
|
|
||||||
if (dev->last_context != buf->context
|
|
||||||
&& !(dev->queuelist[buf->context]->flags
|
|
||||||
& _DRM_CONTEXT_PRESERVED)) {
|
|
||||||
/* PRE: dev->last_context != buf->context */
|
|
||||||
DRM(context_switch)(dev, dev->last_context,
|
|
||||||
buf->context);
|
|
||||||
/* POST: we will wait for the context
|
|
||||||
switch and will dispatch on a later call
|
|
||||||
when dev->last_context == buf->context.
|
|
||||||
NOTE WE HOLD THE LOCK THROUGHOUT THIS
|
|
||||||
TIME! */
|
|
||||||
retcode = tsleep(&dev->context_wait, PZERO|PCATCH,
|
|
||||||
"gamctx", 0);
|
|
||||||
if (retcode)
|
|
||||||
goto cleanup;
|
|
||||||
if (dev->last_context != buf->context) {
|
|
||||||
DRM_ERROR("Context mismatch: %d %d\n",
|
|
||||||
dev->last_context,
|
|
||||||
buf->context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DRM_DMA_HISTOGRAM
|
|
||||||
buf->time_queued = get_cycles();
|
|
||||||
buf->time_dispatched = buf->time_queued;
|
|
||||||
#endif
|
|
||||||
gamma_dma_dispatch(dev, address, length);
|
|
||||||
atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */
|
|
||||||
atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
|
|
||||||
|
|
||||||
if (last_buf) {
|
|
||||||
gamma_free_buffer(dev, last_buf);
|
|
||||||
}
|
|
||||||
last_buf = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (last_buf) {
|
|
||||||
gamma_dma_ready(dev);
|
|
||||||
gamma_free_buffer(dev, last_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (must_free && !dev->context_flag) {
|
|
||||||
if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
|
|
||||||
DRM_KERNEL_CONTEXT)) {
|
|
||||||
DRM_ERROR("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clear_bit(0, &dev->interrupt_flag);
|
|
||||||
return DRM_ERR( retcode );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
|
|
||||||
{
|
|
||||||
drm_buf_t *last_buf = NULL;
|
|
||||||
int retcode = 0;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
|
|
||||||
if (d->flags & _DRM_DMA_BLOCK) {
|
|
||||||
last_buf = dma->buflist[d->send_indices[d->send_count-1]];
|
|
||||||
atomic_inc(&last_buf->dma_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((retcode = gamma_dma_enqueue(dev, d))) {
|
|
||||||
if (d->flags & _DRM_DMA_BLOCK)
|
|
||||||
atomic_dec(&last_buf->dma_wait);
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
gamma_dma_schedule(dev, 0);
|
|
||||||
|
|
||||||
if (d->flags & _DRM_DMA_BLOCK) {
|
|
||||||
DRM_DEBUG("%d waiting\n", DRM_CURRENTPID);
|
|
||||||
for (;;) {
|
|
||||||
retcode = tsleep(&last_buf->dma_wait, PZERO|PCATCH,
|
|
||||||
"gamdw", 0);
|
|
||||||
if (!last_buf->waiting
|
|
||||||
&& !last_buf->pending)
|
|
||||||
break; /* finished */
|
|
||||||
if (retcode)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
atomic_dec(&last_buf->dma_wait);
|
|
||||||
DRM_DEBUG("%d running\n", DRM_CURRENTPID);
|
|
||||||
if (!retcode
|
|
||||||
|| (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
|
|
||||||
if (!last_buf->dma_wait) {
|
|
||||||
gamma_free_buffer(dev, last_buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (retcode) {
|
|
||||||
DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n",
|
|
||||||
d->context,
|
|
||||||
last_buf->waiting,
|
|
||||||
last_buf->pending,
|
|
||||||
DRM_WAITCOUNT(dev, d->context),
|
|
||||||
last_buf->idx,
|
|
||||||
last_buf->list,
|
|
||||||
last_buf->pid,
|
|
||||||
DRM_CURRENTPID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DRM_ERR( retcode );
|
|
||||||
}
|
|
||||||
|
|
||||||
int gamma_dma( DRM_IOCTL_ARGS )
|
|
||||||
{
|
|
||||||
DRM_DEVICE;
|
|
||||||
drm_device_dma_t *dma = dev->dma;
|
|
||||||
int retcode = 0;
|
|
||||||
drm_dma_t d;
|
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t *) data, sizeof(d));
|
|
||||||
|
|
||||||
if (d.send_count < 0 || d.send_count > dma->buf_count) {
|
|
||||||
DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
|
|
||||||
DRM_CURRENTPID, d.send_count, dma->buf_count);
|
|
||||||
return DRM_ERR( EINVAL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.request_count < 0 || d.request_count > dma->buf_count) {
|
|
||||||
DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
|
|
||||||
DRM_CURRENTPID, d.request_count, dma->buf_count);
|
|
||||||
return DRM_ERR( EINVAL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d.send_count) {
|
|
||||||
if (d.flags & _DRM_DMA_PRIORITY)
|
|
||||||
retcode = gamma_dma_priority(dev, &d);
|
|
||||||
else
|
|
||||||
retcode = gamma_dma_send_buffers(dev, &d);
|
|
||||||
}
|
|
||||||
|
|
||||||
d.granted_count = 0;
|
|
||||||
|
|
||||||
if (!retcode && d.request_count) {
|
|
||||||
retcode = gamma_dma_get_buffers(dev, &d);
|
|
||||||
}
|
|
||||||
|
|
||||||
DRM_DEBUG("%d returning, granted = %d\n",
|
|
||||||
DRM_CURRENTPID, d.granted_count);
|
|
||||||
DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d));
|
|
||||||
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DRM(driver_irq_preinstall)(drm_device_t *dev) {
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
#if 1
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 );
|
|
||||||
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
|
|
||||||
#else
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );
|
|
||||||
GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DRM(driver_irq_postinstall)(drm_device_t *dev) {
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
#if 1
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
|
|
||||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 );
|
|
||||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 );
|
|
||||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 );
|
|
||||||
#else
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 );
|
|
||||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
|
|
||||||
drm_gamma_private_t *dev_priv =
|
|
||||||
(drm_gamma_private_t *)dev->dev_private;
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2);
|
|
||||||
while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3);
|
|
||||||
GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 );
|
|
||||||
GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 );
|
|
||||||
GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 );
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
#ifndef _GAMMA_DRM_H_
|
|
||||||
#define _GAMMA_DRM_H_
|
|
||||||
|
|
||||||
typedef struct _drm_gamma_tex_region {
|
|
||||||
unsigned char next, prev; /* indices to form a circular LRU */
|
|
||||||
unsigned char in_use; /* owned by a client, or free? */
|
|
||||||
int age; /* tracked by clients to update local LRU's */
|
|
||||||
} drm_gamma_tex_region_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int GDeltaMode;
|
|
||||||
unsigned int GDepthMode;
|
|
||||||
unsigned int GGeometryMode;
|
|
||||||
unsigned int GTransformMode;
|
|
||||||
} drm_gamma_context_regs_t;
|
|
||||||
|
|
||||||
typedef struct _drm_gamma_sarea {
|
|
||||||
drm_gamma_context_regs_t context_state;
|
|
||||||
|
|
||||||
unsigned int dirty;
|
|
||||||
|
|
||||||
|
|
||||||
/* Maintain an LRU of contiguous regions of texture space. If
|
|
||||||
* you think you own a region of texture memory, and it has an
|
|
||||||
* age different to the one you set, then you are mistaken and
|
|
||||||
* it has been stolen by another client. If global texAge
|
|
||||||
* hasn't changed, there is no need to walk the list.
|
|
||||||
*
|
|
||||||
* These regions can be used as a proxy for the fine-grained
|
|
||||||
* texture information of other clients - by maintaining them
|
|
||||||
* in the same lru which is used to age their own textures,
|
|
||||||
* clients have an approximate lru for the whole of global
|
|
||||||
* texture space, and can make informed decisions as to which
|
|
||||||
* areas to kick out. There is no need to choose whether to
|
|
||||||
* kick out your own texture or someone else's - simply eject
|
|
||||||
* them all in LRU order.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define GAMMA_NR_TEX_REGIONS 64
|
|
||||||
drm_gamma_tex_region_t texList[GAMMA_NR_TEX_REGIONS+1];
|
|
||||||
/* Last elt is sentinal */
|
|
||||||
int texAge; /* last time texture was uploaded */
|
|
||||||
int last_enqueue; /* last time a buffer was enqueued */
|
|
||||||
int last_dispatch; /* age of the most recently dispatched buffer */
|
|
||||||
int last_quiescent; /* */
|
|
||||||
int ctxOwner; /* last context to upload state */
|
|
||||||
|
|
||||||
int vertex_prim;
|
|
||||||
} drm_gamma_sarea_t;
|
|
||||||
|
|
||||||
/* WARNING: If you change any of these defines, make sure to change the
|
|
||||||
* defines in the Xserver file (xf86drmGamma.h)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Gamma specific ioctls
|
|
||||||
* The device specific ioctl range is 0x40 to 0x79.
|
|
||||||
*/
|
|
||||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
|
||||||
#define DRM_IOCTL_GAMMA_COPY DRM_IOW( 0x41, drm_gamma_copy_t)
|
|
||||||
|
|
||||||
typedef struct drm_gamma_copy {
|
|
||||||
unsigned int DMAOutputAddress;
|
|
||||||
unsigned int DMAOutputCount;
|
|
||||||
unsigned int DMAReadGLINTSource;
|
|
||||||
unsigned int DMARectangleWriteAddress;
|
|
||||||
unsigned int DMARectangleWriteLinePitch;
|
|
||||||
unsigned int DMARectangleWrite;
|
|
||||||
unsigned int DMARectangleReadAddress;
|
|
||||||
unsigned int DMARectangleReadLinePitch;
|
|
||||||
unsigned int DMARectangleRead;
|
|
||||||
unsigned int DMARectangleReadTarget;
|
|
||||||
} drm_gamma_copy_t;
|
|
||||||
|
|
||||||
typedef struct drm_gamma_init {
|
|
||||||
enum {
|
|
||||||
GAMMA_INIT_DMA = 0x01,
|
|
||||||
GAMMA_CLEANUP_DMA = 0x02
|
|
||||||
} func;
|
|
||||||
|
|
||||||
int sarea_priv_offset;
|
|
||||||
int pcimode;
|
|
||||||
unsigned int mmio0;
|
|
||||||
unsigned int mmio1;
|
|
||||||
unsigned int mmio2;
|
|
||||||
unsigned int mmio3;
|
|
||||||
unsigned int buffers_offset;
|
|
||||||
} drm_gamma_init_t;
|
|
||||||
|
|
||||||
#endif /* _GAMMA_DRM_H_ */
|
|
|
@ -1,86 +0,0 @@
|
||||||
/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
|
|
||||||
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
|
|
||||||
*
|
|
||||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "gamma.h"
|
|
||||||
#include "drmP.h"
|
|
||||||
#include "drm.h"
|
|
||||||
#include "gamma_drm.h"
|
|
||||||
#include "gamma_drv.h"
|
|
||||||
|
|
||||||
#define DRIVER_AUTHOR "VA Linux Systems Inc."
|
|
||||||
|
|
||||||
#define DRIVER_NAME "gamma"
|
|
||||||
#define DRIVER_DESC "3DLabs gamma"
|
|
||||||
#define DRIVER_DATE "20010216"
|
|
||||||
|
|
||||||
#define DRIVER_MAJOR 1
|
|
||||||
#define DRIVER_MINOR 0
|
|
||||||
#define DRIVER_PATCHLEVEL 0
|
|
||||||
|
|
||||||
#define DRIVER_IOCTLS \
|
|
||||||
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }
|
|
||||||
|
|
||||||
/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
|
|
||||||
* Please report to anholt@teleport.com inaccuracies or if a chip you have works that is marked unsupported here.
|
|
||||||
*/
|
|
||||||
drm_chipinfo_t DRM(devicelist)[] = {
|
|
||||||
{0x3d3d, 0x0008, 1, "3DLabs Gamma"},
|
|
||||||
{0, 0, 0, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define __HAVE_COUNTERS 5
|
|
||||||
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
|
|
||||||
#define __HAVE_COUNTER7 _DRM_STAT_DMA
|
|
||||||
#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY
|
|
||||||
#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL
|
|
||||||
#define __HAVE_COUNTER10 _DRM_STAT_MISSED
|
|
||||||
|
|
||||||
|
|
||||||
#include "drm_auth.h"
|
|
||||||
#include "drm_bufs.h"
|
|
||||||
#include "drm_context.h"
|
|
||||||
#include "drm_dma.h"
|
|
||||||
#include "drm_drawable.h"
|
|
||||||
#include "drm_drv.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "drm_fops.h"
|
|
||||||
#include "drm_init.h"
|
|
||||||
#include "drm_ioctl.h"
|
|
||||||
#include "drm_lists.h"
|
|
||||||
#include "drm_lock.h"
|
|
||||||
#include "drm_memory.h"
|
|
||||||
#include "drm_vm.h"
|
|
||||||
#include "drm_sysctl.h"
|
|
||||||
|
|
||||||
DRIVER_MODULE(gamma, pci, gamma_driver, gamma_devclass, 0, 0);
|
|
104
bsd/gamma_drv.h
104
bsd/gamma_drv.h
|
@ -1,104 +0,0 @@
|
||||||
/* gamma_drv.h -- Private header for 3dlabs GMX 2000 driver -*- linux-c -*-
|
|
||||||
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
|
|
||||||
*
|
|
||||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
||||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the next
|
|
||||||
* paragraph) shall be included in all copies or substantial portions of the
|
|
||||||
* Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Rickard E. (Rik) Faith <faith@valinux.com>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _GAMMA_DRV_H_
|
|
||||||
#define _GAMMA_DRV_H_
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct drm_gamma_private {
|
|
||||||
drm_map_t *buffers;
|
|
||||||
drm_map_t *mmio0;
|
|
||||||
drm_map_t *mmio1;
|
|
||||||
drm_map_t *mmio2;
|
|
||||||
drm_map_t *mmio3;
|
|
||||||
} drm_gamma_private_t;
|
|
||||||
|
|
||||||
#define LOCK_TEST_WITH_RETURN( dev ) \
|
|
||||||
do { \
|
|
||||||
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
|
|
||||||
dev->lock.pid != DRM_CURRENTPID ) { \
|
|
||||||
DRM_ERROR( "%s called without lock held\n", \
|
|
||||||
__FUNCTION__ ); \
|
|
||||||
return DRM_ERR( EINVAL ); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
extern void gamma_dma_ready(drm_device_t *dev);
|
|
||||||
extern void gamma_dma_quiescent_single(drm_device_t *dev);
|
|
||||||
extern void gamma_dma_quiescent_dual(drm_device_t *dev);
|
|
||||||
|
|
||||||
/* gamma_dma.c */
|
|
||||||
extern int gamma_dma_schedule(drm_device_t *dev, int locked);
|
|
||||||
extern int gamma_dma( DRM_IOCTL_ARGS );
|
|
||||||
extern int gamma_find_devices(void);
|
|
||||||
extern int gamma_found(void);
|
|
||||||
|
|
||||||
|
|
||||||
#define GAMMA_OFF(reg) \
|
|
||||||
((reg < 0x1000) \
|
|
||||||
? reg \
|
|
||||||
: ((reg < 0x10000) \
|
|
||||||
? (reg - 0x1000) \
|
|
||||||
: ((reg < 0x11000) \
|
|
||||||
? (reg - 0x10000) \
|
|
||||||
: (reg - 0x11000))))
|
|
||||||
|
|
||||||
#define GAMMA_BASE(reg) ((unsigned long) \
|
|
||||||
((reg < 0x1000) ? dev_priv->mmio0->handle : \
|
|
||||||
((reg < 0x10000) ? dev_priv->mmio1->handle : \
|
|
||||||
((reg < 0x11000) ? dev_priv->mmio2->handle : \
|
|
||||||
dev_priv->mmio3->handle))))
|
|
||||||
|
|
||||||
#define GAMMA_ADDR(reg) (GAMMA_BASE(reg) + GAMMA_OFF(reg))
|
|
||||||
#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
|
|
||||||
#define GAMMA_READ(reg) GAMMA_DEREF(reg)
|
|
||||||
#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
|
|
||||||
|
|
||||||
#define GAMMA_BROADCASTMASK 0x9378
|
|
||||||
#define GAMMA_COMMANDINTENABLE 0x0c48
|
|
||||||
#define GAMMA_DMAADDRESS 0x0028
|
|
||||||
#define GAMMA_DMACOUNT 0x0030
|
|
||||||
#define GAMMA_FILTERMODE 0x8c00
|
|
||||||
#define GAMMA_GCOMMANDINTFLAGS 0x0c50
|
|
||||||
#define GAMMA_GCOMMANDMODE 0x0c40
|
|
||||||
#define GAMMA_GCOMMANDSTATUS 0x0c60
|
|
||||||
#define GAMMA_GDELAYTIMER 0x0c38
|
|
||||||
#define GAMMA_GDMACONTROL 0x0060
|
|
||||||
#define GAMMA_GINTENABLE 0x0808
|
|
||||||
#define GAMMA_GINTFLAGS 0x0810
|
|
||||||
#define GAMMA_INFIFOSPACE 0x0018
|
|
||||||
#define GAMMA_OUTFIFOWORDS 0x0020
|
|
||||||
#define GAMMA_OUTPUTFIFO 0x2000
|
|
||||||
#define GAMMA_SYNC 0x8c40
|
|
||||||
#define GAMMA_SYNC_TAG 0x0188
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -29,8 +29,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "mga.h"
|
#include "mga.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -63,4 +61,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_vm.h"
|
#include "drm_vm.h"
|
||||||
#include "drm_sysctl.h"
|
#include "drm_sysctl.h"
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
|
DRIVER_MODULE(mga, pci, mga_driver, mga_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(mga, DV_TTY, NULL);
|
||||||
|
#endif
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "r128.h"
|
#include "r128.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -83,4 +80,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_scatter.h"
|
#include "drm_scatter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
|
DRIVER_MODULE(r128, pci, r128_driver, r128_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(r128, DV_TTY, NULL);
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "radeon.h"
|
#include "radeon.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
@ -38,21 +36,40 @@
|
||||||
#include "ati_pcigart.h"
|
#include "ati_pcigart.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* List acquired from http://www.yourvote.com/pci/pcihdr.h and xc/xc/programs/Xserver/hw/xfree86/common/xf86PciInfo.h
|
|
||||||
* Please report to eta@lclark.edu inaccuracies or if a chip you have works that is marked unsupported here.
|
|
||||||
*/
|
|
||||||
drm_chipinfo_t DRM(devicelist)[] = {
|
drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
|
{0x1002, 0x4242, 1, "ATI Radeon BB AIW 8500DV (AGP)"},
|
||||||
|
{0x1002, 0x4336, 1, "ATI Radeon Mobility"},
|
||||||
|
{0x1002, 0x4337, 1, "ATI Radeon IGP 340"},
|
||||||
|
{0x1002, 0x4964, 1, "ATI Radeon Id 9000"},
|
||||||
|
{0x1002, 0x4965, 1, "ATI Radeon Ie 9000"},
|
||||||
|
{0x1002, 0x4966, 1, "ATI Radeon If 9000"},
|
||||||
|
{0x1002, 0x4967, 1, "ATI Radeon Ig 9000"},
|
||||||
|
{0x1002, 0x496e, 1, "ATI Radeon Ig 9000"},
|
||||||
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
|
{0x1002, 0x4C57, 1, "ATI Radeon LW Mobility 7 (AGP)"},
|
||||||
|
{0x1002, 0x4C58, 1, "ATI Radeon LX Mobility 7 (AGP)"},
|
||||||
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
|
{0x1002, 0x4C59, 1, "ATI Radeon LY Mobility 6 (AGP)"},
|
||||||
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
|
{0x1002, 0x4C5A, 1, "ATI Radeon LZ Mobility 6 (AGP)"},
|
||||||
{0x1002, 0x5144, 1, "ATI Radeon QD (AGP)"},
|
{0x1002, 0x4C64, 1, "ATI Radeon Ld Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5145, 1, "ATI Radeon QE (AGP)"},
|
{0x1002, 0x4C65, 1, "ATI Radeon Le Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5146, 1, "ATI Radeon QF (AGP)"},
|
{0x1002, 0x4C66, 1, "ATI Radeon Lf Mobility 9000 (AGP)"},
|
||||||
{0x1002, 0x5147, 1, "ATI Radeon QG (AGP)"},
|
{0x1002, 0x4C67, 1, "ATI Radeon Lg Mobility 9000 (AGP)"},
|
||||||
|
{0x1002, 0x5144, 1, "ATI Radeon QD R100 (AGP)"},
|
||||||
|
{0x1002, 0x5145, 1, "ATI Radeon QE R100 (AGP)"},
|
||||||
|
{0x1002, 0x5146, 1, "ATI Radeon QF R100 (AGP)"},
|
||||||
|
{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, 0x514A, 1, "ATI Radeon QJ R200"},
|
||||||
|
{0x1002, 0x514B, 1, "ATI Radeon QK R200"},
|
||||||
|
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
|
||||||
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
|
{0x1002, 0x5157, 1, "ATI Radeon QW 7500 (AGP)"},
|
||||||
|
{0x1002, 0x5158, 1, "ATI Radeon QX 7500 (AGP)"},
|
||||||
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
|
{0x1002, 0x5159, 1, "ATI Radeon QY VE (AGP)"},
|
||||||
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
|
{0x1002, 0x515A, 1, "ATI Radeon QZ VE (AGP)"},
|
||||||
{0x1002, 0x514C, 1, "ATI Radeon QL 8500 (AGP)"},
|
{0x1002, 0x5168, 1, "ATI Radeon Qh R200"},
|
||||||
|
{0x1002, 0x5169, 1, "ATI Radeon Qi R200"},
|
||||||
|
{0x1002, 0x516A, 1, "ATI Radeon Qj R200"},
|
||||||
|
{0x1002, 0x516B, 1, "ATI Radeon Qk R200"},
|
||||||
{0, 0, 0, NULL}
|
{0, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,4 +91,8 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
#include "drm_scatter.h"
|
#include "drm_scatter.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
|
DRIVER_MODULE(DRIVER_NAME, pci, DRM(driver), DRM(devclass), 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(radeon, DV_TTY, NULL);
|
||||||
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
* Gareth Hughes <gareth@valinux.com>
|
* Gareth Hughes <gareth@valinux.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include "tdfx.h"
|
#include "tdfx.h"
|
||||||
#include "drmP.h"
|
#include "drmP.h"
|
||||||
|
|
||||||
|
@ -96,4 +93,6 @@ drm_chipinfo_t DRM(devicelist)[] = {
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
|
DRIVER_MODULE(tdfx, pci, tdfx_driver, tdfx_devclass, 0, 0);
|
||||||
|
#elif defined(__NetBSD__)
|
||||||
|
CFDRIVER_DECL(tdfx, DV_TTY, NULL);
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
|
@ -84,13 +84,16 @@ extern unsigned long _bus_base(void);
|
||||||
|
|
||||||
#include "xf86drm.h"
|
#include "xf86drm.h"
|
||||||
|
|
||||||
#ifndef DRM_MAJOR
|
#ifdef __FreeBSD__
|
||||||
#define DRM_MAJOR 226 /* Linux */
|
#define DRM_MAJOR 145
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifdef __NetBSD__
|
||||||
#undef DRM_MAJOR
|
#define DRM_MAJOR 34
|
||||||
#define DRM_MAJOR 145 /* Should set in drm.h for *BSD */
|
#endif
|
||||||
|
|
||||||
|
#ifndef DRM_MAJOR
|
||||||
|
#define DRM_MAJOR 226 /* Linux */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DRM_MAX_MINOR
|
#ifndef DRM_MAX_MINOR
|
||||||
|
|
|
@ -255,6 +255,7 @@ do { \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
#define DRM_DROP_MAP(_map)
|
||||||
|
|
||||||
/* Internal types and structures */
|
/* Internal types and structures */
|
||||||
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
@ -517,6 +518,8 @@ typedef struct drm_map_list {
|
||||||
drm_map_t *map;
|
drm_map_t *map;
|
||||||
} drm_map_list_t;
|
} drm_map_list_t;
|
||||||
|
|
||||||
|
typedef drm_map_t drm_local_map_t;
|
||||||
|
|
||||||
#if __HAVE_VBL_IRQ
|
#if __HAVE_VBL_IRQ
|
||||||
|
|
||||||
typedef struct drm_vbl_sig {
|
typedef struct drm_vbl_sig {
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
#define DRM_ERR(d) -(d)
|
#define DRM_ERR(d) -(d)
|
||||||
#define DRM_CURRENTPID current->pid
|
#define DRM_CURRENTPID current->pid
|
||||||
#define DRM_UDELAY(d) udelay(d)
|
#define DRM_UDELAY(d) udelay(d)
|
||||||
#define DRM_READ8(addr) readb(addr)
|
#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_READ32(addr) readl(addr)
|
#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE8(addr, val) writeb(val, addr)
|
#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE32(addr, val) writel(val, addr)
|
#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_READMEMORYBARRIER() mb()
|
#define DRM_READMEMORYBARRIER(map) mb()
|
||||||
#define DRM_WRITEMEMORYBARRIER() wmb()
|
#define DRM_WRITEMEMORYBARRIER(map) wmb()
|
||||||
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
|
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
|
||||||
drm_device_t *dev = priv->dev
|
drm_device_t *dev = priv->dev
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,7 @@ do { \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
#define DRM_DROP_MAP(_map)
|
||||||
|
|
||||||
/* Internal types and structures */
|
/* Internal types and structures */
|
||||||
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
@ -517,6 +518,8 @@ typedef struct drm_map_list {
|
||||||
drm_map_t *map;
|
drm_map_t *map;
|
||||||
} drm_map_list_t;
|
} drm_map_list_t;
|
||||||
|
|
||||||
|
typedef drm_map_t drm_local_map_t;
|
||||||
|
|
||||||
#if __HAVE_VBL_IRQ
|
#if __HAVE_VBL_IRQ
|
||||||
|
|
||||||
typedef struct drm_vbl_sig {
|
typedef struct drm_vbl_sig {
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
#define DRM_ERR(d) -(d)
|
#define DRM_ERR(d) -(d)
|
||||||
#define DRM_CURRENTPID current->pid
|
#define DRM_CURRENTPID current->pid
|
||||||
#define DRM_UDELAY(d) udelay(d)
|
#define DRM_UDELAY(d) udelay(d)
|
||||||
#define DRM_READ8(addr) readb(addr)
|
#define DRM_READ8(map, offset) readb(((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_READ32(addr) readl(addr)
|
#define DRM_READ32(map, offset) readl(((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE8(addr, val) writeb(val, addr)
|
#define DRM_WRITE8(map, offset, val) writeb(val, ((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_WRITE32(addr, val) writel(val, addr)
|
#define DRM_WRITE32(map, offset, val) writel(val, ((unsigned long)(map)->handle) + (offset))
|
||||||
#define DRM_READMEMORYBARRIER() mb()
|
#define DRM_READMEMORYBARRIER(map) mb()
|
||||||
#define DRM_WRITEMEMORYBARRIER() wmb()
|
#define DRM_WRITEMEMORYBARRIER(map) wmb()
|
||||||
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
|
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
|
||||||
drm_device_t *dev = priv->dev
|
drm_device_t *dev = priv->dev
|
||||||
|
|
||||||
|
|
|
@ -90,14 +90,14 @@ typedef struct drm_mga_private {
|
||||||
unsigned int texture_offset;
|
unsigned int texture_offset;
|
||||||
unsigned int texture_size;
|
unsigned int texture_size;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *status;
|
drm_local_map_t *status;
|
||||||
drm_map_t *warp;
|
drm_local_map_t *warp;
|
||||||
drm_map_t *primary;
|
drm_local_map_t *primary;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
} drm_mga_private_t;
|
} drm_mga_private_t;
|
||||||
|
|
||||||
/* mga_dma.c */
|
/* mga_dma.c */
|
||||||
|
@ -131,32 +131,30 @@ extern int mga_getparam( DRM_IOCTL_ARGS );
|
||||||
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
|
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
|
||||||
extern int mga_warp_init( drm_mga_private_t *dev_priv );
|
extern int mga_warp_init( drm_mga_private_t *dev_priv );
|
||||||
|
|
||||||
#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER()
|
#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->primary)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__linux__) && defined(__alpha__)
|
||||||
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
|
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
|
||||||
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
|
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
|
||||||
|
|
||||||
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
|
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
|
||||||
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
||||||
|
|
||||||
#ifdef __alpha__
|
|
||||||
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
|
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
|
||||||
#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
|
#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
|
||||||
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
|
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0)
|
||||||
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
|
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0)
|
||||||
|
|
||||||
static inline u32 _MGA_READ(u32 *addr)
|
static inline u32 _MGA_READ(u32 *addr)
|
||||||
{
|
{
|
||||||
DRM_READMEMORYBARRIER();
|
DRM_READMEMORYBARRIER(dev_priv->mmio);
|
||||||
return *(volatile u32 *)addr;
|
return *(volatile u32 *)addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define MGA_READ( reg ) MGA_DEREF( reg )
|
#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg))
|
||||||
#define MGA_READ8( reg ) MGA_DEREF8( reg )
|
#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg))
|
||||||
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
|
#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val))
|
||||||
#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
|
#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DWGREG0 0x1c00
|
#define DWGREG0 0x1c00
|
||||||
|
|
|
@ -579,6 +579,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
||||||
(dev_priv->ring.size / sizeof(u32)) - 1;
|
(dev_priv->ring.size / sizeof(u32)) - 1;
|
||||||
|
|
||||||
dev_priv->ring.high_mark = 128;
|
dev_priv->ring.high_mark = 128;
|
||||||
|
dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
|
||||||
|
|
||||||
dev_priv->sarea_priv->last_frame = 0;
|
dev_priv->sarea_priv->last_frame = 0;
|
||||||
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
|
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#ifndef __R128_DRV_H__
|
#ifndef __R128_DRV_H__
|
||||||
#define __R128_DRV_H__
|
#define __R128_DRV_H__
|
||||||
|
|
||||||
#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head )
|
#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */
|
||||||
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) )
|
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
|
||||||
|
|
||||||
typedef struct drm_r128_freelist {
|
typedef struct drm_r128_freelist {
|
||||||
unsigned int age;
|
unsigned int age;
|
||||||
|
@ -56,6 +56,7 @@ typedef struct drm_r128_ring_buffer {
|
||||||
int space;
|
int space;
|
||||||
|
|
||||||
int high_mark;
|
int high_mark;
|
||||||
|
drm_local_map_t *ring_rptr;
|
||||||
} drm_r128_ring_buffer_t;
|
} drm_r128_ring_buffer_t;
|
||||||
|
|
||||||
typedef struct drm_r128_private {
|
typedef struct drm_r128_private {
|
||||||
|
@ -98,13 +99,13 @@ typedef struct drm_r128_private {
|
||||||
u32 depth_pitch_offset_c;
|
u32 depth_pitch_offset_c;
|
||||||
u32 span_pitch_offset_c;
|
u32 span_pitch_offset_c;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *cce_ring;
|
drm_local_map_t *cce_ring;
|
||||||
drm_map_t *ring_rptr;
|
drm_local_map_t *ring_rptr;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
} drm_r128_private_t;
|
} drm_r128_private_t;
|
||||||
|
|
||||||
typedef struct drm_r128_buf_priv {
|
typedef struct drm_r128_buf_priv {
|
||||||
|
@ -370,15 +371,10 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
|
||||||
|
|
||||||
#define R128_PERFORMANCE_BOXES 0
|
#define R128_PERFORMANCE_BOXES 0
|
||||||
|
|
||||||
|
#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||||
#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||||
#define R128_ADDR(reg) (R128_BASE( reg ) + reg)
|
#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||||
|
#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
|
||||||
#define R128_READ(reg) DRM_READ32( (volatile u32 *) R128_ADDR(reg) )
|
|
||||||
#define R128_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define R128_READ8(reg) DRM_READ8( (volatile u8 *) R128_ADDR(reg) )
|
|
||||||
#define R128_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define R128_WRITE_PLL(addr,val) \
|
#define R128_WRITE_PLL(addr,val) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -453,7 +449,7 @@ do { \
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__)
|
||||||
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
|
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
|
||||||
#else
|
#else
|
||||||
#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER()
|
#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -926,11 +926,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
|
||||||
RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
|
RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
|
||||||
|
|
||||||
/* Writeback doesn't seem to work everywhere, test it first */
|
/* Writeback doesn't seem to work everywhere, test it first */
|
||||||
DRM_WRITE32( &dev_priv->scratch[1], 0 );
|
DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
|
||||||
RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
|
RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
|
||||||
|
|
||||||
for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
|
for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
|
||||||
if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef )
|
if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
|
||||||
break;
|
break;
|
||||||
DRM_UDELAY( 1 );
|
DRM_UDELAY( 1 );
|
||||||
}
|
}
|
||||||
|
@ -1217,6 +1217,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
||||||
(dev_priv->ring.size / sizeof(u32)) - 1;
|
(dev_priv->ring.size / sizeof(u32)) - 1;
|
||||||
|
|
||||||
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
||||||
|
dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
|
||||||
|
|
||||||
#if __REALLY_HAVE_SG
|
#if __REALLY_HAVE_SG
|
||||||
if ( dev_priv->is_pci ) {
|
if ( dev_priv->is_pci ) {
|
||||||
|
@ -1542,7 +1543,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
|
||||||
drm_buf_t *buf;
|
drm_buf_t *buf;
|
||||||
int i, t;
|
int i, t;
|
||||||
int start;
|
int start;
|
||||||
u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
|
u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
|
||||||
|
|
||||||
if ( ++dev_priv->last_buf >= dma->buf_count )
|
if ( ++dev_priv->last_buf >= dma->buf_count )
|
||||||
dev_priv->last_buf = 0;
|
dev_priv->last_buf = 0;
|
||||||
|
|
|
@ -396,7 +396,7 @@ typedef struct drm_radeon_init {
|
||||||
enum {
|
enum {
|
||||||
RADEON_INIT_CP = 0x01,
|
RADEON_INIT_CP = 0x01,
|
||||||
RADEON_CLEANUP_CP = 0x02,
|
RADEON_CLEANUP_CP = 0x02,
|
||||||
RADEON_INIT_R200_CP = 0x03,
|
RADEON_INIT_R200_CP = 0x03
|
||||||
} func;
|
} func;
|
||||||
unsigned long sarea_priv_offset;
|
unsigned long sarea_priv_offset;
|
||||||
int is_pci;
|
int is_pci;
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#ifndef __RADEON_DRV_H__
|
#ifndef __RADEON_DRV_H__
|
||||||
#define __RADEON_DRV_H__
|
#define __RADEON_DRV_H__
|
||||||
|
|
||||||
#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head )
|
#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */
|
||||||
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head , (val))
|
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
|
||||||
|
|
||||||
typedef struct drm_radeon_freelist {
|
typedef struct drm_radeon_freelist {
|
||||||
unsigned int age;
|
unsigned int age;
|
||||||
|
@ -53,6 +53,7 @@ typedef struct drm_radeon_ring_buffer {
|
||||||
int space;
|
int space;
|
||||||
|
|
||||||
int high_mark;
|
int high_mark;
|
||||||
|
drm_local_map_t *ring_rptr;
|
||||||
} drm_radeon_ring_buffer_t;
|
} drm_radeon_ring_buffer_t;
|
||||||
|
|
||||||
typedef struct drm_radeon_depth_clear_t {
|
typedef struct drm_radeon_depth_clear_t {
|
||||||
|
@ -126,13 +127,13 @@ typedef struct drm_radeon_private {
|
||||||
|
|
||||||
drm_radeon_depth_clear_t depth_clear;
|
drm_radeon_depth_clear_t depth_clear;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *cp_ring;
|
drm_local_map_t *cp_ring;
|
||||||
drm_map_t *ring_rptr;
|
drm_local_map_t *ring_rptr;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
|
|
||||||
struct mem_block *agp_heap;
|
struct mem_block *agp_heap;
|
||||||
struct mem_block *fb_heap;
|
struct mem_block *fb_heap;
|
||||||
|
@ -267,8 +268,10 @@ extern void radeon_do_release(drm_device_t *dev);
|
||||||
#define RADEON_SCRATCH_UMSK 0x0770
|
#define RADEON_SCRATCH_UMSK 0x0770
|
||||||
#define RADEON_SCRATCH_ADDR 0x0774
|
#define RADEON_SCRATCH_ADDR 0x0774
|
||||||
|
|
||||||
|
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
|
||||||
|
|
||||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works \
|
#define GET_SCRATCH( x ) (dev_priv->writeback_works \
|
||||||
? DRM_READ32( &dev_priv->scratch[(x)] ) \
|
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
|
||||||
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
||||||
|
|
||||||
|
|
||||||
|
@ -687,15 +690,10 @@ extern void radeon_do_release(drm_device_t *dev);
|
||||||
|
|
||||||
#define RADEON_RING_HIGH_MARK 128
|
#define RADEON_RING_HIGH_MARK 128
|
||||||
|
|
||||||
|
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||||
#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||||
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
|
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||||
|
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
|
||||||
#define RADEON_READ(reg) DRM_READ32( (volatile u32 *) RADEON_ADDR(reg) )
|
|
||||||
#define RADEON_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define RADEON_READ8(reg) DRM_READ8( (volatile u8 *) RADEON_ADDR(reg) )
|
|
||||||
#define RADEON_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define RADEON_WRITE_PLL( addr, val ) \
|
#define RADEON_WRITE_PLL( addr, val ) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -859,7 +857,7 @@ do { \
|
||||||
|
|
||||||
#define COMMIT_RING() do { \
|
#define COMMIT_RING() do { \
|
||||||
/* Flush writes to ring */ \
|
/* Flush writes to ring */ \
|
||||||
DRM_READMEMORYBARRIER(); \
|
DRM_READMEMORYBARRIER(dev_priv->mmio); \
|
||||||
GET_RING_HEAD( &dev_priv->ring ); \
|
GET_RING_HEAD( &dev_priv->ring ); \
|
||||||
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
|
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
|
||||||
/* read from PCI bus to ensure correct posting */ \
|
/* read from PCI bus to ensure correct posting */ \
|
||||||
|
|
|
@ -90,14 +90,14 @@ typedef struct drm_mga_private {
|
||||||
unsigned int texture_offset;
|
unsigned int texture_offset;
|
||||||
unsigned int texture_size;
|
unsigned int texture_size;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *status;
|
drm_local_map_t *status;
|
||||||
drm_map_t *warp;
|
drm_local_map_t *warp;
|
||||||
drm_map_t *primary;
|
drm_local_map_t *primary;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
} drm_mga_private_t;
|
} drm_mga_private_t;
|
||||||
|
|
||||||
/* mga_dma.c */
|
/* mga_dma.c */
|
||||||
|
@ -131,32 +131,30 @@ extern int mga_getparam( DRM_IOCTL_ARGS );
|
||||||
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
|
extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
|
||||||
extern int mga_warp_init( drm_mga_private_t *dev_priv );
|
extern int mga_warp_init( drm_mga_private_t *dev_priv );
|
||||||
|
|
||||||
#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER()
|
#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->primary)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__linux__) && defined(__alpha__)
|
||||||
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
|
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
|
||||||
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
|
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
|
||||||
|
|
||||||
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
|
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
|
||||||
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
||||||
|
|
||||||
#ifdef __alpha__
|
|
||||||
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
|
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
|
||||||
#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
|
#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
|
||||||
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
|
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF( reg ) = val; } while (0)
|
||||||
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
|
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(dev_priv->mmio); MGA_DEREF8( reg ) = val; } while (0)
|
||||||
|
|
||||||
static inline u32 _MGA_READ(u32 *addr)
|
static inline u32 _MGA_READ(u32 *addr)
|
||||||
{
|
{
|
||||||
DRM_READMEMORYBARRIER();
|
DRM_READMEMORYBARRIER(dev_priv->mmio);
|
||||||
return *(volatile u32 *)addr;
|
return *(volatile u32 *)addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define MGA_READ( reg ) MGA_DEREF( reg )
|
#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg))
|
||||||
#define MGA_READ8( reg ) MGA_DEREF8( reg )
|
#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg))
|
||||||
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
|
#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val))
|
||||||
#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
|
#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DWGREG0 0x1c00
|
#define DWGREG0 0x1c00
|
||||||
|
|
|
@ -579,6 +579,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
||||||
(dev_priv->ring.size / sizeof(u32)) - 1;
|
(dev_priv->ring.size / sizeof(u32)) - 1;
|
||||||
|
|
||||||
dev_priv->ring.high_mark = 128;
|
dev_priv->ring.high_mark = 128;
|
||||||
|
dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
|
||||||
|
|
||||||
dev_priv->sarea_priv->last_frame = 0;
|
dev_priv->sarea_priv->last_frame = 0;
|
||||||
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
|
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#ifndef __R128_DRV_H__
|
#ifndef __R128_DRV_H__
|
||||||
#define __R128_DRV_H__
|
#define __R128_DRV_H__
|
||||||
|
|
||||||
#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head )
|
#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */
|
||||||
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head, (val) )
|
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
|
||||||
|
|
||||||
typedef struct drm_r128_freelist {
|
typedef struct drm_r128_freelist {
|
||||||
unsigned int age;
|
unsigned int age;
|
||||||
|
@ -56,6 +56,7 @@ typedef struct drm_r128_ring_buffer {
|
||||||
int space;
|
int space;
|
||||||
|
|
||||||
int high_mark;
|
int high_mark;
|
||||||
|
drm_local_map_t *ring_rptr;
|
||||||
} drm_r128_ring_buffer_t;
|
} drm_r128_ring_buffer_t;
|
||||||
|
|
||||||
typedef struct drm_r128_private {
|
typedef struct drm_r128_private {
|
||||||
|
@ -98,13 +99,13 @@ typedef struct drm_r128_private {
|
||||||
u32 depth_pitch_offset_c;
|
u32 depth_pitch_offset_c;
|
||||||
u32 span_pitch_offset_c;
|
u32 span_pitch_offset_c;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *cce_ring;
|
drm_local_map_t *cce_ring;
|
||||||
drm_map_t *ring_rptr;
|
drm_local_map_t *ring_rptr;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
} drm_r128_private_t;
|
} drm_r128_private_t;
|
||||||
|
|
||||||
typedef struct drm_r128_buf_priv {
|
typedef struct drm_r128_buf_priv {
|
||||||
|
@ -370,15 +371,10 @@ extern int r128_cce_indirect( DRM_IOCTL_ARGS );
|
||||||
|
|
||||||
#define R128_PERFORMANCE_BOXES 0
|
#define R128_PERFORMANCE_BOXES 0
|
||||||
|
|
||||||
|
#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||||
#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||||
#define R128_ADDR(reg) (R128_BASE( reg ) + reg)
|
#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||||
|
#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
|
||||||
#define R128_READ(reg) DRM_READ32( (volatile u32 *) R128_ADDR(reg) )
|
|
||||||
#define R128_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define R128_READ8(reg) DRM_READ8( (volatile u8 *) R128_ADDR(reg) )
|
|
||||||
#define R128_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define R128_WRITE_PLL(addr,val) \
|
#define R128_WRITE_PLL(addr,val) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -453,7 +449,7 @@ do { \
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__)
|
||||||
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
|
#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring )
|
||||||
#else
|
#else
|
||||||
#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER()
|
#define r128_flush_write_combine() DRM_WRITEMEMORYBARRIER(dev_priv->ring_rptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -926,11 +926,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
|
||||||
RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
|
RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
|
||||||
|
|
||||||
/* Writeback doesn't seem to work everywhere, test it first */
|
/* Writeback doesn't seem to work everywhere, test it first */
|
||||||
DRM_WRITE32( &dev_priv->scratch[1], 0 );
|
DRM_WRITE32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0 );
|
||||||
RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
|
RADEON_WRITE( RADEON_SCRATCH_REG1, 0xdeadbeef );
|
||||||
|
|
||||||
for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
|
for ( tmp = 0 ; tmp < dev_priv->usec_timeout ; tmp++ ) {
|
||||||
if ( DRM_READ32( &dev_priv->scratch[1] ) == 0xdeadbeef )
|
if ( DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(1) ) == 0xdeadbeef )
|
||||||
break;
|
break;
|
||||||
DRM_UDELAY( 1 );
|
DRM_UDELAY( 1 );
|
||||||
}
|
}
|
||||||
|
@ -1217,6 +1217,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
||||||
(dev_priv->ring.size / sizeof(u32)) - 1;
|
(dev_priv->ring.size / sizeof(u32)) - 1;
|
||||||
|
|
||||||
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
|
||||||
|
dev_priv->ring.ring_rptr = dev_priv->ring_rptr;
|
||||||
|
|
||||||
#if __REALLY_HAVE_SG
|
#if __REALLY_HAVE_SG
|
||||||
if ( dev_priv->is_pci ) {
|
if ( dev_priv->is_pci ) {
|
||||||
|
@ -1542,7 +1543,7 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
|
||||||
drm_buf_t *buf;
|
drm_buf_t *buf;
|
||||||
int i, t;
|
int i, t;
|
||||||
int start;
|
int start;
|
||||||
u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
|
u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
|
||||||
|
|
||||||
if ( ++dev_priv->last_buf >= dma->buf_count )
|
if ( ++dev_priv->last_buf >= dma->buf_count )
|
||||||
dev_priv->last_buf = 0;
|
dev_priv->last_buf = 0;
|
||||||
|
|
|
@ -396,7 +396,7 @@ typedef struct drm_radeon_init {
|
||||||
enum {
|
enum {
|
||||||
RADEON_INIT_CP = 0x01,
|
RADEON_INIT_CP = 0x01,
|
||||||
RADEON_CLEANUP_CP = 0x02,
|
RADEON_CLEANUP_CP = 0x02,
|
||||||
RADEON_INIT_R200_CP = 0x03,
|
RADEON_INIT_R200_CP = 0x03
|
||||||
} func;
|
} func;
|
||||||
unsigned long sarea_priv_offset;
|
unsigned long sarea_priv_offset;
|
||||||
int is_pci;
|
int is_pci;
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#ifndef __RADEON_DRV_H__
|
#ifndef __RADEON_DRV_H__
|
||||||
#define __RADEON_DRV_H__
|
#define __RADEON_DRV_H__
|
||||||
|
|
||||||
#define GET_RING_HEAD(ring) DRM_READ32( (volatile u32 *) (ring)->head )
|
#define GET_RING_HEAD(ring) DRM_READ32( (ring)->ring_rptr, 0 ) /* (ring)->head */
|
||||||
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (volatile u32 *) (ring)->head , (val))
|
#define SET_RING_HEAD(ring,val) DRM_WRITE32( (ring)->ring_rptr, 0, (val) ) /* (ring)->head */
|
||||||
|
|
||||||
typedef struct drm_radeon_freelist {
|
typedef struct drm_radeon_freelist {
|
||||||
unsigned int age;
|
unsigned int age;
|
||||||
|
@ -53,6 +53,7 @@ typedef struct drm_radeon_ring_buffer {
|
||||||
int space;
|
int space;
|
||||||
|
|
||||||
int high_mark;
|
int high_mark;
|
||||||
|
drm_local_map_t *ring_rptr;
|
||||||
} drm_radeon_ring_buffer_t;
|
} drm_radeon_ring_buffer_t;
|
||||||
|
|
||||||
typedef struct drm_radeon_depth_clear_t {
|
typedef struct drm_radeon_depth_clear_t {
|
||||||
|
@ -126,13 +127,13 @@ typedef struct drm_radeon_private {
|
||||||
|
|
||||||
drm_radeon_depth_clear_t depth_clear;
|
drm_radeon_depth_clear_t depth_clear;
|
||||||
|
|
||||||
drm_map_t *sarea;
|
drm_local_map_t *sarea;
|
||||||
drm_map_t *fb;
|
drm_local_map_t *fb;
|
||||||
drm_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
drm_map_t *cp_ring;
|
drm_local_map_t *cp_ring;
|
||||||
drm_map_t *ring_rptr;
|
drm_local_map_t *ring_rptr;
|
||||||
drm_map_t *buffers;
|
drm_local_map_t *buffers;
|
||||||
drm_map_t *agp_textures;
|
drm_local_map_t *agp_textures;
|
||||||
|
|
||||||
struct mem_block *agp_heap;
|
struct mem_block *agp_heap;
|
||||||
struct mem_block *fb_heap;
|
struct mem_block *fb_heap;
|
||||||
|
@ -267,8 +268,10 @@ extern void radeon_do_release(drm_device_t *dev);
|
||||||
#define RADEON_SCRATCH_UMSK 0x0770
|
#define RADEON_SCRATCH_UMSK 0x0770
|
||||||
#define RADEON_SCRATCH_ADDR 0x0774
|
#define RADEON_SCRATCH_ADDR 0x0774
|
||||||
|
|
||||||
|
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
|
||||||
|
|
||||||
#define GET_SCRATCH( x ) (dev_priv->writeback_works \
|
#define GET_SCRATCH( x ) (dev_priv->writeback_works \
|
||||||
? DRM_READ32( &dev_priv->scratch[(x)] ) \
|
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
|
||||||
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
||||||
|
|
||||||
|
|
||||||
|
@ -687,15 +690,10 @@ extern void radeon_do_release(drm_device_t *dev);
|
||||||
|
|
||||||
#define RADEON_RING_HIGH_MARK 128
|
#define RADEON_RING_HIGH_MARK 128
|
||||||
|
|
||||||
|
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||||
#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
|
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||||
#define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg)
|
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||||
|
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
|
||||||
#define RADEON_READ(reg) DRM_READ32( (volatile u32 *) RADEON_ADDR(reg) )
|
|
||||||
#define RADEON_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define RADEON_READ8(reg) DRM_READ8( (volatile u8 *) RADEON_ADDR(reg) )
|
|
||||||
#define RADEON_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) )
|
|
||||||
|
|
||||||
#define RADEON_WRITE_PLL( addr, val ) \
|
#define RADEON_WRITE_PLL( addr, val ) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -859,7 +857,7 @@ do { \
|
||||||
|
|
||||||
#define COMMIT_RING() do { \
|
#define COMMIT_RING() do { \
|
||||||
/* Flush writes to ring */ \
|
/* Flush writes to ring */ \
|
||||||
DRM_READMEMORYBARRIER(); \
|
DRM_READMEMORYBARRIER(dev_priv->mmio); \
|
||||||
GET_RING_HEAD( &dev_priv->ring ); \
|
GET_RING_HEAD( &dev_priv->ring ); \
|
||||||
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
|
RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
|
||||||
/* read from PCI bus to ensure correct posting */ \
|
/* read from PCI bus to ensure correct posting */ \
|
||||||
|
|
Loading…
Reference in New Issue