Merge master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
Manual fixups for some clashes due to re-indenting.
This commit is contained in:
commit
d8762748ca
93 changed files with 19247 additions and 19118 deletions
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file ati_pcigart.h
|
||||
* \file ati_pcigart.c
|
||||
* ATI PCI GART support
|
||||
*
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
|
@ -52,85 +52,91 @@
|
|||
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
|
||||
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
|
||||
|
||||
static unsigned long drm_ati_alloc_pcigart_table( void )
|
||||
static unsigned long drm_ati_alloc_pcigart_table(void)
|
||||
{
|
||||
unsigned long address;
|
||||
struct page *page;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
|
||||
if ( address == 0UL ) {
|
||||
address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
|
||||
if (address == 0UL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
page = virt_to_page( address );
|
||||
page = virt_to_page(address);
|
||||
|
||||
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
|
||||
get_page(page);
|
||||
SetPageReserved( page );
|
||||
SetPageReserved(page);
|
||||
}
|
||||
|
||||
DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
|
||||
DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
|
||||
return address;
|
||||
}
|
||||
|
||||
static void drm_ati_free_pcigart_table( unsigned long address )
|
||||
static void drm_ati_free_pcigart_table(unsigned long address)
|
||||
{
|
||||
struct page *page;
|
||||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
page = virt_to_page( address );
|
||||
page = virt_to_page(address);
|
||||
|
||||
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
|
||||
__put_page(page);
|
||||
ClearPageReserved( page );
|
||||
ClearPageReserved(page);
|
||||
}
|
||||
|
||||
free_pages( address, ATI_PCIGART_TABLE_ORDER );
|
||||
free_pages(address, ATI_PCIGART_TABLE_ORDER);
|
||||
}
|
||||
|
||||
int drm_ati_pcigart_cleanup( drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr)
|
||||
int drm_ati_pcigart_cleanup(drm_device_t * dev,
|
||||
drm_ati_pcigart_info * gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
|
||||
/* we need to support large memory configurations */
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( bus_addr ) {
|
||||
pci_unmap_single(dev->pdev, bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (gart_info->bus_addr) {
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
pci_unmap_single(dev->pdev, gart_info->bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
if ( !entry->busaddr[i] ) break;
|
||||
for (i = 0; i < pages; i++) {
|
||||
if (!entry->busaddr[i])
|
||||
break;
|
||||
pci_unmap_single(dev->pdev, entry->busaddr[i],
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
|
||||
gart_info->bus_addr = 0;
|
||||
}
|
||||
|
||||
if ( addr ) {
|
||||
drm_ati_free_pcigart_table( addr );
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
|
||||
&& gart_info->addr) {
|
||||
drm_ati_free_pcigart_table(gart_info->addr);
|
||||
gart_info->addr = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
|
||||
|
||||
int drm_ati_pcigart_init( drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr)
|
||||
int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long address = 0;
|
||||
|
@ -138,48 +144,57 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
|||
u32 *pci_gart, page_base, bus_address = 0;
|
||||
int i, j, ret = 0;
|
||||
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
if (!entry) {
|
||||
DRM_ERROR("no scatter/gather memory!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
address = drm_ati_alloc_pcigart_table();
|
||||
if ( !address ) {
|
||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||
goto done;
|
||||
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
|
||||
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
|
||||
|
||||
address = drm_ati_alloc_pcigart_table();
|
||||
if (!address) {
|
||||
DRM_ERROR("cannot allocate PCI GART page!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!dev->pdev) {
|
||||
DRM_ERROR("PCI device unknown!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
bus_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(address);
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
address = gart_info->addr;
|
||||
bus_address = gart_info->bus_addr;
|
||||
DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
|
||||
bus_address, address);
|
||||
}
|
||||
|
||||
if ( !dev->pdev ) {
|
||||
DRM_ERROR( "PCI device unknown!\n" );
|
||||
goto done;
|
||||
}
|
||||
pci_gart = (u32 *) address;
|
||||
|
||||
bus_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( address );
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
pci_gart = (u32 *)address;
|
||||
memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
memset( pci_gart, 0, 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 */
|
||||
entry->busaddr[i] = pci_map_single(dev->pdev,
|
||||
page_address( entry->pagelist[i] ),
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
page_address(entry->
|
||||
pagelist[i]),
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
if (entry->busaddr[i] == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
drm_ati_pcigart_cleanup( dev, address, bus_address );
|
||||
DRM_ERROR("unable to map PCIGART pages!\n");
|
||||
drm_ati_pcigart_cleanup(dev, gart_info);
|
||||
address = 0;
|
||||
bus_address = 0;
|
||||
goto done;
|
||||
|
@ -187,7 +202,11 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
|||
page_base = (u32) entry->busaddr[i];
|
||||
|
||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||
*pci_gart++ = cpu_to_le32( page_base );
|
||||
if (gart_info->is_pcie)
|
||||
*pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc;
|
||||
else
|
||||
*pci_gart = cpu_to_le32(page_base);
|
||||
*pci_gart++;
|
||||
page_base += ATI_PCIGART_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +219,10 @@ int drm_ati_pcigart_init( drm_device_t *dev,
|
|||
mb();
|
||||
#endif
|
||||
|
||||
done:
|
||||
*addr = address;
|
||||
*bus_addr = bus_address;
|
||||
done:
|
||||
gart_info->addr = address;
|
||||
gart_info->bus_addr = bus_address;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_ati_pcigart_init);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm.h
|
||||
* \file drm.h
|
||||
* Header for the Direct Rendering Manager
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
*
|
||||
* \par Acknowledgments:
|
||||
|
@ -33,7 +33,6 @@
|
|||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DRM_H_
|
||||
#define _DRM_H_
|
||||
|
||||
|
@ -56,7 +55,7 @@
|
|||
#define ioctl(a,b,c) xf86ioctl(a,b,c)
|
||||
#else
|
||||
#include <sys/ioccom.h>
|
||||
#endif /* __FreeBSD__ && xf86ioctl */
|
||||
#endif /* __FreeBSD__ && xf86ioctl */
|
||||
#define DRM_IOCTL_NR(n) ((n) & 0xff)
|
||||
#define DRM_IOC_VOID IOC_VOID
|
||||
#define DRM_IOC_READ IOC_OUT
|
||||
|
@ -97,16 +96,14 @@
|
|||
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
|
||||
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
|
||||
|
||||
|
||||
typedef unsigned int drm_handle_t;
|
||||
typedef unsigned int drm_context_t;
|
||||
typedef unsigned int drm_drawable_t;
|
||||
typedef unsigned int drm_magic_t;
|
||||
|
||||
typedef unsigned int drm_handle_t;
|
||||
typedef unsigned int drm_context_t;
|
||||
typedef unsigned int drm_drawable_t;
|
||||
typedef unsigned int drm_magic_t;
|
||||
|
||||
/**
|
||||
* Cliprect.
|
||||
*
|
||||
*
|
||||
* \warning: If you change this structure, make sure you change
|
||||
* XF86DRIClipRectRec in the server as well
|
||||
*
|
||||
|
@ -114,22 +111,21 @@ typedef unsigned int drm_magic_t;
|
|||
* backwards-compatibility reasons.
|
||||
*/
|
||||
typedef struct drm_clip_rect {
|
||||
unsigned short x1;
|
||||
unsigned short y1;
|
||||
unsigned short x2;
|
||||
unsigned short y2;
|
||||
unsigned short x1;
|
||||
unsigned short y1;
|
||||
unsigned short x2;
|
||||
unsigned short y2;
|
||||
} drm_clip_rect_t;
|
||||
|
||||
|
||||
/**
|
||||
* Texture region,
|
||||
*/
|
||||
typedef struct drm_tex_region {
|
||||
unsigned char next;
|
||||
unsigned char prev;
|
||||
unsigned char in_use;
|
||||
unsigned char padding;
|
||||
unsigned int age;
|
||||
unsigned char next;
|
||||
unsigned char prev;
|
||||
unsigned char in_use;
|
||||
unsigned char padding;
|
||||
unsigned int age;
|
||||
} drm_tex_region_t;
|
||||
|
||||
/**
|
||||
|
@ -141,28 +137,26 @@ typedef struct drm_tex_region {
|
|||
*/
|
||||
typedef struct drm_hw_lock {
|
||||
__volatile__ unsigned int lock; /**< lock variable */
|
||||
char padding[60]; /**< Pad to cache line */
|
||||
char padding[60]; /**< Pad to cache line */
|
||||
} drm_hw_lock_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_VERSION ioctl argument type.
|
||||
*
|
||||
*
|
||||
* \sa drmGetVersion().
|
||||
*/
|
||||
typedef struct drm_version {
|
||||
int version_major; /**< Major version */
|
||||
int version_minor; /**< Minor version */
|
||||
int version_patchlevel;/**< Patch level */
|
||||
int version_major; /**< Major version */
|
||||
int version_minor; /**< Minor version */
|
||||
int version_patchlevel; /**< Patch level */
|
||||
size_t name_len; /**< Length of name buffer */
|
||||
char __user *name; /**< Name of driver */
|
||||
char __user *name; /**< Name of driver */
|
||||
size_t date_len; /**< Length of date buffer */
|
||||
char __user *date; /**< User-space buffer to hold date */
|
||||
char __user *date; /**< User-space buffer to hold date */
|
||||
size_t desc_len; /**< Length of desc buffer */
|
||||
char __user *desc; /**< User-space buffer to hold desc */
|
||||
char __user *desc; /**< User-space buffer to hold desc */
|
||||
} drm_version_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
|
||||
*
|
||||
|
@ -170,21 +164,18 @@ typedef struct drm_version {
|
|||
*/
|
||||
typedef struct drm_unique {
|
||||
size_t unique_len; /**< Length of unique */
|
||||
char __user *unique; /**< Unique name for driver instantiation */
|
||||
char __user *unique; /**< Unique name for driver instantiation */
|
||||
} drm_unique_t;
|
||||
|
||||
|
||||
typedef struct drm_list {
|
||||
int count; /**< Length of user-space structures */
|
||||
drm_version_t __user *version;
|
||||
int count; /**< Length of user-space structures */
|
||||
drm_version_t __user *version;
|
||||
} drm_list_t;
|
||||
|
||||
|
||||
typedef struct drm_block {
|
||||
int unused;
|
||||
int unused;
|
||||
} drm_block_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_CONTROL ioctl argument type.
|
||||
*
|
||||
|
@ -196,44 +187,40 @@ typedef struct drm_control {
|
|||
DRM_RM_COMMAND,
|
||||
DRM_INST_HANDLER,
|
||||
DRM_UNINST_HANDLER
|
||||
} func;
|
||||
int irq;
|
||||
} func;
|
||||
int irq;
|
||||
} drm_control_t;
|
||||
|
||||
|
||||
/**
|
||||
* Type of memory to map.
|
||||
*/
|
||||
typedef enum drm_map_type {
|
||||
_DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /**< no caching, no core dump */
|
||||
_DRM_SHM = 2, /**< shared, cached */
|
||||
_DRM_AGP = 3, /**< AGP/GART */
|
||||
_DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
|
||||
_DRM_REGISTERS = 1, /**< no caching, no core dump */
|
||||
_DRM_SHM = 2, /**< shared, cached */
|
||||
_DRM_AGP = 3, /**< AGP/GART */
|
||||
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
|
||||
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
|
||||
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
|
||||
} drm_map_type_t;
|
||||
|
||||
|
||||
/**
|
||||
* Memory mapping flags.
|
||||
*/
|
||||
typedef enum drm_map_flags {
|
||||
_DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
|
||||
_DRM_READ_ONLY = 0x02,
|
||||
_DRM_LOCKED = 0x04, /**< shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /**< kernel requires access */
|
||||
_DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
|
||||
_DRM_READ_ONLY = 0x02,
|
||||
_DRM_LOCKED = 0x04, /**< shared, cached, locked */
|
||||
_DRM_KERNEL = 0x08, /**< kernel requires access */
|
||||
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40 /**< Removable mapping */
|
||||
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
|
||||
_DRM_REMOVABLE = 0x40 /**< Removable mapping */
|
||||
} drm_map_flags_t;
|
||||
|
||||
|
||||
typedef struct drm_ctx_priv_map {
|
||||
unsigned int ctx_id; /**< Context requesting private mapping */
|
||||
void *handle; /**< Handle of map */
|
||||
unsigned int ctx_id; /**< Context requesting private mapping */
|
||||
void *handle; /**< Handle of map */
|
||||
} drm_ctx_priv_map_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
|
||||
* argument type.
|
||||
|
@ -241,30 +228,28 @@ typedef struct drm_ctx_priv_map {
|
|||
* \sa drmAddMap().
|
||||
*/
|
||||
typedef struct drm_map {
|
||||
unsigned long offset; /**< Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /**< Requested physical size (bytes) */
|
||||
drm_map_type_t type; /**< Type of memory to map */
|
||||
unsigned long offset; /**< Requested physical address (0 for SAREA)*/
|
||||
unsigned long size; /**< Requested physical size (bytes) */
|
||||
drm_map_type_t type; /**< Type of memory to map */
|
||||
drm_map_flags_t flags; /**< Flags */
|
||||
void *handle; /**< User-space: "Handle" to pass to mmap() */
|
||||
void *handle; /**< User-space: "Handle" to pass to mmap() */
|
||||
/**< Kernel-space: kernel-virtual address */
|
||||
int mtrr; /**< MTRR slot used */
|
||||
/* Private data */
|
||||
int mtrr; /**< MTRR slot used */
|
||||
/* Private data */
|
||||
} drm_map_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_CLIENT ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_client {
|
||||
int idx; /**< Which client desired? */
|
||||
int auth; /**< Is client authenticated? */
|
||||
unsigned long pid; /**< Process ID */
|
||||
unsigned long uid; /**< User ID */
|
||||
unsigned long magic; /**< Magic */
|
||||
unsigned long iocs; /**< Ioctl count */
|
||||
int idx; /**< Which client desired? */
|
||||
int auth; /**< Is client authenticated? */
|
||||
unsigned long pid; /**< Process ID */
|
||||
unsigned long uid; /**< User ID */
|
||||
unsigned long magic; /**< Magic */
|
||||
unsigned long iocs; /**< Ioctl count */
|
||||
} drm_client_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
_DRM_STAT_LOCK,
|
||||
_DRM_STAT_OPENS,
|
||||
|
@ -282,63 +267,58 @@ typedef enum {
|
|||
_DRM_STAT_DMA, /**< DMA */
|
||||
_DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
|
||||
_DRM_STAT_MISSED /**< Missed DMA opportunity */
|
||||
|
||||
/* Add to the *END* of the list */
|
||||
/* Add to the *END* of the list */
|
||||
} drm_stat_type_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_STATS ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_stats {
|
||||
unsigned long count;
|
||||
struct {
|
||||
unsigned long value;
|
||||
unsigned long value;
|
||||
drm_stat_type_t type;
|
||||
} data[15];
|
||||
} drm_stats_t;
|
||||
|
||||
|
||||
/**
|
||||
* Hardware locking flags.
|
||||
*/
|
||||
typedef enum drm_lock_flags {
|
||||
_DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
|
||||
_DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
|
||||
_DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
|
||||
_DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
|
||||
/* These *HALT* flags aren't supported yet
|
||||
-- they will be used to support the
|
||||
full-screen DGA-like mode. */
|
||||
_DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
|
||||
_DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
|
||||
_DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
|
||||
_DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
|
||||
/* These *HALT* flags aren't supported yet
|
||||
-- they will be used to support the
|
||||
full-screen DGA-like mode. */
|
||||
_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
|
||||
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
|
||||
} drm_lock_flags_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
|
||||
*
|
||||
*
|
||||
* \sa drmGetLock() and drmUnlock().
|
||||
*/
|
||||
typedef struct drm_lock {
|
||||
int context;
|
||||
int context;
|
||||
drm_lock_flags_t flags;
|
||||
} drm_lock_t;
|
||||
|
||||
|
||||
/**
|
||||
* DMA flags
|
||||
*
|
||||
* \warning
|
||||
* \warning
|
||||
* These values \e must match xf86drm.h.
|
||||
*
|
||||
* \sa drm_dma.
|
||||
*/
|
||||
typedef enum drm_dma_flags {
|
||||
/* Flags for DMA buffer dispatch */
|
||||
_DRM_DMA_BLOCK = 0x01, /**<
|
||||
typedef enum drm_dma_flags {
|
||||
/* Flags for DMA buffer dispatch */
|
||||
_DRM_DMA_BLOCK = 0x01, /**<
|
||||
* Block until buffer dispatched.
|
||||
*
|
||||
*
|
||||
* \note The buffer may not yet have
|
||||
* been processed by the hardware --
|
||||
* getting a hardware lock with the
|
||||
|
@ -347,79 +327,73 @@ typedef enum drm_dma_flags {
|
|||
* processed.
|
||||
*/
|
||||
_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
|
||||
_DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
|
||||
_DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
|
||||
|
||||
/* Flags for DMA buffer request */
|
||||
_DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
|
||||
_DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
|
||||
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
|
||||
/* Flags for DMA buffer request */
|
||||
_DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
|
||||
_DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
|
||||
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
|
||||
} drm_dma_flags_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
|
||||
*
|
||||
* \sa drmAddBufs().
|
||||
*/
|
||||
typedef struct drm_buf_desc {
|
||||
int count; /**< Number of buffers of this size */
|
||||
int size; /**< Size in bytes */
|
||||
int low_mark; /**< Low water mark */
|
||||
int high_mark; /**< High water mark */
|
||||
int count; /**< Number of buffers of this size */
|
||||
int size; /**< Size in bytes */
|
||||
int low_mark; /**< Low water mark */
|
||||
int high_mark; /**< High water mark */
|
||||
enum {
|
||||
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
|
||||
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
|
||||
_DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
|
||||
} flags;
|
||||
unsigned long agp_start; /**<
|
||||
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
|
||||
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
|
||||
_DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
|
||||
_DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */
|
||||
} flags;
|
||||
unsigned long agp_start; /**<
|
||||
* Start address of where the AGP buffers are
|
||||
* in the AGP aperture
|
||||
*/
|
||||
} drm_buf_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_INFO_BUFS ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_buf_info {
|
||||
int count; /**< Entries in list */
|
||||
int count; /**< Entries in list */
|
||||
drm_buf_desc_t __user *list;
|
||||
} drm_buf_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_FREE_BUFS ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_buf_free {
|
||||
int count;
|
||||
int __user *list;
|
||||
int count;
|
||||
int __user *list;
|
||||
} drm_buf_free_t;
|
||||
|
||||
|
||||
/**
|
||||
* Buffer information
|
||||
*
|
||||
* \sa drm_buf_map.
|
||||
*/
|
||||
typedef struct drm_buf_pub {
|
||||
int idx; /**< Index into the master buffer list */
|
||||
int total; /**< Buffer size */
|
||||
int used; /**< Amount of buffer in use (for DMA) */
|
||||
void __user *address; /**< Address of buffer */
|
||||
int idx; /**< Index into the master buffer list */
|
||||
int total; /**< Buffer size */
|
||||
int used; /**< Amount of buffer in use (for DMA) */
|
||||
void __user *address; /**< Address of buffer */
|
||||
} drm_buf_pub_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_MAP_BUFS ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_buf_map {
|
||||
int count; /**< Length of the buffer list */
|
||||
void __user *virtual; /**< Mmap'd area in user-virtual */
|
||||
int count; /**< Length of the buffer list */
|
||||
void __user *virtual; /**< Mmap'd area in user-virtual */
|
||||
drm_buf_pub_t __user *list; /**< Buffer information */
|
||||
} drm_buf_map_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_DMA ioctl argument type.
|
||||
*
|
||||
|
@ -428,61 +402,55 @@ typedef struct drm_buf_map {
|
|||
* \sa drmDMA().
|
||||
*/
|
||||
typedef struct drm_dma {
|
||||
int context; /**< Context handle */
|
||||
int send_count; /**< Number of buffers to send */
|
||||
int __user *send_indices; /**< List of handles to buffers */
|
||||
int __user *send_sizes; /**< Lengths of data to send */
|
||||
int context; /**< Context handle */
|
||||
int send_count; /**< Number of buffers to send */
|
||||
int __user *send_indices; /**< List of handles to buffers */
|
||||
int __user *send_sizes; /**< Lengths of data to send */
|
||||
drm_dma_flags_t flags; /**< Flags */
|
||||
int request_count; /**< Number of buffers requested */
|
||||
int request_size; /**< Desired size for buffers */
|
||||
int __user *request_indices; /**< Buffer information */
|
||||
int __user *request_sizes;
|
||||
int granted_count; /**< Number of buffers granted */
|
||||
int request_count; /**< Number of buffers requested */
|
||||
int request_size; /**< Desired size for buffers */
|
||||
int __user *request_indices; /**< Buffer information */
|
||||
int __user *request_sizes;
|
||||
int granted_count; /**< Number of buffers granted */
|
||||
} drm_dma_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
_DRM_CONTEXT_PRESERVED = 0x01,
|
||||
_DRM_CONTEXT_2DONLY = 0x02
|
||||
_DRM_CONTEXT_2DONLY = 0x02
|
||||
} drm_ctx_flags_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_CTX ioctl argument type.
|
||||
*
|
||||
* \sa drmCreateContext() and drmDestroyContext().
|
||||
*/
|
||||
typedef struct drm_ctx {
|
||||
drm_context_t handle;
|
||||
drm_context_t handle;
|
||||
drm_ctx_flags_t flags;
|
||||
} drm_ctx_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_RES_CTX ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_ctx_res {
|
||||
int count;
|
||||
drm_ctx_t __user *contexts;
|
||||
int count;
|
||||
drm_ctx_t __user *contexts;
|
||||
} drm_ctx_res_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_draw {
|
||||
drm_drawable_t handle;
|
||||
drm_drawable_t handle;
|
||||
} drm_draw_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
|
||||
*/
|
||||
typedef struct drm_auth {
|
||||
drm_magic_t magic;
|
||||
drm_magic_t magic;
|
||||
} drm_auth_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
|
||||
*
|
||||
|
@ -495,24 +463,20 @@ typedef struct drm_irq_busid {
|
|||
int funcnum; /**< function number */
|
||||
} drm_irq_busid_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
||||
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
||||
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
|
||||
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
|
||||
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
|
||||
} drm_vblank_seq_type_t;
|
||||
|
||||
|
||||
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
|
||||
|
||||
|
||||
struct drm_wait_vblank_request {
|
||||
drm_vblank_seq_type_t type;
|
||||
unsigned int sequence;
|
||||
unsigned long signal;
|
||||
};
|
||||
|
||||
|
||||
struct drm_wait_vblank_reply {
|
||||
drm_vblank_seq_type_t type;
|
||||
unsigned int sequence;
|
||||
|
@ -520,7 +484,6 @@ struct drm_wait_vblank_reply {
|
|||
long tval_usec;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
|
||||
*
|
||||
|
@ -531,7 +494,6 @@ typedef union drm_wait_vblank {
|
|||
struct drm_wait_vblank_reply reply;
|
||||
} drm_wait_vblank_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
|
||||
*
|
||||
|
@ -541,7 +503,6 @@ typedef struct drm_agp_mode {
|
|||
unsigned long mode; /**< AGP mode */
|
||||
} drm_agp_mode_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
|
||||
*
|
||||
|
@ -550,22 +511,20 @@ typedef struct drm_agp_mode {
|
|||
typedef struct drm_agp_buffer {
|
||||
unsigned long size; /**< In bytes -- will round to page boundary */
|
||||
unsigned long handle; /**< Used for binding / unbinding */
|
||||
unsigned long type; /**< Type of memory to allocate */
|
||||
unsigned long physical; /**< Physical used by i810 */
|
||||
unsigned long type; /**< Type of memory to allocate */
|
||||
unsigned long physical; /**< Physical used by i810 */
|
||||
} drm_agp_buffer_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
|
||||
*
|
||||
* \sa drmAgpBind() and drmAgpUnbind().
|
||||
*/
|
||||
typedef struct drm_agp_binding {
|
||||
unsigned long handle; /**< From drm_agp_buffer */
|
||||
unsigned long handle; /**< From drm_agp_buffer */
|
||||
unsigned long offset; /**< In bytes -- will round to page boundary */
|
||||
} drm_agp_binding_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_AGP_INFO ioctl argument type.
|
||||
*
|
||||
|
@ -574,20 +533,19 @@ typedef struct drm_agp_binding {
|
|||
* drmAgpVendorId() and drmAgpDeviceId().
|
||||
*/
|
||||
typedef struct drm_agp_info {
|
||||
int agp_version_major;
|
||||
int agp_version_minor;
|
||||
unsigned long mode;
|
||||
unsigned long aperture_base; /* physical address */
|
||||
unsigned long aperture_size; /* bytes */
|
||||
unsigned long memory_allowed; /* bytes */
|
||||
unsigned long memory_used;
|
||||
int agp_version_major;
|
||||
int agp_version_minor;
|
||||
unsigned long mode;
|
||||
unsigned long aperture_base; /* physical address */
|
||||
unsigned long aperture_size; /* bytes */
|
||||
unsigned long memory_allowed; /* bytes */
|
||||
unsigned long memory_used;
|
||||
|
||||
/* PCI information */
|
||||
/* PCI information */
|
||||
unsigned short id_vendor;
|
||||
unsigned short id_device;
|
||||
} drm_agp_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* DRM_IOCTL_SG_ALLOC ioctl argument type.
|
||||
*/
|
||||
|
@ -606,7 +564,6 @@ typedef struct drm_set_version {
|
|||
int drm_dd_minor;
|
||||
} drm_set_version_t;
|
||||
|
||||
|
||||
#define DRM_IOCTL_BASE 'd'
|
||||
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
|
||||
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm_agpsupport.h
|
||||
* \file drm_agpsupport.h
|
||||
* DRM support for AGP/GART backend
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
@ -48,30 +48,31 @@
|
|||
* Verifies the AGP device has been initialized and acquired and fills in the
|
||||
* drm_agp_info structure with the information in drm_agp_head::agp_info.
|
||||
*/
|
||||
int drm_agp_info(drm_device_t *dev, drm_agp_info_t *info)
|
||||
int drm_agp_info(drm_device_t * dev, drm_agp_info_t * info)
|
||||
{
|
||||
DRM_AGP_KERN *kern;
|
||||
DRM_AGP_KERN *kern;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
||||
kern = &dev->agp->agp_info;
|
||||
kern = &dev->agp->agp_info;
|
||||
info->agp_version_major = kern->version.major;
|
||||
info->agp_version_minor = kern->version.minor;
|
||||
info->mode = kern->mode;
|
||||
info->aperture_base = kern->aper_base;
|
||||
info->aperture_size = kern->aper_size * 1024 * 1024;
|
||||
info->memory_allowed = kern->max_memory << PAGE_SHIFT;
|
||||
info->memory_used = kern->current_memory << PAGE_SHIFT;
|
||||
info->id_vendor = kern->device->vendor;
|
||||
info->id_device = kern->device->device;
|
||||
info->mode = kern->mode;
|
||||
info->aperture_base = kern->aper_base;
|
||||
info->aperture_size = kern->aper_size * 1024 * 1024;
|
||||
info->memory_allowed = kern->max_memory << PAGE_SHIFT;
|
||||
info->memory_used = kern->current_memory << PAGE_SHIFT;
|
||||
info->id_vendor = kern->device->vendor;
|
||||
info->id_device = kern->device->device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_info);
|
||||
|
||||
int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -81,7 +82,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
|||
err = drm_agp_info(dev, &info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
if (copy_to_user((drm_agp_info_t __user *) arg, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -91,12 +92,12 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
|
|||
* Acquire the AGP device.
|
||||
*
|
||||
* \param dev DRM device that is to acquire AGP
|
||||
* \return zero on success or a negative number on failure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Verifies the AGP device hasn't been acquired before and calls
|
||||
* \c agp_backend_acquire.
|
||||
*/
|
||||
int drm_agp_acquire(drm_device_t *dev)
|
||||
int drm_agp_acquire(drm_device_t * dev)
|
||||
{
|
||||
if (!dev->agp)
|
||||
return -ENODEV;
|
||||
|
@ -107,6 +108,7 @@ int drm_agp_acquire(drm_device_t *dev)
|
|||
dev->agp->acquired = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_acquire);
|
||||
|
||||
/**
|
||||
|
@ -125,8 +127,8 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
|
||||
return drm_agp_acquire( (drm_device_t *) priv->head->dev );
|
||||
|
||||
return drm_agp_acquire((drm_device_t *) priv->head->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,7 +139,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Verifies the AGP device has been acquired and calls \c agp_backend_release.
|
||||
*/
|
||||
int drm_agp_release(drm_device_t *dev)
|
||||
int drm_agp_release(drm_device_t * dev)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
@ -145,6 +147,7 @@ int drm_agp_release(drm_device_t *dev)
|
|||
dev->agp->acquired = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_release);
|
||||
|
||||
int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
||||
|
@ -152,13 +155,13 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
|||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
||||
|
||||
return drm_agp_release(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the AGP bus.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device that has previously acquired AGP.
|
||||
* \param mode Requested AGP mode.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -166,27 +169,27 @@ int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
|
|||
* Verifies the AGP device has been acquired but not enabled, and calls
|
||||
* \c agp_enable.
|
||||
*/
|
||||
int drm_agp_enable(drm_device_t *dev, drm_agp_mode_t mode)
|
||||
int drm_agp_enable(drm_device_t * dev, drm_agp_mode_t mode)
|
||||
{
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
|
||||
dev->agp->mode = mode.mode;
|
||||
dev->agp->mode = mode.mode;
|
||||
agp_enable(dev->agp->bridge, mode.mode);
|
||||
dev->agp->base = dev->agp->agp_info.aper_base;
|
||||
dev->agp->base = dev->agp->agp_info.aper_base;
|
||||
dev->agp->enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_enable);
|
||||
|
||||
int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_mode_t mode;
|
||||
|
||||
|
||||
if (copy_from_user(&mode, (drm_agp_mode_t __user *) arg, sizeof(mode)))
|
||||
return -EFAULT;
|
||||
|
||||
|
@ -201,20 +204,20 @@ int drm_agp_enable_ioctl(struct inode *inode, struct file *filp,
|
|||
* \param cmd command.
|
||||
* \param arg pointer to a drm_agp_buffer structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Verifies the AGP device is present and has been acquired, allocates the
|
||||
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
|
||||
*/
|
||||
int drm_agp_alloc(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
DRM_AGP_MEM *memory;
|
||||
unsigned long pages;
|
||||
u32 type;
|
||||
drm_agp_mem_t *entry;
|
||||
DRM_AGP_MEM *memory;
|
||||
unsigned long pages;
|
||||
u32 type;
|
||||
drm_agp_buffer_t __user *argp = (void __user *)arg;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
|
@ -224,7 +227,7 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
|||
if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
|
||||
return -ENOMEM;
|
||||
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
|
||||
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
type = (u32) request.type;
|
||||
|
@ -234,21 +237,21 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
entry->handle = (unsigned long)memory->key + 1;
|
||||
entry->memory = memory;
|
||||
entry->bound = 0;
|
||||
entry->pages = pages;
|
||||
entry->prev = NULL;
|
||||
entry->next = dev->agp->memory;
|
||||
entry->handle = (unsigned long)memory->key + 1;
|
||||
entry->memory = memory;
|
||||
entry->bound = 0;
|
||||
entry->pages = pages;
|
||||
entry->prev = NULL;
|
||||
entry->next = dev->agp->memory;
|
||||
if (dev->agp->memory)
|
||||
dev->agp->memory->prev = entry;
|
||||
dev->agp->memory = entry;
|
||||
|
||||
request.handle = entry->handle;
|
||||
request.handle = entry->handle;
|
||||
request.physical = memory->physical;
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request))) {
|
||||
dev->agp->memory = entry->next;
|
||||
dev->agp->memory = entry->next;
|
||||
dev->agp->memory->prev = NULL;
|
||||
drm_free_agp(memory, pages);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||
|
@ -263,11 +266,11 @@ int drm_agp_alloc(struct inode *inode, struct file *filp,
|
|||
* \param dev DRM device structure.
|
||||
* \param handle AGP memory handle.
|
||||
* \return pointer to the drm_agp_mem structure associated with \p handle.
|
||||
*
|
||||
*
|
||||
* Walks through drm_agp_head::memory until finding a matching handle.
|
||||
*/
|
||||
static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
|
||||
unsigned long handle)
|
||||
static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t * dev,
|
||||
unsigned long handle)
|
||||
{
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
|
@ -291,17 +294,18 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
|
|||
* entry and passes it to the unbind_agp() function.
|
||||
*/
|
||||
int drm_agp_unbind(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
drm_agp_mem_t *entry;
|
||||
int ret;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
|
@ -309,7 +313,7 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
ret = drm_unbind_agp(entry->memory);
|
||||
if (ret == 0)
|
||||
entry->bound = 0;
|
||||
entry->bound = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -327,18 +331,19 @@ int drm_agp_unbind(struct inode *inode, struct file *filp,
|
|||
* it to bind_agp() function.
|
||||
*/
|
||||
int drm_agp_bind(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_binding_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
int retcode;
|
||||
int page;
|
||||
drm_agp_mem_t *entry;
|
||||
int retcode;
|
||||
int page;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_binding_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
|
@ -368,16 +373,17 @@ int drm_agp_bind(struct inode *inode, struct file *filp,
|
|||
* and unlinks from the doubly linked list it's inserted in.
|
||||
*/
|
||||
int drm_agp_free(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_agp_buffer_t request;
|
||||
drm_agp_mem_t *entry;
|
||||
drm_agp_mem_t *entry;
|
||||
|
||||
if (!dev->agp || !dev->agp->acquired)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
|
||||
if (copy_from_user
|
||||
(&request, (drm_agp_buffer_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
|
||||
return -EINVAL;
|
||||
|
@ -403,9 +409,9 @@ int drm_agp_free(struct inode *inode, struct file *filp,
|
|||
* \return pointer to a drm_agp_head structure.
|
||||
*
|
||||
*/
|
||||
drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
||||
drm_agp_head_t *drm_agp_init(drm_device_t * dev)
|
||||
{
|
||||
drm_agp_head_t *head = NULL;
|
||||
drm_agp_head_t *head = NULL;
|
||||
|
||||
if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
|
||||
return NULL;
|
||||
|
@ -433,13 +439,14 @@ drm_agp_head_t *drm_agp_init(drm_device_t *dev)
|
|||
}
|
||||
|
||||
/** Calls agp_allocate_memory() */
|
||||
DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
|
||||
DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge,
|
||||
size_t pages, u32 type)
|
||||
{
|
||||
return agp_allocate_memory(bridge, pages, type);
|
||||
}
|
||||
|
||||
/** Calls agp_free_memory() */
|
||||
int drm_agp_free_memory(DRM_AGP_MEM *handle)
|
||||
int drm_agp_free_memory(DRM_AGP_MEM * handle)
|
||||
{
|
||||
if (!handle)
|
||||
return 0;
|
||||
|
@ -448,20 +455,21 @@ int drm_agp_free_memory(DRM_AGP_MEM *handle)
|
|||
}
|
||||
|
||||
/** Calls agp_bind_memory() */
|
||||
int drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start)
|
||||
int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
|
||||
{
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
return agp_bind_memory(handle, start);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_agp_bind_memory);
|
||||
|
||||
/** Calls agp_unbind_memory() */
|
||||
int drm_agp_unbind_memory(DRM_AGP_MEM *handle)
|
||||
int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
|
||||
{
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
return agp_unbind_memory(handle);
|
||||
}
|
||||
|
||||
#endif /* __OS_HAS_AGP */
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_auth.h
|
||||
* \file drm_auth.c
|
||||
* IOCTLs for authentication
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -46,7 +46,7 @@
|
|||
*/
|
||||
static int drm_hash_magic(drm_magic_t magic)
|
||||
{
|
||||
return magic & (DRM_HASH_SIZE-1);
|
||||
return magic & (DRM_HASH_SIZE - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,11 +59,11 @@ static int drm_hash_magic(drm_magic_t magic)
|
|||
* the one with matching magic number, while holding the drm_device::struct_sem
|
||||
* lock.
|
||||
*/
|
||||
static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
||||
static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_file_t *retval = NULL;
|
||||
drm_file_t *retval = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash = drm_hash_magic(magic);
|
||||
int hash = drm_hash_magic(magic);
|
||||
|
||||
down(&dev->struct_sem);
|
||||
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
|
||||
|
@ -78,7 +78,7 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
|||
|
||||
/**
|
||||
* Adds a magic number.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param priv file private data.
|
||||
* \param magic magic number.
|
||||
|
@ -87,28 +87,30 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
|
|||
* associated the magic number hash key in drm_device::magiclist, while holding
|
||||
* the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
||||
static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
|
||||
drm_magic_t magic)
|
||||
{
|
||||
int hash;
|
||||
int hash;
|
||||
drm_magic_entry_t *entry;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
|
||||
hash = drm_hash_magic(magic);
|
||||
entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
|
||||
if (!entry) return -ENOMEM;
|
||||
hash = drm_hash_magic(magic);
|
||||
entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->magic = magic;
|
||||
entry->priv = priv;
|
||||
entry->next = NULL;
|
||||
entry->priv = priv;
|
||||
entry->next = NULL;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (dev->magiclist[hash].tail) {
|
||||
dev->magiclist[hash].tail->next = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
} else {
|
||||
dev->magiclist[hash].head = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
dev->magiclist[hash].head = entry;
|
||||
dev->magiclist[hash].tail = entry;
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
|
@ -117,19 +119,18 @@ static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
|
|||
|
||||
/**
|
||||
* Remove a magic number.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param magic magic number.
|
||||
*
|
||||
* Searches and unlinks the entry in drm_device::magiclist with the magic
|
||||
* number hash key, while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
||||
static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
|
||||
{
|
||||
drm_magic_entry_t *prev = NULL;
|
||||
drm_magic_entry_t *pt;
|
||||
int hash;
|
||||
|
||||
int hash;
|
||||
|
||||
DRM_DEBUG("%d\n", magic);
|
||||
hash = drm_hash_magic(magic);
|
||||
|
@ -171,21 +172,22 @@ static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
|
|||
* filp.
|
||||
*/
|
||||
int drm_getmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
static drm_magic_t sequence = 0;
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
|
||||
/* Find unique magic */
|
||||
/* Find unique magic */
|
||||
if (priv->magic) {
|
||||
auth.magic = priv->magic;
|
||||
} else {
|
||||
do {
|
||||
spin_lock(&lock);
|
||||
if (!sequence) ++sequence; /* reserve 0 */
|
||||
if (!sequence)
|
||||
++sequence; /* reserve 0 */
|
||||
auth.magic = sequence++;
|
||||
spin_unlock(&lock);
|
||||
} while (drm_find_file(dev, auth.magic));
|
||||
|
@ -194,7 +196,7 @@ int drm_getmagic(struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
|
||||
if (copy_to_user((drm_auth_t __user *) arg, &auth, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -211,14 +213,14 @@ int drm_getmagic(struct inode *inode, struct file *filp,
|
|||
* Checks if \p filp is associated with the magic number passed in \arg.
|
||||
*/
|
||||
int drm_authmagic(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_auth_t auth;
|
||||
drm_file_t *file;
|
||||
|
||||
if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
|
||||
if (copy_from_user(&auth, (drm_auth_t __user *) arg, sizeof(auth)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%u\n", auth.magic);
|
||||
if ((file = drm_find_file(dev, auth.magic))) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm_context.h
|
||||
* \file drm_context.c
|
||||
* IOCTLs for generic contexts
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
@ -56,25 +56,26 @@
|
|||
* in drm_device::context_sareas, while holding the drm_device::struct_sem
|
||||
* lock.
|
||||
*/
|
||||
void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
|
||||
void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle)
|
||||
{
|
||||
if ( ctx_handle < 0 ) goto failed;
|
||||
if ( !dev->ctx_bitmap ) goto failed;
|
||||
if (ctx_handle < 0)
|
||||
goto failed;
|
||||
if (!dev->ctx_bitmap)
|
||||
goto failed;
|
||||
|
||||
if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
|
||||
if (ctx_handle < DRM_MAX_CTXBITMAP) {
|
||||
down(&dev->struct_sem);
|
||||
clear_bit( ctx_handle, dev->ctx_bitmap );
|
||||
clear_bit(ctx_handle, dev->ctx_bitmap);
|
||||
dev->context_sareas[ctx_handle] = NULL;
|
||||
up(&dev->struct_sem);
|
||||
return;
|
||||
}
|
||||
failed:
|
||||
DRM_ERROR( "Attempt to free invalid context handle: %d\n",
|
||||
ctx_handle );
|
||||
return;
|
||||
failed:
|
||||
DRM_ERROR("Attempt to free invalid context handle: %d\n", ctx_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Context bitmap allocation.
|
||||
*
|
||||
* \param dev DRM device.
|
||||
|
@ -84,29 +85,33 @@ void drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle )
|
|||
* drm_device::context_sareas to accommodate the new entry while holding the
|
||||
* drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_ctxbitmap_next( drm_device_t *dev )
|
||||
static int drm_ctxbitmap_next(drm_device_t * dev)
|
||||
{
|
||||
int bit;
|
||||
|
||||
if(!dev->ctx_bitmap) return -1;
|
||||
if (!dev->ctx_bitmap)
|
||||
return -1;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
|
||||
if ( bit < DRM_MAX_CTXBITMAP ) {
|
||||
set_bit( bit, dev->ctx_bitmap );
|
||||
DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
|
||||
if((bit+1) > dev->max_context) {
|
||||
dev->max_context = (bit+1);
|
||||
if(dev->context_sareas) {
|
||||
bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
|
||||
if (bit < DRM_MAX_CTXBITMAP) {
|
||||
set_bit(bit, dev->ctx_bitmap);
|
||||
DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
|
||||
if ((bit + 1) > dev->max_context) {
|
||||
dev->max_context = (bit + 1);
|
||||
if (dev->context_sareas) {
|
||||
drm_map_t **ctx_sareas;
|
||||
|
||||
ctx_sareas = drm_realloc(dev->context_sareas,
|
||||
(dev->max_context - 1) *
|
||||
sizeof(*dev->context_sareas),
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
if(!ctx_sareas) {
|
||||
(dev->max_context -
|
||||
1) *
|
||||
sizeof(*dev->
|
||||
context_sareas),
|
||||
dev->max_context *
|
||||
sizeof(*dev->
|
||||
context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
if (!ctx_sareas) {
|
||||
clear_bit(bit, dev->ctx_bitmap);
|
||||
up(&dev->struct_sem);
|
||||
return -1;
|
||||
|
@ -115,11 +120,11 @@ static int drm_ctxbitmap_next( drm_device_t *dev )
|
|||
dev->context_sareas[bit] = NULL;
|
||||
} else {
|
||||
/* max_context == 1 at this point */
|
||||
dev->context_sareas = drm_alloc(
|
||||
dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
if(!dev->context_sareas) {
|
||||
dev->context_sareas =
|
||||
drm_alloc(dev->max_context *
|
||||
sizeof(*dev->context_sareas),
|
||||
DRM_MEM_MAPS);
|
||||
if (!dev->context_sareas) {
|
||||
clear_bit(bit, dev->ctx_bitmap);
|
||||
up(&dev->struct_sem);
|
||||
return -1;
|
||||
|
@ -142,26 +147,26 @@ static int drm_ctxbitmap_next( drm_device_t *dev )
|
|||
* Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
|
||||
* the drm_device::struct_sem lock.
|
||||
*/
|
||||
int drm_ctxbitmap_init( drm_device_t *dev )
|
||||
int drm_ctxbitmap_init(drm_device_t * dev)
|
||||
{
|
||||
int i;
|
||||
int temp;
|
||||
int temp;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
dev->ctx_bitmap = (unsigned long *) drm_alloc( PAGE_SIZE,
|
||||
DRM_MEM_CTXBITMAP );
|
||||
if ( dev->ctx_bitmap == NULL ) {
|
||||
dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE,
|
||||
DRM_MEM_CTXBITMAP);
|
||||
if (dev->ctx_bitmap == NULL) {
|
||||
up(&dev->struct_sem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
|
||||
memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE);
|
||||
dev->context_sareas = NULL;
|
||||
dev->max_context = -1;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
|
||||
temp = drm_ctxbitmap_next( dev );
|
||||
DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
|
||||
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
temp = drm_ctxbitmap_next(dev);
|
||||
DRM_DEBUG("drm_ctxbitmap_init : %d\n", temp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -175,14 +180,14 @@ int drm_ctxbitmap_init( drm_device_t *dev )
|
|||
* Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
|
||||
* the drm_device::struct_sem lock.
|
||||
*/
|
||||
void drm_ctxbitmap_cleanup( drm_device_t *dev )
|
||||
void drm_ctxbitmap_cleanup(drm_device_t * dev)
|
||||
{
|
||||
down(&dev->struct_sem);
|
||||
if( dev->context_sareas ) drm_free( dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context,
|
||||
DRM_MEM_MAPS );
|
||||
drm_free( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
|
||||
if (dev->context_sareas)
|
||||
drm_free(dev->context_sareas,
|
||||
sizeof(*dev->context_sareas) *
|
||||
dev->max_context, DRM_MEM_MAPS);
|
||||
drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP);
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
|
||||
|
@ -194,7 +199,7 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev )
|
|||
|
||||
/**
|
||||
* Get per-context SAREA.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
|
@ -205,10 +210,10 @@ void drm_ctxbitmap_cleanup( drm_device_t *dev )
|
|||
* returns its handle.
|
||||
*/
|
||||
int drm_getsareactx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_priv_map_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map;
|
||||
|
@ -218,7 +223,8 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
|
||||
if (dev->max_context < 0
|
||||
|| request.ctx_id >= (unsigned)dev->max_context) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -226,17 +232,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
map = dev->context_sareas[request.ctx_id];
|
||||
up(&dev->struct_sem);
|
||||
|
||||
request.handle = 0;
|
||||
list_for_each_entry(_entry, &dev->maplist->head,head) {
|
||||
request.handle = NULL;
|
||||
list_for_each_entry(_entry, &dev->maplist->head, head) {
|
||||
if (_entry->map == map) {
|
||||
request.handle = (void *)(unsigned long)_entry->user_token;
|
||||
request.handle =
|
||||
(void *)(unsigned long)_entry->user_token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (request.handle == 0)
|
||||
if (request.handle == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
if (copy_to_user(argp, &request, sizeof(request)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -244,7 +250,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
|
||||
/**
|
||||
* Set per-context SAREA.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
|
@ -255,37 +261,37 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
|
|||
* drm_device::context_sareas with it.
|
||||
*/
|
||||
int drm_setsareactx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_priv_map_t request;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct list_head *list;
|
||||
|
||||
if (copy_from_user(&request,
|
||||
(drm_ctx_priv_map_t __user *)arg,
|
||||
sizeof(request)))
|
||||
(drm_ctx_priv_map_t __user *) arg, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
if (r_list->map
|
||||
&& r_list->user_token == (unsigned long) request.handle)
|
||||
&& r_list->user_token == (unsigned long)request.handle)
|
||||
goto found;
|
||||
}
|
||||
bad:
|
||||
bad:
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
|
||||
found:
|
||||
found:
|
||||
map = r_list->map;
|
||||
if (!map) goto bad;
|
||||
if (!map)
|
||||
goto bad;
|
||||
if (dev->max_context < 0)
|
||||
goto bad;
|
||||
if (request.ctx_id >= (unsigned) dev->max_context)
|
||||
if (request.ctx_id >= (unsigned)dev->max_context)
|
||||
goto bad;
|
||||
dev->context_sareas[request.ctx_id] = map;
|
||||
up(&dev->struct_sem);
|
||||
|
@ -308,22 +314,21 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Attempt to set drm_device::context_flag.
|
||||
*/
|
||||
static int drm_context_switch( drm_device_t *dev, int old, int new )
|
||||
static int drm_context_switch(drm_device_t * dev, int old, int new)
|
||||
{
|
||||
if ( test_and_set_bit( 0, &dev->context_flag ) ) {
|
||||
DRM_ERROR( "Reentering -- FIXME\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
if (test_and_set_bit(0, &dev->context_flag)) {
|
||||
DRM_ERROR("Reentering -- FIXME\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
DRM_DEBUG( "Context switch from %d to %d\n", old, new );
|
||||
if (new == dev->last_context) {
|
||||
clear_bit(0, &dev->context_flag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( new == dev->last_context ) {
|
||||
clear_bit( 0, &dev->context_flag );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,22 +342,22 @@ static int drm_context_switch( drm_device_t *dev, int old, int new )
|
|||
* hardware lock is held, clears the drm_device::context_flag and wakes up
|
||||
* drm_device::context_wait.
|
||||
*/
|
||||
static int drm_context_switch_complete( drm_device_t *dev, int new )
|
||||
static int drm_context_switch_complete(drm_device_t * dev, int new)
|
||||
{
|
||||
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
|
||||
dev->last_switch = jiffies;
|
||||
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
|
||||
dev->last_switch = jiffies;
|
||||
|
||||
if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
|
||||
DRM_ERROR( "Lock isn't held after context switch\n" );
|
||||
}
|
||||
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
|
||||
DRM_ERROR("Lock isn't held after context switch\n");
|
||||
}
|
||||
|
||||
/* If a context switch is ever initiated
|
||||
when the kernel holds the lock, release
|
||||
that lock here. */
|
||||
clear_bit( 0, &dev->context_flag );
|
||||
wake_up( &dev->context_wait );
|
||||
/* If a context switch is ever initiated
|
||||
when the kernel holds the lock, release
|
||||
that lock here. */
|
||||
clear_bit(0, &dev->context_flag);
|
||||
wake_up(&dev->context_wait);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -364,29 +369,28 @@ static int drm_context_switch_complete( drm_device_t *dev, int new )
|
|||
* \param arg user argument pointing to a drm_ctx_res structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_resctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_resctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
if ( copy_from_user( &res, argp, sizeof(res) ) )
|
||||
if (copy_from_user(&res, argp, sizeof(res)))
|
||||
return -EFAULT;
|
||||
|
||||
if ( res.count >= DRM_RESERVED_CONTEXTS ) {
|
||||
memset( &ctx, 0, sizeof(ctx) );
|
||||
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
ctx.handle = i;
|
||||
if ( copy_to_user( &res.contexts[i],
|
||||
&ctx, sizeof(ctx) ) )
|
||||
if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
res.count = DRM_RESERVED_CONTEXTS;
|
||||
|
||||
if ( copy_to_user( argp, &res, sizeof(res) ) )
|
||||
if (copy_to_user(argp, &res, sizeof(res)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -402,58 +406,57 @@ int drm_resctx( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Get a new handle for the context and copy to userspace.
|
||||
*/
|
||||
int drm_addctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_addctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_list_t * ctx_entry;
|
||||
drm_ctx_list_t *ctx_entry;
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
|
||||
if (copy_from_user(&ctx, argp, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
ctx.handle = drm_ctxbitmap_next( dev );
|
||||
if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
|
||||
/* Skip kernel's context and get a new one. */
|
||||
ctx.handle = drm_ctxbitmap_next( dev );
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
if (ctx.handle == DRM_KERNEL_CONTEXT) {
|
||||
/* Skip kernel's context and get a new one. */
|
||||
ctx.handle = drm_ctxbitmap_next(dev);
|
||||
}
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
if ( ctx.handle == -1 ) {
|
||||
DRM_DEBUG( "Not enough free contexts.\n" );
|
||||
/* Should this return -EBUSY instead? */
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if (ctx.handle == -1) {
|
||||
DRM_DEBUG("Not enough free contexts.\n");
|
||||
/* Should this return -EBUSY instead? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if ( ctx.handle != DRM_KERNEL_CONTEXT )
|
||||
{
|
||||
if (ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver->context_ctor)
|
||||
dev->driver->context_ctor(dev, ctx.handle);
|
||||
}
|
||||
|
||||
ctx_entry = drm_alloc( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
|
||||
if ( !ctx_entry ) {
|
||||
ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
|
||||
if (!ctx_entry) {
|
||||
DRM_DEBUG("out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD( &ctx_entry->head );
|
||||
INIT_LIST_HEAD(&ctx_entry->head);
|
||||
ctx_entry->handle = ctx.handle;
|
||||
ctx_entry->tag = priv;
|
||||
|
||||
down( &dev->ctxlist_sem );
|
||||
list_add( &ctx_entry->head, &dev->ctxlist->head );
|
||||
down(&dev->ctxlist_sem);
|
||||
list_add(&ctx_entry->head, &dev->ctxlist->head);
|
||||
++dev->ctx_count;
|
||||
up( &dev->ctxlist_sem );
|
||||
up(&dev->ctxlist_sem);
|
||||
|
||||
if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
|
||||
if (copy_to_user(argp, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drm_modctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_modctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
/* This does nothing */
|
||||
return 0;
|
||||
|
@ -468,19 +471,19 @@ int drm_modctx( struct inode *inode, struct file *filp,
|
|||
* \param arg user argument pointing to a drm_ctx structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_getctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_ctx_t __user *argp = (void __user *)arg;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
|
||||
if (copy_from_user(&ctx, argp, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
/* This is 0, because we don't handle any context flags */
|
||||
ctx.flags = 0;
|
||||
|
||||
if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
|
||||
if (copy_to_user(argp, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -496,18 +499,18 @@ int drm_getctx( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Calls context_switch().
|
||||
*/
|
||||
int drm_switchctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_switchctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
return drm_context_switch( dev, dev->last_context, ctx.handle );
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return drm_context_switch(dev, dev->last_context, ctx.handle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -521,18 +524,18 @@ int drm_switchctx( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Calls context_switch_complete().
|
||||
*/
|
||||
int drm_newctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_newctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
drm_context_switch_complete( dev, ctx.handle );
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
drm_context_switch_complete(dev, ctx.handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -548,42 +551,41 @@ int drm_newctx( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
|
||||
*/
|
||||
int drm_rmctx( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_rmctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
DRM_DEBUG( "%d\n", ctx.handle );
|
||||
if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
if (ctx.handle == DRM_KERNEL_CONTEXT + 1) {
|
||||
priv->remove_auth_on_close = 1;
|
||||
}
|
||||
if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
|
||||
if (ctx.handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver->context_dtor)
|
||||
dev->driver->context_dtor(dev, ctx.handle);
|
||||
drm_ctxbitmap_free( dev, ctx.handle );
|
||||
drm_ctxbitmap_free(dev, ctx.handle);
|
||||
}
|
||||
|
||||
down( &dev->ctxlist_sem );
|
||||
if ( !list_empty( &dev->ctxlist->head ) ) {
|
||||
down(&dev->ctxlist_sem);
|
||||
if (!list_empty(&dev->ctxlist->head)) {
|
||||
drm_ctx_list_t *pos, *n;
|
||||
|
||||
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||
if ( pos->handle == ctx.handle ) {
|
||||
list_del( &pos->head );
|
||||
drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||
list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
|
||||
if (pos->handle == ctx.handle) {
|
||||
list_del(&pos->head);
|
||||
drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
|
||||
--dev->ctx_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
up( &dev->ctxlist_sem );
|
||||
up(&dev->ctxlist_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_dma.h
|
||||
* \file drm_dma.c
|
||||
* DMA IOCTL and function support
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -37,23 +37,23 @@
|
|||
|
||||
/**
|
||||
* Initialize the DMA data.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \return zero on success or a negative value on failure.
|
||||
*
|
||||
* Allocate and initialize a drm_device_dma structure.
|
||||
*/
|
||||
int drm_dma_setup( drm_device_t *dev )
|
||||
int drm_dma_setup(drm_device_t * dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
dev->dma = drm_alloc( sizeof(*dev->dma), DRM_MEM_DRIVER );
|
||||
if ( !dev->dma )
|
||||
dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
|
||||
if (!dev->dma)
|
||||
return -ENOMEM;
|
||||
|
||||
memset( dev->dma, 0, sizeof(*dev->dma) );
|
||||
memset(dev->dma, 0, sizeof(*dev->dma));
|
||||
|
||||
for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++)
|
||||
memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
|
||||
|
||||
return 0;
|
||||
|
@ -67,14 +67,15 @@ int drm_dma_setup( drm_device_t *dev )
|
|||
* Free all pages associated with DMA buffers, the buffers and pages lists, and
|
||||
* finally the the drm_device::dma structure itself.
|
||||
*/
|
||||
void drm_dma_takedown(drm_device_t *dev)
|
||||
void drm_dma_takedown(drm_device_t * dev)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i, j;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i, j;
|
||||
|
||||
if (!dma) return;
|
||||
if (!dma)
|
||||
return;
|
||||
|
||||
/* Clear dma buffers */
|
||||
/* Clear dma buffers */
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++) {
|
||||
if (dma->bufs[i].seg_count) {
|
||||
DRM_DEBUG("order %d: buf_count = %d,"
|
||||
|
@ -85,64 +86,63 @@ void drm_dma_takedown(drm_device_t *dev)
|
|||
for (j = 0; j < dma->bufs[i].seg_count; j++) {
|
||||
if (dma->bufs[i].seglist[j]) {
|
||||
drm_free_pages(dma->bufs[i].seglist[j],
|
||||
dma->bufs[i].page_order,
|
||||
DRM_MEM_DMA);
|
||||
dma->bufs[i].page_order,
|
||||
DRM_MEM_DMA);
|
||||
}
|
||||
}
|
||||
drm_free(dma->bufs[i].seglist,
|
||||
dma->bufs[i].seg_count
|
||||
* sizeof(*dma->bufs[0].seglist),
|
||||
DRM_MEM_SEGS);
|
||||
dma->bufs[i].seg_count
|
||||
* sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS);
|
||||
}
|
||||
if (dma->bufs[i].buf_count) {
|
||||
for (j = 0; j < dma->bufs[i].buf_count; j++) {
|
||||
if (dma->bufs[i].buf_count) {
|
||||
for (j = 0; j < dma->bufs[i].buf_count; j++) {
|
||||
if (dma->bufs[i].buflist[j].dev_private) {
|
||||
drm_free(dma->bufs[i].buflist[j].dev_private,
|
||||
dma->bufs[i].buflist[j].dev_priv_size,
|
||||
DRM_MEM_BUFS);
|
||||
drm_free(dma->bufs[i].buflist[j].
|
||||
dev_private,
|
||||
dma->bufs[i].buflist[j].
|
||||
dev_priv_size, DRM_MEM_BUFS);
|
||||
}
|
||||
}
|
||||
drm_free(dma->bufs[i].buflist,
|
||||
dma->bufs[i].buf_count *
|
||||
sizeof(*dma->bufs[0].buflist),
|
||||
DRM_MEM_BUFS);
|
||||
drm_free(dma->bufs[i].buflist,
|
||||
dma->bufs[i].buf_count *
|
||||
sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS);
|
||||
}
|
||||
}
|
||||
|
||||
if (dma->buflist) {
|
||||
drm_free(dma->buflist,
|
||||
dma->buf_count * sizeof(*dma->buflist),
|
||||
DRM_MEM_BUFS);
|
||||
dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS);
|
||||
}
|
||||
|
||||
if (dma->pagelist) {
|
||||
drm_free(dma->pagelist,
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
dma->page_count * sizeof(*dma->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
}
|
||||
drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
|
||||
dev->dma = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free a buffer.
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param buf buffer to free.
|
||||
*
|
||||
*
|
||||
* Resets the fields of \p buf.
|
||||
*/
|
||||
void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
|
||||
void drm_free_buffer(drm_device_t * dev, drm_buf_t * buf)
|
||||
{
|
||||
if (!buf) return;
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->used = 0;
|
||||
buf->waiting = 0;
|
||||
buf->pending = 0;
|
||||
buf->filp = NULL;
|
||||
buf->used = 0;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
|
||||
&& waitqueue_active(&buf->dma_wait)) {
|
||||
wake_up_interruptible(&buf->dma_wait);
|
||||
}
|
||||
}
|
||||
|
@ -154,12 +154,13 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
|
|||
*
|
||||
* Frees each buffer associated with \p filp not already on the hardware.
|
||||
*/
|
||||
void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
|
||||
void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!dma) return;
|
||||
if (!dma)
|
||||
return;
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (dma->buflist[i]->filp == filp) {
|
||||
switch (dma->buflist[i]->list) {
|
||||
|
@ -176,5 +177,5 @@ void drm_core_reclaim_buffers(drm_device_t *dev, struct file *filp)
|
|||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_core_reclaim_buffers);
|
||||
|
||||
EXPORT_SYMBOL(drm_core_reclaim_buffers);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_drawable.h
|
||||
* \file drm_drawable.c
|
||||
* IOCTLs for drawables
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -37,20 +37,20 @@
|
|||
|
||||
/** No-op. */
|
||||
int drm_adddraw(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_draw_t draw;
|
||||
|
||||
draw.handle = 0; /* NOOP */
|
||||
DRM_DEBUG("%d\n", draw.handle);
|
||||
if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
|
||||
if (copy_to_user((drm_draw_t __user *) arg, &draw, sizeof(draw)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** No-op. */
|
||||
int drm_rmdraw(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return 0; /* NOOP */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_drv.h
|
||||
* \file drm_drv.c
|
||||
* Generic driver template
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -55,67 +55,67 @@ static int drm_version(struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/** Ioctl table */
|
||||
static drm_ioctl_desc_t drm_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { drm_version, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_by_busid, 0, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = { drm_getmap, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = { drm_getclient, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = { drm_getstats, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = { drm_setversion, 0, 1 },
|
||||
static drm_ioctl_desc_t drm_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = {drm_getunique, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = {drm_getmagic, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_by_busid, 0, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)] = {drm_getmap, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)] = {drm_getclient, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)] = {drm_getstats, 0, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION)] = {drm_setversion, 0, 1},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_noop, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_noop, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = {drm_setunique, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = {drm_noop, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = {drm_noop, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = {drm_authmagic, 1, 1},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap_ioctl,1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = { drm_rmmap_ioctl, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = {drm_addmap_ioctl, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)] = {drm_rmmap_ioctl, 1, 0},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { drm_setsareactx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { drm_getsareactx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, 1, 0},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = {drm_newctx, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = {drm_resctx, 1, 0},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = {drm_adddraw, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = {drm_rmdraw, 1, 1},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = {drm_lock, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = {drm_unlock, 1, 0},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_noop, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = {drm_noop, 1, 0},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = {drm_addbufs, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = {drm_markbufs, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = {drm_infobufs, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = {drm_mapbufs, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = {drm_freebufs, 1, 0},
|
||||
/* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = {drm_control, 1, 1},
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire_ioctl, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release_ioctl, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable_ioctl, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info_ioctl, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire_ioctl, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release_ioctl, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable_ioctl, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = {drm_agp_info_ioctl, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = {drm_agp_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = {drm_agp_free, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = {drm_agp_bind, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = {drm_agp_unbind, 1, 1},
|
||||
#endif
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = { drm_sg_alloc, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = { drm_sg_free, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)] = {drm_sg_alloc, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)] = {drm_sg_free, 1, 1},
|
||||
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0, 0},
|
||||
};
|
||||
|
||||
#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls )
|
||||
|
@ -129,17 +129,17 @@ static drm_ioctl_desc_t drm_ioctls[] = {
|
|||
*
|
||||
* \sa drm_device
|
||||
*/
|
||||
int drm_takedown( drm_device_t *dev )
|
||||
int drm_takedown(drm_device_t * dev)
|
||||
{
|
||||
drm_magic_entry_t *pt, *next;
|
||||
drm_map_list_t *r_list;
|
||||
drm_vma_entry_t *vma, *vma_next;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG( "\n" );
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
if (dev->driver->pretakedown)
|
||||
dev->driver->pretakedown(dev);
|
||||
dev->driver->pretakedown(dev);
|
||||
DRM_DEBUG("driver pretakedown completed\n");
|
||||
|
||||
if (dev->unique) {
|
||||
|
@ -148,95 +148,95 @@ int drm_takedown( drm_device_t *dev )
|
|||
dev->unique_len = 0;
|
||||
}
|
||||
|
||||
if ( dev->irq_enabled ) drm_irq_uninstall( dev );
|
||||
if (dev->irq_enabled)
|
||||
drm_irq_uninstall(dev);
|
||||
|
||||
down( &dev->struct_sem );
|
||||
del_timer( &dev->timer );
|
||||
down(&dev->struct_sem);
|
||||
del_timer(&dev->timer);
|
||||
|
||||
/* Clear pid list */
|
||||
for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
|
||||
for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
|
||||
/* Clear pid list */
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
for (pt = dev->magiclist[i].head; pt; pt = next) {
|
||||
next = pt->next;
|
||||
drm_free( pt, sizeof(*pt), DRM_MEM_MAGIC );
|
||||
drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
|
||||
}
|
||||
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
|
||||
/* Clear AGP information */
|
||||
/* Clear AGP information */
|
||||
if (drm_core_has_AGP(dev) && dev->agp) {
|
||||
drm_agp_mem_t *entry;
|
||||
drm_agp_mem_t *nexte;
|
||||
|
||||
/* Remove AGP resources, but leave dev->agp
|
||||
intact until drv_cleanup is called. */
|
||||
for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
|
||||
/* Remove AGP resources, but leave dev->agp
|
||||
intact until drv_cleanup is called. */
|
||||
for (entry = dev->agp->memory; entry; entry = nexte) {
|
||||
nexte = entry->next;
|
||||
if ( entry->bound ) drm_unbind_agp( entry->memory );
|
||||
drm_free_agp( entry->memory, entry->pages );
|
||||
drm_free( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
|
||||
if (entry->bound)
|
||||
drm_unbind_agp(entry->memory);
|
||||
drm_free_agp(entry->memory, entry->pages);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
|
||||
}
|
||||
dev->agp->memory = NULL;
|
||||
|
||||
if (dev->agp->acquired)
|
||||
drm_agp_release(dev);
|
||||
drm_agp_release(dev);
|
||||
|
||||
dev->agp->acquired = 0;
|
||||
dev->agp->enabled = 0;
|
||||
dev->agp->enabled = 0;
|
||||
}
|
||||
if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
|
||||
drm_sg_cleanup(dev->sg);
|
||||
dev->sg = NULL;
|
||||
}
|
||||
|
||||
/* Clear vma list (only built for debugging) */
|
||||
if ( dev->vmalist ) {
|
||||
for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
|
||||
/* Clear vma list (only built for debugging) */
|
||||
if (dev->vmalist) {
|
||||
for (vma = dev->vmalist; vma; vma = vma_next) {
|
||||
vma_next = vma->next;
|
||||
drm_free( vma, sizeof(*vma), DRM_MEM_VMAS );
|
||||
drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
|
||||
}
|
||||
dev->vmalist = NULL;
|
||||
}
|
||||
|
||||
if( dev->maplist ) {
|
||||
if (dev->maplist) {
|
||||
while (!list_empty(&dev->maplist->head)) {
|
||||
struct list_head *list = dev->maplist->head.next;
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
drm_rmmap_locked(dev, r_list->map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist ) {
|
||||
for ( i = 0 ; i < dev->queue_count ; i++ ) {
|
||||
if ( dev->queuelist[i] ) {
|
||||
drm_free( dev->queuelist[i],
|
||||
sizeof(*dev->queuelist[0]),
|
||||
DRM_MEM_QUEUES );
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
|
||||
for (i = 0; i < dev->queue_count; i++) {
|
||||
if (dev->queuelist[i]) {
|
||||
drm_free(dev->queuelist[i],
|
||||
sizeof(*dev->queuelist[0]),
|
||||
DRM_MEM_QUEUES);
|
||||
dev->queuelist[i] = NULL;
|
||||
}
|
||||
}
|
||||
drm_free( dev->queuelist,
|
||||
dev->queue_slots * sizeof(*dev->queuelist),
|
||||
DRM_MEM_QUEUES );
|
||||
drm_free(dev->queuelist,
|
||||
dev->queue_slots * sizeof(*dev->queuelist),
|
||||
DRM_MEM_QUEUES);
|
||||
dev->queuelist = NULL;
|
||||
}
|
||||
dev->queue_count = 0;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
drm_dma_takedown( dev );
|
||||
drm_dma_takedown(dev);
|
||||
|
||||
if ( dev->lock.hw_lock ) {
|
||||
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
if (dev->lock.hw_lock) {
|
||||
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
|
||||
dev->lock.filp = NULL;
|
||||
wake_up_interruptible( &dev->lock.lock_queue );
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
}
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
|
||||
DRM_DEBUG("takedown completed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Module initialization. Called via init_module at module load time, or via
|
||||
* linux/init/main.c (this is not currently supported).
|
||||
|
@ -246,26 +246,28 @@ int drm_takedown( drm_device_t *dev )
|
|||
* Initializes an array of drm_device structures, and attempts to
|
||||
* initialize all available devices, using consecutive minors, registering the
|
||||
* stubs and initializing the AGP device.
|
||||
*
|
||||
*
|
||||
* Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
|
||||
* after the initialization for driver customization.
|
||||
*/
|
||||
int drm_init( struct drm_driver *driver )
|
||||
int drm_init(struct drm_driver *driver)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
struct pci_device_id *pid;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG( "\n" );
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
drm_mem_init();
|
||||
|
||||
for (i=0; driver->pci_driver.id_table[i].vendor != 0; i++) {
|
||||
for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
|
||||
pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
|
||||
|
||||
pdev=NULL;
|
||||
/* pass back in pdev to account for multiple identical cards */
|
||||
while ((pdev = pci_get_subsys(pid->vendor, pid->device, pid->subvendor, pid->subdevice, pdev)) != NULL) {
|
||||
|
||||
pdev = NULL;
|
||||
/* pass back in pdev to account for multiple identical cards */
|
||||
while ((pdev =
|
||||
pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
|
||||
pid->subdevice, pdev)) != NULL) {
|
||||
/* stealth mode requires a manual probe */
|
||||
pci_dev_get(pdev);
|
||||
drm_get_dev(pdev, pid, driver);
|
||||
|
@ -273,62 +275,63 @@ int drm_init( struct drm_driver *driver )
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_init);
|
||||
|
||||
/**
|
||||
* Called via cleanup_module() at module unload time.
|
||||
*
|
||||
* Cleans up all DRM device, calling takedown().
|
||||
*
|
||||
*
|
||||
* \sa drm_init
|
||||
*/
|
||||
static void drm_cleanup( drm_device_t *dev )
|
||||
static void drm_cleanup(drm_device_t * dev)
|
||||
{
|
||||
DRM_DEBUG( "\n" );
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
if (!dev) {
|
||||
DRM_ERROR("cleanup called no dev\n");
|
||||
return;
|
||||
}
|
||||
|
||||
drm_takedown( dev );
|
||||
drm_takedown(dev);
|
||||
|
||||
if (dev->maplist) {
|
||||
drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
|
||||
dev->maplist = NULL;
|
||||
}
|
||||
|
||||
drm_ctxbitmap_cleanup( dev );
|
||||
|
||||
drm_ctxbitmap_cleanup(dev);
|
||||
|
||||
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
|
||||
dev->agp && dev->agp->agp_mtrr >= 0) {
|
||||
int retval;
|
||||
retval = mtrr_del( dev->agp->agp_mtrr,
|
||||
dev->agp->agp_info.aper_base,
|
||||
dev->agp->agp_info.aper_size*1024*1024 );
|
||||
DRM_DEBUG( "mtrr_del=%d\n", retval );
|
||||
retval = mtrr_del(dev->agp->agp_mtrr,
|
||||
dev->agp->agp_info.aper_base,
|
||||
dev->agp->agp_info.aper_size * 1024 * 1024);
|
||||
DRM_DEBUG("mtrr_del=%d\n", retval);
|
||||
}
|
||||
|
||||
if (drm_core_has_AGP(dev) && dev->agp ) {
|
||||
drm_free( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
|
||||
|
||||
if (drm_core_has_AGP(dev) && dev->agp) {
|
||||
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
|
||||
dev->agp = NULL;
|
||||
}
|
||||
|
||||
if (dev->driver->postcleanup)
|
||||
dev->driver->postcleanup(dev);
|
||||
|
||||
|
||||
drm_put_head(&dev->primary);
|
||||
if ( drm_put_dev(dev) )
|
||||
DRM_ERROR( "Cannot unload module\n" );
|
||||
if (drm_put_dev(dev))
|
||||
DRM_ERROR("Cannot unload module\n");
|
||||
}
|
||||
|
||||
void drm_exit (struct drm_driver *driver)
|
||||
void drm_exit(struct drm_driver *driver)
|
||||
{
|
||||
int i;
|
||||
drm_device_t *dev = NULL;
|
||||
drm_head_t *head;
|
||||
|
||||
DRM_DEBUG( "\n" );
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
for (i = 0; i < drm_cards_limit; i++) {
|
||||
head = drm_heads[i];
|
||||
|
@ -336,9 +339,9 @@ void drm_exit (struct drm_driver *driver)
|
|||
continue;
|
||||
if (!head->dev)
|
||||
continue;
|
||||
if (head->dev->driver!=driver)
|
||||
if (head->dev->driver != driver)
|
||||
continue;
|
||||
dev=head->dev;
|
||||
dev = head->dev;
|
||||
}
|
||||
if (dev) {
|
||||
/* release the pci driver */
|
||||
|
@ -346,32 +349,35 @@ void drm_exit (struct drm_driver *driver)
|
|||
pci_dev_put(dev->pdev);
|
||||
drm_cleanup(dev);
|
||||
}
|
||||
DRM_INFO( "Module unloaded\n" );
|
||||
DRM_INFO("Module unloaded\n");
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_exit);
|
||||
|
||||
/** File operations structure */
|
||||
static struct file_operations drm_stub_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_stub_open
|
||||
.open = drm_stub_open
|
||||
};
|
||||
|
||||
static int __init drm_core_init(void)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
|
||||
drm_cards_limit = (drm_cards_limit < DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
|
||||
drm_heads = drm_calloc(drm_cards_limit,
|
||||
sizeof(*drm_heads), DRM_MEM_STUB);
|
||||
if(!drm_heads)
|
||||
|
||||
drm_cards_limit =
|
||||
(drm_cards_limit <
|
||||
DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
|
||||
drm_heads =
|
||||
drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
|
||||
if (!drm_heads)
|
||||
goto err_p1;
|
||||
|
||||
|
||||
if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
|
||||
goto err_p1;
|
||||
|
||||
|
||||
drm_class = drm_sysfs_create(THIS_MODULE, "drm");
|
||||
if (IS_ERR(drm_class)) {
|
||||
printk (KERN_ERR "DRM: Error creating drm class.\n");
|
||||
printk(KERN_ERR "DRM: Error creating drm class.\n");
|
||||
ret = PTR_ERR(drm_class);
|
||||
goto err_p2;
|
||||
}
|
||||
|
@ -382,35 +388,31 @@ static int __init drm_core_init(void)
|
|||
ret = -1;
|
||||
goto err_p3;
|
||||
}
|
||||
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s\n",
|
||||
CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL,
|
||||
CORE_DATE);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s\n",
|
||||
CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
|
||||
return 0;
|
||||
err_p3:
|
||||
err_p3:
|
||||
drm_sysfs_destroy(drm_class);
|
||||
err_p2:
|
||||
err_p2:
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
|
||||
err_p1:
|
||||
err_p1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit drm_core_exit (void)
|
||||
static void __exit drm_core_exit(void)
|
||||
{
|
||||
remove_proc_entry("dri", NULL);
|
||||
drm_sysfs_destroy(drm_class);
|
||||
|
||||
unregister_chrdev(DRM_MAJOR, "drm");
|
||||
|
||||
drm_free(drm_heads, sizeof(*drm_heads) *
|
||||
drm_cards_limit, DRM_MEM_STUB);
|
||||
drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
|
||||
}
|
||||
|
||||
|
||||
module_init( drm_core_init );
|
||||
module_exit( drm_core_exit );
|
||||
|
||||
module_init(drm_core_init);
|
||||
module_exit(drm_core_exit);
|
||||
|
||||
/**
|
||||
* Get version information
|
||||
|
@ -423,8 +425,8 @@ module_exit( drm_core_exit );
|
|||
*
|
||||
* Fills in the version information in \p arg.
|
||||
*/
|
||||
static int drm_version( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
static int drm_version(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -432,21 +434,19 @@ static int drm_version( struct inode *inode, struct file *filp,
|
|||
drm_version_t version;
|
||||
int ret;
|
||||
|
||||
if ( copy_from_user( &version, argp, sizeof(version) ) )
|
||||
if (copy_from_user(&version, argp, sizeof(version)))
|
||||
return -EFAULT;
|
||||
|
||||
/* version is a required function to return the personality module version */
|
||||
if ((ret = dev->driver->version(&version)))
|
||||
return ret;
|
||||
|
||||
if ( copy_to_user( argp, &version, sizeof(version) ) )
|
||||
|
||||
if (copy_to_user(argp, &version, sizeof(version)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Called whenever a process performs an ioctl on /dev/drm.
|
||||
*
|
||||
* \param inode device inode.
|
||||
|
@ -458,8 +458,8 @@ static int drm_version( struct inode *inode, struct file *filp,
|
|||
* Looks up the ioctl function in the ::ioctls table, checking for root
|
||||
* previleges if so required, and dispatches to the respective function.
|
||||
*/
|
||||
int drm_ioctl( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_ioctl(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -468,40 +468,43 @@ int drm_ioctl( struct inode *inode, struct file *filp,
|
|||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
int retcode = -EINVAL;
|
||||
|
||||
atomic_inc( &dev->ioctl_count );
|
||||
atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
|
||||
atomic_inc(&dev->ioctl_count);
|
||||
atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
|
||||
++priv->ioctl_count;
|
||||
|
||||
DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
current->pid, cmd, nr, (long)old_encode_dev(priv->head->device),
|
||||
priv->authenticated );
|
||||
|
||||
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
|
||||
current->pid, cmd, nr,
|
||||
(long)old_encode_dev(priv->head->device),
|
||||
priv->authenticated);
|
||||
|
||||
if (nr < DRIVER_IOCTL_COUNT)
|
||||
ioctl = &drm_ioctls[nr];
|
||||
else if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
|
||||
else if ((nr >= DRM_COMMAND_BASE)
|
||||
&& (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
|
||||
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
|
||||
else
|
||||
goto err_i1;
|
||||
|
||||
|
||||
func = ioctl->func;
|
||||
/* is there a local override? */
|
||||
if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
|
||||
func = dev->driver->dma_ioctl;
|
||||
|
||||
if ( !func ) {
|
||||
DRM_DEBUG( "no function\n" );
|
||||
|
||||
if (!func) {
|
||||
DRM_DEBUG("no function\n");
|
||||
retcode = -EINVAL;
|
||||
} else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
|
||||
( ioctl->auth_needed && !priv->authenticated ) ) {
|
||||
} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) ||
|
||||
(ioctl->auth_needed && !priv->authenticated)) {
|
||||
retcode = -EACCES;
|
||||
} else {
|
||||
retcode = func( inode, filp, cmd, arg );
|
||||
retcode = func(inode, filp, cmd, arg);
|
||||
}
|
||||
|
||||
err_i1:
|
||||
atomic_dec( &dev->ioctl_count );
|
||||
if (retcode) DRM_DEBUG( "ret = %x\n", retcode);
|
||||
|
||||
err_i1:
|
||||
atomic_dec(&dev->ioctl_count);
|
||||
if (retcode)
|
||||
DRM_DEBUG("ret = %x\n", retcode);
|
||||
return retcode;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_ioctl);
|
||||
|
||||
EXPORT_SYMBOL(drm_ioctl);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm_fops.h
|
||||
* \file drm_fops.c
|
||||
* File operations for DRM
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Daryll Strauss <daryll@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
|
@ -37,49 +37,48 @@
|
|||
#include "drmP.h"
|
||||
#include <linux/poll.h>
|
||||
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev);
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp,
|
||||
drm_device_t * dev);
|
||||
|
||||
static int drm_setup( drm_device_t *dev )
|
||||
static int drm_setup(drm_device_t * dev)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (dev->driver->presetup)
|
||||
{
|
||||
ret=dev->driver->presetup(dev);
|
||||
if (ret!=0)
|
||||
if (dev->driver->presetup) {
|
||||
ret = dev->driver->presetup(dev);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
atomic_set( &dev->ioctl_count, 0 );
|
||||
atomic_set( &dev->vma_count, 0 );
|
||||
atomic_set(&dev->ioctl_count, 0);
|
||||
atomic_set(&dev->vma_count, 0);
|
||||
dev->buf_use = 0;
|
||||
atomic_set( &dev->buf_alloc, 0 );
|
||||
atomic_set(&dev->buf_alloc, 0);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
|
||||
{
|
||||
i = drm_dma_setup( dev );
|
||||
if ( i < 0 )
|
||||
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) {
|
||||
i = drm_dma_setup(dev);
|
||||
if (i < 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
|
||||
atomic_set( &dev->counts[i], 0 );
|
||||
for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
|
||||
atomic_set(&dev->counts[i], 0);
|
||||
|
||||
for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
|
||||
for (i = 0; i < DRM_HASH_SIZE; i++) {
|
||||
dev->magiclist[i].head = NULL;
|
||||
dev->magiclist[i].tail = NULL;
|
||||
}
|
||||
|
||||
dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist),
|
||||
DRM_MEM_CTXLIST);
|
||||
if(dev->ctxlist == NULL) return -ENOMEM;
|
||||
dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST);
|
||||
if (dev->ctxlist == NULL)
|
||||
return -ENOMEM;
|
||||
memset(dev->ctxlist, 0, sizeof(*dev->ctxlist));
|
||||
INIT_LIST_HEAD(&dev->ctxlist->head);
|
||||
|
||||
dev->vmalist = NULL;
|
||||
dev->sigdata.lock = dev->lock.hw_lock = NULL;
|
||||
init_waitqueue_head( &dev->lock.lock_queue );
|
||||
init_waitqueue_head(&dev->lock.lock_queue);
|
||||
dev->queue_count = 0;
|
||||
dev->queue_reserved = 0;
|
||||
dev->queue_slots = 0;
|
||||
|
@ -91,24 +90,21 @@ static int drm_setup( drm_device_t *dev )
|
|||
dev->last_context = 0;
|
||||
dev->last_switch = 0;
|
||||
dev->last_checked = 0;
|
||||
init_waitqueue_head( &dev->context_wait );
|
||||
init_waitqueue_head(&dev->context_wait);
|
||||
dev->if_version = 0;
|
||||
|
||||
dev->ctx_start = 0;
|
||||
dev->lck_start = 0;
|
||||
|
||||
dev->buf_rp = dev->buf;
|
||||
dev->buf_wp = dev->buf;
|
||||
dev->buf_end = dev->buf + DRM_BSZ;
|
||||
dev->buf_async = NULL;
|
||||
init_waitqueue_head( &dev->buf_readers );
|
||||
init_waitqueue_head( &dev->buf_writers );
|
||||
init_waitqueue_head(&dev->buf_readers);
|
||||
init_waitqueue_head(&dev->buf_writers);
|
||||
|
||||
DRM_DEBUG( "\n" );
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
/*
|
||||
* The kernel's context could be created here, but is now created
|
||||
* in drm_dma_enqueue. This is more resource-efficient for
|
||||
* in drm_dma_enqueue. This is more resource-efficient for
|
||||
* hardware that does not do DMA, but may mean that
|
||||
* drm_select_queue fails between the time the interrupt is
|
||||
* initialized and the time the queues are initialized.
|
||||
|
@ -121,7 +117,7 @@ static int drm_setup( drm_device_t *dev )
|
|||
|
||||
/**
|
||||
* Open file.
|
||||
*
|
||||
*
|
||||
* \param inode device inode
|
||||
* \param filp file pointer.
|
||||
* \return zero on success or a negative number on failure.
|
||||
|
@ -130,7 +126,7 @@ static int drm_setup( drm_device_t *dev )
|
|||
* increments the device open count. If the open count was previous at zero,
|
||||
* i.e., it's the first that the device is open, then calls setup().
|
||||
*/
|
||||
int drm_open( struct inode *inode, struct file *filp )
|
||||
int drm_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_device_t *dev = NULL;
|
||||
int minor = iminor(inode);
|
||||
|
@ -138,26 +134,27 @@ int drm_open( struct inode *inode, struct file *filp )
|
|||
|
||||
if (!((minor >= 0) && (minor < drm_cards_limit)))
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (!drm_heads[minor])
|
||||
return -ENODEV;
|
||||
|
||||
if (!(dev = drm_heads[minor]->dev))
|
||||
return -ENODEV;
|
||||
|
||||
retcode = drm_open_helper( inode, filp, dev );
|
||||
if ( !retcode ) {
|
||||
atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
|
||||
spin_lock( &dev->count_lock );
|
||||
if ( !dev->open_count++ ) {
|
||||
spin_unlock( &dev->count_lock );
|
||||
return drm_setup( dev );
|
||||
|
||||
retcode = drm_open_helper(inode, filp, dev);
|
||||
if (!retcode) {
|
||||
atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!dev->open_count++) {
|
||||
spin_unlock(&dev->count_lock);
|
||||
return drm_setup(dev);
|
||||
}
|
||||
spin_unlock( &dev->count_lock );
|
||||
spin_unlock(&dev->count_lock);
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_open);
|
||||
|
||||
/**
|
||||
|
@ -172,7 +169,7 @@ EXPORT_SYMBOL(drm_open);
|
|||
* data from its list and free it. Decreases the open count and if it reaches
|
||||
* zero calls takedown().
|
||||
*/
|
||||
int drm_release( struct inode *inode, struct file *filp )
|
||||
int drm_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
|
@ -181,7 +178,7 @@ int drm_release( struct inode *inode, struct file *filp )
|
|||
lock_kernel();
|
||||
dev = priv->head->dev;
|
||||
|
||||
DRM_DEBUG( "open_count = %d\n", dev->open_count );
|
||||
DRM_DEBUG("open_count = %d\n", dev->open_count);
|
||||
|
||||
if (dev->driver->prerelease)
|
||||
dev->driver->prerelease(dev, filp);
|
||||
|
@ -190,194 +187,199 @@ int drm_release( struct inode *inode, struct file *filp )
|
|||
* Begin inline drm_release
|
||||
*/
|
||||
|
||||
DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)old_encode_dev(priv->head->device), dev->open_count );
|
||||
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)old_encode_dev(priv->head->device),
|
||||
dev->open_count);
|
||||
|
||||
if (priv->lock_count && dev->lock.hw_lock &&
|
||||
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
|
||||
dev->lock.filp == filp) {
|
||||
DRM_DEBUG("File %p released, freeing lock for context %d\n",
|
||||
filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
|
||||
if ( priv->lock_count && dev->lock.hw_lock &&
|
||||
_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
|
||||
dev->lock.filp == filp ) {
|
||||
DRM_DEBUG( "File %p released, freeing lock for context %d\n",
|
||||
filp,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
|
||||
|
||||
if (dev->driver->release)
|
||||
dev->driver->release(dev, filp);
|
||||
|
||||
drm_lock_free( dev, &dev->lock.hw_lock->lock,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
|
||||
|
||||
/* FIXME: may require heavy-handed reset of
|
||||
hardware at this point, possibly
|
||||
processed via a callback to the X
|
||||
server. */
|
||||
}
|
||||
else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) {
|
||||
/* FIXME: may require heavy-handed reset of
|
||||
hardware at this point, possibly
|
||||
processed via a callback to the X
|
||||
server. */
|
||||
} else if (dev->driver->release && priv->lock_count
|
||||
&& dev->lock.hw_lock) {
|
||||
/* The lock is required to reclaim buffers */
|
||||
DECLARE_WAITQUEUE( entry, current );
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
|
||||
add_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
retcode = -EINTR;
|
||||
break;
|
||||
}
|
||||
if ( drm_lock_take( &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT ) ) {
|
||||
dev->lock.filp = filp;
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
dev->lock.filp = filp;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
}
|
||||
/* Contention */
|
||||
/* Contention */
|
||||
schedule();
|
||||
if ( signal_pending( current ) ) {
|
||||
if (signal_pending(current)) {
|
||||
retcode = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
if( !retcode ) {
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
if (!retcode) {
|
||||
if (dev->driver->release)
|
||||
dev->driver->release(dev, filp);
|
||||
drm_lock_free( dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT );
|
||||
drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release)
|
||||
{
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)
|
||||
&& !dev->driver->release) {
|
||||
dev->driver->reclaim_buffers(dev, filp);
|
||||
}
|
||||
|
||||
drm_fasync( -1, filp, 0 );
|
||||
drm_fasync(-1, filp, 0);
|
||||
|
||||
down( &dev->ctxlist_sem );
|
||||
if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
|
||||
down(&dev->ctxlist_sem);
|
||||
if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
|
||||
drm_ctx_list_t *pos, *n;
|
||||
|
||||
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
|
||||
if ( pos->tag == priv &&
|
||||
pos->handle != DRM_KERNEL_CONTEXT ) {
|
||||
list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) {
|
||||
if (pos->tag == priv &&
|
||||
pos->handle != DRM_KERNEL_CONTEXT) {
|
||||
if (dev->driver->context_dtor)
|
||||
dev->driver->context_dtor(dev, pos->handle);
|
||||
dev->driver->context_dtor(dev,
|
||||
pos->handle);
|
||||
|
||||
drm_ctxbitmap_free( dev, pos->handle );
|
||||
drm_ctxbitmap_free(dev, pos->handle);
|
||||
|
||||
list_del( &pos->head );
|
||||
drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST );
|
||||
list_del(&pos->head);
|
||||
drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
|
||||
--dev->ctx_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
up( &dev->ctxlist_sem );
|
||||
up(&dev->ctxlist_sem);
|
||||
|
||||
down( &dev->struct_sem );
|
||||
if ( priv->remove_auth_on_close == 1 ) {
|
||||
down(&dev->struct_sem);
|
||||
if (priv->remove_auth_on_close == 1) {
|
||||
drm_file_t *temp = dev->file_first;
|
||||
while ( temp ) {
|
||||
while (temp) {
|
||||
temp->authenticated = 0;
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
if ( priv->prev ) {
|
||||
if (priv->prev) {
|
||||
priv->prev->next = priv->next;
|
||||
} else {
|
||||
dev->file_first = priv->next;
|
||||
dev->file_first = priv->next;
|
||||
}
|
||||
if ( priv->next ) {
|
||||
if (priv->next) {
|
||||
priv->next->prev = priv->prev;
|
||||
} else {
|
||||
dev->file_last = priv->prev;
|
||||
dev->file_last = priv->prev;
|
||||
}
|
||||
up( &dev->struct_sem );
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (dev->driver->free_filp_priv)
|
||||
dev->driver->free_filp_priv(dev, priv);
|
||||
|
||||
drm_free( priv, sizeof(*priv), DRM_MEM_FILES );
|
||||
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
|
||||
|
||||
/* ========================================================
|
||||
* End inline drm_release
|
||||
*/
|
||||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
|
||||
spin_lock( &dev->count_lock );
|
||||
if ( !--dev->open_count ) {
|
||||
if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
|
||||
DRM_ERROR( "Device busy: %d %d\n",
|
||||
atomic_read( &dev->ioctl_count ),
|
||||
dev->blocked );
|
||||
spin_unlock( &dev->count_lock );
|
||||
atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
|
||||
spin_lock(&dev->count_lock);
|
||||
if (!--dev->open_count) {
|
||||
if (atomic_read(&dev->ioctl_count) || dev->blocked) {
|
||||
DRM_ERROR("Device busy: %d %d\n",
|
||||
atomic_read(&dev->ioctl_count), dev->blocked);
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return -EBUSY;
|
||||
}
|
||||
spin_unlock( &dev->count_lock );
|
||||
spin_unlock(&dev->count_lock);
|
||||
unlock_kernel();
|
||||
return drm_takedown( dev );
|
||||
return drm_takedown(dev);
|
||||
}
|
||||
spin_unlock( &dev->count_lock );
|
||||
spin_unlock(&dev->count_lock);
|
||||
|
||||
unlock_kernel();
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_release);
|
||||
|
||||
/**
|
||||
* Called whenever a process opens /dev/drm.
|
||||
* Called whenever a process opens /dev/drm.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param dev device.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Creates and initializes a drm_file structure for the file private data in \p
|
||||
* filp and add it into the double linked list in \p dev.
|
||||
*/
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
int minor = iminor(inode);
|
||||
drm_file_t *priv;
|
||||
int minor = iminor(inode);
|
||||
drm_file_t *priv;
|
||||
int ret;
|
||||
|
||||
if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */
|
||||
if (!drm_cpu_valid()) return -EINVAL;
|
||||
if (filp->f_flags & O_EXCL)
|
||||
return -EBUSY; /* No exclusive opens */
|
||||
if (!drm_cpu_valid())
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
|
||||
|
||||
priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
|
||||
if(!priv) return -ENOMEM;
|
||||
priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
filp->private_data = priv;
|
||||
priv->uid = current->euid;
|
||||
priv->pid = current->pid;
|
||||
priv->minor = minor;
|
||||
priv->head = drm_heads[minor];
|
||||
priv->ioctl_count = 0;
|
||||
filp->private_data = priv;
|
||||
priv->uid = current->euid;
|
||||
priv->pid = current->pid;
|
||||
priv->minor = minor;
|
||||
priv->head = drm_heads[minor];
|
||||
priv->ioctl_count = 0;
|
||||
priv->authenticated = capable(CAP_SYS_ADMIN);
|
||||
priv->lock_count = 0;
|
||||
priv->lock_count = 0;
|
||||
|
||||
if (dev->driver->open_helper) {
|
||||
ret=dev->driver->open_helper(dev, priv);
|
||||
ret = dev->driver->open_helper(dev, priv);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
down(&dev->struct_sem);
|
||||
if (!dev->file_last) {
|
||||
priv->next = NULL;
|
||||
priv->prev = NULL;
|
||||
priv->next = NULL;
|
||||
priv->prev = NULL;
|
||||
dev->file_first = priv;
|
||||
dev->file_last = priv;
|
||||
dev->file_last = priv;
|
||||
} else {
|
||||
priv->next = NULL;
|
||||
priv->prev = dev->file_last;
|
||||
priv->next = NULL;
|
||||
priv->prev = dev->file_last;
|
||||
dev->file_last->next = priv;
|
||||
dev->file_last = priv;
|
||||
dev->file_last = priv;
|
||||
}
|
||||
up(&dev->struct_sem);
|
||||
|
||||
|
@ -394,42 +396,48 @@ static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t
|
|||
}
|
||||
if (!dev->hose) {
|
||||
struct pci_bus *b = pci_bus_b(pci_root_buses.next);
|
||||
if (b) dev->hose = b->sysdata;
|
||||
if (b)
|
||||
dev->hose = b->sysdata;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
out_free:
|
||||
out_free:
|
||||
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
|
||||
filp->private_data=NULL;
|
||||
filp->private_data = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** No-op. */
|
||||
int drm_flush(struct file *filp)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
||||
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
|
||||
current->pid, (long)old_encode_dev(priv->head->device), dev->open_count);
|
||||
current->pid, (long)old_encode_dev(priv->head->device),
|
||||
dev->open_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_flush);
|
||||
|
||||
/** No-op. */
|
||||
int drm_fasync(int fd, struct file *filp, int on)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
int retcode;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
int retcode;
|
||||
|
||||
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(priv->head->device));
|
||||
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
|
||||
(long)old_encode_dev(priv->head->device));
|
||||
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
|
||||
if (retcode < 0) return retcode;
|
||||
if (retcode < 0)
|
||||
return retcode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_fasync);
|
||||
|
||||
/** No-op. */
|
||||
|
@ -437,5 +445,5 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_poll);
|
||||
|
||||
EXPORT_SYMBOL(drm_poll);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_init.h
|
||||
* \file drm_init.c
|
||||
* Setup/Cleanup for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -43,10 +43,11 @@
|
|||
int drm_cpu_valid(void)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
|
||||
if (boot_cpu_data.x86 == 3)
|
||||
return 0; /* No cmpxchg on a 386 */
|
||||
#endif
|
||||
#if defined(__sparc__) && !defined(__sparc_v9__)
|
||||
return 0; /* No cmpxchg before v9 sparc. */
|
||||
return 0; /* No cmpxchg before v9 sparc. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -68,15 +68,15 @@
|
|||
#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
|
||||
|
||||
typedef struct drm_version_32 {
|
||||
int version_major; /**< Major version */
|
||||
int version_minor; /**< Minor version */
|
||||
int version_patchlevel;/**< Patch level */
|
||||
u32 name_len; /**< Length of name buffer */
|
||||
u32 name; /**< Name of driver */
|
||||
u32 date_len; /**< Length of date buffer */
|
||||
u32 date; /**< User-space buffer to hold date */
|
||||
u32 desc_len; /**< Length of desc buffer */
|
||||
u32 desc; /**< User-space buffer to hold desc */
|
||||
int version_major; /**< Major version */
|
||||
int version_minor; /**< Minor version */
|
||||
int version_patchlevel; /**< Patch level */
|
||||
u32 name_len; /**< Length of name buffer */
|
||||
u32 name; /**< Name of driver */
|
||||
u32 date_len; /**< Length of date buffer */
|
||||
u32 date; /**< User-space buffer to hold date */
|
||||
u32 desc_len; /**< Length of desc buffer */
|
||||
u32 desc; /**< User-space buffer to hold desc */
|
||||
} drm_version32_t;
|
||||
|
||||
static int compat_drm_version(struct file *file, unsigned int cmd,
|
||||
|
@ -86,7 +86,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|
|||
drm_version_t __user *version;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
|
||||
if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
|
||||
return -EFAULT;
|
||||
|
||||
version = compat_alloc_user_space(sizeof(*version));
|
||||
|
@ -104,7 +104,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_VERSION, (unsigned long) version);
|
||||
DRM_IOCTL_VERSION, (unsigned long)version);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -116,7 +116,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd,
|
|||
|| __get_user(v32.desc_len, &version->desc_len))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
|
||||
if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -133,25 +133,25 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd,
|
|||
drm_unique_t __user *u;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
|
||||
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
|
||||
return -EFAULT;
|
||||
|
||||
u = compat_alloc_user_space(sizeof(*u));
|
||||
if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
|
||||
return -EFAULT;
|
||||
if (__put_user(uq32.unique_len, &u->unique_len)
|
||||
|| __put_user((void __user *)(unsigned long) uq32.unique,
|
||||
|| __put_user((void __user *)(unsigned long)uq32.unique,
|
||||
&u->unique))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
|
||||
DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (__get_user(uq32.unique_len, &u->unique_len))
|
||||
return -EFAULT;
|
||||
if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
|
||||
if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -162,28 +162,28 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd,
|
|||
drm_unique32_t uq32;
|
||||
drm_unique_t __user *u;
|
||||
|
||||
if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
|
||||
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
|
||||
return -EFAULT;
|
||||
|
||||
u = compat_alloc_user_space(sizeof(*u));
|
||||
if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
|
||||
return -EFAULT;
|
||||
if (__put_user(uq32.unique_len, &u->unique_len)
|
||||
|| __put_user((void __user *)(unsigned long) uq32.unique,
|
||||
|| __put_user((void __user *)(unsigned long)uq32.unique,
|
||||
&u->unique))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
|
||||
DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
|
||||
}
|
||||
|
||||
typedef struct drm_map32 {
|
||||
u32 offset; /**< Requested physical address (0 for SAREA)*/
|
||||
u32 size; /**< Requested physical size (bytes) */
|
||||
drm_map_type_t type; /**< Type of memory to map */
|
||||
u32 offset; /**< Requested physical address (0 for SAREA)*/
|
||||
u32 size; /**< Requested physical size (bytes) */
|
||||
drm_map_type_t type; /**< Type of memory to map */
|
||||
drm_map_flags_t flags; /**< Flags */
|
||||
u32 handle; /**< User-space: "Handle" to pass to mmap() */
|
||||
int mtrr; /**< MTRR slot used */
|
||||
u32 handle; /**< User-space: "Handle" to pass to mmap() */
|
||||
int mtrr; /**< MTRR slot used */
|
||||
} drm_map32_t;
|
||||
|
||||
static int compat_drm_getmap(struct file *file, unsigned int cmd,
|
||||
|
@ -205,7 +205,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_MAP, (unsigned long) map);
|
||||
DRM_IOCTL_GET_MAP, (unsigned long)map);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -217,7 +217,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd,
|
|||
|| __get_user(m32.mtrr, &map->mtrr))
|
||||
return -EFAULT;
|
||||
|
||||
m32.handle = (unsigned long) handle;
|
||||
m32.handle = (unsigned long)handle;
|
||||
if (copy_to_user(argp, &m32, sizeof(m32)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -246,7 +246,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_ADD_MAP, (unsigned long) map);
|
||||
DRM_IOCTL_ADD_MAP, (unsigned long)map);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -255,8 +255,8 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|
|||
|| __get_user(handle, &map->handle))
|
||||
return -EFAULT;
|
||||
|
||||
m32.handle = (unsigned long) handle;
|
||||
if (m32.handle != (unsigned long) handle && printk_ratelimit())
|
||||
m32.handle = (unsigned long)handle;
|
||||
if (m32.handle != (unsigned long)handle && printk_ratelimit())
|
||||
printk(KERN_ERR "compat_drm_addmap truncated handle"
|
||||
" %p for type %d offset %x\n",
|
||||
handle, m32.type, m32.offset);
|
||||
|
@ -280,20 +280,20 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd,
|
|||
map = compat_alloc_user_space(sizeof(*map));
|
||||
if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
|
||||
return -EFAULT;
|
||||
if (__put_user((void *)(unsigned long) handle, &map->handle))
|
||||
if (__put_user((void *)(unsigned long)handle, &map->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RM_MAP, (unsigned long) map);
|
||||
DRM_IOCTL_RM_MAP, (unsigned long)map);
|
||||
}
|
||||
|
||||
typedef struct drm_client32 {
|
||||
int idx; /**< Which client desired? */
|
||||
int auth; /**< Is client authenticated? */
|
||||
u32 pid; /**< Process ID */
|
||||
u32 uid; /**< User ID */
|
||||
u32 magic; /**< Magic */
|
||||
u32 iocs; /**< Ioctl count */
|
||||
int idx; /**< Which client desired? */
|
||||
int auth; /**< Is client authenticated? */
|
||||
u32 pid; /**< Process ID */
|
||||
u32 uid; /**< User ID */
|
||||
u32 magic; /**< Magic */
|
||||
u32 iocs; /**< Ioctl count */
|
||||
} drm_client32_t;
|
||||
|
||||
static int compat_drm_getclient(struct file *file, unsigned int cmd,
|
||||
|
@ -314,7 +314,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_CLIENT, (unsigned long) client);
|
||||
DRM_IOCTL_GET_CLIENT, (unsigned long)client);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -351,7 +351,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_STATS, (unsigned long) stats);
|
||||
DRM_IOCTL_GET_STATS, (unsigned long)stats);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -368,12 +368,12 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd,
|
|||
}
|
||||
|
||||
typedef struct drm_buf_desc32 {
|
||||
int count; /**< Number of buffers of this size */
|
||||
int size; /**< Size in bytes */
|
||||
int low_mark; /**< Low water mark */
|
||||
int high_mark; /**< High water mark */
|
||||
int flags;
|
||||
u32 agp_start; /**< Start address in the AGP aperture */
|
||||
int count; /**< Number of buffers of this size */
|
||||
int size; /**< Size in bytes */
|
||||
int low_mark; /**< Low water mark */
|
||||
int high_mark; /**< High water mark */
|
||||
int flags;
|
||||
u32 agp_start; /**< Start address in the AGP aperture */
|
||||
} drm_buf_desc32_t;
|
||||
|
||||
static int compat_drm_addbufs(struct file *file, unsigned int cmd,
|
||||
|
@ -395,7 +395,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
|
||||
DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -427,12 +427,12 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
|
||||
DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
|
||||
}
|
||||
|
||||
typedef struct drm_buf_info32 {
|
||||
int count; /**< Entries in list */
|
||||
u32 list;
|
||||
int count; /**< Entries in list */
|
||||
u32 list;
|
||||
} drm_buf_info32_t;
|
||||
|
||||
static int compat_drm_infobufs(struct file *file, unsigned int cmd,
|
||||
|
@ -451,7 +451,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
count = req32.count;
|
||||
to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
|
||||
to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
if (count > 0
|
||||
|
@ -469,7 +469,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_INFO_BUFS, (unsigned long) request);
|
||||
DRM_IOCTL_INFO_BUFS, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -488,16 +488,16 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
|
|||
}
|
||||
|
||||
typedef struct drm_buf_pub32 {
|
||||
int idx; /**< Index into the master buffer list */
|
||||
int total; /**< Buffer size */
|
||||
int used; /**< Amount of buffer in use (for DMA) */
|
||||
u32 address; /**< Address of buffer */
|
||||
int idx; /**< Index into the master buffer list */
|
||||
int total; /**< Buffer size */
|
||||
int used; /**< Amount of buffer in use (for DMA) */
|
||||
u32 address; /**< Address of buffer */
|
||||
} drm_buf_pub32_t;
|
||||
|
||||
typedef struct drm_buf_map32 {
|
||||
int count; /**< Length of the buffer list */
|
||||
u32 virtual; /**< Mmap'd area in user-virtual */
|
||||
u32 list; /**< Buffer information */
|
||||
int count; /**< Length of the buffer list */
|
||||
u32 virtual; /**< Mmap'd area in user-virtual */
|
||||
u32 list; /**< Buffer information */
|
||||
} drm_buf_map32_t;
|
||||
|
||||
static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
|
||||
|
@ -531,7 +531,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_MAP_BUFS, (unsigned long) request);
|
||||
DRM_IOCTL_MAP_BUFS, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -542,21 +542,21 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
|
|||
if (__copy_in_user(&list32[i], &list[i],
|
||||
offsetof(drm_buf_pub_t, address))
|
||||
|| __get_user(addr, &list[i].address)
|
||||
|| __put_user((unsigned long) addr,
|
||||
|| __put_user((unsigned long)addr,
|
||||
&list32[i].address))
|
||||
return -EFAULT;
|
||||
|
||||
if (__put_user(actual, &argp->count)
|
||||
|| __get_user(addr, &request->virtual)
|
||||
|| __put_user((unsigned long) addr, &argp->virtual))
|
||||
|| __put_user((unsigned long)addr, &argp->virtual))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct drm_buf_free32 {
|
||||
int count;
|
||||
u32 list;
|
||||
int count;
|
||||
u32 list;
|
||||
} drm_buf_free32_t;
|
||||
|
||||
static int compat_drm_freebufs(struct file *file, unsigned int cmd,
|
||||
|
@ -573,17 +573,17 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd,
|
|||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
|
||||
return -EFAULT;
|
||||
if (__put_user(req32.count, &request->count)
|
||||
|| __put_user((int __user *)(unsigned long) req32.list,
|
||||
|| __put_user((int __user *)(unsigned long)req32.list,
|
||||
&request->list))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_FREE_BUFS, (unsigned long) request);
|
||||
DRM_IOCTL_FREE_BUFS, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_ctx_priv_map32 {
|
||||
unsigned int ctx_id; /**< Context requesting private mapping */
|
||||
u32 handle; /**< Handle of map */
|
||||
unsigned int ctx_id; /**< Context requesting private mapping */
|
||||
u32 handle; /**< Handle of map */
|
||||
} drm_ctx_priv_map32_t;
|
||||
|
||||
static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
|
||||
|
@ -600,12 +600,12 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
|
|||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
|
||||
return -EFAULT;
|
||||
if (__put_user(req32.ctx_id, &request->ctx_id)
|
||||
|| __put_user((void *)(unsigned long) req32.handle,
|
||||
|| __put_user((void *)(unsigned long)req32.handle,
|
||||
&request->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
|
||||
DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
|
||||
}
|
||||
|
||||
static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
|
||||
|
@ -628,20 +628,20 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
|
||||
DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (__get_user(handle, &request->handle)
|
||||
|| __put_user((unsigned long) handle, &argp->handle))
|
||||
|| __put_user((unsigned long)handle, &argp->handle))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct drm_ctx_res32 {
|
||||
int count;
|
||||
u32 contexts;
|
||||
int count;
|
||||
u32 contexts;
|
||||
} drm_ctx_res32_t;
|
||||
|
||||
static int compat_drm_resctx(struct file *file, unsigned int cmd,
|
||||
|
@ -659,12 +659,12 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
|
|||
if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
|
||||
return -EFAULT;
|
||||
if (__put_user(res32.count, &res->count)
|
||||
|| __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
|
||||
|| __put_user((drm_ctx_t __user *) (unsigned long)res32.contexts,
|
||||
&res->contexts))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RES_CTX, (unsigned long) res);
|
||||
DRM_IOCTL_RES_CTX, (unsigned long)res);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -676,23 +676,23 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd,
|
|||
}
|
||||
|
||||
typedef struct drm_dma32 {
|
||||
int context; /**< Context handle */
|
||||
int send_count; /**< Number of buffers to send */
|
||||
u32 send_indices; /**< List of handles to buffers */
|
||||
u32 send_sizes; /**< Lengths of data to send */
|
||||
int context; /**< Context handle */
|
||||
int send_count; /**< Number of buffers to send */
|
||||
u32 send_indices; /**< List of handles to buffers */
|
||||
u32 send_sizes; /**< Lengths of data to send */
|
||||
drm_dma_flags_t flags; /**< Flags */
|
||||
int request_count; /**< Number of buffers requested */
|
||||
int request_size; /**< Desired size for buffers */
|
||||
u32 request_indices; /**< Buffer information */
|
||||
u32 request_sizes;
|
||||
int granted_count; /**< Number of buffers granted */
|
||||
int request_count; /**< Number of buffers requested */
|
||||
int request_size; /**< Desired size for buffers */
|
||||
u32 request_indices; /**< Buffer information */
|
||||
u32 request_sizes;
|
||||
int granted_count; /**< Number of buffers granted */
|
||||
} drm_dma32_t;
|
||||
|
||||
static int compat_drm_dma(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_dma32_t d32;
|
||||
drm_dma32_t __user *argp = (void __user *) arg;
|
||||
drm_dma32_t __user *argp = (void __user *)arg;
|
||||
drm_dma_t __user *d;
|
||||
int err;
|
||||
|
||||
|
@ -705,20 +705,20 @@ static int compat_drm_dma(struct file *file, unsigned int cmd,
|
|||
|
||||
if (__put_user(d32.context, &d->context)
|
||||
|| __put_user(d32.send_count, &d->send_count)
|
||||
|| __put_user((int __user *)(unsigned long) d32.send_indices,
|
||||
|| __put_user((int __user *)(unsigned long)d32.send_indices,
|
||||
&d->send_indices)
|
||||
|| __put_user((int __user *)(unsigned long) d32.send_sizes,
|
||||
|| __put_user((int __user *)(unsigned long)d32.send_sizes,
|
||||
&d->send_sizes)
|
||||
|| __put_user(d32.flags, &d->flags)
|
||||
|| __put_user(d32.request_count, &d->request_count)
|
||||
|| __put_user((int __user *)(unsigned long) d32.request_indices,
|
||||
|| __put_user((int __user *)(unsigned long)d32.request_indices,
|
||||
&d->request_indices)
|
||||
|| __put_user((int __user *)(unsigned long) d32.request_sizes,
|
||||
|| __put_user((int __user *)(unsigned long)d32.request_sizes,
|
||||
&d->request_sizes))
|
||||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_DMA, (unsigned long) d);
|
||||
DRM_IOCTL_DMA, (unsigned long)d);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -751,19 +751,19 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
|
||||
DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
|
||||
}
|
||||
|
||||
typedef struct drm_agp_info32 {
|
||||
int agp_version_major;
|
||||
int agp_version_minor;
|
||||
u32 mode;
|
||||
u32 aperture_base; /* physical address */
|
||||
u32 aperture_size; /* bytes */
|
||||
u32 memory_allowed; /* bytes */
|
||||
u32 memory_used;
|
||||
int agp_version_major;
|
||||
int agp_version_minor;
|
||||
u32 mode;
|
||||
u32 aperture_base; /* physical address */
|
||||
u32 aperture_size; /* bytes */
|
||||
u32 memory_allowed; /* bytes */
|
||||
u32 memory_used;
|
||||
|
||||
/* PCI information */
|
||||
/* PCI information */
|
||||
unsigned short id_vendor;
|
||||
unsigned short id_device;
|
||||
} drm_agp_info32_t;
|
||||
|
@ -781,7 +781,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_INFO, (unsigned long) info);
|
||||
DRM_IOCTL_AGP_INFO, (unsigned long)info);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -806,7 +806,7 @@ typedef struct drm_agp_buffer32 {
|
|||
u32 size; /**< In bytes -- will round to page boundary */
|
||||
u32 handle; /**< Used for binding / unbinding */
|
||||
u32 type; /**< Type of memory to allocate */
|
||||
u32 physical; /**< Physical used by i810 */
|
||||
u32 physical; /**< Physical used by i810 */
|
||||
} drm_agp_buffer32_t;
|
||||
|
||||
static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
|
||||
|
@ -827,7 +827,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
|
||||
DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -835,7 +835,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
|
|||
|| __get_user(req32.physical, &request->physical)
|
||||
|| copy_to_user(argp, &req32, sizeof(req32))) {
|
||||
drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long) request);
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -856,7 +856,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long) request);
|
||||
DRM_IOCTL_AGP_FREE, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_agp_binding32 {
|
||||
|
@ -881,7 +881,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_BIND, (unsigned long) request);
|
||||
DRM_IOCTL_AGP_BIND, (unsigned long)request);
|
||||
}
|
||||
|
||||
static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
|
||||
|
@ -898,9 +898,9 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
|
||||
DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
|
||||
}
|
||||
#endif /* __OS_HAS_AGP */
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
||||
typedef struct drm_scatter_gather32 {
|
||||
u32 size; /**< In bytes -- will round to page boundary */
|
||||
|
@ -923,7 +923,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_SG_ALLOC, (unsigned long) request);
|
||||
DRM_IOCTL_SG_ALLOC, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -950,7 +950,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_SG_FREE, (unsigned long) request);
|
||||
DRM_IOCTL_SG_FREE, (unsigned long)request);
|
||||
}
|
||||
|
||||
struct drm_wait_vblank_request32 {
|
||||
|
@ -990,7 +990,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
err = drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
|
||||
DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -1059,11 +1059,12 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_compat_ioctl);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_ioctl.h
|
||||
* \file drm_ioctl.c
|
||||
* IOCTL processing for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
/**
|
||||
* Get the bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
|
@ -50,12 +50,12 @@
|
|||
* Copies the bus id from drm_device::unique into user space.
|
||||
*/
|
||||
int drm_getunique(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t __user *argp = (void __user *)arg;
|
||||
drm_unique_t u;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t __user *argp = (void __user *)arg;
|
||||
drm_unique_t u;
|
||||
|
||||
if (copy_from_user(&u, argp, sizeof(u)))
|
||||
return -EFAULT;
|
||||
|
@ -71,7 +71,7 @@ int drm_getunique(struct inode *inode, struct file *filp,
|
|||
|
||||
/**
|
||||
* Set the bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
|
@ -84,34 +84,39 @@ int drm_getunique(struct inode *inode, struct file *filp,
|
|||
* version 1.1 or greater.
|
||||
*/
|
||||
int drm_setunique(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t u;
|
||||
int domain, bus, slot, func, ret;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_unique_t u;
|
||||
int domain, bus, slot, func, ret;
|
||||
|
||||
if (dev->unique_len || dev->unique) return -EBUSY;
|
||||
if (dev->unique_len || dev->unique)
|
||||
return -EBUSY;
|
||||
|
||||
if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
|
||||
if (copy_from_user(&u, (drm_unique_t __user *) arg, sizeof(u)))
|
||||
return -EFAULT;
|
||||
|
||||
if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
|
||||
if (!u.unique_len || u.unique_len > 1024)
|
||||
return -EINVAL;
|
||||
|
||||
dev->unique_len = u.unique_len;
|
||||
dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
|
||||
if(!dev->unique) return -ENOMEM;
|
||||
dev->unique = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
|
||||
if (!dev->unique)
|
||||
return -ENOMEM;
|
||||
if (copy_from_user(dev->unique, u.unique, dev->unique_len))
|
||||
return -EFAULT;
|
||||
|
||||
dev->unique[dev->unique_len] = '\0';
|
||||
|
||||
dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + strlen(dev->unique) + 2,
|
||||
DRM_MEM_DRIVER);
|
||||
dev->devname =
|
||||
drm_alloc(strlen(dev->driver->pci_driver.name) +
|
||||
strlen(dev->unique) + 2, DRM_MEM_DRIVER);
|
||||
if (!dev->devname)
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
dev->unique);
|
||||
|
||||
/* Return error if the busid submitted doesn't match the device's actual
|
||||
* busid.
|
||||
|
@ -121,18 +126,16 @@ int drm_setunique(struct inode *inode, struct file *filp,
|
|||
return DRM_ERR(EINVAL);
|
||||
domain = bus >> 8;
|
||||
bus &= 0xff;
|
||||
|
||||
|
||||
if ((domain != dev->pci_domain) ||
|
||||
(bus != dev->pci_bus) ||
|
||||
(slot != dev->pci_slot) ||
|
||||
(func != dev->pci_func))
|
||||
(slot != dev->pci_slot) || (func != dev->pci_func))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_set_busid(drm_device_t *dev)
|
||||
static int drm_set_busid(drm_device_t * dev)
|
||||
{
|
||||
if (dev->unique != NULL)
|
||||
return EBUSY;
|
||||
|
@ -143,19 +146,20 @@ drm_set_busid(drm_device_t *dev)
|
|||
return ENOMEM;
|
||||
|
||||
snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
|
||||
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
|
||||
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
|
||||
|
||||
dev->devname = drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2,
|
||||
DRM_MEM_DRIVER);
|
||||
dev->devname =
|
||||
drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
|
||||
2, DRM_MEM_DRIVER);
|
||||
if (dev->devname == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique);
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
dev->unique);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a mapping information.
|
||||
*
|
||||
|
@ -163,23 +167,23 @@ drm_set_busid(drm_device_t *dev)
|
|||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_map structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Searches for the mapping with the specified offset and copies its information
|
||||
* into userspace
|
||||
*/
|
||||
int drm_getmap( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getmap(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t __user *argp = (void __user *)arg;
|
||||
drm_map_t map;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t __user *argp = (void __user *)arg;
|
||||
drm_map_t map;
|
||||
drm_map_list_t *r_list = NULL;
|
||||
struct list_head *list;
|
||||
int idx;
|
||||
int i;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&map, argp, sizeof(map)))
|
||||
return -EFAULT;
|
||||
|
@ -193,26 +197,27 @@ int drm_getmap( struct inode *inode, struct file *filp,
|
|||
|
||||
i = 0;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
if(i == idx) {
|
||||
if (i == idx) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(!r_list || !r_list->map) {
|
||||
if (!r_list || !r_list->map) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map.offset = r_list->map->offset;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = (void *)(unsigned long) r_list->user_token;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
map.size = r_list->map->size;
|
||||
map.type = r_list->map->type;
|
||||
map.flags = r_list->map->flags;
|
||||
map.handle = (void *)(unsigned long)r_list->user_token;
|
||||
map.mtrr = r_list->map->mtrr;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
|
||||
if (copy_to_user(argp, &map, sizeof(map)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -223,83 +228,81 @@ int drm_getmap( struct inode *inode, struct file *filp,
|
|||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_client structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Searches for the client with the specified index and copies its information
|
||||
* into userspace
|
||||
*/
|
||||
int drm_getclient( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getclient(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_client_t __user *argp = (void __user *)arg;
|
||||
drm_client_t client;
|
||||
drm_file_t *pt;
|
||||
int idx;
|
||||
int i;
|
||||
drm_file_t *pt;
|
||||
int idx;
|
||||
int i;
|
||||
|
||||
if (copy_from_user(&client, argp, sizeof(client)))
|
||||
return -EFAULT;
|
||||
idx = client.idx;
|
||||
down(&dev->struct_sem);
|
||||
for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
|
||||
;
|
||||
for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ;
|
||||
|
||||
if (!pt) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
client.auth = pt->authenticated;
|
||||
client.pid = pt->pid;
|
||||
client.uid = pt->uid;
|
||||
client.auth = pt->authenticated;
|
||||
client.pid = pt->pid;
|
||||
client.uid = pt->uid;
|
||||
client.magic = pt->magic;
|
||||
client.iocs = pt->ioctl_count;
|
||||
client.iocs = pt->ioctl_count;
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
|
||||
if (copy_to_user((drm_client_t __user *) arg, &client, sizeof(client)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics information.
|
||||
*
|
||||
/**
|
||||
* Get statistics information.
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_stats structure.
|
||||
*
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*/
|
||||
int drm_getstats( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_getstats(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_stats_t stats;
|
||||
int i;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_stats_t stats;
|
||||
int i;
|
||||
|
||||
memset(&stats, 0, sizeof(stats));
|
||||
|
||||
|
||||
down(&dev->struct_sem);
|
||||
|
||||
for (i = 0; i < dev->counters; i++) {
|
||||
if (dev->types[i] == _DRM_STAT_LOCK)
|
||||
stats.data[i].value
|
||||
= (dev->lock.hw_lock
|
||||
? dev->lock.hw_lock->lock : 0);
|
||||
else
|
||||
= (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
|
||||
else
|
||||
stats.data[i].value = atomic_read(&dev->counts[i]);
|
||||
stats.data[i].type = dev->types[i];
|
||||
stats.data[i].type = dev->types[i];
|
||||
}
|
||||
|
||||
|
||||
stats.count = dev->counters;
|
||||
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
|
||||
if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
@ -352,7 +355,8 @@ int drm_setversion(DRM_IOCTL_ARGS)
|
|||
|
||||
if (sv.drm_dd_major != -1) {
|
||||
if (sv.drm_dd_major != version.version_major ||
|
||||
sv.drm_dd_minor < 0 || sv.drm_dd_minor > version.version_minor)
|
||||
sv.drm_dd_minor < 0
|
||||
|| sv.drm_dd_minor > version.version_minor)
|
||||
return EINVAL;
|
||||
|
||||
if (dev->driver->set_version)
|
||||
|
@ -363,7 +367,7 @@ int drm_setversion(DRM_IOCTL_ARGS)
|
|||
|
||||
/** No-op ioctl. */
|
||||
int drm_noop(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
DRM_DEBUG("\n");
|
||||
return 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_irq.h
|
||||
* \file drm_irq.c
|
||||
* IRQ support
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -39,19 +39,19 @@
|
|||
|
||||
/**
|
||||
* Get interrupt from bus id.
|
||||
*
|
||||
*
|
||||
* \param inode device inode.
|
||||
* \param filp file pointer.
|
||||
* \param cmd command.
|
||||
* \param arg user argument, pointing to a drm_irq_busid structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Finds the PCI device with the specified bus id and gets its IRQ number.
|
||||
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
|
||||
* to that of the device that this DRM instance attached to.
|
||||
*/
|
||||
int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -66,14 +66,12 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
|||
|
||||
if ((p.busnum >> 8) != dev->pci_domain ||
|
||||
(p.busnum & 0xff) != dev->pci_bus ||
|
||||
p.devnum != dev->pci_slot ||
|
||||
p.funcnum != dev->pci_func)
|
||||
p.devnum != dev->pci_slot || p.funcnum != dev->pci_func)
|
||||
return -EINVAL;
|
||||
|
||||
p.irq = dev->irq;
|
||||
|
||||
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
|
||||
p.busnum, p.devnum, p.funcnum, p.irq);
|
||||
DRM_DEBUG("%d:%d:%d => IRQ %d\n", p.busnum, p.devnum, p.funcnum, p.irq);
|
||||
if (copy_to_user(argp, &p, sizeof(p)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -89,61 +87,61 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp,
|
|||
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
|
||||
* before and after the installation.
|
||||
*/
|
||||
static int drm_irq_install( drm_device_t *dev )
|
||||
static int drm_irq_install(drm_device_t * dev)
|
||||
{
|
||||
int ret;
|
||||
unsigned long sh_flags=0;
|
||||
unsigned long sh_flags = 0;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return -EINVAL;
|
||||
|
||||
if ( dev->irq == 0 )
|
||||
if (dev->irq == 0)
|
||||
return -EINVAL;
|
||||
|
||||
down( &dev->struct_sem );
|
||||
down(&dev->struct_sem);
|
||||
|
||||
/* Driver must have been initialized */
|
||||
if ( !dev->dev_private ) {
|
||||
up( &dev->struct_sem );
|
||||
if (!dev->dev_private) {
|
||||
up(&dev->struct_sem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( dev->irq_enabled ) {
|
||||
up( &dev->struct_sem );
|
||||
if (dev->irq_enabled) {
|
||||
up(&dev->struct_sem);
|
||||
return -EBUSY;
|
||||
}
|
||||
dev->irq_enabled = 1;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
|
||||
DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
|
||||
init_waitqueue_head(&dev->vbl_queue);
|
||||
|
||||
spin_lock_init( &dev->vbl_lock );
|
||||
|
||||
INIT_LIST_HEAD( &dev->vbl_sigs.head );
|
||||
|
||||
|
||||
spin_lock_init(&dev->vbl_lock);
|
||||
|
||||
INIT_LIST_HEAD(&dev->vbl_sigs.head);
|
||||
|
||||
dev->vbl_pending = 0;
|
||||
}
|
||||
|
||||
/* Before installing handler */
|
||||
/* Before installing handler */
|
||||
dev->driver->irq_preinstall(dev);
|
||||
|
||||
/* Install handler */
|
||||
/* Install handler */
|
||||
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
|
||||
sh_flags = SA_SHIRQ;
|
||||
|
||||
ret = request_irq( dev->irq, dev->driver->irq_handler,
|
||||
sh_flags, dev->devname, dev );
|
||||
if ( ret < 0 ) {
|
||||
down( &dev->struct_sem );
|
||||
|
||||
ret = request_irq(dev->irq, dev->driver->irq_handler,
|
||||
sh_flags, dev->devname, dev);
|
||||
if (ret < 0) {
|
||||
down(&dev->struct_sem);
|
||||
dev->irq_enabled = 0;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* After installing handler */
|
||||
/* After installing handler */
|
||||
dev->driver->irq_postinstall(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -156,29 +154,30 @@ static int drm_irq_install( drm_device_t *dev )
|
|||
*
|
||||
* Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
|
||||
*/
|
||||
int drm_irq_uninstall( drm_device_t *dev )
|
||||
int drm_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
int irq_enabled;
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return -EINVAL;
|
||||
|
||||
down( &dev->struct_sem );
|
||||
down(&dev->struct_sem);
|
||||
irq_enabled = dev->irq_enabled;
|
||||
dev->irq_enabled = 0;
|
||||
up( &dev->struct_sem );
|
||||
up(&dev->struct_sem);
|
||||
|
||||
if ( !irq_enabled )
|
||||
if (!irq_enabled)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
|
||||
DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq);
|
||||
|
||||
dev->driver->irq_uninstall(dev);
|
||||
|
||||
free_irq( dev->irq, dev );
|
||||
free_irq(dev->irq, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_irq_uninstall);
|
||||
|
||||
/**
|
||||
|
@ -192,30 +191,30 @@ EXPORT_SYMBOL(drm_irq_uninstall);
|
|||
*
|
||||
* Calls irq_install() or irq_uninstall() according to \p arg.
|
||||
*/
|
||||
int drm_control( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_control(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_control_t ctl;
|
||||
|
||||
|
||||
/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
|
||||
|
||||
if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
|
||||
if (copy_from_user(&ctl, (drm_control_t __user *) arg, sizeof(ctl)))
|
||||
return -EFAULT;
|
||||
|
||||
switch ( ctl.func ) {
|
||||
switch (ctl.func) {
|
||||
case DRM_INST_HANDLER:
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return 0;
|
||||
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
|
||||
ctl.irq != dev->irq)
|
||||
return -EINVAL;
|
||||
return drm_irq_install( dev );
|
||||
return drm_irq_install(dev);
|
||||
case DRM_UNINST_HANDLER:
|
||||
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
||||
return 0;
|
||||
return drm_irq_uninstall( dev );
|
||||
return drm_irq_uninstall(dev);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -230,7 +229,7 @@ int drm_control( struct inode *inode, struct file *filp,
|
|||
* \param data user argument, pointing to a drm_wait_vblank structure.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Verifies the IRQ is installed.
|
||||
* Verifies the IRQ is installed.
|
||||
*
|
||||
* If a signal is requested checks if this task has already scheduled the same signal
|
||||
* for the same vblank sequence number - nothing to be done in
|
||||
|
@ -240,7 +239,7 @@ int drm_control( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* If a signal is not requested, then calls vblank_wait().
|
||||
*/
|
||||
int drm_wait_vblank( DRM_IOCTL_ARGS )
|
||||
int drm_wait_vblank(DRM_IOCTL_ARGS)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -256,11 +255,11 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
|
|||
if (!dev->irq)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
|
||||
DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait));
|
||||
|
||||
switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
|
||||
switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) {
|
||||
case _DRM_VBLANK_RELATIVE:
|
||||
vblwait.request.sequence += atomic_read( &dev->vbl_received );
|
||||
vblwait.request.sequence += atomic_read(&dev->vbl_received);
|
||||
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
|
||||
case _DRM_VBLANK_ABSOLUTE:
|
||||
break;
|
||||
|
@ -269,64 +268,68 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
|
|||
}
|
||||
|
||||
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
|
||||
|
||||
if ( flags & _DRM_VBLANK_SIGNAL ) {
|
||||
|
||||
if (flags & _DRM_VBLANK_SIGNAL) {
|
||||
unsigned long irqflags;
|
||||
drm_vbl_sig_t *vbl_sig;
|
||||
|
||||
vblwait.reply.sequence = atomic_read( &dev->vbl_received );
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, irqflags );
|
||||
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
|
||||
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
|
||||
/* Check if this task has already scheduled the same signal
|
||||
* for the same vblank sequence number; nothing to be done in
|
||||
* that case
|
||||
*/
|
||||
list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
|
||||
list_for_each_entry(vbl_sig, &dev->vbl_sigs.head, head) {
|
||||
if (vbl_sig->sequence == vblwait.request.sequence
|
||||
&& vbl_sig->info.si_signo == vblwait.request.signal
|
||||
&& vbl_sig->task == current)
|
||||
{
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
&& vbl_sig->task == current) {
|
||||
spin_unlock_irqrestore(&dev->vbl_lock,
|
||||
irqflags);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dev->vbl_pending >= 100 ) {
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
if (dev->vbl_pending >= 100) {
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dev->vbl_pending++;
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
|
||||
if ( !( vbl_sig = drm_alloc( sizeof( drm_vbl_sig_t ), DRM_MEM_DRIVER ) ) ) {
|
||||
if (!
|
||||
(vbl_sig =
|
||||
drm_alloc(sizeof(drm_vbl_sig_t), DRM_MEM_DRIVER))) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
|
||||
memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
|
||||
|
||||
vbl_sig->sequence = vblwait.request.sequence;
|
||||
vbl_sig->info.si_signo = vblwait.request.signal;
|
||||
vbl_sig->task = current;
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, irqflags );
|
||||
spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
||||
|
||||
list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
|
||||
list_add_tail((struct list_head *)vbl_sig, &dev->vbl_sigs.head);
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
||||
} else {
|
||||
if (dev->driver->vblank_wait)
|
||||
ret = dev->driver->vblank_wait( dev, &vblwait.request.sequence );
|
||||
ret =
|
||||
dev->driver->vblank_wait(dev,
|
||||
&vblwait.request.sequence);
|
||||
|
||||
do_gettimeofday( &now );
|
||||
do_gettimeofday(&now);
|
||||
vblwait.reply.tval_sec = now.tv_sec;
|
||||
vblwait.reply.tval_usec = now.tv_usec;
|
||||
}
|
||||
|
||||
done:
|
||||
DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
|
||||
done:
|
||||
DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -340,31 +343,31 @@ int drm_wait_vblank( DRM_IOCTL_ARGS )
|
|||
*
|
||||
* If a signal is not requested, then calls vblank_wait().
|
||||
*/
|
||||
void drm_vbl_send_signals( drm_device_t *dev )
|
||||
void drm_vbl_send_signals(drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list, *tmp;
|
||||
drm_vbl_sig_t *vbl_sig;
|
||||
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
|
||||
unsigned int vbl_seq = atomic_read(&dev->vbl_received);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave( &dev->vbl_lock, flags );
|
||||
spin_lock_irqsave(&dev->vbl_lock, flags);
|
||||
|
||||
list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
|
||||
vbl_sig = list_entry( list, drm_vbl_sig_t, head );
|
||||
if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
|
||||
list_for_each_safe(list, tmp, &dev->vbl_sigs.head) {
|
||||
vbl_sig = list_entry(list, drm_vbl_sig_t, head);
|
||||
if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
|
||||
vbl_sig->info.si_code = vbl_seq;
|
||||
send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
|
||||
send_sig_info(vbl_sig->info.si_signo, &vbl_sig->info,
|
||||
vbl_sig->task);
|
||||
|
||||
list_del( list );
|
||||
list_del(list);
|
||||
|
||||
drm_free( vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER );
|
||||
drm_free(vbl_sig, sizeof(*vbl_sig), DRM_MEM_DRIVER);
|
||||
|
||||
dev->vbl_pending--;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore( &dev->vbl_lock, flags );
|
||||
spin_unlock_irqrestore(&dev->vbl_lock, flags);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_vbl_send_signals);
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm_lock.h
|
||||
* \file drm_lock.c
|
||||
* IOCTLs for locking
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
@ -35,12 +35,12 @@
|
|||
|
||||
#include "drmP.h"
|
||||
|
||||
static int drm_lock_transfer(drm_device_t *dev,
|
||||
static int drm_lock_transfer(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock,
|
||||
unsigned int context);
|
||||
static int drm_notifier(void *priv);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Lock ioctl.
|
||||
*
|
||||
* \param inode device inode.
|
||||
|
@ -51,91 +51,89 @@ static int drm_notifier(void *priv);
|
|||
*
|
||||
* Add the current task to the lock wait queue, and attempt to take to lock.
|
||||
*/
|
||||
int drm_lock( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_lock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
DECLARE_WAITQUEUE( entry, current );
|
||||
drm_lock_t lock;
|
||||
int ret = 0;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
drm_lock_t lock;
|
||||
int ret = 0;
|
||||
|
||||
++priv->lock_count;
|
||||
|
||||
if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
|
||||
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if ( lock.context == DRM_KERNEL_CONTEXT ) {
|
||||
DRM_ERROR( "Process %d using kernel context %d\n",
|
||||
current->pid, lock.context );
|
||||
return -EINVAL;
|
||||
}
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid,
|
||||
dev->lock.hw_lock->lock, lock.flags );
|
||||
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
|
||||
lock.context, current->pid,
|
||||
dev->lock.hw_lock->lock, lock.flags);
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
|
||||
if ( lock.context < 0 )
|
||||
if (lock.context < 0)
|
||||
return -EINVAL;
|
||||
|
||||
add_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
add_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
for (;;) {
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
if ( !dev->lock.hw_lock ) {
|
||||
if (!dev->lock.hw_lock) {
|
||||
/* Device has been unregistered */
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
if ( drm_lock_take( &dev->lock.hw_lock->lock,
|
||||
lock.context ) ) {
|
||||
dev->lock.filp = filp;
|
||||
if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
|
||||
dev->lock.filp = filp;
|
||||
dev->lock.lock_time = jiffies;
|
||||
atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
|
||||
break; /* Got lock */
|
||||
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
|
||||
break; /* Got lock */
|
||||
}
|
||||
|
||||
|
||||
/* Contention */
|
||||
schedule();
|
||||
if ( signal_pending( current ) ) {
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue( &dev->lock.lock_queue, &entry );
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
|
||||
sigemptyset( &dev->sigmask );
|
||||
sigaddset( &dev->sigmask, SIGSTOP );
|
||||
sigaddset( &dev->sigmask, SIGTSTP );
|
||||
sigaddset( &dev->sigmask, SIGTTIN );
|
||||
sigaddset( &dev->sigmask, SIGTTOU );
|
||||
sigemptyset(&dev->sigmask);
|
||||
sigaddset(&dev->sigmask, SIGSTOP);
|
||||
sigaddset(&dev->sigmask, SIGTSTP);
|
||||
sigaddset(&dev->sigmask, SIGTTIN);
|
||||
sigaddset(&dev->sigmask, SIGTTOU);
|
||||
dev->sigdata.context = lock.context;
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals( drm_notifier,
|
||||
&dev->sigdata, &dev->sigmask );
|
||||
|
||||
dev->sigdata.lock = dev->lock.hw_lock;
|
||||
block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
|
||||
|
||||
if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
|
||||
dev->driver->dma_ready(dev);
|
||||
|
||||
if ( dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT ))
|
||||
|
||||
if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
|
||||
return dev->driver->dma_quiescent(dev);
|
||||
|
||||
/* dev->driver->kernel_context_switch isn't used by any of the x86
|
||||
|
||||
/* dev->driver->kernel_context_switch isn't used by any of the x86
|
||||
* drivers but is used by the Sparc driver.
|
||||
*/
|
||||
|
||||
if (dev->driver->kernel_context_switch &&
|
||||
dev->last_context != lock.context) {
|
||||
dev->driver->kernel_context_switch(dev, dev->last_context,
|
||||
lock.context);
|
||||
}
|
||||
DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
|
||||
|
||||
return ret;
|
||||
if (dev->driver->kernel_context_switch &&
|
||||
dev->last_context != lock.context) {
|
||||
dev->driver->kernel_context_switch(dev, dev->last_context,
|
||||
lock.context);
|
||||
}
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Unlock ioctl.
|
||||
*
|
||||
* \param inode device inode.
|
||||
|
@ -146,23 +144,23 @@ int drm_lock( struct inode *inode, struct file *filp,
|
|||
*
|
||||
* Transfer and free the lock.
|
||||
*/
|
||||
int drm_unlock( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_unlock(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_lock_t lock;
|
||||
|
||||
if ( copy_from_user( &lock, (drm_lock_t __user *)arg, sizeof(lock) ) )
|
||||
if (copy_from_user(&lock, (drm_lock_t __user *) arg, sizeof(lock)))
|
||||
return -EFAULT;
|
||||
|
||||
if ( lock.context == DRM_KERNEL_CONTEXT ) {
|
||||
DRM_ERROR( "Process %d using kernel context %d\n",
|
||||
current->pid, lock.context );
|
||||
if (lock.context == DRM_KERNEL_CONTEXT) {
|
||||
DRM_ERROR("Process %d using kernel context %d\n",
|
||||
current->pid, lock.context);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
|
||||
atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
|
||||
|
||||
/* kernel_context_switch isn't used by any of the x86 drm
|
||||
* modules but is required by the Sparc driver.
|
||||
|
@ -170,12 +168,12 @@ int drm_unlock( struct inode *inode, struct file *filp,
|
|||
if (dev->driver->kernel_context_switch_unlock)
|
||||
dev->driver->kernel_context_switch_unlock(dev, &lock);
|
||||
else {
|
||||
drm_lock_transfer( dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT );
|
||||
|
||||
if ( drm_lock_free( dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT ) ) {
|
||||
DRM_ERROR( "\n" );
|
||||
drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT);
|
||||
|
||||
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
|
||||
DRM_KERNEL_CONTEXT)) {
|
||||
DRM_ERROR("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,8 +196,10 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
|||
|
||||
do {
|
||||
old = *lock;
|
||||
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
|
||||
else new = context | _DRM_LOCK_HELD;
|
||||
if (old & _DRM_LOCK_HELD)
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
else
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
if (_DRM_LOCKING_CONTEXT(old) == context) {
|
||||
|
@ -212,7 +212,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
|||
}
|
||||
}
|
||||
if (new == (context | _DRM_LOCK_HELD)) {
|
||||
/* Have lock */
|
||||
/* Have lock */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -220,8 +220,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
|||
|
||||
/**
|
||||
* This takes a lock forcibly and hands it to context. Should ONLY be used
|
||||
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
|
||||
*
|
||||
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param lock lock pointer.
|
||||
* \param context locking context.
|
||||
|
@ -230,7 +230,7 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
|
|||
* Resets the lock file pointer.
|
||||
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
|
||||
*/
|
||||
static int drm_lock_transfer(drm_device_t *dev,
|
||||
static int drm_lock_transfer(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock,
|
||||
unsigned int context)
|
||||
{
|
||||
|
@ -238,8 +238,8 @@ static int drm_lock_transfer(drm_device_t *dev,
|
|||
|
||||
dev->lock.filp = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
old = *lock;
|
||||
new = context | _DRM_LOCK_HELD;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
return 1;
|
||||
|
@ -247,30 +247,29 @@ static int drm_lock_transfer(drm_device_t *dev,
|
|||
|
||||
/**
|
||||
* Free lock.
|
||||
*
|
||||
*
|
||||
* \param dev DRM device.
|
||||
* \param lock lock.
|
||||
* \param context context.
|
||||
*
|
||||
*
|
||||
* Resets the lock file pointer.
|
||||
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
|
||||
* waiting on the lock queue.
|
||||
*/
|
||||
int drm_lock_free(drm_device_t *dev,
|
||||
__volatile__ unsigned int *lock, unsigned int context)
|
||||
int drm_lock_free(drm_device_t * dev,
|
||||
__volatile__ unsigned int *lock, unsigned int context)
|
||||
{
|
||||
unsigned int old, new, prev;
|
||||
|
||||
dev->lock.filp = NULL;
|
||||
do {
|
||||
old = *lock;
|
||||
new = 0;
|
||||
old = *lock;
|
||||
new = 0;
|
||||
prev = cmpxchg(lock, old, new);
|
||||
} while (prev != old);
|
||||
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
|
||||
DRM_ERROR("%d freed heavyweight lock held by %d\n",
|
||||
context,
|
||||
_DRM_LOCKING_CONTEXT(old));
|
||||
context, _DRM_LOCKING_CONTEXT(old));
|
||||
return 1;
|
||||
}
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
|
@ -290,19 +289,19 @@ int drm_lock_free(drm_device_t *dev,
|
|||
*/
|
||||
static int drm_notifier(void *priv)
|
||||
{
|
||||
drm_sigdata_t *s = (drm_sigdata_t *)priv;
|
||||
unsigned int old, new, prev;
|
||||
drm_sigdata_t *s = (drm_sigdata_t *) priv;
|
||||
unsigned int old, new, prev;
|
||||
|
||||
|
||||
/* Allow signal delivery if lock isn't held */
|
||||
/* Allow signal delivery if lock isn't held */
|
||||
if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
|
||||
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
|
||||
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context)
|
||||
return 1;
|
||||
|
||||
/* Otherwise, set flag to force call to
|
||||
drmUnlock */
|
||||
/* Otherwise, set flag to force call to
|
||||
drmUnlock */
|
||||
do {
|
||||
old = s->lock->lock;
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
old = s->lock->lock;
|
||||
new = old | _DRM_LOCK_CONT;
|
||||
prev = cmpxchg(&s->lock->lock, old, new);
|
||||
} while (prev != old);
|
||||
return 0;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* \file drm_memory.h
|
||||
/**
|
||||
* \file drm_memory.c
|
||||
* Memory management wrappers for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
|
@ -48,7 +48,7 @@ void drm_mem_init(void)
|
|||
|
||||
/**
|
||||
* Called when "/proc/dri/%dev%/mem" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -57,10 +57,10 @@ void drm_mem_init(void)
|
|||
* \param data private data.
|
||||
* \return number of written bytes.
|
||||
*
|
||||
* No-op.
|
||||
* No-op.
|
||||
*/
|
||||
int drm_mem_info(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
|||
{
|
||||
void *pt;
|
||||
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
|
||||
if (!(pt = kmalloc(size, GFP_KERNEL)))
|
||||
return NULL;
|
||||
if (oldpt && oldsize) {
|
||||
memcpy(pt, oldpt, oldsize);
|
||||
kfree(oldpt);
|
||||
|
@ -90,21 +91,20 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
|
|||
unsigned long drm_alloc_pages(int order, int area)
|
||||
{
|
||||
unsigned long address;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
address = __get_free_pages(GFP_KERNEL, order);
|
||||
if (!address)
|
||||
if (!address)
|
||||
return 0;
|
||||
|
||||
/* Zero */
|
||||
/* Zero */
|
||||
memset((void *)address, 0, bytes);
|
||||
|
||||
/* Reserve */
|
||||
/* Reserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
SetPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ unsigned long drm_alloc_pages(int order, int area)
|
|||
|
||||
/**
|
||||
* Free pages.
|
||||
*
|
||||
*
|
||||
* \param address address of the pages to free.
|
||||
* \param order size order.
|
||||
* \param area memory area. (Not used.)
|
||||
|
@ -124,49 +124,51 @@ void drm_free_pages(unsigned long address, int order, int area)
|
|||
{
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
if (!address)
|
||||
if (!address)
|
||||
return;
|
||||
|
||||
/* Unreserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
free_pages(address, order);
|
||||
}
|
||||
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
/** Wrapper around agp_allocate_memory() */
|
||||
DRM_AGP_MEM *drm_alloc_agp(drm_device_t *dev, int pages, u32 type)
|
||||
DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
|
||||
{
|
||||
return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_alloc_agp);
|
||||
|
||||
/** Wrapper around agp_free_memory() */
|
||||
int drm_free_agp(DRM_AGP_MEM *handle, int pages)
|
||||
int drm_free_agp(DRM_AGP_MEM * handle, int pages)
|
||||
{
|
||||
return drm_agp_free_memory(handle) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_free_agp);
|
||||
|
||||
/** Wrapper around agp_bind_memory() */
|
||||
int drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start)
|
||||
int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
|
||||
{
|
||||
return drm_agp_bind_memory(handle, start);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_bind_agp);
|
||||
|
||||
/** Wrapper around agp_unbind_memory() */
|
||||
int drm_unbind_agp(DRM_AGP_MEM *handle)
|
||||
int drm_unbind_agp(DRM_AGP_MEM * handle)
|
||||
{
|
||||
return drm_agp_unbind_memory(handle);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_unbind_agp);
|
||||
#endif /* agp */
|
||||
#endif /* debug_memory */
|
||||
#endif /* agp */
|
||||
#endif /* debug_memory */
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/**
|
||||
* \file drm_memory.h
|
||||
/**
|
||||
* \file drm_memory.h
|
||||
* Memory management wrappers for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
|
||||
*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
/**
|
||||
* Cut down version of drm_memory_debug.h, which used to be called
|
||||
* drm_memory.h.
|
||||
* drm_memory.h.
|
||||
*/
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
|
@ -60,8 +60,8 @@
|
|||
/*
|
||||
* Find the drm_map that covers the range [offset, offset+size).
|
||||
*/
|
||||
static inline drm_map_t *
|
||||
drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
|
@ -72,16 +72,18 @@ drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
|
|||
map = r_list->map;
|
||||
if (!map)
|
||||
continue;
|
||||
if (map->offset <= offset && (offset + size) <= (map->offset + map->size))
|
||||
if (map->offset <= offset
|
||||
&& (offset + size) <= (map->offset + map->size))
|
||||
return map;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE;
|
||||
unsigned long *phys_addr_map, i, num_pages =
|
||||
PAGE_ALIGN(size) / PAGE_SIZE;
|
||||
struct drm_agp_mem *agpmem;
|
||||
struct page **page_map;
|
||||
void *addr;
|
||||
|
@ -94,7 +96,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
|||
|
||||
for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
|
||||
if (agpmem->bound <= offset
|
||||
&& (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size))
|
||||
&& (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
|
||||
(offset + size))
|
||||
break;
|
||||
if (!agpmem)
|
||||
return NULL;
|
||||
|
@ -109,7 +112,8 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
|||
if (!page_map)
|
||||
return NULL;
|
||||
|
||||
phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
|
||||
phys_addr_map =
|
||||
agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
|
||||
for (i = 0; i < num_pages; ++i)
|
||||
page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
|
||||
addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
|
||||
|
@ -118,36 +122,38 @@ agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
|
|||
return addr;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
drm_follow_page (void *vaddr)
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
|
||||
pud_t *pud = pud_offset(pgd, (unsigned long) vaddr);
|
||||
pmd_t *pmd = pmd_offset(pud, (unsigned long) vaddr);
|
||||
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
|
||||
pgd_t *pgd = pgd_offset_k((unsigned long)vaddr);
|
||||
pud_t *pud = pud_offset(pgd, (unsigned long)vaddr);
|
||||
pmd_t *pmd = pmd_offset(pud, (unsigned long)vaddr);
|
||||
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long)vaddr);
|
||||
return pte_pfn(*ptep) << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#else /* __OS_HAS_AGP */
|
||||
#else /* __OS_HAS_AGP */
|
||||
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline drm_map_t *drm_lookup_map(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *agp_remap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline unsigned long drm_follow_page (void *vaddr)
|
||||
static inline unsigned long drm_follow_page(void *vaddr)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
static inline void *drm_ioremap(unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
|
@ -158,8 +164,8 @@ static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_de
|
|||
return ioremap(offset, size);
|
||||
}
|
||||
|
||||
static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
|
||||
drm_device_t *dev)
|
||||
static inline void *drm_ioremap_nocache(unsigned long offset,
|
||||
unsigned long size, drm_device_t * dev)
|
||||
{
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
|
||||
drm_map_t *map = drm_lookup_map(offset, size, dev);
|
||||
|
@ -170,7 +176,8 @@ static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size
|
|||
return ioremap_nocache(offset, size);
|
||||
}
|
||||
|
||||
static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
|
||||
static inline void drm_ioremapfree(void *pt, unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
/*
|
||||
* This is a bit ugly. It would be much cleaner if the DRM API would use separate
|
||||
|
@ -178,12 +185,12 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
|
|||
* a future revision of the interface...
|
||||
*/
|
||||
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
|
||||
&& ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END))
|
||||
{
|
||||
&& ((unsigned long)pt >= VMALLOC_START
|
||||
&& (unsigned long)pt < VMALLOC_END)) {
|
||||
unsigned long offset;
|
||||
drm_map_t *map;
|
||||
|
||||
offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK);
|
||||
offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK);
|
||||
map = drm_lookup_map(offset, size, dev);
|
||||
if (map && map->type == _DRM_AGP) {
|
||||
vunmap(pt);
|
||||
|
@ -193,5 +200,3 @@ static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *d
|
|||
|
||||
iounmap(pt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_memory.h
|
||||
* \file drm_memory.h
|
||||
* Memory management wrappers for DRM.
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -35,75 +35,75 @@
|
|||
#include "drmP.h"
|
||||
|
||||
typedef struct drm_mem_stats {
|
||||
const char *name;
|
||||
int succeed_count;
|
||||
int free_count;
|
||||
int fail_count;
|
||||
unsigned long bytes_allocated;
|
||||
unsigned long bytes_freed;
|
||||
const char *name;
|
||||
int succeed_count;
|
||||
int free_count;
|
||||
int fail_count;
|
||||
unsigned long bytes_allocated;
|
||||
unsigned long bytes_freed;
|
||||
} drm_mem_stats_t;
|
||||
|
||||
static DEFINE_SPINLOCK(DRM(mem_lock));
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] = {
|
||||
[DRM_MEM_DMA] = { "dmabufs" },
|
||||
[DRM_MEM_SAREA] = { "sareas" },
|
||||
[DRM_MEM_DRIVER] = { "driver" },
|
||||
[DRM_MEM_MAGIC] = { "magic" },
|
||||
[DRM_MEM_IOCTLS] = { "ioctltab" },
|
||||
[DRM_MEM_MAPS] = { "maplist" },
|
||||
[DRM_MEM_VMAS] = { "vmalist" },
|
||||
[DRM_MEM_BUFS] = { "buflist" },
|
||||
[DRM_MEM_SEGS] = { "seglist" },
|
||||
[DRM_MEM_PAGES] = { "pagelist" },
|
||||
[DRM_MEM_FILES] = { "files" },
|
||||
[DRM_MEM_QUEUES] = { "queues" },
|
||||
[DRM_MEM_CMDS] = { "commands" },
|
||||
[DRM_MEM_MAPPINGS] = { "mappings" },
|
||||
[DRM_MEM_BUFLISTS] = { "buflists" },
|
||||
[DRM_MEM_AGPLISTS] = { "agplist" },
|
||||
[DRM_MEM_SGLISTS] = { "sglist" },
|
||||
[DRM_MEM_TOTALAGP] = { "totalagp" },
|
||||
[DRM_MEM_BOUNDAGP] = { "boundagp" },
|
||||
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
|
||||
[DRM_MEM_CTXLIST] = { "ctxlist" },
|
||||
[DRM_MEM_STUB] = { "stub" },
|
||||
{ NULL, 0, } /* Last entry must be null */
|
||||
static unsigned long DRM(ram_available) = 0; /* In pages */
|
||||
static unsigned long DRM(ram_used) = 0;
|
||||
static drm_mem_stats_t DRM(mem_stats)[] =
|
||||
{
|
||||
[DRM_MEM_DMA] = {
|
||||
"dmabufs"},[DRM_MEM_SAREA] = {
|
||||
"sareas"},[DRM_MEM_DRIVER] = {
|
||||
"driver"},[DRM_MEM_MAGIC] = {
|
||||
"magic"},[DRM_MEM_IOCTLS] = {
|
||||
"ioctltab"},[DRM_MEM_MAPS] = {
|
||||
"maplist"},[DRM_MEM_VMAS] = {
|
||||
"vmalist"},[DRM_MEM_BUFS] = {
|
||||
"buflist"},[DRM_MEM_SEGS] = {
|
||||
"seglist"},[DRM_MEM_PAGES] = {
|
||||
"pagelist"},[DRM_MEM_FILES] = {
|
||||
"files"},[DRM_MEM_QUEUES] = {
|
||||
"queues"},[DRM_MEM_CMDS] = {
|
||||
"commands"},[DRM_MEM_MAPPINGS] = {
|
||||
"mappings"},[DRM_MEM_BUFLISTS] = {
|
||||
"buflists"},[DRM_MEM_AGPLISTS] = {
|
||||
"agplist"},[DRM_MEM_SGLISTS] = {
|
||||
"sglist"},[DRM_MEM_TOTALAGP] = {
|
||||
"totalagp"},[DRM_MEM_BOUNDAGP] = {
|
||||
"boundagp"},[DRM_MEM_CTXBITMAP] = {
|
||||
"ctxbitmap"},[DRM_MEM_CTXLIST] = {
|
||||
"ctxlist"},[DRM_MEM_STUB] = {
|
||||
"stub"}, {
|
||||
NULL, 0,} /* Last entry must be null */
|
||||
};
|
||||
|
||||
void DRM(mem_init)(void)
|
||||
{
|
||||
void DRM(mem_init) (void) {
|
||||
drm_mem_stats_t *mem;
|
||||
struct sysinfo si;
|
||||
struct sysinfo si;
|
||||
|
||||
for (mem = DRM(mem_stats); mem->name; ++mem) {
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
mem->succeed_count = 0;
|
||||
mem->free_count = 0;
|
||||
mem->fail_count = 0;
|
||||
mem->bytes_allocated = 0;
|
||||
mem->bytes_freed = 0;
|
||||
mem->bytes_freed = 0;
|
||||
}
|
||||
|
||||
si_meminfo(&si);
|
||||
DRM(ram_available) = si.totalram;
|
||||
DRM(ram_used) = 0;
|
||||
DRM(ram_used) = 0;
|
||||
}
|
||||
|
||||
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
|
||||
|
||||
static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
static int DRM(_mem_info) (char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data) {
|
||||
drm_mem_stats_t *pt;
|
||||
int len = 0;
|
||||
int len = 0;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
*start = &buf[offset];
|
||||
|
||||
DRM_PROC_PRINT(" total counts "
|
||||
|
@ -129,24 +129,23 @@ static int DRM(_mem_info)(char *buf, char **start, off_t offset,
|
|||
- (long)pt->bytes_freed);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
int DRM(mem_info)(char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data)
|
||||
{
|
||||
int DRM(mem_info) (char *buf, char **start, off_t offset,
|
||||
int len, int *eof, void *data) {
|
||||
int ret;
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
|
||||
ret = DRM(_mem_info) (buf, start, offset, len, eof, data);
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *DRM(alloc)(size_t size, int area)
|
||||
{
|
||||
void *DRM(alloc) (size_t size, int area) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
|
@ -167,40 +166,40 @@ void *DRM(alloc)(size_t size, int area)
|
|||
return pt;
|
||||
}
|
||||
|
||||
void *DRM(calloc)(size_t nmemb, size_t size, int area)
|
||||
{
|
||||
void *DRM(calloc) (size_t nmemb, size_t size, int area) {
|
||||
void *addr;
|
||||
|
||||
addr = DRM(alloc)(nmemb * size, area);
|
||||
addr = DRM(alloc) (nmemb * size, area);
|
||||
if (addr != NULL)
|
||||
memset((void *)addr, 0, size * nmemb);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
|
||||
{
|
||||
void *DRM(realloc) (void *oldpt, size_t oldsize, size_t size, int area) {
|
||||
void *pt;
|
||||
|
||||
if (!(pt = DRM(alloc)(size, area))) return NULL;
|
||||
if (!(pt = DRM(alloc) (size, area)))
|
||||
return NULL;
|
||||
if (oldpt && oldsize) {
|
||||
memcpy(pt, oldpt, oldsize);
|
||||
DRM(free)(oldpt, oldsize, area);
|
||||
DRM(free) (oldpt, oldsize, area);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
void DRM(free)(void *pt, size_t size, int area)
|
||||
{
|
||||
void DRM(free) (void *pt, size_t size, int area) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
|
||||
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else kfree(pt);
|
||||
if (!pt)
|
||||
DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
|
||||
else
|
||||
kfree(pt);
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[area].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
|
||||
|
@ -208,12 +207,11 @@ void DRM(free)(void *pt, size_t size, int area)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned long DRM(alloc_pages)(int order, int area)
|
||||
{
|
||||
unsigned long DRM(alloc_pages) (int order, int area) {
|
||||
unsigned long address;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
if ((DRM(ram_used) >> PAGE_SHIFT)
|
||||
|
@ -233,48 +231,44 @@ unsigned long DRM(alloc_pages)(int order, int area)
|
|||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_allocated += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
DRM(ram_used) += bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
|
||||
|
||||
/* Zero outside the lock */
|
||||
/* Zero outside the lock */
|
||||
memset((void *)address, 0, bytes);
|
||||
|
||||
/* Reserve */
|
||||
/* Reserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
SetPageReserved(virt_to_page(addr));
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void DRM(free_pages)(unsigned long address, int order, int area)
|
||||
{
|
||||
void DRM(free_pages) (unsigned long address, int order, int area) {
|
||||
unsigned long bytes = PAGE_SIZE << order;
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
unsigned long addr;
|
||||
unsigned int sz;
|
||||
unsigned int sz;
|
||||
|
||||
if (!address) {
|
||||
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
|
||||
} else {
|
||||
/* Unreserve */
|
||||
/* Unreserve */
|
||||
for (addr = address, sz = bytes;
|
||||
sz > 0;
|
||||
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
}
|
||||
free_pages(address, order);
|
||||
}
|
||||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[area].free_count;
|
||||
alloc_count = DRM(mem_stats)[area].succeed_count;
|
||||
DRM(mem_stats)[area].bytes_freed += bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
DRM(ram_used) -= bytes;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(area,
|
||||
|
@ -283,8 +277,8 @@ void DRM(free_pages)(unsigned long address, int order, int area)
|
|||
}
|
||||
}
|
||||
|
||||
void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void *DRM(ioremap) (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
|
@ -306,8 +300,8 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
|||
return pt;
|
||||
}
|
||||
|
||||
void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void *DRM(ioremap_nocache) (unsigned long offset, unsigned long size,
|
||||
drm_device_t * dev) {
|
||||
void *pt;
|
||||
|
||||
if (!size) {
|
||||
|
@ -329,8 +323,7 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_
|
|||
return pt;
|
||||
}
|
||||
|
||||
void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
||||
{
|
||||
void DRM(ioremapfree) (void *pt, unsigned long size, drm_device_t * dev) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
|
||||
|
@ -342,8 +335,8 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
|||
|
||||
spin_lock(&DRM(mem_lock));
|
||||
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
|
||||
|
@ -354,8 +347,7 @@ void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
|
|||
|
||||
#if __OS_HAS_AGP
|
||||
|
||||
DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
||||
{
|
||||
DRM_AGP_MEM *DRM(alloc_agp) (int pages, u32 type) {
|
||||
DRM_AGP_MEM *handle;
|
||||
|
||||
if (!pages) {
|
||||
|
@ -363,11 +355,11 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((handle = DRM(agp_allocate_memory)(pages, type))) {
|
||||
if ((handle = DRM(agp_allocate_memory) (pages, type))) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
|
||||
+= pages << PAGE_SHIFT;
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return handle;
|
||||
}
|
||||
|
@ -377,11 +369,10 @@ DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
||||
{
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retval = -EINVAL;
|
||||
int DRM(free_agp) (DRM_AGP_MEM * handle, int pages) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (!handle) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
|
@ -389,12 +380,12 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
|||
return retval;
|
||||
}
|
||||
|
||||
if (DRM(agp_free_memory)(handle)) {
|
||||
if (DRM(agp_free_memory) (handle)) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
|
||||
+= pages << PAGE_SHIFT;
|
||||
+= pages << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
|
||||
|
@ -406,8 +397,7 @@ int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
||||
{
|
||||
int DRM(bind_agp) (DRM_AGP_MEM * handle, unsigned int start) {
|
||||
int retcode = -EINVAL;
|
||||
|
||||
if (!handle) {
|
||||
|
@ -416,11 +406,11 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
|
||||
if (!(retcode = DRM(agp_bind_memory) (handle, start))) {
|
||||
spin_lock(&DRM(mem_lock));
|
||||
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
return retcode;
|
||||
}
|
||||
|
@ -430,8 +420,7 @@ int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
int DRM(unbind_agp)(DRM_AGP_MEM *handle)
|
||||
{
|
||||
int DRM(unbind_agp) (DRM_AGP_MEM * handle) {
|
||||
int alloc_count;
|
||||
int free_count;
|
||||
int retcode = -EINVAL;
|
||||
|
@ -442,12 +431,13 @@ int DRM(unbind_agp)(DRM_AGP_MEM *handle)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
|
||||
if ((retcode = DRM(agp_unbind_memory) (handle)))
|
||||
return retcode;
|
||||
spin_lock(&DRM(mem_lock));
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
|
||||
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
|
||||
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
+= handle->page_count << PAGE_SHIFT;
|
||||
spin_unlock(&DRM(mem_lock));
|
||||
if (free_count > alloc_count) {
|
||||
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* OS abstraction macros.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
@ -47,25 +46,25 @@
|
|||
#else
|
||||
/* define some dummy types for non AGP supporting kernels */
|
||||
struct no_agp_kern {
|
||||
unsigned long aper_base;
|
||||
unsigned long aper_size;
|
||||
unsigned long aper_base;
|
||||
unsigned long aper_size;
|
||||
};
|
||||
#define DRM_AGP_MEM int
|
||||
#define DRM_AGP_KERN struct no_agp_kern
|
||||
#endif
|
||||
|
||||
#if !(__OS_HAS_MTRR)
|
||||
static __inline__ int mtrr_add (unsigned long base, unsigned long size,
|
||||
unsigned int type, char increment)
|
||||
static __inline__ int mtrr_add(unsigned long base, unsigned long size,
|
||||
unsigned int type, char increment)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static __inline__ int mtrr_del (int reg, unsigned long base,
|
||||
unsigned long size)
|
||||
static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
|
||||
#endif
|
||||
|
@ -99,7 +98,7 @@ static __inline__ int mtrr_del (int reg, unsigned long base,
|
|||
|
||||
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
|
||||
|
||||
/**
|
||||
/**
|
||||
* Get the pointer to the SAREA.
|
||||
*
|
||||
* Searches the SAREA on the mapping lists and points drm_device::sarea to it.
|
||||
|
@ -143,7 +142,5 @@ do { \
|
|||
remove_wait_queue(&(queue), &entry); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
|
||||
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
|||
dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
|
||||
if (!dmah)
|
||||
return NULL;
|
||||
|
||||
|
||||
dmah->size = size;
|
||||
dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr);
|
||||
|
||||
|
@ -106,6 +106,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
|
|||
|
||||
return dmah;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_pci_alloc);
|
||||
|
||||
/**
|
||||
|
@ -113,8 +114,7 @@ EXPORT_SYMBOL(drm_pci_alloc);
|
|||
*
|
||||
* This function is for internal use in the Linux-specific DRM core code.
|
||||
*/
|
||||
void
|
||||
__drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
|
||||
void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
|
||||
{
|
||||
#ifdef DRM_DEBUG_MEMORY
|
||||
int area = DRM_MEM_DMA;
|
||||
|
@ -150,12 +150,12 @@ __drm_pci_free(drm_device_t * dev, drm_dma_handle_t *dmah)
|
|||
/**
|
||||
* \brief Free a PCI consistent memory block
|
||||
*/
|
||||
void
|
||||
drm_pci_free(drm_device_t *dev, drm_dma_handle_t *dmah)
|
||||
void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
|
||||
{
|
||||
__drm_pci_free(dev, dmah);
|
||||
kfree(dmah);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_pci_free);
|
||||
|
||||
/*@}*/
|
||||
|
|
|
@ -234,4 +234,3 @@
|
|||
{0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||
{0, 0, 0}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_proc.h
|
||||
* \file drm_proc.c
|
||||
* /proc support for DRM
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
|
@ -39,19 +39,19 @@
|
|||
|
||||
#include "drmP.h"
|
||||
|
||||
static int drm_name_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_name_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
#if DRM_DEBUG_CODE
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -59,18 +59,21 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
|
|||
*/
|
||||
static struct drm_proc_list {
|
||||
const char *name; /**< file name */
|
||||
int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
|
||||
int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
|
||||
} drm_proc_list[] = {
|
||||
{ "name", drm_name_info },
|
||||
{ "mem", drm_mem_info },
|
||||
{ "vm", drm_vm_info },
|
||||
{ "clients", drm_clients_info },
|
||||
{ "queues", drm_queues_info },
|
||||
{ "bufs", drm_bufs_info },
|
||||
{
|
||||
"name", drm_name_info}, {
|
||||
"mem", drm_mem_info}, {
|
||||
"vm", drm_vm_info}, {
|
||||
"clients", drm_clients_info}, {
|
||||
"queues", drm_queues_info}, {
|
||||
"bufs", drm_bufs_info},
|
||||
#if DRM_DEBUG_CODE
|
||||
{ "vma", drm_vma_info },
|
||||
{
|
||||
"vma", drm_vma_info},
|
||||
#endif
|
||||
};
|
||||
|
||||
#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
|
||||
|
||||
/**
|
||||
|
@ -81,18 +84,17 @@ static struct drm_proc_list {
|
|||
* \param root DRI proc dir entry.
|
||||
* \param dev_root resulting DRI device proc dir entry.
|
||||
* \return root entry pointer on success, or NULL on failure.
|
||||
*
|
||||
*
|
||||
* Create the DRI proc root entry "/proc/dri", the device proc root entry
|
||||
* "/proc/dri/%minor%/", and each entry in proc_list as
|
||||
* "/proc/dri/%minor%/%name%".
|
||||
*/
|
||||
int drm_proc_init(drm_device_t *dev, int minor,
|
||||
struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **dev_root)
|
||||
int drm_proc_init(drm_device_t * dev, int minor,
|
||||
struct proc_dir_entry *root, struct proc_dir_entry **dev_root)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
int i, j;
|
||||
char name[64];
|
||||
int i, j;
|
||||
char name[64];
|
||||
|
||||
sprintf(name, "%d", minor);
|
||||
*dev_root = proc_mkdir(name, root);
|
||||
|
@ -103,7 +105,7 @@ int drm_proc_init(drm_device_t *dev, int minor,
|
|||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
|
||||
ent = create_proc_entry(drm_proc_list[i].name,
|
||||
S_IFREG|S_IRUGO, *dev_root);
|
||||
S_IFREG | S_IRUGO, *dev_root);
|
||||
if (!ent) {
|
||||
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
|
||||
name, drm_proc_list[i].name);
|
||||
|
@ -114,13 +116,12 @@ int drm_proc_init(drm_device_t *dev, int minor,
|
|||
return -1;
|
||||
}
|
||||
ent->read_proc = drm_proc_list[i].f;
|
||||
ent->data = dev;
|
||||
ent->data = dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleanup the proc filesystem resources.
|
||||
*
|
||||
|
@ -132,12 +133,13 @@ int drm_proc_init(drm_device_t *dev, int minor,
|
|||
* Remove all proc entries created by proc_init().
|
||||
*/
|
||||
int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
|
||||
struct proc_dir_entry *dev_root)
|
||||
struct proc_dir_entry *dev_root)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
char name[64];
|
||||
|
||||
if (!root || !dev_root) return 0;
|
||||
if (!root || !dev_root)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < DRM_PROC_ENTRIES; i++)
|
||||
remove_proc_entry(drm_proc_list[i].name, dev_root);
|
||||
|
@ -149,7 +151,7 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
|
|||
|
||||
/**
|
||||
* Called when "/proc/dri/.../name" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -157,14 +159,14 @@ int drm_proc_cleanup(int minor, struct proc_dir_entry *root,
|
|||
* \param eof whether there is no more data to return.
|
||||
* \param data private data.
|
||||
* \return number of written bytes.
|
||||
*
|
||||
*
|
||||
* Prints the device name together with the bus id if available.
|
||||
*/
|
||||
static int drm_name_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
|
@ -172,23 +174,26 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
if (dev->unique) {
|
||||
DRM_PROC_PRINT("%s %s %s\n",
|
||||
dev->driver->pci_driver.name, pci_name(dev->pdev), dev->unique);
|
||||
dev->driver->pci_driver.name,
|
||||
pci_name(dev->pdev), dev->unique);
|
||||
} else {
|
||||
DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, pci_name(dev->pdev));
|
||||
DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
|
||||
pci_name(dev->pdev));
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when "/proc/dri/.../vm" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -196,24 +201,24 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
|
|||
* \param eof whether there is no more data to return.
|
||||
* \param data private data.
|
||||
* \return number of written bytes.
|
||||
*
|
||||
*
|
||||
* Prints information about all mappings in drm_device::maplist.
|
||||
*/
|
||||
static int drm__vm_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_map_t *map;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/* Hardcoded from _DRM_FRAME_BUFFER,
|
||||
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
|
||||
_DRM_SCATTER_GATHER and _DRM_CONSISTENT */
|
||||
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
|
||||
const char *type;
|
||||
int i;
|
||||
/* Hardcoded from _DRM_FRAME_BUFFER,
|
||||
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
|
||||
_DRM_SCATTER_GATHER and _DRM_CONSISTENT */
|
||||
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
|
||||
const char *type;
|
||||
int i;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
|
@ -221,36 +226,35 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
DRM_PROC_PRINT("slot offset size type flags "
|
||||
"address mtrr\n\n");
|
||||
i = 0;
|
||||
if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
|
||||
if (dev->maplist != NULL)
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
map = r_list->map;
|
||||
if(!map)
|
||||
if (!map)
|
||||
continue;
|
||||
if (map->type < 0 || map->type > 5)
|
||||
type = "??";
|
||||
else
|
||||
else
|
||||
type = types[map->type];
|
||||
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08x ",
|
||||
i,
|
||||
map->offset,
|
||||
map->size,
|
||||
type,
|
||||
map->flags,
|
||||
r_list->user_token);
|
||||
map->size, type, map->flags, r_list->user_token);
|
||||
if (map->mtrr < 0) {
|
||||
DRM_PROC_PRINT("none\n");
|
||||
} else {
|
||||
DRM_PROC_PRINT("%4d\n", map->mtrr);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
@ -259,10 +263,10 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
|
|||
* Simply calls _vm_info() while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_vm_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = drm__vm_info(buf, start, offset, request, eof, data);
|
||||
|
@ -272,7 +276,7 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
|
|||
|
||||
/**
|
||||
* Called when "/proc/dri/.../queues" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -282,12 +286,12 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request,
|
|||
* \return number of written bytes.
|
||||
*/
|
||||
static int drm__queues_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
int i;
|
||||
drm_queue_t *q;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
int i;
|
||||
drm_queue_t *q;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
|
@ -295,7 +299,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
DRM_PROC_PRINT(" ctx/flags use fin"
|
||||
" blk/rw/rwf wait flushed queued"
|
||||
|
@ -313,14 +317,17 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
|
|||
atomic_read(&q->block_count),
|
||||
atomic_read(&q->block_read) ? 'r' : '-',
|
||||
atomic_read(&q->block_write) ? 'w' : '-',
|
||||
waitqueue_active(&q->read_queue) ? 'r':'-',
|
||||
waitqueue_active(&q->write_queue) ? 'w':'-',
|
||||
waitqueue_active(&q->flush_queue) ? 'f':'-',
|
||||
waitqueue_active(&q->read_queue) ? 'r' : '-',
|
||||
waitqueue_active(&q->
|
||||
write_queue) ? 'w' : '-',
|
||||
waitqueue_active(&q->
|
||||
flush_queue) ? 'f' : '-',
|
||||
DRM_BUFCOUNT(&q->waitlist));
|
||||
atomic_dec(&q->use_count);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
@ -329,10 +336,10 @@ static int drm__queues_info(char *buf, char **start, off_t offset,
|
|||
* Simply calls _queues_info() while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_queues_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = drm__queues_info(buf, start, offset, request, eof, data);
|
||||
|
@ -342,7 +349,7 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
|
|||
|
||||
/**
|
||||
* Called when "/proc/dri/.../bufs" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -352,12 +359,12 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request,
|
|||
* \return number of written bytes.
|
||||
*/
|
||||
static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if (!dma || offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
|
@ -365,7 +372,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
|
||||
for (i = 0; i <= DRM_MAX_ORDER; i++) {
|
||||
|
@ -378,19 +385,21 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
|
|||
.freelist.count),
|
||||
dma->bufs[i].seg_count,
|
||||
dma->bufs[i].seg_count
|
||||
*(1 << dma->bufs[i].page_order),
|
||||
* (1 << dma->bufs[i].page_order),
|
||||
(dma->bufs[i].seg_count
|
||||
* (1 << dma->bufs[i].page_order))
|
||||
* PAGE_SIZE / 1024);
|
||||
}
|
||||
DRM_PROC_PRINT("\n");
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
if (i && !(i%32)) DRM_PROC_PRINT("\n");
|
||||
if (i && !(i % 32))
|
||||
DRM_PROC_PRINT("\n");
|
||||
DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
|
||||
}
|
||||
DRM_PROC_PRINT("\n");
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
@ -399,10 +408,10 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
|
|||
* Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = drm__bufs_info(buf, start, offset, request, eof, data);
|
||||
|
@ -412,7 +421,7 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
|
|||
|
||||
/**
|
||||
* Called when "/proc/dri/.../clients" is read.
|
||||
*
|
||||
*
|
||||
* \param buf output buffer.
|
||||
* \param start start of output data.
|
||||
* \param offset requested start offset.
|
||||
|
@ -422,11 +431,11 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
|
|||
* \return number of written bytes.
|
||||
*/
|
||||
static int drm__clients_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_file_t *priv;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
drm_file_t *priv;
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
*eof = 1;
|
||||
|
@ -434,7 +443,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
|
||||
for (priv = dev->file_first; priv; priv = priv->next) {
|
||||
|
@ -442,12 +451,11 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
|
|||
priv->authenticated ? 'y' : 'n',
|
||||
priv->minor,
|
||||
priv->pid,
|
||||
priv->uid,
|
||||
priv->magic,
|
||||
priv->ioctl_count);
|
||||
priv->uid, priv->magic, priv->ioctl_count);
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
@ -456,10 +464,10 @@ static int drm__clients_info(char *buf, char **start, off_t offset,
|
|||
* Simply calls _clients_info() while holding the drm_device::struct_sem lock.
|
||||
*/
|
||||
static int drm_clients_info(char *buf, char **start, off_t offset,
|
||||
int request, int *eof, void *data)
|
||||
int request, int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = drm__clients_info(buf, start, offset, request, eof, data);
|
||||
|
@ -470,14 +478,14 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
|
|||
#if DRM_DEBUG_CODE
|
||||
|
||||
static int drm__vma_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int len = 0;
|
||||
drm_vma_entry_t *pt;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int len = 0;
|
||||
drm_vma_entry_t *pt;
|
||||
struct vm_area_struct *vma;
|
||||
#if defined(__i386__)
|
||||
unsigned int pgprot;
|
||||
unsigned int pgprot;
|
||||
#endif
|
||||
|
||||
if (offset > DRM_PROC_LIMIT) {
|
||||
|
@ -486,51 +494,53 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request,
|
|||
}
|
||||
|
||||
*start = &buf[offset];
|
||||
*eof = 0;
|
||||
*eof = 0;
|
||||
|
||||
DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
|
||||
atomic_read(&dev->vma_count),
|
||||
high_memory, virt_to_phys(high_memory));
|
||||
for (pt = dev->vmalist; pt; pt = pt->next) {
|
||||
if (!(vma = pt->vma)) continue;
|
||||
if (!(vma = pt->vma))
|
||||
continue;
|
||||
DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
|
||||
pt->pid,
|
||||
vma->vm_start,
|
||||
vma->vm_end,
|
||||
vma->vm_flags & VM_READ ? 'r' : '-',
|
||||
vma->vm_flags & VM_WRITE ? 'w' : '-',
|
||||
vma->vm_flags & VM_EXEC ? 'x' : '-',
|
||||
vma->vm_flags & VM_READ ? 'r' : '-',
|
||||
vma->vm_flags & VM_WRITE ? 'w' : '-',
|
||||
vma->vm_flags & VM_EXEC ? 'x' : '-',
|
||||
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
|
||||
vma->vm_flags & VM_LOCKED ? 'l' : '-',
|
||||
vma->vm_flags & VM_IO ? 'i' : '-',
|
||||
vma->vm_flags & VM_LOCKED ? 'l' : '-',
|
||||
vma->vm_flags & VM_IO ? 'i' : '-',
|
||||
VM_OFFSET(vma));
|
||||
|
||||
#if defined(__i386__)
|
||||
pgprot = pgprot_val(vma->vm_page_prot);
|
||||
DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
|
||||
pgprot & _PAGE_PRESENT ? 'p' : '-',
|
||||
pgprot & _PAGE_RW ? 'w' : 'r',
|
||||
pgprot & _PAGE_USER ? 'u' : 's',
|
||||
pgprot & _PAGE_PWT ? 't' : 'b',
|
||||
pgprot & _PAGE_PCD ? 'u' : 'c',
|
||||
pgprot & _PAGE_PRESENT ? 'p' : '-',
|
||||
pgprot & _PAGE_RW ? 'w' : 'r',
|
||||
pgprot & _PAGE_USER ? 'u' : 's',
|
||||
pgprot & _PAGE_PWT ? 't' : 'b',
|
||||
pgprot & _PAGE_PCD ? 'u' : 'c',
|
||||
pgprot & _PAGE_ACCESSED ? 'a' : '-',
|
||||
pgprot & _PAGE_DIRTY ? 'd' : '-',
|
||||
pgprot & _PAGE_PSE ? 'm' : 'k',
|
||||
pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
|
||||
pgprot & _PAGE_DIRTY ? 'd' : '-',
|
||||
pgprot & _PAGE_PSE ? 'm' : 'k',
|
||||
pgprot & _PAGE_GLOBAL ? 'g' : 'l');
|
||||
#endif
|
||||
DRM_PROC_PRINT("\n");
|
||||
}
|
||||
|
||||
if (len > request + offset) return request;
|
||||
if (len > request + offset)
|
||||
return request;
|
||||
*eof = 1;
|
||||
return len - offset;
|
||||
}
|
||||
|
||||
static int drm_vma_info(char *buf, char **start, off_t offset, int request,
|
||||
int *eof, void *data)
|
||||
int *eof, void *data)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)data;
|
||||
int ret;
|
||||
drm_device_t *dev = (drm_device_t *) data;
|
||||
int ret;
|
||||
|
||||
down(&dev->struct_sem);
|
||||
ret = drm__vma_info(buf, start, offset, request, eof, data);
|
||||
|
@ -538,5 +548,3 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int request,
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_sarea.h
|
||||
* \file drm_sarea.h
|
||||
* \brief SAREA definitions
|
||||
*
|
||||
* \author Michel Dänzer <michel@daenzer.net>
|
||||
|
@ -38,7 +38,7 @@
|
|||
#if defined(__alpha__)
|
||||
#define SAREA_MAX 0x2000
|
||||
#elif defined(__ia64__)
|
||||
#define SAREA_MAX 0x10000 /* 64kB */
|
||||
#define SAREA_MAX 0x10000 /* 64kB */
|
||||
#else
|
||||
/* Intel 830M driver needs at least 8k SAREA */
|
||||
#define SAREA_MAX 0x2000
|
||||
|
@ -51,28 +51,28 @@
|
|||
|
||||
/** SAREA drawable */
|
||||
typedef struct drm_sarea_drawable {
|
||||
unsigned int stamp;
|
||||
unsigned int flags;
|
||||
unsigned int stamp;
|
||||
unsigned int flags;
|
||||
} drm_sarea_drawable_t;
|
||||
|
||||
/** SAREA frame */
|
||||
typedef struct drm_sarea_frame {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int fullscreen;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int fullscreen;
|
||||
} drm_sarea_frame_t;
|
||||
|
||||
/** SAREA */
|
||||
typedef struct drm_sarea {
|
||||
/** first thing is always the DRM locking structure */
|
||||
drm_hw_lock_t lock;
|
||||
drm_hw_lock_t lock;
|
||||
/** \todo Use readers/writer lock for drm_sarea::drawable_lock */
|
||||
drm_hw_lock_t drawable_lock;
|
||||
drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
|
||||
drm_sarea_frame_t frame; /**< frame */
|
||||
drm_context_t dummy_context;
|
||||
drm_hw_lock_t drawable_lock;
|
||||
drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
|
||||
drm_sarea_frame_t frame; /**< frame */
|
||||
drm_context_t dummy_context;
|
||||
} drm_sarea_t;
|
||||
|
||||
#endif /* _DRM_SAREA_H_ */
|
||||
#endif /* _DRM_SAREA_H_ */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* \file drm_scatter.h
|
||||
* \file drm_scatter.c
|
||||
* IOCTLs to manage scatter/gather memory
|
||||
*
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
|
@ -37,28 +37,24 @@
|
|||
|
||||
#define DEBUG_SCATTER 0
|
||||
|
||||
void drm_sg_cleanup( drm_sg_mem_t *entry )
|
||||
void drm_sg_cleanup(drm_sg_mem_t * entry)
|
||||
{
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < entry->pages ; i++ ) {
|
||||
for (i = 0; i < entry->pages; i++) {
|
||||
page = entry->pagelist[i];
|
||||
if ( page )
|
||||
ClearPageReserved( page );
|
||||
if (page)
|
||||
ClearPageReserved(page);
|
||||
}
|
||||
|
||||
vfree( entry->virtual );
|
||||
vfree(entry->virtual);
|
||||
|
||||
drm_free( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
drm_free(entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
|
||||
drm_free(entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
|
@ -67,8 +63,8 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
|
|||
# define ScatterHandle(x) (unsigned int)(x)
|
||||
#endif
|
||||
|
||||
int drm_sg_alloc( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_sg_alloc(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -77,75 +73,70 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
drm_sg_mem_t *entry;
|
||||
unsigned long pages, i, j;
|
||||
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (!drm_core_check_feature(dev, DRIVER_SG))
|
||||
return -EINVAL;
|
||||
|
||||
if ( dev->sg )
|
||||
if (dev->sg)
|
||||
return -EINVAL;
|
||||
|
||||
if ( copy_from_user( &request, argp, sizeof(request) ) )
|
||||
if (copy_from_user(&request, argp, sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
entry = drm_alloc( sizeof(*entry), DRM_MEM_SGLISTS );
|
||||
if ( !entry )
|
||||
entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
memset( entry, 0, sizeof(*entry) );
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
|
||||
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
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->pagelist = drm_alloc( pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
if ( !entry->pagelist ) {
|
||||
drm_free( entry, sizeof(*entry), DRM_MEM_SGLISTS );
|
||||
entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
if (!entry->pagelist) {
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
|
||||
|
||||
entry->busaddr = drm_alloc( pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
if ( !entry->busaddr ) {
|
||||
drm_free( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES);
|
||||
if (!entry->busaddr) {
|
||||
drm_free(entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
|
||||
memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
|
||||
|
||||
entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
|
||||
if ( !entry->virtual ) {
|
||||
drm_free( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
drm_free( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
entry->virtual = vmalloc_32(pages << PAGE_SHIFT);
|
||||
if (!entry->virtual) {
|
||||
drm_free(entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
|
||||
drm_free(entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES);
|
||||
drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* This also forces the mapping of COW pages, so our page list
|
||||
* will be valid. Please don't remove it...
|
||||
*/
|
||||
memset( entry->virtual, 0, pages << PAGE_SHIFT );
|
||||
memset(entry->virtual, 0, pages << PAGE_SHIFT);
|
||||
|
||||
entry->handle = ScatterHandle((unsigned long)entry->virtual);
|
||||
|
||||
DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
|
||||
DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
|
||||
DRM_DEBUG("sg alloc handle = %08lx\n", entry->handle);
|
||||
DRM_DEBUG("sg alloc virtual = %p\n", entry->virtual);
|
||||
|
||||
for (i = (unsigned long)entry->virtual, j = 0; j < pages;
|
||||
i += PAGE_SIZE, j++) {
|
||||
for (i = (unsigned long)entry->virtual, j = 0; j < pages;
|
||||
i += PAGE_SIZE, j++) {
|
||||
entry->pagelist[j] = vmalloc_to_page((void *)i);
|
||||
if (!entry->pagelist[j])
|
||||
goto failed;
|
||||
|
@ -154,8 +145,8 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
|
||||
request.handle = entry->handle;
|
||||
|
||||
if ( copy_to_user( argp, &request, sizeof(request) ) ) {
|
||||
drm_sg_cleanup( entry );
|
||||
if (copy_to_user(argp, &request, sizeof(request))) {
|
||||
drm_sg_cleanup(entry);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -166,50 +157,50 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
|
|||
* versa.
|
||||
*/
|
||||
{
|
||||
int error = 0;
|
||||
int error = 0;
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
unsigned long *tmp;
|
||||
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 = 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;
|
||||
}
|
||||
}
|
||||
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" );
|
||||
if (error == 0)
|
||||
DRM_ERROR("Scatter allocation matches pagelist\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
drm_sg_cleanup( entry );
|
||||
failed:
|
||||
drm_sg_cleanup(entry);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int drm_sg_free( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg )
|
||||
int drm_sg_free(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
|
@ -219,20 +210,20 @@ int drm_sg_free( struct inode *inode, struct file *filp,
|
|||
if (!drm_core_check_feature(dev, DRIVER_SG))
|
||||
return -EINVAL;
|
||||
|
||||
if ( copy_from_user( &request,
|
||||
(drm_scatter_gather_t __user *)arg,
|
||||
sizeof(request) ) )
|
||||
if (copy_from_user(&request,
|
||||
(drm_scatter_gather_t __user *) arg,
|
||||
sizeof(request)))
|
||||
return -EFAULT;
|
||||
|
||||
entry = dev->sg;
|
||||
dev->sg = NULL;
|
||||
|
||||
if ( !entry || entry->handle != request.handle )
|
||||
if (!entry || entry->handle != request.handle)
|
||||
return -EINVAL;
|
||||
|
||||
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
|
||||
DRM_DEBUG("sg free virtual = %p\n", entry->virtual);
|
||||
|
||||
drm_sg_cleanup( entry );
|
||||
drm_sg_cleanup(entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
#include "drm_core.h"
|
||||
|
||||
unsigned int drm_cards_limit = 16; /* Enough for one machine */
|
||||
unsigned int drm_debug = 0; /* 1 to enable debug output */
|
||||
unsigned int drm_debug = 0; /* 1 to enable debug output */
|
||||
EXPORT_SYMBOL(drm_debug);
|
||||
|
||||
MODULE_AUTHOR( CORE_AUTHOR );
|
||||
MODULE_DESCRIPTION( CORE_DESC );
|
||||
MODULE_AUTHOR(CORE_AUTHOR);
|
||||
MODULE_DESCRIPTION(CORE_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards");
|
||||
MODULE_PARM_DESC(debug, "Enable debug output");
|
||||
|
@ -53,19 +53,21 @@ drm_head_t **drm_heads;
|
|||
struct drm_sysfs_class *drm_class;
|
||||
struct proc_dir_entry *drm_proc_root;
|
||||
|
||||
static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver)
|
||||
static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
int retcode;
|
||||
|
||||
spin_lock_init(&dev->count_lock);
|
||||
init_timer( &dev->timer );
|
||||
sema_init( &dev->struct_sem, 1 );
|
||||
sema_init( &dev->ctxlist_sem, 1 );
|
||||
init_timer(&dev->timer);
|
||||
sema_init(&dev->struct_sem, 1);
|
||||
sema_init(&dev->ctxlist_sem, 1);
|
||||
|
||||
dev->pdev = pdev;
|
||||
dev->pdev = pdev;
|
||||
|
||||
#ifdef __alpha__
|
||||
dev->hose = pdev->sysdata;
|
||||
dev->hose = pdev->sysdata;
|
||||
dev->pci_domain = dev->hose->bus->number;
|
||||
#else
|
||||
dev->pci_domain = 0;
|
||||
|
@ -82,15 +84,15 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
|
|||
|
||||
/* the DRM has 6 basic counters */
|
||||
dev->counters = 6;
|
||||
dev->types[0] = _DRM_STAT_LOCK;
|
||||
dev->types[1] = _DRM_STAT_OPENS;
|
||||
dev->types[2] = _DRM_STAT_CLOSES;
|
||||
dev->types[3] = _DRM_STAT_IOCTLS;
|
||||
dev->types[4] = _DRM_STAT_LOCKS;
|
||||
dev->types[5] = _DRM_STAT_UNLOCKS;
|
||||
dev->types[0] = _DRM_STAT_LOCK;
|
||||
dev->types[1] = _DRM_STAT_OPENS;
|
||||
dev->types[2] = _DRM_STAT_CLOSES;
|
||||
dev->types[3] = _DRM_STAT_IOCTLS;
|
||||
dev->types[4] = _DRM_STAT_LOCKS;
|
||||
dev->types[5] = _DRM_STAT_UNLOCKS;
|
||||
|
||||
dev->driver = driver;
|
||||
|
||||
|
||||
if (dev->driver->preinit)
|
||||
if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
|
||||
goto error_out_unreg;
|
||||
|
@ -98,29 +100,30 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct
|
|||
if (drm_core_has_AGP(dev)) {
|
||||
if (drm_device_is_agp(dev))
|
||||
dev->agp = drm_agp_init(dev);
|
||||
if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
|
||||
DRM_ERROR( "Cannot initialize the agpgart module.\n" );
|
||||
if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
|
||||
&& (dev->agp == NULL)) {
|
||||
DRM_ERROR("Cannot initialize the agpgart module.\n");
|
||||
retcode = -EINVAL;
|
||||
goto error_out_unreg;
|
||||
}
|
||||
if (drm_core_has_MTRR(dev)) {
|
||||
if (dev->agp)
|
||||
dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
|
||||
dev->agp->agp_info.aper_size*1024*1024,
|
||||
MTRR_TYPE_WRCOMB,
|
||||
1 );
|
||||
dev->agp->agp_mtrr =
|
||||
mtrr_add(dev->agp->agp_info.aper_base,
|
||||
dev->agp->agp_info.aper_size *
|
||||
1024 * 1024, MTRR_TYPE_WRCOMB, 1);
|
||||
}
|
||||
}
|
||||
|
||||
retcode = drm_ctxbitmap_init( dev );
|
||||
if( retcode ) {
|
||||
DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
|
||||
retcode = drm_ctxbitmap_init(dev);
|
||||
if (retcode) {
|
||||
DRM_ERROR("Cannot allocate memory for context bitmap.\n");
|
||||
goto error_out_unreg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_out_unreg:
|
||||
|
||||
error_out_unreg:
|
||||
drm_takedown(dev);
|
||||
return retcode;
|
||||
}
|
||||
|
@ -140,7 +143,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
|
|||
int minor = iminor(inode);
|
||||
int err = -ENODEV;
|
||||
struct file_operations *old_fops;
|
||||
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
if (!((minor >= 0) && (minor < drm_cards_limit)))
|
||||
|
@ -148,7 +151,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
|
|||
|
||||
if (!drm_heads[minor])
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (!(dev = drm_heads[minor]->dev))
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -174,7 +177,7 @@ int drm_stub_open(struct inode *inode, struct file *filp)
|
|||
* create the proc init entry via proc_init(). This routines assigns
|
||||
* minor numbers to secondary heads of multi-headed cards
|
||||
*/
|
||||
static int drm_get_head(drm_device_t *dev, drm_head_t *head)
|
||||
static int drm_get_head(drm_device_t * dev, drm_head_t * head)
|
||||
{
|
||||
drm_head_t **heads = drm_heads;
|
||||
int ret;
|
||||
|
@ -184,26 +187,27 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head)
|
|||
|
||||
for (minor = 0; minor < drm_cards_limit; minor++, heads++) {
|
||||
if (!*heads) {
|
||||
|
||||
|
||||
*head = (drm_head_t) {
|
||||
.dev = dev,
|
||||
.device = MKDEV(DRM_MAJOR, minor),
|
||||
.minor = minor,
|
||||
};
|
||||
|
||||
if ((ret = drm_proc_init(dev, minor, drm_proc_root, &head->dev_root))) {
|
||||
printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n");
|
||||
.dev = dev,.device =
|
||||
MKDEV(DRM_MAJOR, minor),.minor = minor,};
|
||||
|
||||
if ((ret =
|
||||
drm_proc_init(dev, minor, drm_proc_root,
|
||||
&head->dev_root))) {
|
||||
printk(KERN_ERR
|
||||
"DRM: Failed to initialize /proc/dri.\n");
|
||||
goto err_g1;
|
||||
}
|
||||
|
||||
|
||||
head->dev_class = drm_sysfs_device_add(drm_class,
|
||||
MKDEV(DRM_MAJOR,
|
||||
minor),
|
||||
&dev->pdev->dev,
|
||||
"card%d", minor);
|
||||
if (IS_ERR(head->dev_class)) {
|
||||
printk(KERN_ERR "DRM: Error sysfs_device_add.\n");
|
||||
printk(KERN_ERR
|
||||
"DRM: Error sysfs_device_add.\n");
|
||||
ret = PTR_ERR(head->dev_class);
|
||||
goto err_g2;
|
||||
}
|
||||
|
@ -215,13 +219,14 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head)
|
|||
}
|
||||
DRM_ERROR("out of minors\n");
|
||||
return -ENOMEM;
|
||||
err_g2:
|
||||
err_g2:
|
||||
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
|
||||
err_g1:
|
||||
*head = (drm_head_t) {.dev = NULL};
|
||||
err_g1:
|
||||
*head = (drm_head_t) {
|
||||
.dev = NULL};
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register.
|
||||
*
|
||||
|
@ -234,7 +239,7 @@ static int drm_get_head(drm_device_t *dev, drm_head_t *head)
|
|||
* Try and register, if we fail to register, backout previous work.
|
||||
*/
|
||||
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
struct drm_driver *driver)
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
drm_device_t *dev;
|
||||
int ret;
|
||||
|
@ -261,10 +266,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
|||
|
||||
return 0;
|
||||
|
||||
err_g1:
|
||||
err_g1:
|
||||
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_get_dev);
|
||||
|
||||
/**
|
||||
|
@ -305,19 +311,19 @@ int drm_put_dev(drm_device_t * dev)
|
|||
* last minor released.
|
||||
*
|
||||
*/
|
||||
int drm_put_head(drm_head_t *head)
|
||||
int drm_put_head(drm_head_t * head)
|
||||
{
|
||||
int minor = head->minor;
|
||||
|
||||
|
||||
DRM_DEBUG("release secondary minor %d\n", minor);
|
||||
|
||||
|
||||
drm_proc_cleanup(minor, drm_proc_root, head->dev_root);
|
||||
drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor));
|
||||
|
||||
*head = (drm_head_t){.dev = NULL};
|
||||
|
||||
*head = (drm_head_t) {
|
||||
.dev = NULL};
|
||||
|
||||
drm_heads[minor] = NULL;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* \file drm_vm.h
|
||||
* \file drm_vm.c
|
||||
* Memory mapping for DRM
|
||||
*
|
||||
*
|
||||
* \author Rickard E. (Rik) Faith <faith@valinux.com>
|
||||
* \author Gareth Hughes <gareth@valinux.com>
|
||||
*/
|
||||
|
@ -47,32 +47,34 @@ static void drm_vm_close(struct vm_area_struct *vma);
|
|||
* \param vma virtual memory area.
|
||||
* \param address access address.
|
||||
* \return pointer to the page structure.
|
||||
*
|
||||
*
|
||||
* Find the right map and if it's AGP memory find the real physical page to
|
||||
* map, get the page, increment the use count and return it.
|
||||
*/
|
||||
#if __OS_HAS_AGP
|
||||
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
unsigned long address)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/*
|
||||
* Find the right map
|
||||
*/
|
||||
* Find the right map
|
||||
*/
|
||||
if (!drm_core_has_AGP(dev))
|
||||
goto vm_nopage_error;
|
||||
|
||||
if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
|
||||
if (!dev->agp || !dev->agp->cant_use_aperture)
|
||||
goto vm_nopage_error;
|
||||
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (!map)
|
||||
continue;
|
||||
if (r_list->user_token == VM_OFFSET(vma))
|
||||
break;
|
||||
}
|
||||
|
@ -85,45 +87,47 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
|
|||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Adjust to a bus-relative address
|
||||
*/
|
||||
* Adjust to a bus-relative address
|
||||
*/
|
||||
baddr -= dev->hose->mem_space->start;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* It's AGP memory - find the real physical page to map
|
||||
*/
|
||||
for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
|
||||
* It's AGP memory - find the real physical page to map
|
||||
*/
|
||||
for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
|
||||
if (agpmem->bound <= baddr &&
|
||||
agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
|
||||
agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!agpmem) goto vm_nopage_error;
|
||||
if (!agpmem)
|
||||
goto vm_nopage_error;
|
||||
|
||||
/*
|
||||
* Get the page, inc the use count, and return it
|
||||
*/
|
||||
* Get the page, inc the use count, and return it
|
||||
*/
|
||||
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
|
||||
page = virt_to_page(__va(agpmem->memory->memory[offset]));
|
||||
get_page(page);
|
||||
|
||||
DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
|
||||
baddr, __va(agpmem->memory->memory[offset]), offset,
|
||||
page_count(page));
|
||||
DRM_DEBUG
|
||||
("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
|
||||
baddr, __va(agpmem->memory->memory[offset]), offset,
|
||||
page_count(page));
|
||||
|
||||
return page;
|
||||
}
|
||||
vm_nopage_error:
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
}
|
||||
vm_nopage_error:
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
}
|
||||
#else /* __OS_HAS_AGP */
|
||||
#else /* __OS_HAS_AGP */
|
||||
static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
unsigned long address)
|
||||
{
|
||||
return NOPAGE_SIGBUS;
|
||||
}
|
||||
#endif /* __OS_HAS_AGP */
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
||||
/**
|
||||
* \c nopage method for shared virtual memory.
|
||||
|
@ -131,22 +135,24 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
|
|||
* \param vma virtual memory area.
|
||||
* \param address access address.
|
||||
* \return pointer to the page structure.
|
||||
*
|
||||
*
|
||||
* Get the the mapping, find the real physical page to map, get the page, and
|
||||
* return it.
|
||||
*/
|
||||
static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
unsigned long address)
|
||||
{
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
|
||||
unsigned long offset;
|
||||
unsigned long i;
|
||||
struct page *page;
|
||||
drm_map_t *map = (drm_map_t *) vma->vm_private_data;
|
||||
unsigned long offset;
|
||||
unsigned long i;
|
||||
struct page *page;
|
||||
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!map) return NOPAGE_OOM; /* Nothing allocated */
|
||||
if (address > vma->vm_end)
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!map)
|
||||
return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
offset = address - vma->vm_start;
|
||||
i = (unsigned long)map->handle + offset;
|
||||
page = (map->type == _DRM_CONSISTENT) ?
|
||||
virt_to_page((void *)i) : vmalloc_to_page((void *)i);
|
||||
|
@ -158,19 +164,18 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
|
|||
return page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \c close method for shared virtual memory.
|
||||
*
|
||||
*
|
||||
* \param vma virtual memory area.
|
||||
*
|
||||
*
|
||||
* Deletes map information if we are the last
|
||||
* person to close a mapping and it's not in the global maplist.
|
||||
*/
|
||||
static void drm_vm_shm_close(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_vma_entry_t *pt, *prev, *next;
|
||||
drm_map_t *map;
|
||||
drm_map_list_t *r_list;
|
||||
|
@ -186,7 +191,8 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
|||
down(&dev->struct_sem);
|
||||
for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
|
||||
next = pt->next;
|
||||
if (pt->vma->vm_private_data == map) found_maps++;
|
||||
if (pt->vma->vm_private_data == map)
|
||||
found_maps++;
|
||||
if (pt->vma == vma) {
|
||||
if (prev) {
|
||||
prev->next = pt->next;
|
||||
|
@ -199,8 +205,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
|||
}
|
||||
}
|
||||
/* We were the only map that was found */
|
||||
if(found_maps == 1 &&
|
||||
map->flags & _DRM_REMOVABLE) {
|
||||
if (found_maps == 1 && map->flags & _DRM_REMOVABLE) {
|
||||
/* Check to see if we are in the maplist, if we are not, then
|
||||
* we delete this mappings information.
|
||||
*/
|
||||
|
@ -208,10 +213,11 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
|||
list = &dev->maplist->head;
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
if (r_list->map == map) found_maps++;
|
||||
if (r_list->map == map)
|
||||
found_maps++;
|
||||
}
|
||||
|
||||
if(!found_maps) {
|
||||
if (!found_maps) {
|
||||
drm_dma_handle_t dmah;
|
||||
|
||||
switch (map->type) {
|
||||
|
@ -251,27 +257,29 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
|
|||
* \param vma virtual memory area.
|
||||
* \param address access address.
|
||||
* \return pointer to the page structure.
|
||||
*
|
||||
*
|
||||
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
|
||||
*/
|
||||
static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
unsigned long address)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
unsigned long offset;
|
||||
unsigned long page_nr;
|
||||
struct page *page;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
unsigned long offset;
|
||||
unsigned long page_nr;
|
||||
struct page *page;
|
||||
|
||||
if (!dma) return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
|
||||
if (!dma)
|
||||
return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end)
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!dma->pagelist)
|
||||
return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
|
||||
page_nr = offset >> PAGE_SHIFT;
|
||||
page = virt_to_page((dma->pagelist[page_nr] +
|
||||
(offset & (~PAGE_MASK))));
|
||||
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
|
||||
page_nr = offset >> PAGE_SHIFT;
|
||||
page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
|
||||
|
||||
get_page(page);
|
||||
|
||||
|
@ -285,13 +293,13 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma,
|
|||
* \param vma virtual memory area.
|
||||
* \param address access address.
|
||||
* \return pointer to the page structure.
|
||||
*
|
||||
*
|
||||
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
|
||||
*/
|
||||
static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address)
|
||||
unsigned long address)
|
||||
{
|
||||
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
|
||||
drm_map_t *map = (drm_map_t *) vma->vm_private_data;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
|
@ -300,10 +308,12 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
|
|||
unsigned long page_offset;
|
||||
struct page *page;
|
||||
|
||||
if (!entry) return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
|
||||
|
||||
if (!entry)
|
||||
return NOPAGE_SIGBUS; /* Error */
|
||||
if (address > vma->vm_end)
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
if (!entry->pagelist)
|
||||
return NOPAGE_OOM; /* Nothing allocated */
|
||||
|
||||
offset = address - vma->vm_start;
|
||||
map_offset = map->offset - (unsigned long)dev->sg->virtual;
|
||||
|
@ -314,76 +324,78 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
|
|||
return page;
|
||||
}
|
||||
|
||||
|
||||
static struct page *drm_vm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int *type) {
|
||||
if (type) *type = VM_FAULT_MINOR;
|
||||
unsigned long address, int *type)
|
||||
{
|
||||
if (type)
|
||||
*type = VM_FAULT_MINOR;
|
||||
return drm_do_vm_nopage(vma, address);
|
||||
}
|
||||
|
||||
static struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int *type) {
|
||||
if (type) *type = VM_FAULT_MINOR;
|
||||
unsigned long address, int *type)
|
||||
{
|
||||
if (type)
|
||||
*type = VM_FAULT_MINOR;
|
||||
return drm_do_vm_shm_nopage(vma, address);
|
||||
}
|
||||
|
||||
static struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int *type) {
|
||||
if (type) *type = VM_FAULT_MINOR;
|
||||
unsigned long address, int *type)
|
||||
{
|
||||
if (type)
|
||||
*type = VM_FAULT_MINOR;
|
||||
return drm_do_vm_dma_nopage(vma, address);
|
||||
}
|
||||
|
||||
static struct page *drm_vm_sg_nopage(struct vm_area_struct *vma,
|
||||
unsigned long address,
|
||||
int *type) {
|
||||
if (type) *type = VM_FAULT_MINOR;
|
||||
unsigned long address, int *type)
|
||||
{
|
||||
if (type)
|
||||
*type = VM_FAULT_MINOR;
|
||||
return drm_do_vm_sg_nopage(vma, address);
|
||||
}
|
||||
|
||||
/** AGP virtual memory operations */
|
||||
static struct vm_operations_struct drm_vm_ops = {
|
||||
static struct vm_operations_struct drm_vm_ops = {
|
||||
.nopage = drm_vm_nopage,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
};
|
||||
|
||||
/** Shared virtual memory operations */
|
||||
static struct vm_operations_struct drm_vm_shm_ops = {
|
||||
static struct vm_operations_struct drm_vm_shm_ops = {
|
||||
.nopage = drm_vm_shm_nopage,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_shm_close,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_shm_close,
|
||||
};
|
||||
|
||||
/** DMA virtual memory operations */
|
||||
static struct vm_operations_struct drm_vm_dma_ops = {
|
||||
static struct vm_operations_struct drm_vm_dma_ops = {
|
||||
.nopage = drm_vm_dma_nopage,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
};
|
||||
|
||||
/** Scatter-gather virtual memory operations */
|
||||
static struct vm_operations_struct drm_vm_sg_ops = {
|
||||
static struct vm_operations_struct drm_vm_sg_ops = {
|
||||
.nopage = drm_vm_sg_nopage,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
.open = drm_vm_open,
|
||||
.close = drm_vm_close,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \c open method for shared virtual memory.
|
||||
*
|
||||
*
|
||||
* \param vma virtual memory area.
|
||||
*
|
||||
*
|
||||
* Create a new drm_vma_entry structure as the \p vma private data entry and
|
||||
* add it to drm_device::vmalist.
|
||||
*/
|
||||
static void drm_vm_open(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_vma_entry_t *vma_entry;
|
||||
|
||||
DRM_DEBUG("0x%08lx,0x%08lx\n",
|
||||
|
@ -393,26 +405,26 @@ static void drm_vm_open(struct vm_area_struct *vma)
|
|||
vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
|
||||
if (vma_entry) {
|
||||
down(&dev->struct_sem);
|
||||
vma_entry->vma = vma;
|
||||
vma_entry->vma = vma;
|
||||
vma_entry->next = dev->vmalist;
|
||||
vma_entry->pid = current->pid;
|
||||
dev->vmalist = vma_entry;
|
||||
vma_entry->pid = current->pid;
|
||||
dev->vmalist = vma_entry;
|
||||
up(&dev->struct_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \c close method for all virtual memory types.
|
||||
*
|
||||
*
|
||||
* \param vma virtual memory area.
|
||||
*
|
||||
*
|
||||
* Search the \p vma private data entry in drm_device::vmalist, unlink it, and
|
||||
* free it.
|
||||
*/
|
||||
static void drm_vm_close(struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_vma_entry_t *pt, *prev;
|
||||
|
||||
DRM_DEBUG("0x%08lx,0x%08lx\n",
|
||||
|
@ -440,43 +452,44 @@ static void drm_vm_close(struct vm_area_struct *vma)
|
|||
* \param filp file pointer.
|
||||
* \param vma virtual memory area.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* Sets the virtual memory area operations structure to vm_dma_ops, the file
|
||||
* pointer, and calls vm_open().
|
||||
*/
|
||||
static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
drm_device_dma_t *dma;
|
||||
unsigned long length = vma->vm_end - vma->vm_start;
|
||||
unsigned long length = vma->vm_end - vma->vm_start;
|
||||
|
||||
lock_kernel();
|
||||
dev = priv->head->dev;
|
||||
dma = dev->dma;
|
||||
dev = priv->head->dev;
|
||||
dma = dev->dma;
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
||||
/* Length must match exact page count */
|
||||
/* Length must match exact page count */
|
||||
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
|
||||
unlock_kernel();
|
||||
return -EINVAL;
|
||||
}
|
||||
unlock_kernel();
|
||||
|
||||
vma->vm_ops = &drm_vm_dma_ops;
|
||||
vma->vm_ops = &drm_vm_dma_ops;
|
||||
|
||||
vma->vm_flags |= VM_RESERVED; /* Don't swap */
|
||||
vma->vm_flags |= VM_RESERVED; /* Don't swap */
|
||||
|
||||
vma->vm_file = filp; /* Needed for drm_vm_open() */
|
||||
vma->vm_file = filp; /* Needed for drm_vm_open() */
|
||||
drm_vm_open(vma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long drm_core_get_map_ofs(drm_map_t *map)
|
||||
unsigned long drm_core_get_map_ofs(drm_map_t * map)
|
||||
{
|
||||
return map->offset;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_core_get_map_ofs);
|
||||
|
||||
unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
|
||||
|
@ -487,6 +500,7 @@ unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_core_get_reg_ofs);
|
||||
|
||||
/**
|
||||
|
@ -495,7 +509,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
|
|||
* \param filp file pointer.
|
||||
* \param vma virtual memory area.
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
*
|
||||
* If the virtual memory area has no offset associated with it then it's a DMA
|
||||
* area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
|
||||
* checks that the restricted flag is not set, sets the virtual memory operations
|
||||
|
@ -504,17 +518,18 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
|
|||
*/
|
||||
int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
unsigned long offset = 0;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
unsigned long offset = 0;
|
||||
struct list_head *list;
|
||||
|
||||
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
|
||||
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
|
||||
|
||||
if ( !priv->authenticated ) return -EACCES;
|
||||
if (!priv->authenticated)
|
||||
return -EACCES;
|
||||
|
||||
/* We check for "dma". On Apple's UniNorth, it's valid to have
|
||||
* the AGP mapped at physical address 0
|
||||
|
@ -522,61 +537,66 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
*/
|
||||
if (!VM_OFFSET(vma)
|
||||
#if __OS_HAS_AGP
|
||||
&& (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
|
||||
&& (!dev->agp
|
||||
|| dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
|
||||
#endif
|
||||
)
|
||||
return drm_mmap_dma(filp, vma);
|
||||
|
||||
/* A sequential search of a linked list is
|
||||
fine here because: 1) there will only be
|
||||
about 5-10 entries in the list and, 2) a
|
||||
DRI client only has to do this mapping
|
||||
once, so it doesn't have to be optimized
|
||||
for performance, even if the list was a
|
||||
bit longer. */
|
||||
/* A sequential search of a linked list is
|
||||
fine here because: 1) there will only be
|
||||
about 5-10 entries in the list and, 2) a
|
||||
DRI client only has to do this mapping
|
||||
once, so it doesn't have to be optimized
|
||||
for performance, even if the list was a
|
||||
bit longer. */
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
|
||||
r_list = list_entry(list, drm_map_list_t, head);
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (!map)
|
||||
continue;
|
||||
if (r_list->user_token == VM_OFFSET(vma))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
|
||||
if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
|
||||
return -EPERM;
|
||||
|
||||
/* Check for valid size. */
|
||||
if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
|
||||
/* Check for valid size. */
|
||||
if (map->size != vma->vm_end - vma->vm_start)
|
||||
return -EINVAL;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
|
||||
vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
|
||||
#else
|
||||
/* Ye gads this is ugly. With more thought
|
||||
we could move this up higher and use
|
||||
`protection_map' instead. */
|
||||
vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
|
||||
__pte(pgprot_val(vma->vm_page_prot)))));
|
||||
/* Ye gads this is ugly. With more thought
|
||||
we could move this up higher and use
|
||||
`protection_map' instead. */
|
||||
vma->vm_page_prot =
|
||||
__pgprot(pte_val
|
||||
(pte_wrprotect
|
||||
(__pte(pgprot_val(vma->vm_page_prot)))));
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_AGP:
|
||||
if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
|
||||
/*
|
||||
* On some platforms we can't talk to bus dma address from the CPU, so for
|
||||
* memory of type DRM_AGP, we'll deal with sorting out the real physical
|
||||
* pages and mappings in nopage()
|
||||
*/
|
||||
case _DRM_AGP:
|
||||
if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
|
||||
/*
|
||||
* On some platforms we can't talk to bus dma address from the CPU, so for
|
||||
* memory of type DRM_AGP, we'll deal with sorting out the real physical
|
||||
* pages and mappings in nopage()
|
||||
*/
|
||||
#if defined(__powerpc__)
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
|
||||
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
|
||||
#endif
|
||||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
}
|
||||
/* fall through to _DRM_FRAME_BUFFER... */
|
||||
vma->vm_ops = &drm_vm_ops;
|
||||
break;
|
||||
}
|
||||
/* fall through to _DRM_FRAME_BUFFER... */
|
||||
case _DRM_FRAME_BUFFER:
|
||||
case _DRM_REGISTERS:
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
@ -591,27 +611,25 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
#endif
|
||||
vma->vm_flags |= VM_IO; /* not in core dump */
|
||||
#if defined(__ia64__)
|
||||
if (efi_range_is_wc(vma->vm_start, vma->vm_end -
|
||||
vma->vm_start))
|
||||
if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
|
||||
vma->vm_page_prot =
|
||||
pgprot_writecombine(vma->vm_page_prot);
|
||||
pgprot_writecombine(vma->vm_page_prot);
|
||||
else
|
||||
vma->vm_page_prot =
|
||||
pgprot_noncached(vma->vm_page_prot);
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
#endif
|
||||
offset = dev->driver->get_reg_ofs(dev);
|
||||
#ifdef __sparc__
|
||||
if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
#else
|
||||
if (io_remap_pfn_range(vma, vma->vm_start,
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
(map->offset + offset) >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start,
|
||||
vma->vm_page_prot))
|
||||
#endif
|
||||
return -EAGAIN;
|
||||
return -EAGAIN;
|
||||
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
|
||||
" offset = 0x%lx\n",
|
||||
map->type,
|
||||
|
@ -624,22 +642,23 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
* allocate in a different way */
|
||||
vma->vm_ops = &drm_vm_shm_ops;
|
||||
vma->vm_private_data = (void *)map;
|
||||
/* Don't let this area swap. Change when
|
||||
DRM_KERNEL advisory is supported. */
|
||||
/* Don't let this area swap. Change when
|
||||
DRM_KERNEL advisory is supported. */
|
||||
vma->vm_flags |= VM_RESERVED;
|
||||
break;
|
||||
case _DRM_SCATTER_GATHER:
|
||||
vma->vm_ops = &drm_vm_sg_ops;
|
||||
vma->vm_private_data = (void *)map;
|
||||
vma->vm_flags |= VM_RESERVED;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL; /* This should never happen. */
|
||||
}
|
||||
vma->vm_flags |= VM_RESERVED; /* Don't swap */
|
||||
vma->vm_flags |= VM_RESERVED; /* Don't swap */
|
||||
|
||||
vma->vm_file = filp; /* Needed for drm_vm_open() */
|
||||
vma->vm_file = filp; /* Needed for drm_vm_open() */
|
||||
drm_vm_open(vma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(drm_mmap);
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
#include "ffb_drv.h"
|
||||
|
||||
static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
|
||||
{
|
||||
static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) {
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
int i;
|
||||
|
||||
|
@ -37,7 +36,7 @@ static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
|
|||
return i + 1;
|
||||
}
|
||||
|
||||
static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
|
||||
static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx)
|
||||
{
|
||||
ffb_fbcPtr ffb = fpriv->regs;
|
||||
struct ffb_hw_context *ctx;
|
||||
|
@ -94,36 +93,36 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
|
|||
|
||||
/* Capture rendering attributes. */
|
||||
|
||||
ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
|
||||
ctx->wid = upa_readl(&ffb->wid); /* Current WID */
|
||||
ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
|
||||
ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
|
||||
ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
|
||||
ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
|
||||
ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
|
||||
ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
|
||||
ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
|
||||
ctx->wid = upa_readl(&ffb->wid); /* Current WID */
|
||||
ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
|
||||
ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
|
||||
ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
|
||||
ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
|
||||
ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
|
||||
ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
|
||||
ctx->vclipmin = upa_readl(&ffb->vclipmin); /* Primary XY clip, minimum */
|
||||
ctx->vclipmax = upa_readl(&ffb->vclipmax); /* Primary XY clip, maximum */
|
||||
ctx->vclipzmin = upa_readl(&ffb->vclipzmin); /* Primary Z clip, minimum */
|
||||
ctx->vclipzmax = upa_readl(&ffb->vclipzmax); /* Primary Z clip, maximum */
|
||||
ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
|
||||
ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
|
||||
ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
|
||||
ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
|
||||
ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
|
||||
ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
|
||||
ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
|
||||
ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
|
||||
ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
|
||||
ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
|
||||
ctx->blendc1 = upa_readl(&ffb->blendc1); /* Alpha Blend Color 1 */
|
||||
ctx->blendc2 = upa_readl(&ffb->blendc2); /* Alpha Blend Color 2 */
|
||||
ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
|
||||
ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
|
||||
ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
|
||||
ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
|
||||
ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
|
||||
ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
|
||||
ctx->matchab = upa_readl(&ffb->matchab); /* Buffer A/B Match Ops */
|
||||
ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
|
||||
ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
|
||||
ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
|
||||
ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
|
||||
ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
|
||||
ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
|
||||
ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
|
||||
ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
|
||||
ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
|
||||
ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
|
||||
ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
|
||||
ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
|
||||
ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
|
||||
ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
|
||||
|
||||
/* Auxiliary Clips. */
|
||||
ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
|
||||
|
@ -135,9 +134,9 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
|
|||
ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
|
||||
ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
|
||||
|
||||
ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
|
||||
ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
|
||||
ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
|
||||
ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
|
||||
ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
|
||||
ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
|
||||
ctx->fontinc = upa_readl(&ffb->fontinc); /* Font X/Y Increment */
|
||||
|
||||
/* These registers/features only exist on FFB2 and later chips. */
|
||||
|
@ -145,12 +144,12 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
|
|||
ctx->dcss1 = upa_readl(&ffb->dcss1); /* Depth Cue Scale Slope 1 */
|
||||
ctx->dcss2 = upa_readl(&ffb->dcss2); /* Depth Cue Scale Slope 2 */
|
||||
ctx->dcss2 = upa_readl(&ffb->dcss3); /* Depth Cue Scale Slope 3 */
|
||||
ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
|
||||
ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
|
||||
ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
|
||||
ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
|
||||
ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
|
||||
ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
|
||||
ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
|
||||
ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
|
||||
ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
|
||||
ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
|
||||
ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
|
||||
ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
|
||||
|
||||
/* And stencil/stencilctl only exists on FFB2+ and later
|
||||
* due to the introduction of 3DRAM-III.
|
||||
|
@ -170,7 +169,7 @@ static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
|
|||
ctx->ucsr = upa_readl(&ffb->ucsr);
|
||||
}
|
||||
|
||||
static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
|
||||
static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx)
|
||||
{
|
||||
ffb_fbcPtr ffb = fpriv->regs;
|
||||
struct ffb_hw_context *ctx;
|
||||
|
@ -193,7 +192,7 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
|
|||
|
||||
upa_writel(ctx->ppc, &ffb->ppc);
|
||||
upa_writel(ctx->wid, &ffb->wid);
|
||||
upa_writel(ctx->fg, &ffb->fg);
|
||||
upa_writel(ctx->fg, &ffb->fg);
|
||||
upa_writel(ctx->bg, &ffb->bg);
|
||||
upa_writel(ctx->xclip, &ffb->xclip);
|
||||
upa_writel(ctx->fbc, &ffb->fbc);
|
||||
|
@ -237,36 +236,36 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
|
|||
|
||||
/* Restore rendering attributes. */
|
||||
|
||||
upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
|
||||
upa_writel(ctx->wid, &ffb->wid); /* Current WID */
|
||||
upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
|
||||
upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
|
||||
upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
|
||||
upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
|
||||
upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
|
||||
upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
|
||||
upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
|
||||
upa_writel(ctx->wid, &ffb->wid); /* Current WID */
|
||||
upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
|
||||
upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
|
||||
upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
|
||||
upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
|
||||
upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
|
||||
upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
|
||||
upa_writel(ctx->vclipmin, &ffb->vclipmin); /* Primary XY clip, minimum */
|
||||
upa_writel(ctx->vclipmax, &ffb->vclipmax); /* Primary XY clip, maximum */
|
||||
upa_writel(ctx->vclipzmin, &ffb->vclipzmin); /* Primary Z clip, minimum */
|
||||
upa_writel(ctx->vclipzmax, &ffb->vclipzmax); /* Primary Z clip, maximum */
|
||||
upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
|
||||
upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
|
||||
upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
|
||||
upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
|
||||
upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
|
||||
upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
|
||||
upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
|
||||
upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
|
||||
upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
|
||||
upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
|
||||
upa_writel(ctx->blendc1, &ffb->blendc1); /* Alpha Blend Color 1 */
|
||||
upa_writel(ctx->blendc2, &ffb->blendc2); /* Alpha Blend Color 2 */
|
||||
upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
|
||||
upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
|
||||
upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
|
||||
upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
|
||||
upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
|
||||
upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
|
||||
upa_writel(ctx->matchab, &ffb->matchab); /* Buffer A/B Match Ops */
|
||||
upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
|
||||
upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
|
||||
upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
|
||||
upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
|
||||
upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
|
||||
upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
|
||||
upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
|
||||
upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
|
||||
upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
|
||||
upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
|
||||
upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
|
||||
upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
|
||||
upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
|
||||
upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
|
||||
|
||||
/* Auxiliary Clips. */
|
||||
upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
|
||||
|
@ -278,9 +277,9 @@ static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
|
|||
upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
|
||||
upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
|
||||
|
||||
upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
|
||||
upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
|
||||
upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
|
||||
upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
|
||||
upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
|
||||
upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
|
||||
upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */
|
||||
|
||||
/* These registers/features only exist on FFB2 and later chips. */
|
||||
|
@ -354,91 +353,87 @@ static void FFBWait(ffb_fbcPtr ffb)
|
|||
} while (--limit);
|
||||
}
|
||||
|
||||
int ffb_driver_context_switch(drm_device_t *dev, int old, int new)
|
||||
int ffb_driver_context_switch(drm_device_t * dev, int old, int new)
|
||||
{
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
|
||||
#ifdef DRM_DMA_HISTOGRAM
|
||||
dev->ctx_start = get_cycles();
|
||||
dev->ctx_start = get_cycles();
|
||||
#endif
|
||||
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
if (new == dev->last_context ||
|
||||
dev->last_context == 0) {
|
||||
DRM_DEBUG("Context switch from %d to %d\n", old, new);
|
||||
|
||||
if (new == dev->last_context || dev->last_context == 0) {
|
||||
dev->last_context = new;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FFBWait(fpriv->regs);
|
||||
ffb_save_context(fpriv, old);
|
||||
ffb_restore_context(fpriv, old, new);
|
||||
FFBWait(fpriv->regs);
|
||||
|
||||
|
||||
dev->last_context = new;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_t ctx;
|
||||
int i;
|
||||
drm_ctx_res_t res;
|
||||
drm_ctx_t ctx;
|
||||
int i;
|
||||
|
||||
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
|
||||
if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res)))
|
||||
if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res)))
|
||||
return -EFAULT;
|
||||
if (res.count >= DRM_RESERVED_CONTEXTS) {
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
|
||||
ctx.handle = i;
|
||||
if (copy_to_user(&res.contexts[i],
|
||||
&i,
|
||||
sizeof(i)))
|
||||
if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
res.count = DRM_RESERVED_CONTEXTS;
|
||||
if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res)))
|
||||
if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
int idx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
|
||||
idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
|
||||
if (idx < 0)
|
||||
return -ENFILE;
|
||||
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
ctx.handle = idx;
|
||||
if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
|
||||
if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
struct ffb_hw_context *hwctx;
|
||||
drm_ctx_t ctx;
|
||||
int idx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
idx = ctx.handle;
|
||||
|
@ -458,16 +453,16 @@ int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
|
||||
int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
struct ffb_hw_context *hwctx;
|
||||
drm_ctx_t ctx;
|
||||
int idx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
idx = ctx.handle;
|
||||
|
@ -483,31 +478,31 @@ int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
else
|
||||
ctx.flags = 0;
|
||||
|
||||
if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
|
||||
if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
int ffb_driver_switchctx(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
|
||||
}
|
||||
|
||||
int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_t ctx;
|
||||
drm_ctx_t ctx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
|
||||
|
@ -515,15 +510,15 @@ int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
|||
}
|
||||
|
||||
int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_ctx_t ctx;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
drm_ctx_t ctx;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
int idx;
|
||||
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
|
||||
if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
|
||||
return -EFAULT;
|
||||
DRM_DEBUG("%d\n", ctx.handle);
|
||||
|
||||
|
@ -544,7 +539,8 @@ void ffb_set_context_ioctls(void)
|
|||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func =
|
||||
ffb_driver_switchctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
|
||||
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
|
||||
|
||||
|
|
|
@ -33,13 +33,13 @@ typedef struct _ffb_position_t {
|
|||
|
||||
static ffb_position_t *ffb_position;
|
||||
|
||||
static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
|
||||
static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance)
|
||||
{
|
||||
volatile unsigned char *strap_bits;
|
||||
unsigned char val;
|
||||
|
||||
strap_bits = (volatile unsigned char *)
|
||||
(ffb_priv->card_phys_base + 0x00200000UL);
|
||||
(ffb_priv->card_phys_base + 0x00200000UL);
|
||||
|
||||
/* Don't ask, you have to read the value twice for whatever
|
||||
* reason to get correct contents.
|
||||
|
@ -61,7 +61,8 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
|
|||
break;
|
||||
case (0x1 << 5) | (0x0 << 3):
|
||||
ffb_priv->ffb_type = ffb2_prototype;
|
||||
printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", instance);
|
||||
printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n",
|
||||
instance);
|
||||
break;
|
||||
case (0x1 << 5) | (0x1 << 3):
|
||||
ffb_priv->ffb_type = ffb2_vertical;
|
||||
|
@ -81,12 +82,13 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
|
|||
break;
|
||||
default:
|
||||
ffb_priv->ffb_type = ffb2_vertical;
|
||||
printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", instance, val);
|
||||
printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n",
|
||||
instance, val);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
static void ffb_apply_upa_parent_ranges(int parent,
|
||||
static void ffb_apply_upa_parent_ranges(int parent,
|
||||
struct linux_prom64_registers *regs)
|
||||
{
|
||||
struct linux_prom64_ranges ranges[PROMREG_MAX];
|
||||
|
@ -97,7 +99,8 @@ static void ffb_apply_upa_parent_ranges(int parent,
|
|||
if (strcmp(name, "upa") != 0)
|
||||
return;
|
||||
|
||||
len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
|
||||
len =
|
||||
prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges));
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
|
@ -117,11 +120,11 @@ static void ffb_apply_upa_parent_ranges(int parent,
|
|||
return;
|
||||
}
|
||||
|
||||
static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
|
||||
static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node,
|
||||
int instance)
|
||||
{
|
||||
struct linux_prom64_registers regs[2*PROMREG_MAX];
|
||||
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
|
||||
struct linux_prom64_registers regs[2 * PROMREG_MAX];
|
||||
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
int i;
|
||||
|
||||
ffb_priv->prom_node = prom_node;
|
||||
|
@ -132,27 +135,27 @@ static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
|
|||
ffb_apply_upa_parent_ranges(parent_node, ®s[0]);
|
||||
ffb_priv->card_phys_base = regs[0].phys_addr;
|
||||
ffb_priv->regs = (ffb_fbcPtr)
|
||||
(regs[0].phys_addr + 0x00600000UL);
|
||||
(regs[0].phys_addr + 0x00600000UL);
|
||||
get_ffb_type(ffb_priv, instance);
|
||||
for (i = 0; i < FFB_MAX_CTXS; i++)
|
||||
ffb_priv->hw_state[i] = NULL;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
drm_map_list_t *r_list;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
drm_map_t *map;
|
||||
drm_map_t *map;
|
||||
|
||||
if (!priv || (dev = priv->dev) == NULL)
|
||||
return NULL;
|
||||
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
r_list = (drm_map_list_t *) list;
|
||||
map = r_list->map;
|
||||
if (!map)
|
||||
continue;
|
||||
|
@ -166,8 +169,7 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
|
|||
unsigned long ffb_get_unmapped_area(struct file *filp,
|
||||
unsigned long hint,
|
||||
unsigned long len,
|
||||
unsigned long pgoff,
|
||||
unsigned long flags)
|
||||
unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
|
||||
unsigned long addr = -ENOMEM;
|
||||
|
@ -175,8 +177,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
|
|||
if (!map)
|
||||
return get_unmapped_area(NULL, hint, len, pgoff, flags);
|
||||
|
||||
if (map->type == _DRM_FRAME_BUFFER ||
|
||||
map->type == _DRM_REGISTERS) {
|
||||
if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) {
|
||||
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
|
||||
addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
|
||||
#else
|
||||
|
@ -187,7 +188,7 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
|
|||
|
||||
addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
|
||||
if (!(addr & ~PAGE_MASK)) {
|
||||
unsigned long kvirt = (unsigned long) map->handle;
|
||||
unsigned long kvirt = (unsigned long)map->handle;
|
||||
|
||||
if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
|
||||
unsigned long koff, aoff;
|
||||
|
@ -207,9 +208,9 @@ unsigned long ffb_get_unmapped_area(struct file *filp,
|
|||
return addr;
|
||||
}
|
||||
|
||||
static int ffb_presetup(drm_device_t *dev)
|
||||
static int ffb_presetup(drm_device_t * dev)
|
||||
{
|
||||
ffb_dev_priv_t *ffb_priv;
|
||||
ffb_dev_priv_t *ffb_priv;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
|
@ -224,14 +225,11 @@ static int ffb_presetup(drm_device_t *dev)
|
|||
memset(ffb_priv, 0, sizeof(*ffb_priv));
|
||||
dev->dev_private = ffb_priv;
|
||||
|
||||
ret = ffb_init_one(dev,
|
||||
ffb_position[i].node,
|
||||
ffb_position[i].root,
|
||||
i);
|
||||
ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ffb_driver_release(drm_device_t *dev, struct file *filp)
|
||||
static void ffb_driver_release(drm_device_t * dev, struct file *filp)
|
||||
{
|
||||
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
|
||||
|
@ -239,84 +237,82 @@ static void ffb_driver_release(drm_device_t *dev, struct file *filp)
|
|||
|
||||
idx = context - 1;
|
||||
if (fpriv &&
|
||||
context != DRM_KERNEL_CONTEXT &&
|
||||
fpriv->hw_state[idx] != NULL) {
|
||||
context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) {
|
||||
kfree(fpriv->hw_state[idx]);
|
||||
fpriv->hw_state[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ffb_driver_pretakedown(drm_device_t *dev)
|
||||
static void ffb_driver_pretakedown(drm_device_t * dev)
|
||||
{
|
||||
if (dev->dev_private) kfree(dev->dev_private);
|
||||
if (dev->dev_private)
|
||||
kfree(dev->dev_private);
|
||||
}
|
||||
|
||||
static int ffb_driver_postcleanup(drm_device_t *dev)
|
||||
static int ffb_driver_postcleanup(drm_device_t * dev)
|
||||
{
|
||||
if (ffb_position != NULL) kfree(ffb_position);
|
||||
if (ffb_position != NULL)
|
||||
kfree(ffb_position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, drm_lock_t *lock)
|
||||
static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev,
|
||||
drm_lock_t * lock)
|
||||
{
|
||||
dev->lock.filp = 0;
|
||||
{
|
||||
__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
|
||||
unsigned int old, new, prev, ctx;
|
||||
|
||||
|
||||
ctx = lock->context;
|
||||
do {
|
||||
old = *plock;
|
||||
new = ctx;
|
||||
old = *plock;
|
||||
new = ctx;
|
||||
prev = cmpxchg(plock, old, new);
|
||||
} while (prev != old);
|
||||
}
|
||||
wake_up_interruptible(&dev->lock.lock_queue);
|
||||
}
|
||||
|
||||
static unsigned long ffb_driver_get_map_ofs(drm_map_t *map)
|
||||
static unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
|
||||
{
|
||||
return (map->offset & 0xffffffff);
|
||||
}
|
||||
|
||||
static unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev)
|
||||
static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
|
||||
{
|
||||
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
|
||||
|
||||
if (ffb_priv)
|
||||
return ffb_priv->card_phys_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
|
||||
|
||||
if (ffb_priv)
|
||||
return ffb_priv->card_phys_base;
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->minor
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static drm_ioctl_desc_t ioctls[] = {
|
||||
|
||||
|
||||
};
|
||||
|
||||
static struct drm_driver driver = {
|
||||
|
@ -335,14 +331,15 @@ static struct drm_driver driver = {
|
|||
.ioctls = ioctls,
|
||||
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
}
|
||||
,
|
||||
};
|
||||
|
||||
static int __init ffb_init(void)
|
||||
|
@ -357,6 +354,6 @@ static void __exit ffb_exit(void)
|
|||
module_init(ffb_init);
|
||||
module_exit(ffb_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/* Auxilliary clips. */
|
||||
typedef struct {
|
||||
typedef struct {
|
||||
volatile unsigned int min;
|
||||
volatile unsigned int max;
|
||||
} ffb_auxclip, *ffb_auxclipPtr;
|
||||
|
@ -15,172 +15,265 @@ typedef struct _ffb_fbc {
|
|||
/* Next vertex registers, on the right we list which drawops
|
||||
* use said register and the logical name the register has in
|
||||
* that context.
|
||||
*/ /* DESCRIPTION DRAWOP(NAME) */
|
||||
/*0x00*/unsigned int pad1[3]; /* Reserved */
|
||||
/*0x0c*/volatile unsigned int alpha; /* ALPHA Transparency */
|
||||
/*0x10*/volatile unsigned int red; /* RED */
|
||||
/*0x14*/volatile unsigned int green; /* GREEN */
|
||||
/*0x18*/volatile unsigned int blue; /* BLUE */
|
||||
/*0x1c*/volatile unsigned int z; /* DEPTH */
|
||||
/*0x20*/volatile unsigned int y; /* Y triangle(DOYF) */
|
||||
/* aadot(DYF) */
|
||||
/* ddline(DYF) */
|
||||
/* aaline(DYF) */
|
||||
/*0x24*/volatile unsigned int x; /* X triangle(DOXF) */
|
||||
/* aadot(DXF) */
|
||||
/* ddline(DXF) */
|
||||
/* aaline(DXF) */
|
||||
/*0x28*/unsigned int pad2[2]; /* Reserved */
|
||||
/*0x30*/volatile unsigned int ryf; /* Y (alias to DOYF) ddline(RYF) */
|
||||
/* aaline(RYF) */
|
||||
/* triangle(RYF) */
|
||||
/*0x34*/volatile unsigned int rxf; /* X ddline(RXF) */
|
||||
/* aaline(RXF) */
|
||||
/* triangle(RXF) */
|
||||
/*0x38*/unsigned int pad3[2]; /* Reserved */
|
||||
/*0x40*/volatile unsigned int dmyf; /* Y (alias to DOYF) triangle(DMYF) */
|
||||
/*0x44*/volatile unsigned int dmxf; /* X triangle(DMXF) */
|
||||
/*0x48*/unsigned int pad4[2]; /* Reserved */
|
||||
/*0x50*/volatile unsigned int ebyi; /* Y (alias to RYI) polygon(EBYI) */
|
||||
/*0x54*/volatile unsigned int ebxi; /* X polygon(EBXI) */
|
||||
/*0x58*/unsigned int pad5[2]; /* Reserved */
|
||||
/*0x60*/volatile unsigned int by; /* Y brline(RYI) */
|
||||
/* fastfill(OP) */
|
||||
/* polygon(YI) */
|
||||
/* rectangle(YI) */
|
||||
/* bcopy(SRCY) */
|
||||
/* vscroll(SRCY) */
|
||||
/*0x64*/volatile unsigned int bx; /* X brline(RXI) */
|
||||
/* polygon(XI) */
|
||||
/* rectangle(XI) */
|
||||
/* bcopy(SRCX) */
|
||||
/* vscroll(SRCX) */
|
||||
/* fastfill(GO) */
|
||||
/*0x68*/volatile unsigned int dy; /* destination Y fastfill(DSTY) */
|
||||
/* bcopy(DSRY) */
|
||||
/* vscroll(DSRY) */
|
||||
/*0x6c*/volatile unsigned int dx; /* destination X fastfill(DSTX) */
|
||||
/* bcopy(DSTX) */
|
||||
/* vscroll(DSTX) */
|
||||
/*0x70*/volatile unsigned int bh; /* Y (alias to RYI) brline(DYI) */
|
||||
/* dot(DYI) */
|
||||
/* polygon(ETYI) */
|
||||
/* Height fastfill(H) */
|
||||
/* bcopy(H) */
|
||||
/* vscroll(H) */
|
||||
/* Y count fastfill(NY) */
|
||||
/*0x74*/volatile unsigned int bw; /* X dot(DXI) */
|
||||
/* brline(DXI) */
|
||||
/* polygon(ETXI) */
|
||||
/* fastfill(W) */
|
||||
/* bcopy(W) */
|
||||
/* vscroll(W) */
|
||||
/* fastfill(NX) */
|
||||
/*0x78*/unsigned int pad6[2]; /* Reserved */
|
||||
/*0x80*/unsigned int pad7[32]; /* Reserved */
|
||||
|
||||
/* Setup Unit's vertex state register */
|
||||
/*100*/ volatile unsigned int suvtx;
|
||||
/*104*/ unsigned int pad8[63]; /* Reserved */
|
||||
|
||||
/* Frame Buffer Control Registers */
|
||||
/*200*/ volatile unsigned int ppc; /* Pixel Processor Control */
|
||||
/*204*/ volatile unsigned int wid; /* Current WID */
|
||||
/*208*/ volatile unsigned int fg; /* FG data */
|
||||
/*20c*/ volatile unsigned int bg; /* BG data */
|
||||
/*210*/ volatile unsigned int consty; /* Constant Y */
|
||||
/*214*/ volatile unsigned int constz; /* Constant Z */
|
||||
/*218*/ volatile unsigned int xclip; /* X Clip */
|
||||
/*21c*/ volatile unsigned int dcss; /* Depth Cue Scale Slope */
|
||||
/*220*/ volatile unsigned int vclipmin; /* Viewclip XY Min Bounds */
|
||||
/*224*/ volatile unsigned int vclipmax; /* Viewclip XY Max Bounds */
|
||||
/*228*/ volatile unsigned int vclipzmin; /* Viewclip Z Min Bounds */
|
||||
/*22c*/ volatile unsigned int vclipzmax; /* Viewclip Z Max Bounds */
|
||||
/*230*/ volatile unsigned int dcsf; /* Depth Cue Scale Front Bound */
|
||||
/*234*/ volatile unsigned int dcsb; /* Depth Cue Scale Back Bound */
|
||||
/*238*/ volatile unsigned int dczf; /* Depth Cue Z Front */
|
||||
/*23c*/ volatile unsigned int dczb; /* Depth Cue Z Back */
|
||||
/*240*/ unsigned int pad9; /* Reserved */
|
||||
/*244*/ volatile unsigned int blendc; /* Alpha Blend Control */
|
||||
/*248*/ volatile unsigned int blendc1; /* Alpha Blend Color 1 */
|
||||
/*24c*/ volatile unsigned int blendc2; /* Alpha Blend Color 2 */
|
||||
/*250*/ volatile unsigned int fbramitc; /* FB RAM Interleave Test Control */
|
||||
/*254*/ volatile unsigned int fbc; /* Frame Buffer Control */
|
||||
/*258*/ volatile unsigned int rop; /* Raster OPeration */
|
||||
/*25c*/ volatile unsigned int cmp; /* Frame Buffer Compare */
|
||||
/*260*/ volatile unsigned int matchab; /* Buffer AB Match Mask */
|
||||
/*264*/ volatile unsigned int matchc; /* Buffer C(YZ) Match Mask */
|
||||
/*268*/ volatile unsigned int magnab; /* Buffer AB Magnitude Mask */
|
||||
/*26c*/ volatile unsigned int magnc; /* Buffer C(YZ) Magnitude Mask */
|
||||
/*270*/ volatile unsigned int fbcfg0; /* Frame Buffer Config 0 */
|
||||
/*274*/ volatile unsigned int fbcfg1; /* Frame Buffer Config 1 */
|
||||
/*278*/ volatile unsigned int fbcfg2; /* Frame Buffer Config 2 */
|
||||
/*27c*/ volatile unsigned int fbcfg3; /* Frame Buffer Config 3 */
|
||||
/*280*/ volatile unsigned int ppcfg; /* Pixel Processor Config */
|
||||
/*284*/ volatile unsigned int pick; /* Picking Control */
|
||||
/*288*/ volatile unsigned int fillmode; /* FillMode */
|
||||
/*28c*/ volatile unsigned int fbramwac; /* FB RAM Write Address Control */
|
||||
/*290*/ volatile unsigned int pmask; /* RGB PlaneMask */
|
||||
/*294*/ volatile unsigned int xpmask; /* X PlaneMask */
|
||||
/*298*/ volatile unsigned int ypmask; /* Y PlaneMask */
|
||||
/*29c*/ volatile unsigned int zpmask; /* Z PlaneMask */
|
||||
/*2a0*/ ffb_auxclip auxclip[4]; /* Auxilliary Viewport Clip */
|
||||
|
||||
/* New 3dRAM III support regs */
|
||||
/*2c0*/ volatile unsigned int rawblend2;
|
||||
/*2c4*/ volatile unsigned int rawpreblend;
|
||||
/*2c8*/ volatile unsigned int rawstencil;
|
||||
/*2cc*/ volatile unsigned int rawstencilctl;
|
||||
/*2d0*/ volatile unsigned int threedram1;
|
||||
/*2d4*/ volatile unsigned int threedram2;
|
||||
/*2d8*/ volatile unsigned int passin;
|
||||
/*2dc*/ volatile unsigned int rawclrdepth;
|
||||
/*2e0*/ volatile unsigned int rawpmask;
|
||||
/*2e4*/ volatile unsigned int rawcsrc;
|
||||
/*2e8*/ volatile unsigned int rawmatch;
|
||||
/*2ec*/ volatile unsigned int rawmagn;
|
||||
/*2f0*/ volatile unsigned int rawropblend;
|
||||
/*2f4*/ volatile unsigned int rawcmp;
|
||||
/*2f8*/ volatile unsigned int rawwac;
|
||||
/*2fc*/ volatile unsigned int fbramid;
|
||||
|
||||
/*300*/ volatile unsigned int drawop; /* Draw OPeration */
|
||||
/*304*/ unsigned int pad10[2]; /* Reserved */
|
||||
/*30c*/ volatile unsigned int lpat; /* Line Pattern control */
|
||||
/*310*/ unsigned int pad11; /* Reserved */
|
||||
/*314*/ volatile unsigned int fontxy; /* XY Font coordinate */
|
||||
/*318*/ volatile unsigned int fontw; /* Font Width */
|
||||
/*31c*/ volatile unsigned int fontinc; /* Font Increment */
|
||||
/*320*/ volatile unsigned int font; /* Font bits */
|
||||
/*324*/ unsigned int pad12[3]; /* Reserved */
|
||||
/*330*/ volatile unsigned int blend2;
|
||||
/*334*/ volatile unsigned int preblend;
|
||||
/*338*/ volatile unsigned int stencil;
|
||||
/*33c*/ volatile unsigned int stencilctl;
|
||||
*//* DESCRIPTION DRAWOP(NAME) */
|
||||
/*0x00*/ unsigned int pad1[3];
|
||||
/* Reserved */
|
||||
/*0x0c*/ volatile unsigned int alpha;
|
||||
/* ALPHA Transparency */
|
||||
/*0x10*/ volatile unsigned int red;
|
||||
/* RED */
|
||||
/*0x14*/ volatile unsigned int green;
|
||||
/* GREEN */
|
||||
/*0x18*/ volatile unsigned int blue;
|
||||
/* BLUE */
|
||||
/*0x1c*/ volatile unsigned int z;
|
||||
/* DEPTH */
|
||||
/*0x20*/ volatile unsigned int y;
|
||||
/* Y triangle(DOYF) */
|
||||
/* aadot(DYF) */
|
||||
/* ddline(DYF) */
|
||||
/* aaline(DYF) */
|
||||
/*0x24*/ volatile unsigned int x;
|
||||
/* X triangle(DOXF) */
|
||||
/* aadot(DXF) */
|
||||
/* ddline(DXF) */
|
||||
/* aaline(DXF) */
|
||||
/*0x28*/ unsigned int pad2[2];
|
||||
/* Reserved */
|
||||
/*0x30*/ volatile unsigned int ryf;
|
||||
/* Y (alias to DOYF) ddline(RYF) */
|
||||
/* aaline(RYF) */
|
||||
/* triangle(RYF) */
|
||||
/*0x34*/ volatile unsigned int rxf;
|
||||
/* X ddline(RXF) */
|
||||
/* aaline(RXF) */
|
||||
/* triangle(RXF) */
|
||||
/*0x38*/ unsigned int pad3[2];
|
||||
/* Reserved */
|
||||
/*0x40*/ volatile unsigned int dmyf;
|
||||
/* Y (alias to DOYF) triangle(DMYF) */
|
||||
/*0x44*/ volatile unsigned int dmxf;
|
||||
/* X triangle(DMXF) */
|
||||
/*0x48*/ unsigned int pad4[2];
|
||||
/* Reserved */
|
||||
/*0x50*/ volatile unsigned int ebyi;
|
||||
/* Y (alias to RYI) polygon(EBYI) */
|
||||
/*0x54*/ volatile unsigned int ebxi;
|
||||
/* X polygon(EBXI) */
|
||||
/*0x58*/ unsigned int pad5[2];
|
||||
/* Reserved */
|
||||
/*0x60*/ volatile unsigned int by;
|
||||
/* Y brline(RYI) */
|
||||
/* fastfill(OP) */
|
||||
/* polygon(YI) */
|
||||
/* rectangle(YI) */
|
||||
/* bcopy(SRCY) */
|
||||
/* vscroll(SRCY) */
|
||||
/*0x64*/ volatile unsigned int bx;
|
||||
/* X brline(RXI) */
|
||||
/* polygon(XI) */
|
||||
/* rectangle(XI) */
|
||||
/* bcopy(SRCX) */
|
||||
/* vscroll(SRCX) */
|
||||
/* fastfill(GO) */
|
||||
/*0x68*/ volatile unsigned int dy;
|
||||
/* destination Y fastfill(DSTY) */
|
||||
/* bcopy(DSRY) */
|
||||
/* vscroll(DSRY) */
|
||||
/*0x6c*/ volatile unsigned int dx;
|
||||
/* destination X fastfill(DSTX) */
|
||||
/* bcopy(DSTX) */
|
||||
/* vscroll(DSTX) */
|
||||
/*0x70*/ volatile unsigned int bh;
|
||||
/* Y (alias to RYI) brline(DYI) */
|
||||
/* dot(DYI) */
|
||||
/* polygon(ETYI) */
|
||||
/* Height fastfill(H) */
|
||||
/* bcopy(H) */
|
||||
/* vscroll(H) */
|
||||
/* Y count fastfill(NY) */
|
||||
/*0x74*/ volatile unsigned int bw;
|
||||
/* X dot(DXI) */
|
||||
/* brline(DXI) */
|
||||
/* polygon(ETXI) */
|
||||
/* fastfill(W) */
|
||||
/* bcopy(W) */
|
||||
/* vscroll(W) */
|
||||
/* fastfill(NX) */
|
||||
/*0x78*/ unsigned int pad6[2];
|
||||
/* Reserved */
|
||||
/*0x80*/ unsigned int pad7[32];
|
||||
/* Reserved */
|
||||
|
||||
/*340*/ unsigned int pad13[4]; /* Reserved */
|
||||
/*350*/ volatile unsigned int dcss1; /* Depth Cue Scale Slope 1 */
|
||||
/*354*/ volatile unsigned int dcss2; /* Depth Cue Scale Slope 2 */
|
||||
/*358*/ volatile unsigned int dcss3; /* Depth Cue Scale Slope 3 */
|
||||
/*35c*/ volatile unsigned int widpmask;
|
||||
/*360*/ volatile unsigned int dcs2;
|
||||
/*364*/ volatile unsigned int dcs3;
|
||||
/*368*/ volatile unsigned int dcs4;
|
||||
/*36c*/ unsigned int pad14; /* Reserved */
|
||||
/*370*/ volatile unsigned int dcd2;
|
||||
/*374*/ volatile unsigned int dcd3;
|
||||
/*378*/ volatile unsigned int dcd4;
|
||||
/*37c*/ unsigned int pad15; /* Reserved */
|
||||
/*380*/ volatile unsigned int pattern[32]; /* area Pattern */
|
||||
/*400*/ unsigned int pad16[8]; /* Reserved */
|
||||
/*420*/ volatile unsigned int reset; /* chip RESET */
|
||||
/*424*/ unsigned int pad17[247]; /* Reserved */
|
||||
/*800*/ volatile unsigned int devid; /* Device ID */
|
||||
/*804*/ unsigned int pad18[63]; /* Reserved */
|
||||
/*900*/ volatile unsigned int ucsr; /* User Control & Status Register */
|
||||
/*904*/ unsigned int pad19[31]; /* Reserved */
|
||||
/*980*/ volatile unsigned int mer; /* Mode Enable Register */
|
||||
/*984*/ unsigned int pad20[1439]; /* Reserved */
|
||||
/* Setup Unit's vertex state register */
|
||||
/*100*/ volatile unsigned int suvtx;
|
||||
/*104*/ unsigned int pad8[63];
|
||||
/* Reserved */
|
||||
|
||||
/* Frame Buffer Control Registers */
|
||||
/*200*/ volatile unsigned int ppc;
|
||||
/* Pixel Processor Control */
|
||||
/*204*/ volatile unsigned int wid;
|
||||
/* Current WID */
|
||||
/*208*/ volatile unsigned int fg;
|
||||
/* FG data */
|
||||
/*20c*/ volatile unsigned int bg;
|
||||
/* BG data */
|
||||
/*210*/ volatile unsigned int consty;
|
||||
/* Constant Y */
|
||||
/*214*/ volatile unsigned int constz;
|
||||
/* Constant Z */
|
||||
/*218*/ volatile unsigned int xclip;
|
||||
/* X Clip */
|
||||
/*21c*/ volatile unsigned int dcss;
|
||||
/* Depth Cue Scale Slope */
|
||||
/*220*/ volatile unsigned int vclipmin;
|
||||
/* Viewclip XY Min Bounds */
|
||||
/*224*/ volatile unsigned int vclipmax;
|
||||
/* Viewclip XY Max Bounds */
|
||||
/*228*/ volatile unsigned int vclipzmin;
|
||||
/* Viewclip Z Min Bounds */
|
||||
/*22c*/ volatile unsigned int vclipzmax;
|
||||
/* Viewclip Z Max Bounds */
|
||||
/*230*/ volatile unsigned int dcsf;
|
||||
/* Depth Cue Scale Front Bound */
|
||||
/*234*/ volatile unsigned int dcsb;
|
||||
/* Depth Cue Scale Back Bound */
|
||||
/*238*/ volatile unsigned int dczf;
|
||||
/* Depth Cue Z Front */
|
||||
/*23c*/ volatile unsigned int dczb;
|
||||
/* Depth Cue Z Back */
|
||||
/*240*/ unsigned int pad9;
|
||||
/* Reserved */
|
||||
/*244*/ volatile unsigned int blendc;
|
||||
/* Alpha Blend Control */
|
||||
/*248*/ volatile unsigned int blendc1;
|
||||
/* Alpha Blend Color 1 */
|
||||
/*24c*/ volatile unsigned int blendc2;
|
||||
/* Alpha Blend Color 2 */
|
||||
/*250*/ volatile unsigned int fbramitc;
|
||||
/* FB RAM Interleave Test Control */
|
||||
/*254*/ volatile unsigned int fbc;
|
||||
/* Frame Buffer Control */
|
||||
/*258*/ volatile unsigned int rop;
|
||||
/* Raster OPeration */
|
||||
/*25c*/ volatile unsigned int cmp;
|
||||
/* Frame Buffer Compare */
|
||||
/*260*/ volatile unsigned int matchab;
|
||||
/* Buffer AB Match Mask */
|
||||
/*264*/ volatile unsigned int matchc;
|
||||
/* Buffer C(YZ) Match Mask */
|
||||
/*268*/ volatile unsigned int magnab;
|
||||
/* Buffer AB Magnitude Mask */
|
||||
/*26c*/ volatile unsigned int magnc;
|
||||
/* Buffer C(YZ) Magnitude Mask */
|
||||
/*270*/ volatile unsigned int fbcfg0;
|
||||
/* Frame Buffer Config 0 */
|
||||
/*274*/ volatile unsigned int fbcfg1;
|
||||
/* Frame Buffer Config 1 */
|
||||
/*278*/ volatile unsigned int fbcfg2;
|
||||
/* Frame Buffer Config 2 */
|
||||
/*27c*/ volatile unsigned int fbcfg3;
|
||||
/* Frame Buffer Config 3 */
|
||||
/*280*/ volatile unsigned int ppcfg;
|
||||
/* Pixel Processor Config */
|
||||
/*284*/ volatile unsigned int pick;
|
||||
/* Picking Control */
|
||||
/*288*/ volatile unsigned int fillmode;
|
||||
/* FillMode */
|
||||
/*28c*/ volatile unsigned int fbramwac;
|
||||
/* FB RAM Write Address Control */
|
||||
/*290*/ volatile unsigned int pmask;
|
||||
/* RGB PlaneMask */
|
||||
/*294*/ volatile unsigned int xpmask;
|
||||
/* X PlaneMask */
|
||||
/*298*/ volatile unsigned int ypmask;
|
||||
/* Y PlaneMask */
|
||||
/*29c*/ volatile unsigned int zpmask;
|
||||
/* Z PlaneMask */
|
||||
/*2a0*/ ffb_auxclip auxclip[4];
|
||||
/* Auxilliary Viewport Clip */
|
||||
|
||||
/* New 3dRAM III support regs */
|
||||
/*2c0*/ volatile unsigned int rawblend2;
|
||||
/*2c4*/ volatile unsigned int rawpreblend;
|
||||
/*2c8*/ volatile unsigned int rawstencil;
|
||||
/*2cc*/ volatile unsigned int rawstencilctl;
|
||||
/*2d0*/ volatile unsigned int threedram1;
|
||||
/*2d4*/ volatile unsigned int threedram2;
|
||||
/*2d8*/ volatile unsigned int passin;
|
||||
/*2dc*/ volatile unsigned int rawclrdepth;
|
||||
/*2e0*/ volatile unsigned int rawpmask;
|
||||
/*2e4*/ volatile unsigned int rawcsrc;
|
||||
/*2e8*/ volatile unsigned int rawmatch;
|
||||
/*2ec*/ volatile unsigned int rawmagn;
|
||||
/*2f0*/ volatile unsigned int rawropblend;
|
||||
/*2f4*/ volatile unsigned int rawcmp;
|
||||
/*2f8*/ volatile unsigned int rawwac;
|
||||
/*2fc*/ volatile unsigned int fbramid;
|
||||
|
||||
/*300*/ volatile unsigned int drawop;
|
||||
/* Draw OPeration */
|
||||
/*304*/ unsigned int pad10[2];
|
||||
/* Reserved */
|
||||
/*30c*/ volatile unsigned int lpat;
|
||||
/* Line Pattern control */
|
||||
/*310*/ unsigned int pad11;
|
||||
/* Reserved */
|
||||
/*314*/ volatile unsigned int fontxy;
|
||||
/* XY Font coordinate */
|
||||
/*318*/ volatile unsigned int fontw;
|
||||
/* Font Width */
|
||||
/*31c*/ volatile unsigned int fontinc;
|
||||
/* Font Increment */
|
||||
/*320*/ volatile unsigned int font;
|
||||
/* Font bits */
|
||||
/*324*/ unsigned int pad12[3];
|
||||
/* Reserved */
|
||||
/*330*/ volatile unsigned int blend2;
|
||||
/*334*/ volatile unsigned int preblend;
|
||||
/*338*/ volatile unsigned int stencil;
|
||||
/*33c*/ volatile unsigned int stencilctl;
|
||||
|
||||
/*340*/ unsigned int pad13[4];
|
||||
/* Reserved */
|
||||
/*350*/ volatile unsigned int dcss1;
|
||||
/* Depth Cue Scale Slope 1 */
|
||||
/*354*/ volatile unsigned int dcss2;
|
||||
/* Depth Cue Scale Slope 2 */
|
||||
/*358*/ volatile unsigned int dcss3;
|
||||
/* Depth Cue Scale Slope 3 */
|
||||
/*35c*/ volatile unsigned int widpmask;
|
||||
/*360*/ volatile unsigned int dcs2;
|
||||
/*364*/ volatile unsigned int dcs3;
|
||||
/*368*/ volatile unsigned int dcs4;
|
||||
/*36c*/ unsigned int pad14;
|
||||
/* Reserved */
|
||||
/*370*/ volatile unsigned int dcd2;
|
||||
/*374*/ volatile unsigned int dcd3;
|
||||
/*378*/ volatile unsigned int dcd4;
|
||||
/*37c*/ unsigned int pad15;
|
||||
/* Reserved */
|
||||
/*380*/ volatile unsigned int pattern[32];
|
||||
/* area Pattern */
|
||||
/*400*/ unsigned int pad16[8];
|
||||
/* Reserved */
|
||||
/*420*/ volatile unsigned int reset;
|
||||
/* chip RESET */
|
||||
/*424*/ unsigned int pad17[247];
|
||||
/* Reserved */
|
||||
/*800*/ volatile unsigned int devid;
|
||||
/* Device ID */
|
||||
/*804*/ unsigned int pad18[63];
|
||||
/* Reserved */
|
||||
/*900*/ volatile unsigned int ucsr;
|
||||
/* User Control & Status Register */
|
||||
/*904*/ unsigned int pad19[31];
|
||||
/* Reserved */
|
||||
/*980*/ volatile unsigned int mer;
|
||||
/* Mode Enable Register */
|
||||
/*984*/ unsigned int pad20[1439];
|
||||
/* Reserved */
|
||||
} ffb_fbc, *ffb_fbcPtr;
|
||||
|
||||
struct ffb_hw_context {
|
||||
|
@ -263,16 +356,16 @@ enum ffb_chip_type {
|
|||
|
||||
typedef struct ffb_dev_priv {
|
||||
/* Misc software state. */
|
||||
int prom_node;
|
||||
enum ffb_chip_type ffb_type;
|
||||
u64 card_phys_base;
|
||||
struct miscdevice miscdev;
|
||||
int prom_node;
|
||||
enum ffb_chip_type ffb_type;
|
||||
u64 card_phys_base;
|
||||
struct miscdevice miscdev;
|
||||
|
||||
/* Controller registers. */
|
||||
ffb_fbcPtr regs;
|
||||
ffb_fbcPtr regs;
|
||||
|
||||
/* Context table. */
|
||||
struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
|
||||
struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
|
||||
} ffb_dev_priv_t;
|
||||
|
||||
extern unsigned long ffb_get_unmapped_area(struct file *filp,
|
||||
|
@ -283,4 +376,4 @@ extern unsigned long ffb_get_unmapped_area(struct file *filp,
|
|||
extern void ffb_set_context_ioctls(void);
|
||||
extern drm_ioctl_desc_t DRM(ioctls)[];
|
||||
|
||||
extern int ffb_driver_context_switch(drm_device_t *dev, int old, int new);
|
||||
extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,21 +19,20 @@
|
|||
#define I810_LOG_MIN_TEX_REGION_SIZE 16
|
||||
#endif
|
||||
|
||||
#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
|
||||
#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
|
||||
#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
|
||||
#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
|
||||
#define I810_UPLOAD_CTX 0x4
|
||||
#define I810_UPLOAD_BUFFERS 0x8
|
||||
#define I810_UPLOAD_TEX0 0x10
|
||||
#define I810_UPLOAD_TEX1 0x20
|
||||
#define I810_UPLOAD_CLIPRECTS 0x40
|
||||
|
||||
|
||||
/* Indices into buf.Setup where various bits of state are mirrored per
|
||||
* context and per buffer. These can be fired at the card as a unit,
|
||||
* or in a piecewise fashion as required.
|
||||
*/
|
||||
|
||||
/* Destbuffer state
|
||||
/* Destbuffer state
|
||||
* - backbuffer linear offset and pitch -- invarient in the current dri
|
||||
* - zbuffer linear offset and pitch -- also invarient
|
||||
* - drawing origin in back and depth buffers.
|
||||
|
@ -55,13 +54,13 @@
|
|||
/* Context state
|
||||
*/
|
||||
#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
|
||||
#define I810_CTXREG_CF1 1
|
||||
#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
|
||||
#define I810_CTXREG_CF1 1
|
||||
#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
|
||||
#define I810_CTXREG_ST1 3
|
||||
#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
|
||||
#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
|
||||
#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
|
||||
#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
|
||||
#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
|
||||
#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
|
||||
#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
|
||||
#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
|
||||
|
@ -74,14 +73,14 @@
|
|||
#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
|
||||
#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
|
||||
#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
|
||||
#define I810_CTX_SETUP_SIZE 20
|
||||
#define I810_CTX_SETUP_SIZE 20
|
||||
|
||||
/* Texture state (per tex unit)
|
||||
*/
|
||||
#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
|
||||
#define I810_TEXREG_MI1 1
|
||||
#define I810_TEXREG_MI2 2
|
||||
#define I810_TEXREG_MI3 3
|
||||
#define I810_TEXREG_MI1 1
|
||||
#define I810_TEXREG_MI2 2
|
||||
#define I810_TEXREG_MI3 3
|
||||
#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
|
||||
#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
|
||||
#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
|
||||
|
@ -98,7 +97,7 @@ typedef enum _drm_i810_init_func {
|
|||
I810_INIT_DMA = 0x01,
|
||||
I810_CLEANUP_DMA = 0x02,
|
||||
I810_INIT_DMA_1_4 = 0x03
|
||||
} drm_i810_init_func_t;
|
||||
} drm_i810_init_func_t;
|
||||
|
||||
/* This is the init structure after v1.2 */
|
||||
typedef struct _drm_i810_init {
|
||||
|
@ -122,7 +121,7 @@ typedef struct _drm_i810_init {
|
|||
unsigned int w;
|
||||
unsigned int h;
|
||||
unsigned int pitch;
|
||||
unsigned int pitch_bits;
|
||||
unsigned int pitch_bits;
|
||||
} drm_i810_init_t;
|
||||
|
||||
/* This is the init structure prior to v1.2 */
|
||||
|
@ -140,23 +139,23 @@ typedef struct _drm_i810_pre12_init {
|
|||
unsigned int w;
|
||||
unsigned int h;
|
||||
unsigned int pitch;
|
||||
unsigned int pitch_bits;
|
||||
unsigned int pitch_bits;
|
||||
} drm_i810_pre12_init_t;
|
||||
|
||||
/* Warning: If you change the SAREA structure you must change the Xserver
|
||||
* structure as well */
|
||||
|
||||
typedef struct _drm_i810_tex_region {
|
||||
unsigned char next, prev; /* indices to form a circular LRU */
|
||||
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_i810_tex_region_t;
|
||||
|
||||
typedef struct _drm_i810_sarea {
|
||||
unsigned int ContextState[I810_CTX_SETUP_SIZE];
|
||||
unsigned int BufferState[I810_DEST_SETUP_SIZE];
|
||||
unsigned int TexState[2][I810_TEX_SETUP_SIZE];
|
||||
unsigned int dirty;
|
||||
unsigned int ContextState[I810_CTX_SETUP_SIZE];
|
||||
unsigned int BufferState[I810_DEST_SETUP_SIZE];
|
||||
unsigned int TexState[2][I810_TEX_SETUP_SIZE];
|
||||
unsigned int dirty;
|
||||
|
||||
unsigned int nbox;
|
||||
drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
|
||||
|
@ -174,22 +173,22 @@ typedef struct _drm_i810_sarea {
|
|||
* 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.
|
||||
* them all in LRU order.
|
||||
*/
|
||||
|
||||
drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
|
||||
/* Last elt is sentinal */
|
||||
int texAge; /* last time texture was uploaded */
|
||||
int last_enqueue; /* last time a buffer was enqueued */
|
||||
|
||||
drm_i810_tex_region_t texList[I810_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 last_quiescent; /* */
|
||||
int ctxOwner; /* last context to upload state */
|
||||
|
||||
int vertex_prim;
|
||||
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_active;
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
} drm_i810_sarea_t;
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
|
@ -243,13 +242,13 @@ typedef struct _drm_i810_clear {
|
|||
* new set of cliprects.
|
||||
*/
|
||||
typedef struct _drm_i810_vertex {
|
||||
int idx; /* buffer index */
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
int discard; /* client is finished with the buffer? */
|
||||
} drm_i810_vertex_t;
|
||||
|
||||
typedef struct _drm_i810_copy_t {
|
||||
int idx; /* buffer index */
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
void *address; /* Address to copy from */
|
||||
} drm_i810_copy_t;
|
||||
|
@ -264,7 +263,6 @@ typedef struct _drm_i810_copy_t {
|
|||
#define PR_RECTS (0x7<<18)
|
||||
#define PR_MASK (0x7<<18)
|
||||
|
||||
|
||||
typedef struct drm_i810_dma {
|
||||
void *virtual;
|
||||
int request_idx;
|
||||
|
@ -273,17 +271,16 @@ typedef struct drm_i810_dma {
|
|||
} drm_i810_dma_t;
|
||||
|
||||
typedef struct _drm_i810_overlay_t {
|
||||
unsigned int offset; /* Address of the Overlay Regs */
|
||||
unsigned int offset; /* Address of the Overlay Regs */
|
||||
unsigned int physical;
|
||||
} drm_i810_overlay_t;
|
||||
|
||||
typedef struct _drm_i810_mc {
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
int num_blocks; /* number of GFXBlocks */
|
||||
int *length; /* List of lengths for GFXBlocks (FUTURE)*/
|
||||
unsigned int last_render; /* Last Render Request */
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
int num_blocks; /* number of GFXBlocks */
|
||||
int *length; /* List of lengths for GFXBlocks (FUTURE) */
|
||||
unsigned int last_render; /* Last Render Request */
|
||||
} drm_i810_mc_t;
|
||||
|
||||
|
||||
#endif /* _I810_DRM_H_ */
|
||||
#endif /* _I810_DRM_H_ */
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
/* i810 has 4 more counters */
|
||||
dev->counters += 4;
|
||||
|
@ -46,29 +46,27 @@ static int postinit( struct drm_device *dev, unsigned long flags )
|
|||
dev->types[7] = _DRM_STAT_PRIMARY;
|
||||
dev->types[8] = _DRM_STAT_SECONDARY;
|
||||
dev->types[9] = _DRM_STAT_DMA;
|
||||
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -76,11 +74,10 @@ static struct pci_device_id pciidlist[] = {
|
|||
i810_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t i810_ioctls[];
|
||||
extern int i810_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
|
||||
.dev_priv_size = sizeof(drm_i810_buf_priv_t),
|
||||
.pretakedown = i810_driver_pretakedown,
|
||||
.prerelease = i810_driver_prerelease,
|
||||
|
@ -94,18 +91,20 @@ static struct drm_driver driver = {
|
|||
.version = version,
|
||||
.ioctls = i810_ioctls,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
}
|
||||
,
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
},
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
,
|
||||
};
|
||||
|
||||
static int __init i810_init(void)
|
||||
|
@ -122,6 +121,6 @@ static void __exit i810_exit(void)
|
|||
module_init(i810_init);
|
||||
module_exit(i810_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -56,14 +56,14 @@
|
|||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
typedef struct drm_i810_buf_priv {
|
||||
u32 *in_use;
|
||||
int my_use_idx;
|
||||
u32 *in_use;
|
||||
int my_use_idx;
|
||||
int currently_mapped;
|
||||
void *virtual;
|
||||
void *kernel_virtual;
|
||||
} drm_i810_buf_priv_t;
|
||||
|
||||
typedef struct _drm_i810_ring_buffer{
|
||||
typedef struct _drm_i810_ring_buffer {
|
||||
int tail_mask;
|
||||
unsigned long Start;
|
||||
unsigned long End;
|
||||
|
@ -79,16 +79,15 @@ typedef struct drm_i810_private {
|
|||
drm_map_t *mmio_map;
|
||||
|
||||
drm_i810_sarea_t *sarea_priv;
|
||||
drm_i810_ring_buffer_t ring;
|
||||
drm_i810_ring_buffer_t ring;
|
||||
|
||||
void *hw_status_page;
|
||||
unsigned long counter;
|
||||
void *hw_status_page;
|
||||
unsigned long counter;
|
||||
|
||||
dma_addr_t dma_status_page;
|
||||
|
||||
drm_buf_t *mmap_buffer;
|
||||
|
||||
|
||||
u32 front_di1, back_di1, zi1;
|
||||
|
||||
int back_offset;
|
||||
|
@ -97,7 +96,7 @@ typedef struct drm_i810_private {
|
|||
int overlay_physical;
|
||||
int w, h;
|
||||
int pitch;
|
||||
int back_pitch;
|
||||
int back_pitch;
|
||||
int depth_pitch;
|
||||
|
||||
int do_boxes;
|
||||
|
@ -107,21 +106,24 @@ typedef struct drm_i810_private {
|
|||
int page_flipping;
|
||||
|
||||
wait_queue_head_t irq_queue;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int front_offset;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int front_offset;
|
||||
} drm_i810_private_t;
|
||||
|
||||
/* i810_dma.c */
|
||||
extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
|
||||
extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
|
||||
|
||||
extern int i810_driver_dma_quiescent(drm_device_t *dev);
|
||||
extern void i810_driver_release(drm_device_t *dev, struct file *filp);
|
||||
extern void i810_driver_pretakedown(drm_device_t *dev);
|
||||
extern void i810_driver_prerelease(drm_device_t *dev, DRMFILE filp);
|
||||
extern int i810_driver_dma_quiescent(drm_device_t * dev);
|
||||
extern void i810_driver_release(drm_device_t * dev, struct file *filp);
|
||||
extern void i810_driver_pretakedown(drm_device_t * dev);
|
||||
extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp);
|
||||
extern int i810_driver_device_is_agp(drm_device_t * dev);
|
||||
|
||||
extern drm_ioctl_desc_t i810_ioctls[];
|
||||
extern int i810_max_ioctl;
|
||||
|
||||
#define I810_BASE(reg) ((unsigned long) \
|
||||
dev_priv->mmio_map->handle)
|
||||
#define I810_ADDR(reg) (I810_BASE(reg) + reg)
|
||||
|
@ -170,7 +172,6 @@ extern int i810_driver_device_is_agp(drm_device_t * dev);
|
|||
#define INST_OP_FLUSH 0x02000000
|
||||
#define INST_FLUSH_MAP_CACHE 0x00000001
|
||||
|
||||
|
||||
#define BB1_START_ADDR_MASK (~0x7)
|
||||
#define BB1_PROTECTED (1<<0)
|
||||
#define BB1_UNPROTECTED (0<<0)
|
||||
|
@ -229,8 +230,8 @@ extern int i810_driver_device_is_agp(drm_device_t * dev);
|
|||
#define BR00_OP_SRC_COPY_BLT 0x10C00000
|
||||
#define BR13_SOLID_PATTERN 0x80000000
|
||||
|
||||
#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
#define WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
#define WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define WAIT_FOR_VBLANK (1<<3)
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,14 +33,14 @@
|
|||
#define I830_UPLOAD_CTX 0x1
|
||||
#define I830_UPLOAD_BUFFERS 0x2
|
||||
#define I830_UPLOAD_CLIPRECTS 0x4
|
||||
#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
|
||||
#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2))
|
||||
#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2))
|
||||
#define I830_UPLOAD_TEXIMAGE_MASK 0xff00
|
||||
|
@ -65,7 +65,7 @@
|
|||
* or in a piecewise fashion as required.
|
||||
*/
|
||||
|
||||
/* Destbuffer state
|
||||
/* Destbuffer state
|
||||
* - backbuffer linear offset and pitch -- invarient in the current dri
|
||||
* - zbuffer linear offset and pitch -- also invarient
|
||||
* - drawing origin in back and depth buffers.
|
||||
|
@ -103,7 +103,7 @@
|
|||
#define I830_CTXREG_AA 9
|
||||
#define I830_CTXREG_FOGCOLOR 10
|
||||
#define I830_CTXREG_BLENDCOLR0 11
|
||||
#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
|
||||
#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
|
||||
#define I830_CTXREG_VF 13
|
||||
#define I830_CTXREG_VF2 14
|
||||
#define I830_CTXREG_MCSB0 15
|
||||
|
@ -111,12 +111,11 @@
|
|||
#define I830_CTX_SETUP_SIZE 17
|
||||
|
||||
/* 1.3: Stipple state
|
||||
*/
|
||||
*/
|
||||
#define I830_STPREG_ST0 0
|
||||
#define I830_STPREG_ST1 1
|
||||
#define I830_STP_SETUP_SIZE 2
|
||||
|
||||
|
||||
/* Texture state (per tex unit)
|
||||
*/
|
||||
|
||||
|
@ -132,23 +131,23 @@
|
|||
#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
|
||||
#define I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
|
||||
#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
|
||||
#define I830_TEXREG_TM0S0 1
|
||||
#define I830_TEXREG_TM0S1 2
|
||||
#define I830_TEXREG_TM0S2 3
|
||||
#define I830_TEXREG_TM0S3 4
|
||||
#define I830_TEXREG_TM0S4 5
|
||||
#define I830_TEXREG_NOP0 6 /* noop */
|
||||
#define I830_TEXREG_NOP1 7 /* noop */
|
||||
#define I830_TEXREG_NOP2 8 /* noop */
|
||||
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
|
||||
#define I830_TEXREG_NOP0 6 /* noop */
|
||||
#define I830_TEXREG_NOP1 7 /* noop */
|
||||
#define I830_TEXREG_NOP2 8 /* noop */
|
||||
#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
|
||||
#define __I830_TEX_SETUP_SIZE 10
|
||||
|
||||
#define I830_FRONT 0x1
|
||||
#define I830_BACK 0x2
|
||||
#define I830_DEPTH 0x4
|
||||
|
||||
#endif /* _I830_DEFINES_ */
|
||||
#endif /* _I830_DEFINES_ */
|
||||
|
||||
typedef struct _drm_i830_init {
|
||||
enum {
|
||||
|
@ -177,19 +176,19 @@ typedef struct _drm_i830_init {
|
|||
* structure as well */
|
||||
|
||||
typedef struct _drm_i830_tex_region {
|
||||
unsigned char next, prev; /* indices to form a circular LRU */
|
||||
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_i830_tex_region_t;
|
||||
|
||||
typedef struct _drm_i830_sarea {
|
||||
unsigned int ContextState[I830_CTX_SETUP_SIZE];
|
||||
unsigned int BufferState[I830_DEST_SETUP_SIZE];
|
||||
unsigned int BufferState[I830_DEST_SETUP_SIZE];
|
||||
unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
|
||||
unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
|
||||
unsigned int Palette[2][256];
|
||||
unsigned int dirty;
|
||||
unsigned int dirty;
|
||||
|
||||
unsigned int nbox;
|
||||
drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS];
|
||||
|
@ -207,26 +206,26 @@ typedef struct _drm_i830_sarea {
|
|||
* 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.
|
||||
* them all in LRU order.
|
||||
*/
|
||||
|
||||
drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS+1];
|
||||
/* Last elt is sentinal */
|
||||
int texAge; /* last time texture was uploaded */
|
||||
int last_enqueue; /* last time a buffer was enqueued */
|
||||
drm_i830_tex_region_t texList[I830_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 last_quiescent; /* */
|
||||
int ctxOwner; /* last context to upload state */
|
||||
|
||||
int vertex_prim;
|
||||
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_active;
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
int pf_enabled; /* is pageflipping allowed? */
|
||||
int pf_active;
|
||||
int pf_current_page; /* which buffer is being displayed? */
|
||||
|
||||
int perf_boxes; /* performance boxes to be displayed */
|
||||
|
||||
/* Here's the state for texunits 2,3:
|
||||
int perf_boxes; /* performance boxes to be displayed */
|
||||
|
||||
/* Here's the state for texunits 2,3:
|
||||
*/
|
||||
unsigned int TexState2[I830_TEX_SETUP_SIZE];
|
||||
unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
|
||||
|
@ -241,12 +240,11 @@ typedef struct _drm_i830_sarea {
|
|||
|
||||
/* Flags for perf_boxes
|
||||
*/
|
||||
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
|
||||
#define I830_BOX_FLIP 0x2 /* populated by kernel */
|
||||
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
|
||||
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
|
||||
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
|
||||
|
||||
#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
|
||||
#define I830_BOX_FLIP 0x2 /* populated by kernel */
|
||||
#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
|
||||
#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
|
||||
#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
|
||||
|
||||
/* I830 specific ioctls
|
||||
* The device specific ioctl range is 0x40 to 0x79.
|
||||
|
@ -289,23 +287,21 @@ typedef struct _drm_i830_clear {
|
|||
unsigned int clear_depthmask;
|
||||
} drm_i830_clear_t;
|
||||
|
||||
|
||||
|
||||
/* These may be placeholders if we have more cliprects than
|
||||
* I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
|
||||
* false, indicating that the buffer will be dispatched again with a
|
||||
* new set of cliprects.
|
||||
*/
|
||||
typedef struct _drm_i830_vertex {
|
||||
int idx; /* buffer index */
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
int discard; /* client is finished with the buffer? */
|
||||
} drm_i830_vertex_t;
|
||||
|
||||
typedef struct _drm_i830_copy_t {
|
||||
int idx; /* buffer index */
|
||||
int idx; /* buffer index */
|
||||
int used; /* nr bytes in use */
|
||||
void __user *address; /* Address to copy from */
|
||||
void __user *address; /* Address to copy from */
|
||||
} drm_i830_copy_t;
|
||||
|
||||
typedef struct drm_i830_dma {
|
||||
|
@ -315,7 +311,6 @@ typedef struct drm_i830_dma {
|
|||
int granted;
|
||||
} drm_i830_dma_t;
|
||||
|
||||
|
||||
/* 1.3: Userspace can request & wait on irq's:
|
||||
*/
|
||||
typedef struct drm_i830_irq_emit {
|
||||
|
@ -326,7 +321,6 @@ typedef struct drm_i830_irq_wait {
|
|||
int irq_seq;
|
||||
} drm_i830_irq_wait_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to query kernel params:
|
||||
*/
|
||||
#define I830_PARAM_IRQ_ACTIVE 1
|
||||
|
@ -336,7 +330,6 @@ typedef struct drm_i830_getparam {
|
|||
int __user *value;
|
||||
} drm_i830_getparam_t;
|
||||
|
||||
|
||||
/* 1.3: New ioctl to set kernel params:
|
||||
*/
|
||||
#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
|
||||
|
@ -346,5 +339,4 @@ typedef struct drm_i830_setparam {
|
|||
int value;
|
||||
} drm_i830_setparam_t;
|
||||
|
||||
|
||||
#endif /* _I830_DRM_H_ */
|
||||
#endif /* _I830_DRM_H_ */
|
||||
|
|
|
@ -40,36 +40,34 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
dev->counters += 4;
|
||||
dev->types[6] = _DRM_STAT_IRQ;
|
||||
dev->types[7] = _DRM_STAT_PRIMARY;
|
||||
dev->types[8] = _DRM_STAT_SECONDARY;
|
||||
dev->types[9] = _DRM_STAT_DMA;
|
||||
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -77,11 +75,10 @@ static struct pci_device_id pciidlist[] = {
|
|||
i830_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t i830_ioctls[];
|
||||
extern int i830_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
|
||||
#if USE_IRQS
|
||||
.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
|
||||
#endif
|
||||
|
@ -104,18 +101,19 @@ static struct drm_driver driver = {
|
|||
.version = version,
|
||||
.ioctls = i830_ioctls,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
}
|
||||
,
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -133,6 +131,6 @@ static void __exit i830_exit(void)
|
|||
module_init(i830_init);
|
||||
module_exit(i830_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -63,14 +63,14 @@
|
|||
#define USE_IRQS 0
|
||||
|
||||
typedef struct drm_i830_buf_priv {
|
||||
u32 *in_use;
|
||||
int my_use_idx;
|
||||
u32 *in_use;
|
||||
int my_use_idx;
|
||||
int currently_mapped;
|
||||
void __user *virtual;
|
||||
void *kernel_virtual;
|
||||
} drm_i830_buf_priv_t;
|
||||
|
||||
typedef struct _drm_i830_ring_buffer{
|
||||
typedef struct _drm_i830_ring_buffer {
|
||||
int tail_mask;
|
||||
unsigned long Start;
|
||||
unsigned long End;
|
||||
|
@ -86,17 +86,17 @@ typedef struct drm_i830_private {
|
|||
drm_map_t *mmio_map;
|
||||
|
||||
drm_i830_sarea_t *sarea_priv;
|
||||
drm_i830_ring_buffer_t ring;
|
||||
drm_i830_ring_buffer_t ring;
|
||||
|
||||
void * hw_status_page;
|
||||
unsigned long counter;
|
||||
void *hw_status_page;
|
||||
unsigned long counter;
|
||||
|
||||
dma_addr_t dma_status_page;
|
||||
|
||||
drm_buf_t *mmap_buffer;
|
||||
|
||||
|
||||
u32 front_di1, back_di1, zi1;
|
||||
|
||||
|
||||
int back_offset;
|
||||
int depth_offset;
|
||||
int front_offset;
|
||||
|
@ -113,43 +113,39 @@ typedef struct drm_i830_private {
|
|||
int page_flipping;
|
||||
|
||||
wait_queue_head_t irq_queue;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
atomic_t irq_received;
|
||||
atomic_t irq_emitted;
|
||||
|
||||
int use_mi_batchbuffer_start;
|
||||
|
||||
} drm_i830_private_t;
|
||||
|
||||
extern drm_ioctl_desc_t i830_ioctls[];
|
||||
extern int i830_max_ioctl;
|
||||
|
||||
/* i830_dma.c */
|
||||
extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
|
||||
extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp);
|
||||
|
||||
/* i830_irq.c */
|
||||
extern int i830_irq_emit( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_irq_wait( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int i830_irq_emit(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
extern int i830_irq_wait(struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
extern irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS );
|
||||
extern void i830_driver_irq_preinstall( drm_device_t *dev );
|
||||
extern void i830_driver_irq_postinstall( drm_device_t *dev );
|
||||
extern void i830_driver_irq_uninstall( drm_device_t *dev );
|
||||
extern void i830_driver_pretakedown(drm_device_t *dev);
|
||||
extern void i830_driver_release(drm_device_t *dev, struct file *filp);
|
||||
extern int i830_driver_dma_quiescent(drm_device_t *dev);
|
||||
extern void i830_driver_prerelease(drm_device_t *dev, DRMFILE filp);
|
||||
extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
|
||||
extern void i830_driver_irq_preinstall(drm_device_t * dev);
|
||||
extern void i830_driver_irq_postinstall(drm_device_t * dev);
|
||||
extern void i830_driver_irq_uninstall(drm_device_t * dev);
|
||||
extern void i830_driver_pretakedown(drm_device_t * dev);
|
||||
extern void i830_driver_release(drm_device_t * dev, struct file *filp);
|
||||
extern int i830_driver_dma_quiescent(drm_device_t * dev);
|
||||
extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
|
||||
extern int i830_driver_device_is_agp(drm_device_t * dev);
|
||||
|
||||
#define I830_BASE(reg) ((unsigned long) \
|
||||
dev_priv->mmio_map->handle)
|
||||
#define I830_ADDR(reg) (I830_BASE(reg) + reg)
|
||||
#define I830_DEREF(reg) *(__volatile__ unsigned int *)I830_ADDR(reg)
|
||||
#define I830_READ(reg) readl((volatile u32 *)I830_ADDR(reg))
|
||||
#define I830_WRITE(reg,val) writel(val, (volatile u32 *)I830_ADDR(reg))
|
||||
#define I830_DEREF16(reg) *(__volatile__ u16 *)I830_ADDR(reg)
|
||||
#define I830_READ16(reg) I830_DEREF16(reg)
|
||||
#define I830_WRITE16(reg,val) do { I830_DEREF16(reg) = val; } while (0)
|
||||
|
||||
|
||||
#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
|
||||
#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
|
||||
#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
|
||||
#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
|
||||
|
||||
#define I830_VERBOSE 0
|
||||
|
||||
|
@ -168,7 +164,6 @@ extern int i830_driver_device_is_agp(drm_device_t * dev);
|
|||
virt = dev_priv->ring.virtual_start; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OUT_RING(n) do { \
|
||||
if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
|
||||
*(volatile unsigned int *)(virt + outring) = n; \
|
||||
|
@ -184,8 +179,7 @@ extern int i830_driver_device_is_agp(drm_device_t * dev);
|
|||
I830_WRITE(LP_RING + RING_TAIL, outring); \
|
||||
} while(0)
|
||||
|
||||
extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
||||
|
||||
extern int i830_wait_ring(drm_device_t * dev, int n, const char *caller);
|
||||
|
||||
#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
|
||||
#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
|
||||
|
@ -200,7 +194,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
|||
#define INST_OP_FLUSH 0x02000000
|
||||
#define INST_FLUSH_MAP_CACHE 0x00000001
|
||||
|
||||
|
||||
#define BB1_START_ADDR_MASK (~0x7)
|
||||
#define BB1_PROTECTED (1<<0)
|
||||
#define BB1_UNPROTECTED (0<<0)
|
||||
|
@ -213,7 +206,6 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
|||
|
||||
#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
|
||||
|
||||
|
||||
#define LP_RING 0x2030
|
||||
#define HP_RING 0x2040
|
||||
#define RING_TAIL 0x00
|
||||
|
@ -225,7 +217,7 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
|||
#define RING_START 0x08
|
||||
#define START_ADDR 0x0xFFFFF000
|
||||
#define RING_LEN 0x0C
|
||||
#define RING_NR_PAGES 0x001FF000
|
||||
#define RING_NR_PAGES 0x001FF000
|
||||
#define RING_REPORT_MASK 0x00000006
|
||||
#define RING_REPORT_64K 0x00000002
|
||||
#define RING_REPORT_128K 0x00000004
|
||||
|
@ -291,10 +283,9 @@ extern int i830_wait_ring(drm_device_t *dev, int n, const char *caller);
|
|||
#define MI_BATCH_NON_SECURE (1)
|
||||
|
||||
#define MI_WAIT_FOR_EVENT ((0x3<<23))
|
||||
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
|
||||
#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
|
||||
|
||||
#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -33,28 +33,27 @@
|
|||
#include <linux/interrupt.h> /* For task queue support */
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
irqreturn_t i830_driver_irq_handler( DRM_IRQ_ARGS )
|
||||
irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *)arg;
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
|
||||
u16 temp;
|
||||
drm_device_t *dev = (drm_device_t *) arg;
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
|
||||
u16 temp;
|
||||
|
||||
temp = I830_READ16(I830REG_INT_IDENTITY_R);
|
||||
temp = I830_READ16(I830REG_INT_IDENTITY_R);
|
||||
DRM_DEBUG("%x\n", temp);
|
||||
|
||||
if ( !( temp & 2 ) )
|
||||
if (!(temp & 2))
|
||||
return IRQ_NONE;
|
||||
|
||||
I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
|
||||
I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
|
||||
|
||||
atomic_inc(&dev_priv->irq_received);
|
||||
wake_up_interruptible(&dev_priv->irq_queue);
|
||||
wake_up_interruptible(&dev_priv->irq_queue);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int i830_emit_irq(drm_device_t *dev)
|
||||
static int i830_emit_irq(drm_device_t * dev)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
RING_LOCALS;
|
||||
|
@ -63,27 +62,25 @@ static int i830_emit_irq(drm_device_t *dev)
|
|||
|
||||
atomic_inc(&dev_priv->irq_emitted);
|
||||
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING( 0 );
|
||||
OUT_RING( GFX_OP_USER_INTERRUPT );
|
||||
ADVANCE_LP_RING();
|
||||
BEGIN_LP_RING(2);
|
||||
OUT_RING(0);
|
||||
OUT_RING(GFX_OP_USER_INTERRUPT);
|
||||
ADVANCE_LP_RING();
|
||||
|
||||
return atomic_read(&dev_priv->irq_emitted);
|
||||
}
|
||||
|
||||
|
||||
static int i830_wait_irq(drm_device_t *dev, int irq_nr)
|
||||
static int i830_wait_irq(drm_device_t * dev, int irq_nr)
|
||||
{
|
||||
drm_i830_private_t *dev_priv =
|
||||
(drm_i830_private_t *)dev->dev_private;
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
|
||||
DECLARE_WAITQUEUE(entry, current);
|
||||
unsigned long end = jiffies + HZ*3;
|
||||
unsigned long end = jiffies + HZ * 3;
|
||||
int ret = 0;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
|
||||
return 0;
|
||||
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
|
||||
return 0;
|
||||
|
||||
dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
|
||||
|
||||
|
@ -91,21 +88,21 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
|
|||
|
||||
for (;;) {
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
|
||||
break;
|
||||
if((signed)(end - jiffies) <= 0) {
|
||||
if (atomic_read(&dev_priv->irq_received) >= irq_nr)
|
||||
break;
|
||||
if ((signed)(end - jiffies) <= 0) {
|
||||
DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
|
||||
I830_READ16( I830REG_INT_IDENTITY_R ),
|
||||
I830_READ16( I830REG_INT_MASK_R ),
|
||||
I830_READ16( I830REG_INT_ENABLE_R ),
|
||||
I830_READ16( I830REG_HWSTAM ));
|
||||
I830_READ16(I830REG_INT_IDENTITY_R),
|
||||
I830_READ16(I830REG_INT_MASK_R),
|
||||
I830_READ16(I830REG_INT_ENABLE_R),
|
||||
I830_READ16(I830REG_HWSTAM));
|
||||
|
||||
ret = -EBUSY; /* Lockup? Missed irq? */
|
||||
ret = -EBUSY; /* Lockup? Missed irq? */
|
||||
break;
|
||||
}
|
||||
schedule_timeout(HZ*3);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
schedule_timeout(HZ * 3);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,89 +112,87 @@ static int i830_wait_irq(drm_device_t *dev, int irq_nr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Needs the lock as it touches the ring.
|
||||
*/
|
||||
int i830_irq_emit( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
int i830_irq_emit(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_irq_emit_t emit;
|
||||
int result;
|
||||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user( &emit, (drm_i830_irq_emit_t __user *)arg, sizeof(emit) ))
|
||||
if (copy_from_user
|
||||
(&emit, (drm_i830_irq_emit_t __user *) arg, sizeof(emit)))
|
||||
return -EFAULT;
|
||||
|
||||
result = i830_emit_irq( dev );
|
||||
result = i830_emit_irq(dev);
|
||||
|
||||
if ( copy_to_user( emit.irq_seq, &result, sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
if (copy_to_user(emit.irq_seq, &result, sizeof(int))) {
|
||||
DRM_ERROR("copy_to_user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Doesn't need the hardware lock.
|
||||
*/
|
||||
int i830_irq_wait( struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg )
|
||||
int i830_irq_wait(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_file_t *priv = filp->private_data;
|
||||
drm_device_t *dev = priv->head->dev;
|
||||
drm_i830_private_t *dev_priv = dev->dev_private;
|
||||
drm_i830_irq_wait_t irqwait;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (copy_from_user( &irqwait, (drm_i830_irq_wait_t __user *)arg,
|
||||
sizeof(irqwait) ))
|
||||
if (copy_from_user(&irqwait, (drm_i830_irq_wait_t __user *) arg,
|
||||
sizeof(irqwait)))
|
||||
return -EFAULT;
|
||||
|
||||
return i830_wait_irq( dev, irqwait.irq_seq );
|
||||
return i830_wait_irq(dev, irqwait.irq_seq);
|
||||
}
|
||||
|
||||
|
||||
/* drm_dma.h hooks
|
||||
*/
|
||||
void i830_driver_irq_preinstall( drm_device_t *dev ) {
|
||||
drm_i830_private_t *dev_priv =
|
||||
(drm_i830_private_t *)dev->dev_private;
|
||||
void i830_driver_irq_preinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
|
||||
|
||||
I830_WRITE16( I830REG_HWSTAM, 0xffff );
|
||||
I830_WRITE16( I830REG_INT_MASK_R, 0x0 );
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
|
||||
I830_WRITE16(I830REG_HWSTAM, 0xffff);
|
||||
I830_WRITE16(I830REG_INT_MASK_R, 0x0);
|
||||
I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
|
||||
atomic_set(&dev_priv->irq_received, 0);
|
||||
atomic_set(&dev_priv->irq_emitted, 0);
|
||||
init_waitqueue_head(&dev_priv->irq_queue);
|
||||
}
|
||||
|
||||
void i830_driver_irq_postinstall( drm_device_t *dev ) {
|
||||
drm_i830_private_t *dev_priv =
|
||||
(drm_i830_private_t *)dev->dev_private;
|
||||
void i830_driver_irq_postinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
|
||||
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x2 );
|
||||
I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
|
||||
}
|
||||
|
||||
void i830_driver_irq_uninstall( drm_device_t *dev ) {
|
||||
drm_i830_private_t *dev_priv =
|
||||
(drm_i830_private_t *)dev->dev_private;
|
||||
void i830_driver_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
I830_WRITE16( I830REG_INT_MASK_R, 0xffff );
|
||||
I830_WRITE16( I830REG_INT_ENABLE_R, 0x0 );
|
||||
I830_WRITE16(I830REG_INT_MASK_R, 0xffff);
|
||||
I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
|
||||
}
|
||||
|
|
|
@ -85,14 +85,14 @@ static int i915_dma_cleanup(drm_device_t * dev)
|
|||
* is freed, it's too late.
|
||||
*/
|
||||
if (dev->irq)
|
||||
drm_irq_uninstall (dev);
|
||||
drm_irq_uninstall(dev);
|
||||
|
||||
if (dev->dev_private) {
|
||||
drm_i915_private_t *dev_priv =
|
||||
(drm_i915_private_t *) dev->dev_private;
|
||||
|
||||
if (dev_priv->ring.virtual_start) {
|
||||
drm_core_ioremapfree( &dev_priv->ring.map, dev);
|
||||
drm_core_ioremapfree(&dev_priv->ring.map, dev);
|
||||
}
|
||||
|
||||
if (dev_priv->status_page_dmah) {
|
||||
|
@ -101,8 +101,8 @@ static int i915_dma_cleanup(drm_device_t * dev)
|
|||
I915_WRITE(0x02080, 0x1ffff000);
|
||||
}
|
||||
|
||||
drm_free (dev->dev_private, sizeof(drm_i915_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
drm_free(dev->dev_private, sizeof(drm_i915_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
|
||||
dev->dev_private = NULL;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ static int i915_initialize(drm_device_t * dev,
|
|||
dev_priv->ring.map.flags = 0;
|
||||
dev_priv->ring.map.mtrr = 0;
|
||||
|
||||
drm_core_ioremap( &dev_priv->ring.map, dev );
|
||||
drm_core_ioremap(&dev_priv->ring.map, dev);
|
||||
|
||||
if (dev_priv->ring.map.handle == NULL) {
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
|
@ -243,8 +243,8 @@ static int i915_dma_init(DRM_IOCTL_ARGS)
|
|||
|
||||
switch (init.func) {
|
||||
case I915_INIT_DMA:
|
||||
dev_priv = drm_alloc (sizeof(drm_i915_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
dev_priv = drm_alloc(sizeof(drm_i915_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
if (dev_priv == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
retcode = i915_initialize(dev, dev_priv, &init);
|
||||
|
@ -297,7 +297,7 @@ static int do_validate_cmd(int cmd)
|
|||
case 0x1c:
|
||||
return 1;
|
||||
case 0x1d:
|
||||
switch ((cmd>>16)&0xff) {
|
||||
switch ((cmd >> 16) & 0xff) {
|
||||
case 0x3:
|
||||
return (cmd & 0x1f) + 2;
|
||||
case 0x4:
|
||||
|
@ -699,20 +699,20 @@ static int i915_setparam(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void i915_driver_pretakedown(drm_device_t *dev)
|
||||
void i915_driver_pretakedown(drm_device_t * dev)
|
||||
{
|
||||
if ( dev->dev_private ) {
|
||||
if (dev->dev_private) {
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
i915_mem_takedown( &(dev_priv->agp_heap) );
|
||||
}
|
||||
i915_dma_cleanup( dev );
|
||||
i915_mem_takedown(&(dev_priv->agp_heap));
|
||||
}
|
||||
i915_dma_cleanup(dev);
|
||||
}
|
||||
|
||||
void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp)
|
||||
void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
|
||||
{
|
||||
if ( dev->dev_private ) {
|
||||
if (dev->dev_private) {
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
i915_mem_release( dev, filp, dev_priv->agp_heap );
|
||||
i915_mem_release(dev, filp, dev_priv->agp_heap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,36 +34,34 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
dev->counters += 4;
|
||||
dev->types[6] = _DRM_STAT_IRQ;
|
||||
dev->types[7] = _DRM_STAT_PRIMARY;
|
||||
dev->types[8] = _DRM_STAT_SECONDARY;
|
||||
dev->types[9] = _DRM_STAT_DMA;
|
||||
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -71,12 +69,10 @@ static struct pci_device_id pciidlist[] = {
|
|||
i915_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t i915_ioctls[];
|
||||
extern int i915_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
|
||||
.pretakedown = i915_driver_pretakedown,
|
||||
.prerelease = i915_driver_prerelease,
|
||||
.device_is_agp = i915_driver_device_is_agp,
|
||||
|
@ -91,21 +87,21 @@ static struct drm_driver driver = {
|
|||
.version = version,
|
||||
.ioctls = i915_ioctls,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = i915_compat_ioctl,
|
||||
.compat_ioctl = i915_compat_ioctl,
|
||||
#endif
|
||||
},
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init i915_init(void)
|
||||
|
@ -122,6 +118,6 @@ static void __exit i915_exit(void)
|
|||
module_init(i915_init);
|
||||
module_exit(i915_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -99,20 +99,23 @@ typedef struct drm_i915_private {
|
|||
struct mem_block *agp_heap;
|
||||
} drm_i915_private_t;
|
||||
|
||||
extern drm_ioctl_desc_t i915_ioctls[];
|
||||
extern int i915_max_ioctl;
|
||||
|
||||
/* i915_dma.c */
|
||||
extern void i915_kernel_lost_context(drm_device_t * dev);
|
||||
extern void i915_driver_pretakedown(drm_device_t *dev);
|
||||
extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
|
||||
extern int i915_driver_device_is_agp(drm_device_t *dev);
|
||||
extern void i915_driver_pretakedown(drm_device_t * dev);
|
||||
extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp);
|
||||
extern int i915_driver_device_is_agp(drm_device_t * dev);
|
||||
|
||||
/* i915_irq.c */
|
||||
extern int i915_irq_emit(DRM_IOCTL_ARGS);
|
||||
extern int i915_irq_wait(DRM_IOCTL_ARGS);
|
||||
|
||||
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
|
||||
extern void i915_driver_irq_preinstall(drm_device_t *dev);
|
||||
extern void i915_driver_irq_postinstall(drm_device_t *dev);
|
||||
extern void i915_driver_irq_uninstall(drm_device_t *dev);
|
||||
extern void i915_driver_irq_preinstall(drm_device_t * dev);
|
||||
extern void i915_driver_irq_postinstall(drm_device_t * dev);
|
||||
extern void i915_driver_irq_uninstall(drm_device_t * dev);
|
||||
|
||||
/* i915_mem.c */
|
||||
extern int i915_mem_alloc(DRM_IOCTL_ARGS);
|
||||
|
@ -125,7 +128,6 @@ extern void i915_mem_release(drm_device_t * dev,
|
|||
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
|
||||
#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
|
||||
#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
|
||||
#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* 32-bit ioctl compatibility routines for the i915 DRM.
|
||||
*
|
||||
* \author Alan Hourihane <alanh@fairlite.demon.co.uk>
|
||||
* \author Alan Hourihane <alanh@fairlite.demon.co.uk>
|
||||
*
|
||||
*
|
||||
* Copyright (C) Paul Mackerras 2005
|
||||
|
@ -42,51 +42,55 @@ typedef struct _drm_i915_batchbuffer32 {
|
|||
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
|
||||
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
|
||||
int num_cliprects; /* mulitpass with multiple cliprects? */
|
||||
u32 cliprects; /* pointer to userspace cliprects */
|
||||
u32 cliprects; /* pointer to userspace cliprects */
|
||||
} drm_i915_batchbuffer32_t;
|
||||
|
||||
static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_i915_batchbuffer32_t batchbuffer32;
|
||||
drm_i915_batchbuffer_t __user *batchbuffer;
|
||||
|
||||
if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
|
||||
|
||||
if (copy_from_user
|
||||
(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
|
||||
if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
|
||||
|| __put_user(batchbuffer32.start, &batchbuffer->start)
|
||||
|| __put_user(batchbuffer32.used, &batchbuffer->used)
|
||||
|| __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
|
||||
|| __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
|
||||
|| __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects)
|
||||
|| __put_user(batchbuffer32.num_cliprects,
|
||||
&batchbuffer->num_cliprects)
|
||||
|| __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
|
||||
&batchbuffer->cliprects))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer);
|
||||
DRM_IOCTL_I915_BATCHBUFFER,
|
||||
(unsigned long)batchbuffer);
|
||||
}
|
||||
|
||||
typedef struct _drm_i915_cmdbuffer32 {
|
||||
u32 buf; /* pointer to userspace command buffer */
|
||||
u32 buf; /* pointer to userspace command buffer */
|
||||
int sz; /* nr bytes in buf */
|
||||
int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
|
||||
int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
|
||||
int num_cliprects; /* mulitpass with multiple cliprects? */
|
||||
u32 cliprects; /* pointer to userspace cliprects */
|
||||
u32 cliprects; /* pointer to userspace cliprects */
|
||||
} drm_i915_cmdbuffer32_t;
|
||||
|
||||
static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_i915_cmdbuffer32_t cmdbuffer32;
|
||||
drm_i915_cmdbuffer_t __user *cmdbuffer;
|
||||
|
||||
if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
|
||||
|
||||
if (copy_from_user
|
||||
(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
|
||||
if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
|
||||
|| __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
|
||||
|
@ -98,9 +102,9 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
|
|||
|| __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
|
||||
&cmdbuffer->cliprects))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer);
|
||||
DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
|
||||
}
|
||||
|
||||
typedef struct drm_i915_irq_emit32 {
|
||||
|
@ -108,12 +112,12 @@ typedef struct drm_i915_irq_emit32 {
|
|||
} drm_i915_irq_emit32_t;
|
||||
|
||||
static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_i915_irq_emit32_t req32;
|
||||
drm_i915_irq_emit_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -123,7 +127,7 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request);
|
||||
DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
|
||||
}
|
||||
typedef struct drm_i915_getparam32 {
|
||||
int param;
|
||||
|
@ -131,12 +135,12 @@ typedef struct drm_i915_getparam32 {
|
|||
} drm_i915_getparam32_t;
|
||||
|
||||
static int compat_i915_getparam(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_i915_getparam32_t req32;
|
||||
drm_i915_getparam_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -147,7 +151,7 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_GETPARAM, (unsigned long) request);
|
||||
DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_i915_mem_alloc32 {
|
||||
|
@ -158,12 +162,12 @@ typedef struct drm_i915_mem_alloc32 {
|
|||
} drm_i915_mem_alloc32_t;
|
||||
|
||||
static int compat_i915_alloc(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_i915_mem_alloc32_t req32;
|
||||
drm_i915_mem_alloc_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -176,10 +180,9 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_I915_ALLOC, (unsigned long) request);
|
||||
DRM_IOCTL_I915_ALLOC, (unsigned long)request);
|
||||
}
|
||||
|
||||
|
||||
drm_ioctl_compat_t *i915_compat_ioctls[] = {
|
||||
[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
|
||||
[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
|
||||
|
@ -197,8 +200,7 @@ drm_ioctl_compat_t *i915_compat_ioctls[] = {
|
|||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*/
|
||||
long i915_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_ioctl_compat_t *fn = NULL;
|
||||
|
@ -206,13 +208,13 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
|
||||
if (nr < DRM_COMMAND_BASE)
|
||||
return drm_compat_ioctl(filp, cmd, arg);
|
||||
|
||||
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
|
||||
fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
|
|
@ -86,7 +86,7 @@ static void mark_block(drm_device_t * dev, struct mem_block *p, int in_use)
|
|||
}
|
||||
|
||||
/* Very simple allocator for agp memory, working on a static range
|
||||
* already mapped into each client's address space.
|
||||
* already mapped into each client's address space.
|
||||
*/
|
||||
|
||||
static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
||||
|
@ -94,7 +94,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
|||
{
|
||||
/* Maybe cut off the start of an existing block */
|
||||
if (start > p->start) {
|
||||
struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
|
||||
struct mem_block *newblock =
|
||||
drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
|
||||
if (!newblock)
|
||||
goto out;
|
||||
newblock->start = start;
|
||||
|
@ -110,7 +111,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
|||
|
||||
/* Maybe cut off the end of an existing block */
|
||||
if (size < p->size) {
|
||||
struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
|
||||
struct mem_block *newblock =
|
||||
drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
|
||||
if (!newblock)
|
||||
goto out;
|
||||
newblock->start = start + size;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -44,10 +44,10 @@
|
|||
|
||||
/* WARP pipe flags
|
||||
*/
|
||||
#define MGA_F 0x1 /* fog */
|
||||
#define MGA_A 0x2 /* alpha */
|
||||
#define MGA_S 0x4 /* specular */
|
||||
#define MGA_T2 0x8 /* multitexture */
|
||||
#define MGA_F 0x1 /* fog */
|
||||
#define MGA_A 0x2 /* alpha */
|
||||
#define MGA_S 0x4 /* specular */
|
||||
#define MGA_T2 0x8 /* multitexture */
|
||||
|
||||
#define MGA_WARP_TGZ 0
|
||||
#define MGA_WARP_TGZF (MGA_F)
|
||||
|
@ -66,14 +66,14 @@
|
|||
#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
|
||||
#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
|
||||
|
||||
#define MGA_MAX_G200_PIPES 8 /* no multitex */
|
||||
#define MGA_MAX_G200_PIPES 8 /* no multitex */
|
||||
#define MGA_MAX_G400_PIPES 16
|
||||
#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
|
||||
#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */
|
||||
#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */
|
||||
|
||||
#define MGA_CARD_TYPE_G200 1
|
||||
#define MGA_CARD_TYPE_G400 2
|
||||
#define MGA_CARD_TYPE_G450 3 /* not currently used */
|
||||
#define MGA_CARD_TYPE_G450 3 /* not currently used */
|
||||
#define MGA_CARD_TYPE_G550 4
|
||||
|
||||
#define MGA_FRONT 0x1
|
||||
|
@ -86,14 +86,14 @@
|
|||
#define MGA_UPLOAD_TEX0 0x2
|
||||
#define MGA_UPLOAD_TEX1 0x4
|
||||
#define MGA_UPLOAD_PIPE 0x8
|
||||
#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
|
||||
#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
|
||||
#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
|
||||
#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
|
||||
#define MGA_UPLOAD_2D 0x40
|
||||
#define MGA_WAIT_AGE 0x80 /* handled client-side */
|
||||
#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
|
||||
#define MGA_WAIT_AGE 0x80 /* handled client-side */
|
||||
#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
|
||||
#if 0
|
||||
#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
|
||||
quiescent */
|
||||
#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
|
||||
quiescent */
|
||||
#endif
|
||||
|
||||
/* 32 buffers of 64k each, total 2 meg.
|
||||
|
@ -120,8 +120,7 @@
|
|||
|
||||
#define DRM_MGA_IDLE_RETRY 2048
|
||||
|
||||
#endif /* __MGA_SAREA_DEFINES__ */
|
||||
|
||||
#endif /* __MGA_SAREA_DEFINES__ */
|
||||
|
||||
/* Setup registers for 3D context
|
||||
*/
|
||||
|
@ -165,25 +164,25 @@ typedef struct {
|
|||
/* General aging mechanism
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int head; /* Position of head pointer */
|
||||
unsigned int wrap; /* Primary DMA wrap count */
|
||||
unsigned int head; /* Position of head pointer */
|
||||
unsigned int wrap; /* Primary DMA wrap count */
|
||||
} drm_mga_age_t;
|
||||
|
||||
typedef struct _drm_mga_sarea {
|
||||
/* The channel for communication of state information to the kernel
|
||||
* on firing a vertex dma buffer.
|
||||
*/
|
||||
drm_mga_context_regs_t context_state;
|
||||
drm_mga_server_regs_t server_state;
|
||||
drm_mga_texture_regs_t tex_state[2];
|
||||
unsigned int warp_pipe;
|
||||
unsigned int dirty;
|
||||
unsigned int vertsize;
|
||||
drm_mga_context_regs_t context_state;
|
||||
drm_mga_server_regs_t server_state;
|
||||
drm_mga_texture_regs_t tex_state[2];
|
||||
unsigned int warp_pipe;
|
||||
unsigned int dirty;
|
||||
unsigned int vertsize;
|
||||
|
||||
/* The current cliprects, or a subset thereof.
|
||||
*/
|
||||
drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
|
||||
unsigned int nbox;
|
||||
drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
|
||||
unsigned int nbox;
|
||||
|
||||
/* Information about the most recently used 3d drawable. The
|
||||
* client fills in the req_* fields, the server fills in the
|
||||
|
@ -192,18 +191,18 @@ typedef struct _drm_mga_sarea {
|
|||
* The client clears the exported_drawable field before
|
||||
* clobbering the boxes data.
|
||||
*/
|
||||
unsigned int req_drawable; /* the X drawable id */
|
||||
unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
|
||||
unsigned int req_drawable; /* the X drawable id */
|
||||
unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
|
||||
|
||||
unsigned int exported_drawable;
|
||||
unsigned int exported_drawable;
|
||||
unsigned int exported_index;
|
||||
unsigned int exported_stamp;
|
||||
unsigned int exported_buffers;
|
||||
unsigned int exported_nfront;
|
||||
unsigned int exported_nback;
|
||||
unsigned int exported_stamp;
|
||||
unsigned int exported_buffers;
|
||||
unsigned int exported_nfront;
|
||||
unsigned int exported_nback;
|
||||
int exported_back_x, exported_front_x, exported_w;
|
||||
int exported_back_y, exported_front_y, exported_h;
|
||||
drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
|
||||
drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
|
||||
|
||||
/* Counters for aging textures and for client-side throttling.
|
||||
*/
|
||||
|
@ -211,21 +210,20 @@ typedef struct _drm_mga_sarea {
|
|||
unsigned int last_wrap;
|
||||
|
||||
drm_mga_age_t last_frame;
|
||||
unsigned int last_enqueue; /* last time a buffer was enqueued */
|
||||
unsigned int last_enqueue; /* last time a buffer was enqueued */
|
||||
unsigned int last_dispatch; /* age of the most recently dispatched buffer */
|
||||
unsigned int last_quiescent; /* */
|
||||
unsigned int last_quiescent; /* */
|
||||
|
||||
/* LRU lists for texture memory in agp space and on the card.
|
||||
*/
|
||||
drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
|
||||
drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
|
||||
unsigned int texAge[MGA_NR_TEX_HEAPS];
|
||||
|
||||
/* Mechanism to validate card state.
|
||||
*/
|
||||
int ctxOwner;
|
||||
int ctxOwner;
|
||||
} drm_mga_sarea_t;
|
||||
|
||||
|
||||
/* MGA specific ioctls
|
||||
* The device specific ioctl range is 0x40 to 0x79.
|
||||
*/
|
||||
|
@ -247,7 +245,6 @@ typedef struct _drm_mga_sarea {
|
|||
#define DRM_MGA_WAIT_FENCE 0x0b
|
||||
#define DRM_MGA_DMA_BOOTSTRAP 0x0c
|
||||
|
||||
|
||||
#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
|
||||
#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
|
||||
#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
|
||||
|
@ -263,33 +260,33 @@ typedef struct _drm_mga_sarea {
|
|||
#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
|
||||
|
||||
typedef struct _drm_mga_warp_index {
|
||||
int installed;
|
||||
unsigned long phys_addr;
|
||||
int size;
|
||||
int installed;
|
||||
unsigned long phys_addr;
|
||||
int size;
|
||||
} drm_mga_warp_index_t;
|
||||
|
||||
typedef struct drm_mga_init {
|
||||
enum {
|
||||
MGA_INIT_DMA = 0x01,
|
||||
MGA_CLEANUP_DMA = 0x02
|
||||
enum {
|
||||
MGA_INIT_DMA = 0x01,
|
||||
MGA_CLEANUP_DMA = 0x02
|
||||
} func;
|
||||
|
||||
unsigned long sarea_priv_offset;
|
||||
unsigned long sarea_priv_offset;
|
||||
|
||||
int chipset;
|
||||
int sgram;
|
||||
int sgram;
|
||||
|
||||
unsigned int maccess;
|
||||
|
||||
unsigned int fb_cpp;
|
||||
unsigned int fb_cpp;
|
||||
unsigned int front_offset, front_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
|
||||
unsigned int depth_cpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
unsigned int depth_cpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
|
||||
unsigned int texture_offset[MGA_NR_TEX_HEAPS];
|
||||
unsigned int texture_size[MGA_NR_TEX_HEAPS];
|
||||
unsigned int texture_offset[MGA_NR_TEX_HEAPS];
|
||||
unsigned int texture_size[MGA_NR_TEX_HEAPS];
|
||||
|
||||
unsigned long fb_offset;
|
||||
unsigned long mmio_offset;
|
||||
|
@ -302,64 +299,59 @@ typedef struct drm_mga_init {
|
|||
typedef struct drm_mga_dma_bootstrap {
|
||||
/**
|
||||
* \name AGP texture region
|
||||
*
|
||||
*
|
||||
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will
|
||||
* be filled in with the actual AGP texture settings.
|
||||
*
|
||||
*
|
||||
* \warning
|
||||
* If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode
|
||||
* is zero, it means that PCI memory (most likely through the use of
|
||||
* an IOMMU) is being used for "AGP" textures.
|
||||
*/
|
||||
/*@{*/
|
||||
/*@{ */
|
||||
unsigned long texture_handle; /**< Handle used to map AGP textures. */
|
||||
uint32_t texture_size; /**< Size of the AGP texture region. */
|
||||
/*@}*/
|
||||
|
||||
uint32_t texture_size; /**< Size of the AGP texture region. */
|
||||
/*@} */
|
||||
|
||||
/**
|
||||
* Requested size of the primary DMA region.
|
||||
*
|
||||
*
|
||||
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
|
||||
* filled in with the actual AGP mode. If AGP was not available
|
||||
*/
|
||||
uint32_t primary_size;
|
||||
|
||||
|
||||
/**
|
||||
* Requested number of secondary DMA buffers.
|
||||
*
|
||||
*
|
||||
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
|
||||
* filled in with the actual number of secondary DMA buffers
|
||||
* allocated. Particularly when PCI DMA is used, this may be
|
||||
* (subtantially) less than the number requested.
|
||||
*/
|
||||
uint32_t secondary_bin_count;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Requested size of each secondary DMA buffer.
|
||||
*
|
||||
*
|
||||
* While the kernel \b is free to reduce
|
||||
* dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed
|
||||
* to reduce dma_mga_dma_bootstrap::secondary_bin_size.
|
||||
*/
|
||||
uint32_t secondary_bin_size;
|
||||
|
||||
|
||||
/**
|
||||
* Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X,
|
||||
* \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is
|
||||
* zero, it means that PCI DMA should be used, even if AGP is
|
||||
* possible.
|
||||
*
|
||||
*
|
||||
* On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
|
||||
* filled in with the actual AGP mode. If AGP was not available
|
||||
* (i.e., PCI DMA was used), this value will be zero.
|
||||
*/
|
||||
uint32_t agp_mode;
|
||||
|
||||
|
||||
/**
|
||||
* Desired AGP GART size, measured in megabytes.
|
||||
*/
|
||||
|
@ -375,16 +367,16 @@ typedef struct drm_mga_clear {
|
|||
} drm_mga_clear_t;
|
||||
|
||||
typedef struct drm_mga_vertex {
|
||||
int idx; /* buffer to queue */
|
||||
int used; /* bytes in use */
|
||||
int discard; /* client finished with buffer? */
|
||||
int idx; /* buffer to queue */
|
||||
int used; /* bytes in use */
|
||||
int discard; /* client finished with buffer? */
|
||||
} drm_mga_vertex_t;
|
||||
|
||||
typedef struct drm_mga_indices {
|
||||
int idx; /* buffer to queue */
|
||||
int idx; /* buffer to queue */
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
int discard; /* client finished with buffer? */
|
||||
int discard; /* client finished with buffer? */
|
||||
} drm_mga_indices_t;
|
||||
|
||||
typedef struct drm_mga_iload {
|
||||
|
@ -400,12 +392,12 @@ typedef struct _drm_mga_blit {
|
|||
int src_pitch, dst_pitch;
|
||||
int delta_sx, delta_sy;
|
||||
int delta_dx, delta_dy;
|
||||
int height, ydir; /* flip image vertically */
|
||||
int height, ydir; /* flip image vertically */
|
||||
int source_pitch, dest_pitch;
|
||||
} drm_mga_blit_t;
|
||||
|
||||
/* 3.1: An ioctl to get parameters that aren't available to the 3d
|
||||
* client any other way.
|
||||
* client any other way.
|
||||
*/
|
||||
#define MGA_PARAM_IRQ_NR 1
|
||||
|
||||
|
|
|
@ -35,14 +35,13 @@
|
|||
#include "mga_drm.h"
|
||||
#include "mga_drv.h"
|
||||
|
||||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int mga_driver_device_is_agp(drm_device_t * dev);
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
drm_mga_private_t * const dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
drm_mga_private_t *const dev_priv =
|
||||
(drm_mga_private_t *) dev->dev_private;
|
||||
|
||||
dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
|
||||
dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
|
||||
|
@ -52,28 +51,26 @@ static int postinit( struct drm_device *dev, unsigned long flags )
|
|||
dev->types[7] = _DRM_STAT_PRIMARY;
|
||||
dev->types[8] = _DRM_STAT_SECONDARY;
|
||||
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -81,11 +78,11 @@ static struct pci_device_id pciidlist[] = {
|
|||
mga_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t mga_ioctls[];
|
||||
extern int mga_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
|
||||
DRIVER_IRQ_VBL,
|
||||
.preinit = mga_driver_preinit,
|
||||
.postcleanup = mga_driver_postcleanup,
|
||||
.pretakedown = mga_driver_pretakedown,
|
||||
|
@ -104,21 +101,21 @@ static struct drm_driver driver = {
|
|||
.ioctls = mga_ioctls,
|
||||
.dma_ioctl = mga_dma_buffers,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = mga_compat_ioctl,
|
||||
.compat_ioctl = mga_compat_ioctl,
|
||||
#endif
|
||||
},
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init mga_init(void)
|
||||
|
@ -135,8 +132,8 @@ static void __exit mga_exit(void)
|
|||
module_init(mga_init);
|
||||
module_exit(mga_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
||||
/**
|
||||
|
@ -151,10 +148,9 @@ MODULE_LICENSE("GPL and additional rights");
|
|||
* \returns
|
||||
* If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
|
||||
*/
|
||||
int mga_driver_device_is_agp(drm_device_t * dev)
|
||||
static int mga_driver_device_is_agp(drm_device_t * dev)
|
||||
{
|
||||
const struct pci_dev * const pdev = dev->pdev;
|
||||
|
||||
const struct pci_dev *const pdev = dev->pdev;
|
||||
|
||||
/* There are PCI versions of the G450. These cards have the
|
||||
* same PCI ID as the AGP G450, but have an additional PCI-to-PCI
|
||||
|
@ -164,10 +160,10 @@ int mga_driver_device_is_agp(drm_device_t * dev)
|
|||
* device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
|
||||
* device.
|
||||
*/
|
||||
|
||||
if ( (pdev->device == 0x0525)
|
||||
&& (pdev->bus->self->vendor == 0x3388)
|
||||
&& (pdev->bus->self->device == 0x0021) ) {
|
||||
|
||||
if ((pdev->device == 0x0525)
|
||||
&& (pdev->bus->self->vendor == 0x3388)
|
||||
&& (pdev->bus->self->device == 0x0021)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,14 +62,14 @@ typedef struct drm_mga_primary_buffer {
|
|||
} drm_mga_primary_buffer_t;
|
||||
|
||||
typedef struct drm_mga_freelist {
|
||||
struct drm_mga_freelist *next;
|
||||
struct drm_mga_freelist *prev;
|
||||
struct drm_mga_freelist *next;
|
||||
struct drm_mga_freelist *prev;
|
||||
drm_mga_age_t age;
|
||||
drm_buf_t *buf;
|
||||
drm_buf_t *buf;
|
||||
} drm_mga_freelist_t;
|
||||
|
||||
typedef struct {
|
||||
drm_mga_freelist_t *list_entry;
|
||||
drm_mga_freelist_t *list_entry;
|
||||
int discard;
|
||||
int dispatched;
|
||||
} drm_mga_buf_priv_t;
|
||||
|
@ -78,8 +78,8 @@ typedef struct drm_mga_private {
|
|||
drm_mga_primary_buffer_t prim;
|
||||
drm_mga_sarea_t *sarea_priv;
|
||||
|
||||
drm_mga_freelist_t *head;
|
||||
drm_mga_freelist_t *tail;
|
||||
drm_mga_freelist_t *head;
|
||||
drm_mga_freelist_t *tail;
|
||||
|
||||
unsigned int warp_pipe;
|
||||
unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
|
||||
|
@ -109,13 +109,13 @@ typedef struct drm_mga_private {
|
|||
|
||||
/**
|
||||
* \name MMIO region parameters.
|
||||
*
|
||||
*
|
||||
* \sa drm_mga_private_t::mmio
|
||||
*/
|
||||
/*@{*/
|
||||
u32 mmio_base; /**< Bus address of base of MMIO. */
|
||||
u32 mmio_size; /**< Size of the MMIO region. */
|
||||
/*@}*/
|
||||
/*@{ */
|
||||
u32 mmio_base; /**< Bus address of base of MMIO. */
|
||||
u32 mmio_size; /**< Size of the MMIO region. */
|
||||
/*@} */
|
||||
|
||||
u32 clear_cmd;
|
||||
u32 maccess;
|
||||
|
@ -143,11 +143,14 @@ typedef struct drm_mga_private {
|
|||
drm_local_map_t *warp;
|
||||
drm_local_map_t *primary;
|
||||
drm_local_map_t *agp_textures;
|
||||
|
||||
|
||||
DRM_AGP_MEM *agp_mem;
|
||||
unsigned int agp_pages;
|
||||
} drm_mga_private_t;
|
||||
|
||||
extern drm_ioctl_desc_t mga_ioctls[];
|
||||
extern int mga_max_ioctl;
|
||||
|
||||
/* mga_dma.c */
|
||||
extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
|
||||
extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
|
||||
|
@ -165,7 +168,7 @@ extern void mga_do_dma_flush(drm_mga_private_t * dev_priv);
|
|||
extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
|
||||
extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
|
||||
|
||||
extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
|
||||
extern int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf);
|
||||
|
||||
/* mga_warp.c */
|
||||
extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
|
||||
|
@ -196,7 +199,7 @@ extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
|
||||
#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
|
||||
|
||||
static inline u32 _MGA_READ(u32 *addr)
|
||||
static inline u32 _MGA_READ(u32 * addr)
|
||||
{
|
||||
DRM_MEMORYBARRIER();
|
||||
return *(volatile u32 *)addr;
|
||||
|
@ -218,8 +221,6 @@ static inline u32 _MGA_READ(u32 *addr)
|
|||
#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
|
||||
#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
|
||||
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Helper macross...
|
||||
*/
|
||||
|
@ -261,7 +262,6 @@ do { \
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Primary DMA command stream
|
||||
*/
|
||||
|
@ -346,7 +346,6 @@ do { \
|
|||
write += DMA_BLOCK_SIZE; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Buffer aging via primary DMA stream head pointer.
|
||||
*/
|
||||
|
||||
|
@ -373,7 +372,6 @@ do { \
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \
|
||||
MGA_DWGENGSTS | \
|
||||
MGA_ENDPRDMASTS)
|
||||
|
@ -382,8 +380,6 @@ do { \
|
|||
|
||||
#define MGA_DMA_DEBUG 0
|
||||
|
||||
|
||||
|
||||
/* A reduced set of the mga registers.
|
||||
*/
|
||||
#define MGA_CRTC_INDEX 0x1fd4
|
||||
|
@ -644,7 +640,6 @@ do { \
|
|||
# define MGA_G400_WR_MAGIC (1 << 6)
|
||||
# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */
|
||||
|
||||
|
||||
#define MGA_ILOAD_ALIGN 64
|
||||
#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1)
|
||||
|
||||
|
@ -679,10 +674,10 @@ do { \
|
|||
|
||||
/* Simple idle test.
|
||||
*/
|
||||
static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv )
|
||||
static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
|
||||
return ( status == MGA_ENDPRDMASTS );
|
||||
u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
|
||||
return (status == MGA_ENDPRDMASTS);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,17 +39,17 @@
|
|||
|
||||
typedef struct drm32_mga_init {
|
||||
int func;
|
||||
u32 sarea_priv_offset;
|
||||
u32 sarea_priv_offset;
|
||||
int chipset;
|
||||
int sgram;
|
||||
int sgram;
|
||||
unsigned int maccess;
|
||||
unsigned int fb_cpp;
|
||||
unsigned int fb_cpp;
|
||||
unsigned int front_offset, front_pitch;
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int depth_cpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
unsigned int texture_offset[MGA_NR_TEX_HEAPS];
|
||||
unsigned int texture_size[MGA_NR_TEX_HEAPS];
|
||||
unsigned int back_offset, back_pitch;
|
||||
unsigned int depth_cpp;
|
||||
unsigned int depth_offset, depth_pitch;
|
||||
unsigned int texture_offset[MGA_NR_TEX_HEAPS];
|
||||
unsigned int texture_size[MGA_NR_TEX_HEAPS];
|
||||
u32 fb_offset;
|
||||
u32 mmio_offset;
|
||||
u32 status_offset;
|
||||
|
@ -64,10 +64,10 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
|
|||
drm_mga_init32_t init32;
|
||||
drm_mga_init_t __user *init;
|
||||
int err = 0, i;
|
||||
|
||||
|
||||
if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
init = compat_alloc_user_space(sizeof(*init));
|
||||
if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
|
||||
|| __put_user(init32.func, &init->func)
|
||||
|
@ -90,42 +90,43 @@ static int compat_mga_init(struct file *file, unsigned int cmd,
|
|||
|| __put_user(init32.primary_offset, &init->primary_offset)
|
||||
|| __put_user(init32.buffers_offset, &init->buffers_offset))
|
||||
return -EFAULT;
|
||||
|
||||
for (i=0; i<MGA_NR_TEX_HEAPS; i++)
|
||||
{
|
||||
err |= __put_user(init32.texture_offset[i], &init->texture_offset[i]);
|
||||
err |= __put_user(init32.texture_size[i], &init->texture_size[i]);
|
||||
|
||||
for (i = 0; i < MGA_NR_TEX_HEAPS; i++) {
|
||||
err |=
|
||||
__put_user(init32.texture_offset[i],
|
||||
&init->texture_offset[i]);
|
||||
err |=
|
||||
__put_user(init32.texture_size[i], &init->texture_size[i]);
|
||||
}
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_INIT, (unsigned long) init);
|
||||
}
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_INIT, (unsigned long)init);
|
||||
}
|
||||
|
||||
typedef struct drm_mga_getparam32 {
|
||||
int param;
|
||||
u32 value;
|
||||
} drm_mga_getparam32_t;
|
||||
|
||||
|
||||
static int compat_mga_getparam(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_mga_getparam32_t getparam32;
|
||||
drm_mga_getparam_t __user *getparam;
|
||||
|
||||
|
||||
if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
|
||||
return -EFAULT;
|
||||
|
||||
getparam = compat_alloc_user_space(sizeof(*getparam));
|
||||
if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
|
||||
|| __put_user(getparam32.param, &getparam->param)
|
||||
|| __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
|
||||
|| __put_user((void __user *)(unsigned long)getparam32.value,
|
||||
&getparam->value))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
|
||||
}
|
||||
|
||||
|
@ -182,14 +183,12 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
|
|||
&dma_bootstrap->secondary_bin_count)
|
||||
|| __get_user(dma_bootstrap32.secondary_bin_size,
|
||||
&dma_bootstrap->secondary_bin_size)
|
||||
|| __get_user(dma_bootstrap32.agp_mode,
|
||||
&dma_bootstrap->agp_mode)
|
||||
|| __get_user(dma_bootstrap32.agp_size,
|
||||
&dma_bootstrap->agp_size))
|
||||
|| __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
|
||||
|| __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &dma_bootstrap32,
|
||||
sizeof(dma_bootstrap32)))
|
||||
sizeof(dma_bootstrap32)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
@ -210,8 +209,7 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = {
|
|||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*/
|
||||
long mga_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_ioctl_compat_t *fn = NULL;
|
||||
|
@ -219,13 +217,13 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
|
||||
if (nr < DRM_COMMAND_BASE)
|
||||
return drm_compat_ioctl(filp, cmd, arg);
|
||||
|
||||
|
||||
if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
|
||||
fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
|
||||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
|
||||
*
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
*
|
||||
* The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
* initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
* This notice must be preserved.
|
||||
|
@ -35,19 +35,18 @@
|
|||
#include "mga_drm.h"
|
||||
#include "mga_drv.h"
|
||||
|
||||
irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
|
||||
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *) arg;
|
||||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *)dev->dev_private;
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
|
||||
int status;
|
||||
int handled = 0;
|
||||
|
||||
status = MGA_READ(MGA_STATUS);
|
||||
|
||||
/* VBLANK interrupt */
|
||||
if ( status & MGA_VLINEPEN ) {
|
||||
MGA_WRITE( MGA_ICLEAR, MGA_VLINEICLR );
|
||||
if (status & MGA_VLINEPEN) {
|
||||
MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
|
||||
atomic_inc(&dev->vbl_received);
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals(dev);
|
||||
|
@ -57,15 +56,14 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
|
|||
/* SOFTRAP interrupt */
|
||||
if (status & MGA_SOFTRAPEN) {
|
||||
const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
|
||||
const u32 prim_end = MGA_READ(MGA_PRIMEND);
|
||||
|
||||
const u32 prim_end = MGA_READ(MGA_PRIMEND);
|
||||
|
||||
MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
|
||||
|
||||
/* In addition to clearing the interrupt-pending bit, we
|
||||
* have to write to MGA_PRIMEND to re-start the DMA operation.
|
||||
*/
|
||||
if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
|
||||
if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
|
||||
MGA_WRITE(MGA_PRIMEND, prim_end);
|
||||
}
|
||||
|
||||
|
@ -74,24 +72,24 @@ irqreturn_t mga_driver_irq_handler( DRM_IRQ_ARGS )
|
|||
handled = 1;
|
||||
}
|
||||
|
||||
if ( handled ) {
|
||||
if (handled) {
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
int mga_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||
int mga_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
|
||||
{
|
||||
unsigned int cur_vblank;
|
||||
int ret = 0;
|
||||
|
||||
/* Assume that the user has missed the current sequence number
|
||||
* by about a day rather than she wants to wait for years
|
||||
* using vertical blanks...
|
||||
* using vertical blanks...
|
||||
*/
|
||||
DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
|
||||
( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
|
||||
- *sequence ) <= (1<<23) ) );
|
||||
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
||||
(((cur_vblank = atomic_read(&dev->vbl_received))
|
||||
- *sequence) <= (1 << 23)));
|
||||
|
||||
*sequence = cur_vblank;
|
||||
|
||||
|
@ -122,29 +120,29 @@ void mga_driver_irq_preinstall(drm_device_t * dev)
|
|||
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
MGA_WRITE( MGA_IEN, 0 );
|
||||
MGA_WRITE(MGA_IEN, 0);
|
||||
/* Clear bits if they're already high */
|
||||
MGA_WRITE( MGA_ICLEAR, ~0 );
|
||||
MGA_WRITE(MGA_ICLEAR, ~0);
|
||||
}
|
||||
|
||||
void mga_driver_irq_postinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
|
||||
|
||||
DRM_INIT_WAITQUEUE( &dev_priv->fence_queue );
|
||||
DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
|
||||
|
||||
/* Turn on vertical blank interrupt and soft trap interrupt. */
|
||||
MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
|
||||
}
|
||||
|
||||
void mga_driver_irq_uninstall( drm_device_t *dev ) {
|
||||
drm_mga_private_t *dev_priv =
|
||||
(drm_mga_private_t *)dev->dev_private;
|
||||
void mga_driver_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
MGA_WRITE(MGA_IEN, 0);
|
||||
|
||||
|
||||
dev->irq_enabled = 0;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -33,8 +33,7 @@
|
|||
#include "mga_drv.h"
|
||||
#include "mga_ucode.h"
|
||||
|
||||
|
||||
#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
|
||||
#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
|
||||
|
||||
#define WARP_UCODE_SIZE( which ) \
|
||||
((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
|
||||
|
@ -49,33 +48,30 @@ do { \
|
|||
} while (0)
|
||||
|
||||
static const unsigned int mga_warp_g400_microcode_size =
|
||||
(WARP_UCODE_SIZE(warp_g400_tgz) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgza) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzs) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsa) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gz) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gza) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzs) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzsa) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzsaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzsf));
|
||||
(WARP_UCODE_SIZE(warp_g400_tgz) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgza) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzs) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsa) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_tgzsf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gz) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gza) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzaf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzf) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzs) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzsa) +
|
||||
WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
|
||||
|
||||
static const unsigned int mga_warp_g200_microcode_size =
|
||||
(WARP_UCODE_SIZE(warp_g200_tgz) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgza) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzaf) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzf) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzs) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzsa) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzsaf) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzsf));
|
||||
|
||||
(WARP_UCODE_SIZE(warp_g200_tgz) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgza) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzaf) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzf) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzs) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzsa) +
|
||||
WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
|
||||
|
||||
unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
|
||||
{
|
||||
|
@ -90,36 +86,35 @@ unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
|
|||
}
|
||||
}
|
||||
|
||||
static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
|
||||
static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
unsigned char *vcbase = dev_priv->warp->handle;
|
||||
unsigned long pcbase = dev_priv->warp->offset;
|
||||
|
||||
memset( dev_priv->warp_pipe_phys, 0,
|
||||
sizeof(dev_priv->warp_pipe_phys) );
|
||||
memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
|
||||
|
||||
WARP_UCODE_INSTALL( warp_g400_tgz, MGA_WARP_TGZ );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzf, MGA_WARP_TGZF );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgza, MGA_WARP_TGZA );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzaf, MGA_WARP_TGZAF );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzs, MGA_WARP_TGZS );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzsf, MGA_WARP_TGZSF );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzsa, MGA_WARP_TGZSA );
|
||||
WARP_UCODE_INSTALL( warp_g400_tgzsaf, MGA_WARP_TGZSAF );
|
||||
WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
|
||||
WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
|
||||
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gz, MGA_WARP_T2GZ );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzf, MGA_WARP_T2GZF );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gza, MGA_WARP_T2GZA );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzaf, MGA_WARP_T2GZAF );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzs, MGA_WARP_T2GZS );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzsf, MGA_WARP_T2GZSF );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzsa, MGA_WARP_T2GZSA );
|
||||
WARP_UCODE_INSTALL( warp_g400_t2gzsaf, MGA_WARP_T2GZSAF );
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
|
||||
WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
|
||||
static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
unsigned char *vcbase = dev_priv->warp->handle;
|
||||
unsigned long pcbase = dev_priv->warp->offset;
|
||||
|
@ -138,7 +133,7 @@ static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
|
||||
int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
const unsigned int size = mga_warp_microcode_size(dev_priv);
|
||||
|
||||
|
@ -154,7 +149,7 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
|
|||
case MGA_CARD_TYPE_G550:
|
||||
return mga_warp_install_g400_microcode(dev_priv);
|
||||
case MGA_CARD_TYPE_G200:
|
||||
return mga_warp_install_g200_microcode( dev_priv );
|
||||
return mga_warp_install_g200_microcode(dev_priv);
|
||||
default:
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
@ -162,13 +157,13 @@ int mga_warp_install_microcode( drm_mga_private_t *dev_priv )
|
|||
|
||||
#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
|
||||
|
||||
int mga_warp_init( drm_mga_private_t *dev_priv )
|
||||
int mga_warp_init(drm_mga_private_t * dev_priv)
|
||||
{
|
||||
u32 wmisc;
|
||||
|
||||
/* FIXME: Get rid of these damned magic numbers...
|
||||
*/
|
||||
switch ( dev_priv->chipset ) {
|
||||
switch (dev_priv->chipset) {
|
||||
case MGA_CARD_TYPE_G400:
|
||||
case MGA_CARD_TYPE_G550:
|
||||
MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND);
|
||||
|
@ -177,21 +172,20 @@ int mga_warp_init( drm_mga_private_t *dev_priv )
|
|||
MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000);
|
||||
break;
|
||||
case MGA_CARD_TYPE_G200:
|
||||
MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
|
||||
MGA_WRITE( MGA_WGETMSB, 0x1606 );
|
||||
MGA_WRITE( MGA_WVRTXSZ, 7 );
|
||||
MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND);
|
||||
MGA_WRITE(MGA_WGETMSB, 0x1606);
|
||||
MGA_WRITE(MGA_WVRTXSZ, 7);
|
||||
break;
|
||||
default:
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
|
||||
MGA_WMASTER_ENABLE |
|
||||
MGA_WCACHEFLUSH_ENABLE) );
|
||||
wmisc = MGA_READ( MGA_WMISC );
|
||||
if ( wmisc != WMISC_EXPECTED ) {
|
||||
DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
|
||||
wmisc, WMISC_EXPECTED );
|
||||
MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
|
||||
MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE));
|
||||
wmisc = MGA_READ(MGA_WMISC);
|
||||
if (wmisc != WMISC_EXPECTED) {
|
||||
DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n",
|
||||
wmisc, WMISC_EXPECTED);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -93,7 +93,7 @@
|
|||
#define R128_MAX_TEXTURE_LEVELS 11
|
||||
#define R128_MAX_TEXTURE_UNITS 2
|
||||
|
||||
#endif /* __R128_SAREA_DEFINES__ */
|
||||
#endif /* __R128_SAREA_DEFINES__ */
|
||||
|
||||
typedef struct {
|
||||
/* Context state - can be written in one large chunk */
|
||||
|
@ -140,7 +140,6 @@ typedef struct {
|
|||
unsigned int tex_border_color;
|
||||
} drm_r128_texture_regs_t;
|
||||
|
||||
|
||||
typedef struct drm_r128_sarea {
|
||||
/* The channel for communication of state information to the kernel
|
||||
* on firing a vertex buffer.
|
||||
|
@ -161,14 +160,13 @@ typedef struct drm_r128_sarea {
|
|||
unsigned int last_frame;
|
||||
unsigned int last_dispatch;
|
||||
|
||||
drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1];
|
||||
drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
|
||||
unsigned int tex_age[R128_NR_TEX_HEAPS];
|
||||
int ctx_owner;
|
||||
int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
|
||||
int pfCurrentPage; /* which buffer is being displayed? */
|
||||
int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
|
||||
int pfCurrentPage; /* which buffer is being displayed? */
|
||||
} drm_r128_sarea_t;
|
||||
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the Xserver file (xf86drmR128.h)
|
||||
*/
|
||||
|
@ -220,7 +218,7 @@ typedef struct drm_r128_sarea {
|
|||
|
||||
typedef struct drm_r128_init {
|
||||
enum {
|
||||
R128_INIT_CCE = 0x01,
|
||||
R128_INIT_CCE = 0x01,
|
||||
R128_CLEANUP_CCE = 0x02
|
||||
} func;
|
||||
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
|
||||
|
@ -278,9 +276,9 @@ typedef struct drm_r128_clear {
|
|||
|
||||
typedef struct drm_r128_vertex {
|
||||
int prim;
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_r128_vertex_t;
|
||||
|
||||
typedef struct drm_r128_indices {
|
||||
|
@ -288,7 +286,7 @@ typedef struct drm_r128_indices {
|
|||
int idx;
|
||||
int start;
|
||||
int end;
|
||||
int discard; /* Client finished with buffer? */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_r128_indices_t;
|
||||
|
||||
typedef struct drm_r128_blit {
|
||||
|
@ -302,10 +300,10 @@ typedef struct drm_r128_blit {
|
|||
|
||||
typedef struct drm_r128_depth {
|
||||
enum {
|
||||
R128_WRITE_SPAN = 0x01,
|
||||
R128_WRITE_PIXELS = 0x02,
|
||||
R128_READ_SPAN = 0x03,
|
||||
R128_READ_PIXELS = 0x04
|
||||
R128_WRITE_SPAN = 0x01,
|
||||
R128_WRITE_PIXELS = 0x02,
|
||||
R128_READ_SPAN = 0x03,
|
||||
R128_READ_PIXELS = 0x04
|
||||
} func;
|
||||
int n;
|
||||
int __user *x;
|
||||
|
@ -327,13 +325,13 @@ typedef struct drm_r128_indirect {
|
|||
|
||||
typedef struct drm_r128_fullscreen {
|
||||
enum {
|
||||
R128_INIT_FULLSCREEN = 0x01,
|
||||
R128_INIT_FULLSCREEN = 0x01,
|
||||
R128_CLEANUP_FULLSCREEN = 0x02
|
||||
} func;
|
||||
} drm_r128_fullscreen_t;
|
||||
|
||||
/* 2.3: An ioctl to get parameters that aren't available to the 3d
|
||||
* client any other way.
|
||||
* client any other way.
|
||||
*/
|
||||
#define R128_PARAM_IRQ_NR 1
|
||||
|
||||
|
|
|
@ -37,30 +37,28 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -68,11 +66,11 @@ static struct pci_device_id pciidlist[] = {
|
|||
r128_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t r128_ioctls[];
|
||||
extern int r128_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
|
||||
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
|
||||
DRIVER_IRQ_VBL,
|
||||
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
|
||||
.prerelease = r128_driver_prerelease,
|
||||
.pretakedown = r128_driver_pretakedown,
|
||||
|
@ -89,21 +87,22 @@ static struct drm_driver driver = {
|
|||
.ioctls = r128_ioctls,
|
||||
.dma_ioctl = r128_cce_buffers,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = r128_compat_ioctl,
|
||||
.compat_ioctl = r128_compat_ioctl,
|
||||
#endif
|
||||
},
|
||||
}
|
||||
,
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init r128_init(void)
|
||||
|
@ -120,6 +119,6 @@ static void __exit r128_exit(void)
|
|||
module_init(r128_init);
|
||||
module_exit(r128_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -52,14 +52,13 @@
|
|||
#define DRIVER_MINOR 5
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
|
||||
#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR )
|
||||
|
||||
typedef struct drm_r128_freelist {
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
struct drm_r128_freelist *next;
|
||||
struct drm_r128_freelist *prev;
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
struct drm_r128_freelist *next;
|
||||
struct drm_r128_freelist *prev;
|
||||
} drm_r128_freelist_t;
|
||||
|
||||
typedef struct drm_r128_ring_buffer {
|
||||
|
@ -83,13 +82,11 @@ typedef struct drm_r128_private {
|
|||
int cce_fifo_size;
|
||||
int cce_running;
|
||||
|
||||
drm_r128_freelist_t *head;
|
||||
drm_r128_freelist_t *tail;
|
||||
drm_r128_freelist_t *head;
|
||||
drm_r128_freelist_t *tail;
|
||||
|
||||
int usec_timeout;
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
dma_addr_t bus_pci_gart;
|
||||
unsigned long cce_buffers_offset;
|
||||
|
||||
atomic_t idle_count;
|
||||
|
@ -120,6 +117,7 @@ typedef struct drm_r128_private {
|
|||
drm_local_map_t *cce_ring;
|
||||
drm_local_map_t *ring_rptr;
|
||||
drm_local_map_t *agp_textures;
|
||||
drm_ati_pcigart_info gart_info;
|
||||
} drm_r128_private_t;
|
||||
|
||||
typedef struct drm_r128_buf_priv {
|
||||
|
@ -127,34 +125,37 @@ typedef struct drm_r128_buf_priv {
|
|||
int prim;
|
||||
int discard;
|
||||
int dispatched;
|
||||
drm_r128_freelist_t *list_entry;
|
||||
drm_r128_freelist_t *list_entry;
|
||||
} drm_r128_buf_priv_t;
|
||||
|
||||
extern drm_ioctl_desc_t r128_ioctls[];
|
||||
extern int r128_max_ioctl;
|
||||
|
||||
/* r128_cce.c */
|
||||
extern int r128_cce_init( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_start( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_stop( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_reset( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_idle( DRM_IOCTL_ARGS );
|
||||
extern int r128_engine_reset( DRM_IOCTL_ARGS );
|
||||
extern int r128_fullscreen( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_buffers( DRM_IOCTL_ARGS );
|
||||
extern int r128_cce_init(DRM_IOCTL_ARGS);
|
||||
extern int r128_cce_start(DRM_IOCTL_ARGS);
|
||||
extern int r128_cce_stop(DRM_IOCTL_ARGS);
|
||||
extern int r128_cce_reset(DRM_IOCTL_ARGS);
|
||||
extern int r128_cce_idle(DRM_IOCTL_ARGS);
|
||||
extern int r128_engine_reset(DRM_IOCTL_ARGS);
|
||||
extern int r128_fullscreen(DRM_IOCTL_ARGS);
|
||||
extern int r128_cce_buffers(DRM_IOCTL_ARGS);
|
||||
|
||||
extern void r128_freelist_reset( drm_device_t *dev );
|
||||
extern void r128_freelist_reset(drm_device_t * dev);
|
||||
|
||||
extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
|
||||
extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
|
||||
|
||||
extern int r128_do_cce_idle( drm_r128_private_t *dev_priv );
|
||||
extern int r128_do_cleanup_cce( drm_device_t *dev );
|
||||
extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
|
||||
extern int r128_do_cleanup_cce(drm_device_t * dev);
|
||||
|
||||
extern int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
|
||||
extern int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
|
||||
|
||||
extern irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS );
|
||||
extern void r128_driver_irq_preinstall( drm_device_t *dev );
|
||||
extern void r128_driver_irq_postinstall( drm_device_t *dev );
|
||||
extern void r128_driver_irq_uninstall( drm_device_t *dev );
|
||||
extern void r128_driver_pretakedown(drm_device_t *dev);
|
||||
extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
|
||||
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
|
||||
extern void r128_driver_irq_preinstall(drm_device_t * dev);
|
||||
extern void r128_driver_irq_postinstall(drm_device_t * dev);
|
||||
extern void r128_driver_irq_uninstall(drm_device_t * dev);
|
||||
extern void r128_driver_pretakedown(drm_device_t * dev);
|
||||
extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp);
|
||||
|
||||
extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
@ -266,7 +267,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
# define R128_EVENT_CRTC_OFFSET (1 << 0)
|
||||
#define R128_WINDOW_XY_OFFSET 0x1bcc
|
||||
|
||||
|
||||
/* CCE registers
|
||||
*/
|
||||
#define R128_PM4_BUFFER_OFFSET 0x0700
|
||||
|
@ -317,7 +317,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
#define R128_PM4_FIFO_DATA_EVEN 0x1000
|
||||
#define R128_PM4_FIFO_DATA_ODD 0x1004
|
||||
|
||||
|
||||
/* CCE command packets
|
||||
*/
|
||||
#define R128_CCE_PACKET0 0x00000000
|
||||
|
@ -395,7 +394,6 @@ do { \
|
|||
R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \
|
||||
((n) << 16) | ((reg) >> 2))
|
||||
#define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \
|
||||
|
@ -404,13 +402,11 @@ do { \
|
|||
#define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \
|
||||
(pkt) | ((n) << 16))
|
||||
|
||||
|
||||
static __inline__ void
|
||||
r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
|
||||
static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
|
||||
{
|
||||
drm_r128_ring_buffer_t *ring = &dev_priv->ring;
|
||||
ring->space = (GET_RING_HEAD( dev_priv ) - ring->tail) * sizeof(u32);
|
||||
if ( ring->space <= 0 )
|
||||
ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32);
|
||||
if (ring->space <= 0)
|
||||
ring->space += ring->size;
|
||||
}
|
||||
|
||||
|
@ -451,7 +447,6 @@ do { \
|
|||
OUT_RING( R128_EVENT_CRTC_OFFSET ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Ring control
|
||||
*/
|
||||
|
@ -521,4 +516,4 @@ do { \
|
|||
write &= tail_mask; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __R128_DRV_H__ */
|
||||
#endif /* __R128_DRV_H__ */
|
||||
|
|
|
@ -65,10 +65,10 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
|
|||
{
|
||||
drm_r128_init32_t init32;
|
||||
drm_r128_init_t __user *init;
|
||||
|
||||
|
||||
if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
init = compat_alloc_user_space(sizeof(*init));
|
||||
if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
|
||||
|| __put_user(init32.func, &init->func)
|
||||
|
@ -92,14 +92,14 @@ static int compat_r128_init(struct file *file, unsigned int cmd,
|
|||
|| __put_user(init32.ring_offset, &init->ring_offset)
|
||||
|| __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
|
||||
|| __put_user(init32.buffers_offset, &init->buffers_offset)
|
||||
|| __put_user(init32.agp_textures_offset, &init->agp_textures_offset))
|
||||
|| __put_user(init32.agp_textures_offset,
|
||||
&init->agp_textures_offset))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_R128_INIT, (unsigned long)init);
|
||||
}
|
||||
|
||||
|
||||
typedef struct drm_r128_depth32 {
|
||||
int func;
|
||||
int n;
|
||||
|
@ -124,13 +124,15 @@ static int compat_r128_depth(struct file *file, unsigned int cmd,
|
|||
|| __put_user(depth32.n, &depth->n)
|
||||
|| __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
|
||||
|| __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
|
||||
|| __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)
|
||||
|| __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))
|
||||
|| __put_user((unsigned int __user *)(unsigned long)depth32.buffer,
|
||||
&depth->buffer)
|
||||
|| __put_user((unsigned char __user *)(unsigned long)depth32.mask,
|
||||
&depth->mask))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
|
||||
|
||||
DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
|
||||
|
||||
}
|
||||
|
||||
typedef struct drm_r128_stipple32 {
|
||||
|
@ -148,7 +150,8 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd,
|
|||
|
||||
stipple = compat_alloc_user_space(sizeof(*stipple));
|
||||
if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
|
||||
|| __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))
|
||||
|| __put_user((unsigned int __user *)(unsigned long)stipple32.mask,
|
||||
&stipple->mask))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
|
@ -172,9 +175,10 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd,
|
|||
getparam = compat_alloc_user_space(sizeof(*getparam));
|
||||
if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
|
||||
|| __put_user(getparam32.param, &getparam->param)
|
||||
|| __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
|
||||
|| __put_user((void __user *)(unsigned long)getparam32.value,
|
||||
&getparam->value))
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
|
||||
}
|
||||
|
@ -195,8 +199,7 @@ drm_ioctl_compat_t *r128_compat_ioctls[] = {
|
|||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*/
|
||||
long r128_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_ioctl_compat_t *fn = NULL;
|
||||
|
@ -210,7 +213,7 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*-
|
||||
*
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
*
|
||||
* The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
* initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
* This notice must be preserved.
|
||||
|
@ -35,68 +35,67 @@
|
|||
#include "r128_drm.h"
|
||||
#include "r128_drv.h"
|
||||
|
||||
irqreturn_t r128_driver_irq_handler( DRM_IRQ_ARGS )
|
||||
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *) arg;
|
||||
drm_r128_private_t *dev_priv =
|
||||
(drm_r128_private_t *)dev->dev_private;
|
||||
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
|
||||
int status;
|
||||
|
||||
status = R128_READ( R128_GEN_INT_STATUS );
|
||||
|
||||
status = R128_READ(R128_GEN_INT_STATUS);
|
||||
|
||||
/* VBLANK interrupt */
|
||||
if ( status & R128_CRTC_VBLANK_INT ) {
|
||||
R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
|
||||
if (status & R128_CRTC_VBLANK_INT) {
|
||||
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
|
||||
atomic_inc(&dev->vbl_received);
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals( dev );
|
||||
drm_vbl_send_signals(dev);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
int r128_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||
int r128_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
|
||||
{
|
||||
unsigned int cur_vblank;
|
||||
int ret = 0;
|
||||
|
||||
/* Assume that the user has missed the current sequence number
|
||||
* by about a day rather than she wants to wait for years
|
||||
* using vertical blanks...
|
||||
* using vertical blanks...
|
||||
*/
|
||||
DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
|
||||
( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
|
||||
- *sequence ) <= (1<<23) ) );
|
||||
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
||||
(((cur_vblank = atomic_read(&dev->vbl_received))
|
||||
- *sequence) <= (1 << 23)));
|
||||
|
||||
*sequence = cur_vblank;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void r128_driver_irq_preinstall( drm_device_t *dev ) {
|
||||
drm_r128_private_t *dev_priv =
|
||||
(drm_r128_private_t *)dev->dev_private;
|
||||
void r128_driver_irq_preinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
R128_WRITE( R128_GEN_INT_CNTL, 0 );
|
||||
R128_WRITE(R128_GEN_INT_CNTL, 0);
|
||||
/* Clear vblank bit if it's already high */
|
||||
R128_WRITE( R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK );
|
||||
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
|
||||
}
|
||||
|
||||
void r128_driver_irq_postinstall( drm_device_t *dev ) {
|
||||
drm_r128_private_t *dev_priv =
|
||||
(drm_r128_private_t *)dev->dev_private;
|
||||
void r128_driver_irq_postinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
|
||||
|
||||
/* Turn on VBL interrupt */
|
||||
R128_WRITE( R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN );
|
||||
R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
|
||||
}
|
||||
|
||||
void r128_driver_irq_uninstall( drm_device_t *dev ) {
|
||||
drm_r128_private_t *dev_priv =
|
||||
(drm_r128_private_t *)dev->dev_private;
|
||||
void r128_driver_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
R128_WRITE( R128_GEN_INT_CNTL, 0 );
|
||||
R128_WRITE(R128_GEN_INT_CNTL, 0);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -37,7 +37,6 @@
|
|||
#include "radeon_drv.h"
|
||||
#include "r300_reg.h"
|
||||
|
||||
|
||||
#define R300_SIMULTANEOUS_CLIPRECTS 4
|
||||
|
||||
/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
|
||||
|
@ -49,14 +48,12 @@ static const int r300_cliprect_cntl[4] = {
|
|||
0xFFFE
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
|
||||
* buffer, starting with index n.
|
||||
*/
|
||||
static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
int n)
|
||||
static int r300_emit_cliprects(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf, int n)
|
||||
{
|
||||
drm_clip_rect_t box;
|
||||
int nr;
|
||||
|
@ -70,38 +67,47 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
|
|||
DRM_DEBUG("%i cliprects\n", nr);
|
||||
|
||||
if (nr) {
|
||||
BEGIN_RING(6 + nr*2);
|
||||
OUT_RING( CP_PACKET0( R300_RE_CLIPRECT_TL_0, nr*2 - 1 ) );
|
||||
BEGIN_RING(6 + nr * 2);
|
||||
OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
|
||||
|
||||
for(i = 0; i < nr; ++i) {
|
||||
if (DRM_COPY_FROM_USER_UNCHECKED(&box, &cmdbuf->boxes[n+i], sizeof(box))) {
|
||||
for (i = 0; i < nr; ++i) {
|
||||
if (DRM_COPY_FROM_USER_UNCHECKED
|
||||
(&box, &cmdbuf->boxes[n + i], sizeof(box))) {
|
||||
DRM_ERROR("copy cliprect faulted\n");
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
||||
box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.x1 =
|
||||
(box.x1 +
|
||||
R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.y1 =
|
||||
(box.y1 +
|
||||
R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.x2 =
|
||||
(box.x2 +
|
||||
R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
box.y2 =
|
||||
(box.y2 +
|
||||
R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
|
||||
|
||||
OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
|
||||
(box.y1 << R300_CLIPRECT_Y_SHIFT));
|
||||
(box.y1 << R300_CLIPRECT_Y_SHIFT));
|
||||
OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
|
||||
(box.y2 << R300_CLIPRECT_Y_SHIFT));
|
||||
(box.y2 << R300_CLIPRECT_Y_SHIFT));
|
||||
}
|
||||
|
||||
OUT_RING_REG( R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr-1] );
|
||||
OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
|
||||
|
||||
/* TODO/SECURITY: Force scissors to a safe value, otherwise the
|
||||
* client might be able to trample over memory.
|
||||
* The impact should be very limited, but I'd rather be safe than
|
||||
* sorry.
|
||||
*/
|
||||
OUT_RING( CP_PACKET0( R300_RE_SCISSORS_TL, 1 ) );
|
||||
OUT_RING( 0 );
|
||||
OUT_RING( R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK );
|
||||
* client might be able to trample over memory.
|
||||
* The impact should be very limited, but I'd rather be safe than
|
||||
* sorry.
|
||||
*/
|
||||
OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1));
|
||||
OUT_RING(0);
|
||||
OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK);
|
||||
ADVANCE_RING();
|
||||
} else {
|
||||
} else {
|
||||
/* Why we allow zero cliprect rendering:
|
||||
* There are some commands in a command buffer that must be submitted
|
||||
* even when there are no cliprects, e.g. DMA buffer discard
|
||||
|
@ -118,28 +124,27 @@ static int r300_emit_cliprects(drm_radeon_private_t* dev_priv,
|
|||
* can't produce any fragments.
|
||||
*/
|
||||
BEGIN_RING(2);
|
||||
OUT_RING_REG( R300_RE_CLIPRECT_CNTL, 0 );
|
||||
OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 r300_reg_flags[0x10000>>2];
|
||||
|
||||
static u8 r300_reg_flags[0x10000 >> 2];
|
||||
|
||||
void r300_init_reg_flags(void)
|
||||
{
|
||||
int i;
|
||||
memset(r300_reg_flags, 0, 0x10000>>2);
|
||||
#define ADD_RANGE_MARK(reg, count,mark) \
|
||||
memset(r300_reg_flags, 0, 0x10000 >> 2);
|
||||
#define ADD_RANGE_MARK(reg, count,mark) \
|
||||
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
|
||||
r300_reg_flags[i]|=(mark);
|
||||
|
||||
#define MARK_SAFE 1
|
||||
#define MARK_CHECK_OFFSET 2
|
||||
|
||||
#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
|
||||
|
||||
#define MARK_SAFE 1
|
||||
#define MARK_CHECK_OFFSET 2
|
||||
|
||||
#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
|
||||
|
||||
/* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
|
||||
ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
|
||||
|
@ -193,15 +198,15 @@ void r300_init_reg_flags(void)
|
|||
ADD_RANGE(R300_RB3D_CBLEND, 2);
|
||||
ADD_RANGE(R300_RB3D_COLORMASK, 1);
|
||||
ADD_RANGE(0x4E10, 3);
|
||||
ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
|
||||
ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
|
||||
ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
|
||||
ADD_RANGE(0x4E50, 9);
|
||||
ADD_RANGE(0x4E88, 1);
|
||||
ADD_RANGE(0x4EA0, 2);
|
||||
ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
|
||||
ADD_RANGE(0x4F10, 4);
|
||||
ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
|
||||
ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
|
||||
ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
|
||||
ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
|
||||
ADD_RANGE(0x4F28, 1);
|
||||
ADD_RANGE(0x4F30, 2);
|
||||
ADD_RANGE(0x4F44, 1);
|
||||
|
@ -211,7 +216,7 @@ void r300_init_reg_flags(void)
|
|||
ADD_RANGE(R300_TX_UNK1_0, 16);
|
||||
ADD_RANGE(R300_TX_SIZE_0, 16);
|
||||
ADD_RANGE(R300_TX_FORMAT_0, 16);
|
||||
/* Texture offset is dangerous and needs more checking */
|
||||
/* Texture offset is dangerous and needs more checking */
|
||||
ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
|
||||
ADD_RANGE(R300_TX_UNK4_0, 16);
|
||||
ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
|
||||
|
@ -224,33 +229,41 @@ void r300_init_reg_flags(void)
|
|||
|
||||
}
|
||||
|
||||
static __inline__ int r300_check_range(unsigned reg, int count)
|
||||
static __inline__ int r300_check_range(unsigned reg, int count)
|
||||
{
|
||||
int i;
|
||||
if(reg & ~0xffff)return -1;
|
||||
for(i=(reg>>2);i<(reg>>2)+count;i++)
|
||||
if(r300_reg_flags[i]!=MARK_SAFE)return 1;
|
||||
if (reg & ~0xffff)
|
||||
return -1;
|
||||
for (i = (reg >> 2); i < (reg >> 2) + count; i++)
|
||||
if (r300_reg_flags[i] != MARK_SAFE)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we expect offsets passed to the framebuffer to be either within video memory or
|
||||
within AGP space */
|
||||
static __inline__ int r300_check_offset(drm_radeon_private_t* dev_priv, u32 offset)
|
||||
within AGP space */
|
||||
static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv,
|
||||
u32 offset)
|
||||
{
|
||||
/* we realy want to check against end of video aperture
|
||||
but this value is not being kept.
|
||||
This code is correct for now (does the same thing as the
|
||||
code that sets MC_FB_LOCATION) in radeon_cp.c */
|
||||
if((offset>=dev_priv->fb_location) &&
|
||||
(offset<dev_priv->gart_vm_start))return 0;
|
||||
if((offset>=dev_priv->gart_vm_start) &&
|
||||
(offset<dev_priv->gart_vm_start+dev_priv->gart_size))return 0;
|
||||
but this value is not being kept.
|
||||
This code is correct for now (does the same thing as the
|
||||
code that sets MC_FB_LOCATION) in radeon_cp.c */
|
||||
if ((offset >= dev_priv->fb_location) &&
|
||||
(offset < dev_priv->gart_vm_start))
|
||||
return 0;
|
||||
if ((offset >= dev_priv->gart_vm_start) &&
|
||||
(offset < dev_priv->gart_vm_start + dev_priv->gart_size))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
drm_r300_cmd_header_t header)
|
||||
static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
|
||||
dev_priv,
|
||||
drm_radeon_kcmd_buffer_t
|
||||
* cmdbuf,
|
||||
drm_r300_cmd_header_t
|
||||
header)
|
||||
{
|
||||
int reg;
|
||||
int sz;
|
||||
|
@ -260,35 +273,40 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t*
|
|||
|
||||
sz = header.packet0.count;
|
||||
reg = (header.packet0.reghi << 8) | header.packet0.reglo;
|
||||
|
||||
if((sz>64)||(sz<0)){
|
||||
DRM_ERROR("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n", reg, sz);
|
||||
|
||||
if ((sz > 64) || (sz < 0)) {
|
||||
DRM_ERROR
|
||||
("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
|
||||
reg, sz);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
for(i=0;i<sz;i++){
|
||||
values[i]=((int __user*)cmdbuf->buf)[i];
|
||||
switch(r300_reg_flags[(reg>>2)+i]){
|
||||
}
|
||||
for (i = 0; i < sz; i++) {
|
||||
values[i] = ((int *)cmdbuf->buf)[i];
|
||||
switch (r300_reg_flags[(reg >> 2) + i]) {
|
||||
case MARK_SAFE:
|
||||
break;
|
||||
case MARK_CHECK_OFFSET:
|
||||
if(r300_check_offset(dev_priv, (u32)values[i])){
|
||||
DRM_ERROR("Offset failed range check (reg=%04x sz=%d)\n", reg, sz);
|
||||
if (r300_check_offset(dev_priv, (u32) values[i])) {
|
||||
DRM_ERROR
|
||||
("Offset failed range check (reg=%04x sz=%d)\n",
|
||||
reg, sz);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Register %04x failed check as flag=%02x\n", reg+i*4, r300_reg_flags[(reg>>2)+i]);
|
||||
DRM_ERROR("Register %04x failed check as flag=%02x\n",
|
||||
reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_RING(1+sz);
|
||||
OUT_RING( CP_PACKET0( reg, sz-1 ) );
|
||||
OUT_RING_TABLE( values, sz );
|
||||
}
|
||||
|
||||
BEGIN_RING(1 + sz);
|
||||
OUT_RING(CP_PACKET0(reg, sz - 1));
|
||||
OUT_RING_TABLE(values, sz);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += sz*4;
|
||||
cmdbuf->bufsz -= sz*4;
|
||||
cmdbuf->buf += sz * 4;
|
||||
cmdbuf->bufsz -= sz * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -299,9 +317,9 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t*
|
|||
*
|
||||
* Note that checks are performed on contents and addresses of the registers
|
||||
*/
|
||||
static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
drm_r300_cmd_header_t header)
|
||||
static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf,
|
||||
drm_r300_cmd_header_t header)
|
||||
{
|
||||
int reg;
|
||||
int sz;
|
||||
|
@ -313,39 +331,40 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t* dev_priv,
|
|||
if (!sz)
|
||||
return 0;
|
||||
|
||||
if (sz*4 > cmdbuf->bufsz)
|
||||
if (sz * 4 > cmdbuf->bufsz)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
if (reg+sz*4 >= 0x10000){
|
||||
DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg, sz);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if(r300_check_range(reg, sz)){
|
||||
if (reg + sz * 4 >= 0x10000) {
|
||||
DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg,
|
||||
sz);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (r300_check_range(reg, sz)) {
|
||||
/* go and check everything */
|
||||
return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf, header);
|
||||
}
|
||||
return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf,
|
||||
header);
|
||||
}
|
||||
/* the rest of the data is safe to emit, whatever the values the user passed */
|
||||
|
||||
BEGIN_RING(1+sz);
|
||||
OUT_RING( CP_PACKET0( reg, sz-1 ) );
|
||||
OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz );
|
||||
BEGIN_RING(1 + sz);
|
||||
OUT_RING(CP_PACKET0(reg, sz - 1));
|
||||
OUT_RING_TABLE((int *)cmdbuf->buf, sz);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += sz*4;
|
||||
cmdbuf->bufsz -= sz*4;
|
||||
cmdbuf->buf += sz * 4;
|
||||
cmdbuf->bufsz -= sz * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uploads user-supplied vertex program instructions or parameters onto
|
||||
* the graphics card.
|
||||
* Called by r300_do_cp_cmdbuf.
|
||||
*/
|
||||
static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf,
|
||||
drm_r300_cmd_header_t header)
|
||||
{
|
||||
int sz;
|
||||
|
@ -357,114 +376,121 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t* dev_priv,
|
|||
|
||||
if (!sz)
|
||||
return 0;
|
||||
if (sz*16 > cmdbuf->bufsz)
|
||||
if (sz * 16 > cmdbuf->bufsz)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
BEGIN_RING(5+sz*4);
|
||||
BEGIN_RING(5 + sz * 4);
|
||||
/* Wait for VAP to come to senses.. */
|
||||
/* there is no need to emit it multiple times, (only once before VAP is programmed,
|
||||
but this optimization is for later */
|
||||
OUT_RING_REG( R300_VAP_PVS_WAITIDLE, 0 );
|
||||
OUT_RING_REG( R300_VAP_PVS_UPLOAD_ADDRESS, addr );
|
||||
OUT_RING( CP_PACKET0_TABLE( R300_VAP_PVS_UPLOAD_DATA, sz*4 - 1 ) );
|
||||
OUT_RING_TABLE( (int __user*)cmdbuf->buf, sz*4 );
|
||||
OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
|
||||
OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
|
||||
OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
|
||||
OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
|
||||
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += sz*16;
|
||||
cmdbuf->bufsz -= sz*16;
|
||||
cmdbuf->buf += sz * 16;
|
||||
cmdbuf->bufsz -= sz * 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit a clear packet from userspace.
|
||||
* Called by r300_emit_packet3.
|
||||
*/
|
||||
static __inline__ int r300_emit_clear(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf)
|
||||
static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf)
|
||||
{
|
||||
RING_LOCALS;
|
||||
|
||||
if (8*4 > cmdbuf->bufsz)
|
||||
if (8 * 4 > cmdbuf->bufsz)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
BEGIN_RING(10);
|
||||
OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 8 ) );
|
||||
OUT_RING( R300_PRIM_TYPE_POINT|R300_PRIM_WALK_RING|
|
||||
(1<<R300_PRIM_NUM_VERTICES_SHIFT) );
|
||||
OUT_RING_TABLE( (int __user*)cmdbuf->buf, 8 );
|
||||
OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
|
||||
OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
|
||||
(1 << R300_PRIM_NUM_VERTICES_SHIFT));
|
||||
OUT_RING_TABLE((int *)cmdbuf->buf, 8);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += 8*4;
|
||||
cmdbuf->bufsz -= 8*4;
|
||||
cmdbuf->buf += 8 * 4;
|
||||
cmdbuf->bufsz -= 8 * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
u32 header)
|
||||
static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf,
|
||||
u32 header)
|
||||
{
|
||||
int count, i,k;
|
||||
#define MAX_ARRAY_PACKET 64
|
||||
int count, i, k;
|
||||
#define MAX_ARRAY_PACKET 64
|
||||
u32 payload[MAX_ARRAY_PACKET];
|
||||
u32 narrays;
|
||||
RING_LOCALS;
|
||||
|
||||
count=(header>>16) & 0x3fff;
|
||||
|
||||
if((count+1)>MAX_ARRAY_PACKET){
|
||||
DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n", count);
|
||||
count = (header >> 16) & 0x3fff;
|
||||
|
||||
if ((count + 1) > MAX_ARRAY_PACKET) {
|
||||
DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
|
||||
count);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
memset(payload, 0, MAX_ARRAY_PACKET*4);
|
||||
memcpy(payload, cmdbuf->buf+4, (count+1)*4);
|
||||
|
||||
}
|
||||
memset(payload, 0, MAX_ARRAY_PACKET * 4);
|
||||
memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
|
||||
|
||||
/* carefully check packet contents */
|
||||
|
||||
narrays=payload[0];
|
||||
k=0;
|
||||
i=1;
|
||||
while((k<narrays) && (i<(count+1))){
|
||||
i++; /* skip attribute field */
|
||||
if(r300_check_offset(dev_priv, payload[i])){
|
||||
DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
|
||||
|
||||
narrays = payload[0];
|
||||
k = 0;
|
||||
i = 1;
|
||||
while ((k < narrays) && (i < (count + 1))) {
|
||||
i++; /* skip attribute field */
|
||||
if (r300_check_offset(dev_priv, payload[i])) {
|
||||
DRM_ERROR
|
||||
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
|
||||
k, i);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
k++;
|
||||
i++;
|
||||
if(k==narrays)break;
|
||||
if (k == narrays)
|
||||
break;
|
||||
/* have one more to process, they come in pairs */
|
||||
if(r300_check_offset(dev_priv, payload[i])){
|
||||
DRM_ERROR("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n", k, i);
|
||||
if (r300_check_offset(dev_priv, payload[i])) {
|
||||
DRM_ERROR
|
||||
("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
|
||||
k, i);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
k++;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* do the counts match what we expect ? */
|
||||
if((k!=narrays) || (i!=(count+1))){
|
||||
DRM_ERROR("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n", k, i, narrays, count+1);
|
||||
if ((k != narrays) || (i != (count + 1))) {
|
||||
DRM_ERROR
|
||||
("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
|
||||
k, i, narrays, count + 1);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* all clear, output packet */
|
||||
|
||||
BEGIN_RING(count+2);
|
||||
BEGIN_RING(count + 2);
|
||||
OUT_RING(header);
|
||||
OUT_RING_TABLE(payload, count+1);
|
||||
OUT_RING_TABLE(payload, count + 1);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += (count+2)*4;
|
||||
cmdbuf->bufsz -= (count+2)*4;
|
||||
cmdbuf->buf += (count + 2) * 4;
|
||||
cmdbuf->bufsz -= (count + 2) * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf)
|
||||
static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf)
|
||||
{
|
||||
u32 header;
|
||||
int count;
|
||||
|
@ -473,36 +499,37 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
|
|||
if (4 > cmdbuf->bufsz)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
/* Fixme !! This simply emits a packet without much checking.
|
||||
/* Fixme !! This simply emits a packet without much checking.
|
||||
We need to be smarter. */
|
||||
|
||||
/* obtain first word - actual packet3 header */
|
||||
header = *(u32 __user*)cmdbuf->buf;
|
||||
header = *(u32 *) cmdbuf->buf;
|
||||
|
||||
/* Is it packet 3 ? */
|
||||
if( (header>>30)!=0x3 ) {
|
||||
if ((header >> 30) != 0x3) {
|
||||
DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
count=(header>>16) & 0x3fff;
|
||||
count = (header >> 16) & 0x3fff;
|
||||
|
||||
/* Check again now that we know how much data to expect */
|
||||
if ((count+2)*4 > cmdbuf->bufsz){
|
||||
DRM_ERROR("Expected packet3 of length %d but have only %d bytes left\n",
|
||||
(count+2)*4, cmdbuf->bufsz);
|
||||
if ((count + 2) * 4 > cmdbuf->bufsz) {
|
||||
DRM_ERROR
|
||||
("Expected packet3 of length %d but have only %d bytes left\n",
|
||||
(count + 2) * 4, cmdbuf->bufsz);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Is it a packet type we know about ? */
|
||||
switch(header & 0xff00){
|
||||
case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
|
||||
switch (header & 0xff00) {
|
||||
case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
|
||||
return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
|
||||
|
||||
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
||||
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
||||
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
||||
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
||||
case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
|
||||
case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
|
||||
case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
|
||||
case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
|
||||
case RADEON_WAIT_FOR_IDLE:
|
||||
case RADEON_CP_NOP:
|
||||
/* these packets are safe */
|
||||
|
@ -510,32 +537,30 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t* dev_priv,
|
|||
default:
|
||||
DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BEGIN_RING(count+2);
|
||||
BEGIN_RING(count + 2);
|
||||
OUT_RING(header);
|
||||
OUT_RING_TABLE( (int __user*)(cmdbuf->buf+4), count+1);
|
||||
OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
|
||||
ADVANCE_RING();
|
||||
|
||||
cmdbuf->buf += (count+2)*4;
|
||||
cmdbuf->bufsz -= (count+2)*4;
|
||||
cmdbuf->buf += (count + 2) * 4;
|
||||
cmdbuf->bufsz -= (count + 2) * 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Emit a rendering packet3 from userspace.
|
||||
* Called by r300_do_cp_cmdbuf.
|
||||
*/
|
||||
static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf,
|
||||
static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf,
|
||||
drm_r300_cmd_header_t header)
|
||||
{
|
||||
int n;
|
||||
int ret;
|
||||
char __user* orig_buf = cmdbuf->buf;
|
||||
char *orig_buf = cmdbuf->buf;
|
||||
int orig_bufsz = cmdbuf->bufsz;
|
||||
|
||||
/* This is a do-while-loop so that we run the interior at least once,
|
||||
|
@ -550,16 +575,16 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
|
|||
|
||||
cmdbuf->buf = orig_buf;
|
||||
cmdbuf->bufsz = orig_bufsz;
|
||||
}
|
||||
}
|
||||
|
||||
switch(header.packet3.packet) {
|
||||
switch (header.packet3.packet) {
|
||||
case R300_CMD_PACKET3_CLEAR:
|
||||
DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
|
||||
ret = r300_emit_clear(dev_priv, cmdbuf);
|
||||
if (ret) {
|
||||
DRM_ERROR("r300_emit_clear failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R300_CMD_PACKET3_RAW:
|
||||
|
@ -568,18 +593,18 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
|
|||
if (ret) {
|
||||
DRM_ERROR("r300_emit_raw_packet3 failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("bad packet3 type %i at %p\n",
|
||||
header.packet3.packet,
|
||||
cmdbuf->buf - sizeof(header));
|
||||
header.packet3.packet,
|
||||
cmdbuf->buf - sizeof(header));
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
n += R300_SIMULTANEOUS_CLIPRECTS;
|
||||
} while(n < cmdbuf->nbox);
|
||||
} while (n < cmdbuf->nbox);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -598,21 +623,20 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t* dev_priv,
|
|||
/**
|
||||
* Emit the sequence to pacify R300.
|
||||
*/
|
||||
static __inline__ void r300_pacify(drm_radeon_private_t* dev_priv)
|
||||
static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv)
|
||||
{
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_RING(6);
|
||||
OUT_RING( CP_PACKET0( R300_RB3D_DSTCACHE_CTLSTAT, 0 ) );
|
||||
OUT_RING( 0xa );
|
||||
OUT_RING( CP_PACKET0( 0x4f18, 0 ) );
|
||||
OUT_RING( 0x3 );
|
||||
OUT_RING( CP_PACKET3( RADEON_CP_NOP, 0 ) );
|
||||
OUT_RING( 0x0 );
|
||||
OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
|
||||
OUT_RING(0xa);
|
||||
OUT_RING(CP_PACKET0(0x4f18, 0));
|
||||
OUT_RING(0x3);
|
||||
OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
|
||||
OUT_RING(0x0);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
|
||||
* The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
|
||||
|
@ -628,20 +652,18 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
|
|||
buf->used = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses and validates a user-supplied command buffer and emits appropriate
|
||||
* commands on the DMA ring buffer.
|
||||
* Called by the ioctl handler function radeon_cp_cmdbuf.
|
||||
*/
|
||||
int r300_do_cp_cmdbuf(drm_device_t* dev,
|
||||
DRMFILE filp,
|
||||
drm_file_t* filp_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf)
|
||||
int r300_do_cp_cmdbuf(drm_device_t * dev,
|
||||
DRMFILE filp,
|
||||
drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf = NULL;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf = NULL;
|
||||
int emit_dispatch_age = 0;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -655,9 +677,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
while(cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
|
||||
while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
|
||||
int idx;
|
||||
drm_r300_cmd_header_t header;
|
||||
|
||||
|
@ -666,14 +688,14 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
cmdbuf->buf += sizeof(header);
|
||||
cmdbuf->bufsz -= sizeof(header);
|
||||
|
||||
switch(header.header.cmd_type) {
|
||||
case R300_CMD_PACKET0:
|
||||
switch (header.header.cmd_type) {
|
||||
case R300_CMD_PACKET0:
|
||||
DRM_DEBUG("R300_CMD_PACKET0\n");
|
||||
ret = r300_emit_packet0(dev_priv, cmdbuf, header);
|
||||
if (ret) {
|
||||
DRM_ERROR("r300_emit_packet0 failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R300_CMD_VPU:
|
||||
|
@ -682,7 +704,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
if (ret) {
|
||||
DRM_ERROR("r300_emit_vpu failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R300_CMD_PACKET3:
|
||||
|
@ -691,26 +713,26 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
if (ret) {
|
||||
DRM_ERROR("r300_emit_packet3 failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case R300_CMD_END3D:
|
||||
DRM_DEBUG("R300_CMD_END3D\n");
|
||||
/* TODO:
|
||||
Ideally userspace driver should not need to issue this call,
|
||||
i.e. the drm driver should issue it automatically and prevent
|
||||
lockups.
|
||||
|
||||
In practice, we do not understand why this call is needed and what
|
||||
it does (except for some vague guesses that it has to do with cache
|
||||
coherence) and so the user space driver does it.
|
||||
|
||||
Once we are sure which uses prevent lockups the code could be moved
|
||||
into the kernel and the userspace driver will not
|
||||
need to use this command.
|
||||
/* TODO:
|
||||
Ideally userspace driver should not need to issue this call,
|
||||
i.e. the drm driver should issue it automatically and prevent
|
||||
lockups.
|
||||
|
||||
Note that issuing this command does not hurt anything
|
||||
except, possibly, performance */
|
||||
In practice, we do not understand why this call is needed and what
|
||||
it does (except for some vague guesses that it has to do with cache
|
||||
coherence) and so the user space driver does it.
|
||||
|
||||
Once we are sure which uses prevent lockups the code could be moved
|
||||
into the kernel and the userspace driver will not
|
||||
need to use this command.
|
||||
|
||||
Note that issuing this command does not hurt anything
|
||||
except, possibly, performance */
|
||||
r300_pacify(dev_priv);
|
||||
break;
|
||||
|
||||
|
@ -722,7 +744,7 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
RING_LOCALS;
|
||||
|
||||
BEGIN_RING(header.delay.count);
|
||||
for(i=0;i<header.delay.count;i++)
|
||||
for (i = 0; i < header.delay.count; i++)
|
||||
OUT_RING(RADEON_CP_PACKET2);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
@ -730,53 +752,54 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
|
||||
case R300_CMD_DMA_DISCARD:
|
||||
DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
|
||||
idx = header.dma.buf_idx;
|
||||
if (idx < 0 || idx >= dma->buf_count) {
|
||||
DRM_ERROR("buffer index %d (of %d max)\n",
|
||||
idx, dma->buf_count - 1);
|
||||
idx = header.dma.buf_idx;
|
||||
if (idx < 0 || idx >= dma->buf_count) {
|
||||
DRM_ERROR("buffer index %d (of %d max)\n",
|
||||
idx, dma->buf_count - 1);
|
||||
ret = DRM_ERR(EINVAL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
buf = dma->buflist[idx];
|
||||
if (buf->filp != filp || buf->pending) {
|
||||
DRM_ERROR("bad buffer %p %p %d\n",
|
||||
buf->filp, filp, buf->pending);
|
||||
ret = DRM_ERR(EINVAL);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
buf = dma->buflist[idx];
|
||||
if (buf->filp != filp || buf->pending) {
|
||||
DRM_ERROR("bad buffer %p %p %d\n",
|
||||
buf->filp, filp, buf->pending);
|
||||
ret = DRM_ERR(EINVAL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
emit_dispatch_age = 1;
|
||||
r300_discard_buffer(dev, buf);
|
||||
break;
|
||||
break;
|
||||
|
||||
case R300_CMD_WAIT:
|
||||
/* simple enough, we can do it here */
|
||||
DRM_DEBUG("R300_CMD_WAIT\n");
|
||||
if(header.wait.flags==0)break; /* nothing to do */
|
||||
if (header.wait.flags == 0)
|
||||
break; /* nothing to do */
|
||||
|
||||
{
|
||||
RING_LOCALS;
|
||||
|
||||
BEGIN_RING(2);
|
||||
OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );
|
||||
OUT_RING( (header.wait.flags & 0xf)<<14 );
|
||||
OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
|
||||
OUT_RING((header.wait.flags & 0xf) << 14);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("bad cmd_type %i at %p\n",
|
||||
header.header.cmd_type,
|
||||
header.header.cmd_type,
|
||||
cmdbuf->buf - sizeof(header));
|
||||
ret = DRM_ERR(EINVAL);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("END\n");
|
||||
|
||||
cleanup:
|
||||
cleanup:
|
||||
r300_pacify(dev_priv);
|
||||
|
||||
/* We emit the vertex buffer age here, outside the pacifier "brackets"
|
||||
|
@ -792,10 +815,9 @@ int r300_do_cp_cmdbuf(drm_device_t* dev,
|
|||
BEGIN_RING(2);
|
||||
RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
|
||||
ADVANCE_RING();
|
||||
}
|
||||
}
|
||||
|
||||
COMMIT_RING();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24
|
||||
# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28
|
||||
|
||||
|
||||
#define R300_MC_INIT_GFX_LAT_TIMER 0x154
|
||||
# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0
|
||||
# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4
|
||||
|
@ -62,7 +61,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_SE_VPORT_ZSCALE 0x1DA8
|
||||
#define R300_SE_VPORT_ZOFFSET 0x1DAC
|
||||
|
||||
|
||||
/* This register is written directly and also starts data section in many 3d CP_PACKET3's */
|
||||
#define R300_VAP_VF_CNTL 0x2084
|
||||
|
||||
|
@ -93,17 +91,17 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
|
||||
/* index size - when not set the indices are assumed to be 16 bit */
|
||||
# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
|
||||
/* number of vertices */
|
||||
/* number of vertices */
|
||||
# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
|
||||
|
||||
/* BEGIN: Wild guesses */
|
||||
#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
|
||||
|
||||
#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
|
||||
# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
|
||||
|
@ -159,14 +157,14 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
|
||||
# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
|
||||
# define R300_VAP_INPUT_ROUTE_END (1 << 13)
|
||||
# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
|
||||
# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
|
||||
#define R300_VAP_INPUT_ROUTE_0_1 0x2154
|
||||
#define R300_VAP_INPUT_ROUTE_0_2 0x2158
|
||||
#define R300_VAP_INPUT_ROUTE_0_3 0x215C
|
||||
|
@ -188,12 +186,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_INPUT_CNTL_COLOR 0x00000004
|
||||
# define R300_INPUT_CNTL_TC0 0x00000400
|
||||
# define R300_INPUT_CNTL_TC1 0x00000800
|
||||
# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
|
||||
# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
|
||||
|
||||
/* gap */
|
||||
/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
|
||||
|
@ -270,12 +268,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
// rendering commands and overwriting vertex program parameters.
|
||||
// Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
|
||||
// avoids bugs caused by still running shaders reading bad data from memory. */
|
||||
#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
|
||||
#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
|
||||
|
||||
/* Absolutely no clue what this register is about. */
|
||||
#define R300_VAP_UNKNOWN_2288 0x2288
|
||||
# define R300_2288_R300 0x00750000 /* -- nh */
|
||||
# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
|
||||
# define R300_2288_R300 0x00750000 /* -- nh */
|
||||
# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
|
||||
|
||||
/* gap */
|
||||
/* Addresses are relative to the vertex program instruction area of the
|
||||
|
@ -286,10 +284,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
// experiments so far have shown that both *must* point to an instruction
|
||||
// inside the vertex program, otherwise the GPU locks up.
|
||||
// fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
|
||||
// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
|
||||
// CNTL_1_UNKNOWN points to instruction where last write to position takes place.
|
||||
// Most likely this is used to ignore rest of the program in cases where group of verts arent visible.
|
||||
// For some reason this "section" is sometimes accepted other instruction that have
|
||||
// no relationship with position calculations.
|
||||
// no relationship with position calculations.
|
||||
*/
|
||||
#define R300_VAP_PVS_CNTL_1 0x22D0
|
||||
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
|
||||
|
@ -308,13 +306,13 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_VAP_VTX_COLOR_R 0x2464
|
||||
#define R300_VAP_VTX_COLOR_G 0x2468
|
||||
#define R300_VAP_VTX_COLOR_B 0x246C
|
||||
#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
|
||||
#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
|
||||
#define R300_VAP_VTX_POS_0_Y_1 0x2494
|
||||
#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
|
||||
#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
|
||||
#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
|
||||
#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
|
||||
#define R300_VAP_VTX_POS_0_Y_2 0x24A4
|
||||
#define R300_VAP_VTX_POS_0_Z_2 0x24A8
|
||||
#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
|
||||
#define R300_VAP_VTX_END_OF_PKT 0x24AC /* write 0 to indicate end of packet? */
|
||||
|
||||
/* gap */
|
||||
|
||||
|
@ -385,7 +383,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
|
||||
# define R300_GB_MSPOS1__MSBD1 24
|
||||
|
||||
|
||||
#define R300_GB_TILE_CONFIG 0x4018
|
||||
# define R300_GB_TILE_ENABLE (1<<0)
|
||||
# define R300_GB_TILE_PIPE_COUNT_RV300 0
|
||||
|
@ -478,9 +475,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
// framebuffer. */
|
||||
#define R300_RE_POINTSIZE 0x421C
|
||||
# define R300_POINTSIZE_Y_SHIFT 0
|
||||
# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
|
||||
# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
|
||||
# define R300_POINTSIZE_X_SHIFT 16
|
||||
# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
|
||||
# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
|
||||
# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6)
|
||||
|
||||
/* The line width is given in multiples of 6.
|
||||
|
@ -491,7 +488,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
*/
|
||||
#define R300_RE_LINE_CNT 0x4234
|
||||
# define R300_LINESIZE_SHIFT 0
|
||||
# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
|
||||
# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
|
||||
# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6)
|
||||
# define R300_LINE_CNT_HO (1 << 16)
|
||||
# define R300_LINE_CNT_VE (1 << 17)
|
||||
|
@ -513,8 +510,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_PM_BACK_LINE (1 << 7)
|
||||
# define R300_PM_BACK_FILL (1 << 8)
|
||||
|
||||
/* Not sure why there are duplicate of factor and constant values.
|
||||
My best guess so far is that there are seperate zbiases for test and write.
|
||||
/* Not sure why there are duplicate of factor and constant values.
|
||||
My best guess so far is that there are seperate zbiases for test and write.
|
||||
Ordering might be wrong.
|
||||
Some of the tests indicate that fgl has a fallback implementation of zbias
|
||||
via pixel shaders. */
|
||||
|
@ -540,7 +537,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_FRONT_FACE_CCW (0 << 2)
|
||||
# define R300_FRONT_FACE_CW (1 << 2)
|
||||
|
||||
|
||||
/* BEGIN: Rasterization / Interpolators - many guesses
|
||||
// 0_UNKNOWN_18 has always been set except for clear operations.
|
||||
// TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
|
||||
|
@ -548,7 +544,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_RS_CNTL_0 0x4300
|
||||
# define R300_RS_CNTL_TC_CNT_SHIFT 2
|
||||
# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
|
||||
# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */
|
||||
# define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */
|
||||
# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
|
||||
/* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */
|
||||
#define R300_RS_CNTL_1 0x4304
|
||||
|
@ -585,29 +581,29 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_RS_ROUTE_0 0x4330
|
||||
#define R300_RS_ROUTE_1 0x4334
|
||||
#define R300_RS_ROUTE_2 0x4338
|
||||
#define R300_RS_ROUTE_3 0x433C /* GUESS */
|
||||
#define R300_RS_ROUTE_4 0x4340 /* GUESS */
|
||||
#define R300_RS_ROUTE_5 0x4344 /* GUESS */
|
||||
#define R300_RS_ROUTE_6 0x4348 /* GUESS */
|
||||
#define R300_RS_ROUTE_7 0x434C /* GUESS */
|
||||
#define R300_RS_ROUTE_3 0x433C /* GUESS */
|
||||
#define R300_RS_ROUTE_4 0x4340 /* GUESS */
|
||||
#define R300_RS_ROUTE_5 0x4344 /* GUESS */
|
||||
#define R300_RS_ROUTE_6 0x4348 /* GUESS */
|
||||
#define R300_RS_ROUTE_7 0x434C /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_0 0
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_1 1
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_2 2
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_3 3
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_4 4
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
|
||||
# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
|
||||
# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
|
||||
# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
|
||||
# define R300_RS_ROUTE_DEST_SHIFT 6
|
||||
# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
|
||||
# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
|
||||
|
||||
/* Special handling for color: When the fragment program uses color,
|
||||
// the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
|
||||
// color register index. */
|
||||
# define R300_RS_ROUTE_0_COLOR (1 << 14)
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
|
||||
# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
|
||||
/* As above, but for secondary color */
|
||||
# define R300_RS_ROUTE_1_COLOR1 (1 << 14)
|
||||
# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
|
||||
|
@ -721,7 +717,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_TX_HEIGHTMASK_SHIFT 11
|
||||
# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
|
||||
# define R300_TX_UNK23 (1 << 23)
|
||||
# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
|
||||
# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
|
||||
# define R300_TX_SIZE_MASK (15 << 26)
|
||||
#define R300_TX_FORMAT_0 0x44C0
|
||||
/* The interpretation of the format word by Wladimir van der Laan */
|
||||
|
@ -746,12 +742,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_TX_FORMAT_DXT1 0xF
|
||||
# define R300_TX_FORMAT_DXT3 0x10
|
||||
# define R300_TX_FORMAT_DXT5 0x11
|
||||
# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
|
||||
# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
|
||||
# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
|
||||
# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
|
||||
# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
|
||||
# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
|
||||
# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
|
||||
# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
|
||||
/* 0x16 - some 16 bit green format.. ?? */
|
||||
# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
|
||||
# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
|
||||
|
||||
/* gap */
|
||||
/* Floating point formats */
|
||||
|
@ -777,8 +773,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_TX_FORMAT_W 3
|
||||
# define R300_TX_FORMAT_ZERO 4
|
||||
# define R300_TX_FORMAT_ONE 5
|
||||
# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */
|
||||
# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */
|
||||
# define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */
|
||||
# define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */
|
||||
|
||||
# define R300_TX_FORMAT_B_SHIFT 18
|
||||
# define R300_TX_FORMAT_G_SHIFT 15
|
||||
|
@ -811,7 +807,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_TXO_OFFSET_SHIFT 5
|
||||
/* END */
|
||||
#define R300_TX_UNK4_0 0x4580
|
||||
#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
|
||||
#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
|
||||
|
||||
/* END */
|
||||
|
||||
|
@ -844,9 +840,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_PFS_CNTL_ALU_END_SHIFT 6
|
||||
# define R300_PFS_CNTL_ALU_END_MASK (63 << 0)
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
|
||||
# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
|
||||
# define R300_PFS_CNTL_TEX_END_SHIFT 18
|
||||
# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
|
||||
# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
|
||||
|
||||
/* gap */
|
||||
/* Nodes are stored backwards. The last active node is always stored in
|
||||
|
@ -877,11 +873,11 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_PFS_TEXI_0 0x4620
|
||||
# define R300_FPITX_SRC_SHIFT 0
|
||||
# define R300_FPITX_SRC_MASK (31 << 0)
|
||||
# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
|
||||
# define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */
|
||||
# define R300_FPITX_DST_SHIFT 6
|
||||
# define R300_FPITX_DST_MASK (31 << 6)
|
||||
# define R300_FPITX_IMAGE_SHIFT 11
|
||||
# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
|
||||
# define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */
|
||||
/* Unsure if these are opcodes, or some kind of bitfield, but this is how
|
||||
* they were set when I checked
|
||||
*/
|
||||
|
@ -1003,7 +999,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_FPI0_ARGC_SRC1C_LRP 15
|
||||
# define R300_FPI0_ARGC_ZERO 20
|
||||
# define R300_FPI0_ARGC_ONE 21
|
||||
# define R300_FPI0_ARGC_HALF 22 /* GUESS */
|
||||
# define R300_FPI0_ARGC_HALF 22 /* GUESS */
|
||||
# define R300_FPI0_ARGC_SRC0C_YZX 23
|
||||
# define R300_FPI0_ARGC_SRC1C_YZX 24
|
||||
# define R300_FPI0_ARGC_SRC2C_YZX 25
|
||||
|
@ -1054,20 +1050,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_FPI2_ARGA_SRC1A_LRP 15
|
||||
# define R300_FPI2_ARGA_ZERO 16
|
||||
# define R300_FPI2_ARGA_ONE 17
|
||||
# define R300_FPI2_ARGA_HALF 18 /* GUESS */
|
||||
# define R300_FPI2_ARGA_HALF 18 /* GUESS */
|
||||
|
||||
# define R300_FPI2_ARG0A_SHIFT 0
|
||||
# define R300_FPI2_ARG0A_MASK (31 << 0)
|
||||
# define R300_FPI2_ARG0A_NEG (1 << 5)
|
||||
# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */
|
||||
# define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */
|
||||
# define R300_FPI2_ARG1A_SHIFT 7
|
||||
# define R300_FPI2_ARG1A_MASK (31 << 7)
|
||||
# define R300_FPI2_ARG1A_NEG (1 << 12)
|
||||
# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */
|
||||
# define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */
|
||||
# define R300_FPI2_ARG2A_SHIFT 14
|
||||
# define R300_FPI2_ARG2A_MASK (31 << 14)
|
||||
# define R300_FPI2_ARG2A_NEG (1 << 19)
|
||||
# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */
|
||||
# define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */
|
||||
# define R300_FPI2_SPECIAL_LRP (1 << 21)
|
||||
# define R300_FPI2_OUTA_MAD (0 << 23)
|
||||
# define R300_FPI2_OUTA_DP4 (1 << 23)
|
||||
|
@ -1157,26 +1153,26 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
|
||||
/* gap */
|
||||
#define R300_RB3D_COLOROFFSET0 0x4E28
|
||||
# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
|
||||
# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
|
||||
#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
|
||||
/* gap */
|
||||
/* Bit 16: Larger tiles
|
||||
// Bit 17: 4x2 tiles
|
||||
// Bit 18: Extremely weird tile like, but some pixels duplicated? */
|
||||
#define R300_RB3D_COLORPITCH0 0x4E38
|
||||
# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
# define R300_COLOR_FORMAT_RGB565 (2 << 22)
|
||||
# define R300_COLOR_FORMAT_ARGB8888 (3 << 22)
|
||||
#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
|
||||
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
|
||||
|
||||
/* gap */
|
||||
/* Guess by Vladimir.
|
||||
|
@ -1189,8 +1185,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
/* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */
|
||||
/* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */
|
||||
#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00
|
||||
# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
|
||||
# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
|
||||
# define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */
|
||||
# define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */
|
||||
# define R300_RB3D_Z_TEST 0x00000012
|
||||
# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
|
||||
# define R300_RB3D_Z_WRITE_ONLY 0x00000006
|
||||
|
@ -1233,8 +1229,6 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21
|
||||
# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24
|
||||
|
||||
|
||||
|
||||
#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08
|
||||
# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0
|
||||
# define R300_RB3D_ZS2_STENCIL_MASK 0xFF
|
||||
|
@ -1250,12 +1244,12 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
/* gap */
|
||||
#define R300_RB3D_DEPTHOFFSET 0x4F20
|
||||
#define R300_RB3D_DEPTHPITCH 0x4F24
|
||||
# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
|
||||
# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
|
||||
# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
|
||||
# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
|
||||
|
||||
/* BEGIN: Vertex program instruction set
|
||||
// Every instruction is four dwords long:
|
||||
|
@ -1295,26 +1289,26 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_VPI_OUT_OP_MIN (8 << 0)
|
||||
#define R300_VPI_OUT_OP_SGE (9 << 0)
|
||||
#define R300_VPI_OUT_OP_SLT (10 << 0)
|
||||
#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
|
||||
#define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
|
||||
#define R300_VPI_OUT_OP_EXP (65 << 0)
|
||||
#define R300_VPI_OUT_OP_LOG (66 << 0)
|
||||
#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */
|
||||
#define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */
|
||||
#define R300_VPI_OUT_OP_LIT (68 << 0)
|
||||
#define R300_VPI_OUT_OP_POW (69 << 0)
|
||||
#define R300_VPI_OUT_OP_RCP (70 << 0)
|
||||
#define R300_VPI_OUT_OP_RSQ (72 << 0)
|
||||
#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
|
||||
#define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
|
||||
#define R300_VPI_OUT_OP_EX2 (75 << 0)
|
||||
#define R300_VPI_OUT_OP_LG2 (76 << 0)
|
||||
#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
|
||||
#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */
|
||||
#define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */
|
||||
|
||||
#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
|
||||
#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
|
||||
#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
|
||||
|
||||
#define R300_VPI_OUT_REG_INDEX_SHIFT 13
|
||||
#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
|
||||
#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */
|
||||
|
||||
#define R300_VPI_OUT_WRITE_X (1 << 20)
|
||||
#define R300_VPI_OUT_WRITE_Y (1 << 21)
|
||||
|
@ -1325,10 +1319,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
|
||||
#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
|
||||
#define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */
|
||||
|
||||
#define R300_VPI_IN_REG_INDEX_SHIFT 5
|
||||
#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
|
||||
#define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */
|
||||
|
||||
/* The R300 can select components from the input register arbitrarily.
|
||||
// Use the following constants, shifted by the component shift you
|
||||
|
@ -1366,7 +1360,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_PRIM_TYPE_RECT_LIST (8 << 0)
|
||||
#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
|
||||
#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
|
||||
#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200)
|
||||
#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200)
|
||||
#define R300_PRIM_TYPE_LINE_LOOP (12 << 0)
|
||||
#define R300_PRIM_TYPE_QUADS (13 << 0)
|
||||
#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0)
|
||||
|
@ -1376,8 +1370,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
#define R300_PRIM_WALK_LIST (2 << 4)
|
||||
#define R300_PRIM_WALK_RING (3 << 4)
|
||||
#define R300_PRIM_WALK_MASK (3 << 4)
|
||||
#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200)
|
||||
#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS
|
||||
#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200)
|
||||
#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS
|
||||
#define R300_PRIM_NUM_VERTICES_SHIFT 16
|
||||
|
||||
// Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
|
||||
|
@ -1409,4 +1403,4 @@ I am fairly certain that they are correct unless stated otherwise in comments.
|
|||
|
||||
//END
|
||||
|
||||
#endif /* _R300_REG_H */
|
||||
#endif /* _R300_REG_H */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,78 +57,77 @@
|
|||
#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
|
||||
#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
|
||||
#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
|
||||
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
|
||||
#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
|
||||
#define RADEON_REQUIRE_QUIESCENCE 0x00010000
|
||||
#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
|
||||
#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
|
||||
#define RADEON_UPLOAD_ALL 0x003effff
|
||||
#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff
|
||||
|
||||
|
||||
/* New style per-packet identifiers for use in cmd_buffer ioctl with
|
||||
* the RADEON_EMIT_PACKET command. Comments relate new packets to old
|
||||
* state bits and the packet size:
|
||||
*/
|
||||
#define RADEON_EMIT_PP_MISC 0 /* context/7 */
|
||||
#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
|
||||
#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
|
||||
#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
|
||||
#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
|
||||
#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
|
||||
#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
|
||||
#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
|
||||
#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
|
||||
#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
|
||||
#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
|
||||
#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
|
||||
#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
|
||||
#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
|
||||
#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
|
||||
#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
|
||||
#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
|
||||
#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
|
||||
#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
|
||||
#define R200_EMIT_VAP_CTL 32 /* vap/1 */
|
||||
#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
|
||||
#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
|
||||
#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
|
||||
#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
|
||||
#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
|
||||
#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
|
||||
#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
|
||||
#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
|
||||
#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
|
||||
#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
|
||||
#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
|
||||
#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
|
||||
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
|
||||
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
|
||||
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
|
||||
#define RADEON_EMIT_PP_MISC 0 /* context/7 */
|
||||
#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
|
||||
#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
|
||||
#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
|
||||
#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
|
||||
#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
|
||||
#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
|
||||
#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
|
||||
#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
|
||||
#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
|
||||
#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
|
||||
#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
|
||||
#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
|
||||
#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
|
||||
#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
|
||||
#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
|
||||
#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
|
||||
#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
|
||||
#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
|
||||
#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
|
||||
#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
|
||||
#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
|
||||
#define R200_EMIT_VAP_CTL 32 /* vap/1 */
|
||||
#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
|
||||
#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
|
||||
#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
|
||||
#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
|
||||
#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
|
||||
#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
|
||||
#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
|
||||
#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
|
||||
#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
|
||||
#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
|
||||
#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
|
||||
#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
|
||||
#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
|
||||
#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
|
||||
#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
|
||||
#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
|
||||
#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
|
||||
#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
|
||||
#define R200_EMIT_PP_CUBIC_FACES_0 61
|
||||
#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
|
||||
#define R200_EMIT_PP_CUBIC_FACES_1 63
|
||||
|
@ -153,42 +152,50 @@
|
|||
#define RADEON_EMIT_PP_CUBIC_FACES_2 82
|
||||
#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83
|
||||
#define R200_EMIT_PP_TRI_PERF_CNTL 84
|
||||
#define RADEON_MAX_STATE_PACKETS 85
|
||||
#define R200_EMIT_PP_AFS_0 85
|
||||
#define R200_EMIT_PP_AFS_1 86
|
||||
#define R200_EMIT_ATF_TFACTOR 87
|
||||
#define R200_EMIT_PP_TXCTLALL_0 88
|
||||
#define R200_EMIT_PP_TXCTLALL_1 89
|
||||
#define R200_EMIT_PP_TXCTLALL_2 90
|
||||
#define R200_EMIT_PP_TXCTLALL_3 91
|
||||
#define R200_EMIT_PP_TXCTLALL_4 92
|
||||
#define R200_EMIT_PP_TXCTLALL_5 93
|
||||
#define RADEON_MAX_STATE_PACKETS 94
|
||||
|
||||
/* Commands understood by cmd_buffer ioctl. More can be added but
|
||||
* obviously these can't be removed or changed:
|
||||
*/
|
||||
#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
|
||||
#define RADEON_CMD_SCALARS 2 /* emit scalar data */
|
||||
#define RADEON_CMD_VECTORS 3 /* emit vector data */
|
||||
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
|
||||
#define RADEON_CMD_PACKET3 5 /* emit hw packet */
|
||||
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
|
||||
#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
|
||||
#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
|
||||
* doesn't make the cpu wait, just
|
||||
* the graphics hardware */
|
||||
|
||||
#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
|
||||
#define RADEON_CMD_SCALARS 2 /* emit scalar data */
|
||||
#define RADEON_CMD_VECTORS 3 /* emit vector data */
|
||||
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
|
||||
#define RADEON_CMD_PACKET3 5 /* emit hw packet */
|
||||
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
|
||||
#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
|
||||
#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
|
||||
* doesn't make the cpu wait, just
|
||||
* the graphics hardware */
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
struct {
|
||||
struct {
|
||||
unsigned char cmd_type, pad0, pad1, pad2;
|
||||
} header;
|
||||
struct {
|
||||
struct {
|
||||
unsigned char cmd_type, packet_id, pad0, pad1;
|
||||
} packet;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
} scalars;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
struct {
|
||||
unsigned char cmd_type, offset, stride, count;
|
||||
} vectors;
|
||||
struct {
|
||||
unsigned char cmd_type, buf_idx, pad0, pad1;
|
||||
struct {
|
||||
unsigned char cmd_type, buf_idx, pad0, pad1;
|
||||
} dma;
|
||||
struct {
|
||||
unsigned char cmd_type, flags, pad0, pad1;
|
||||
struct {
|
||||
unsigned char cmd_type, flags, pad0, pad1;
|
||||
} wait;
|
||||
} drm_radeon_cmd_header_t;
|
||||
|
||||
|
@ -204,10 +211,10 @@ typedef union {
|
|||
* The interface has not been stabilized, so some of these may be removed
|
||||
* and eventually reordered before stabilization.
|
||||
*/
|
||||
#define R300_CMD_PACKET0 1
|
||||
#define R300_CMD_VPU 2 /* emit vertex program upload */
|
||||
#define R300_CMD_PACKET3 3 /* emit a packet3 */
|
||||
#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
|
||||
#define R300_CMD_PACKET0 1
|
||||
#define R300_CMD_VPU 2 /* emit vertex program upload */
|
||||
#define R300_CMD_PACKET3 3 /* emit a packet3 */
|
||||
#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
|
||||
#define R300_CMD_CP_DELAY 5
|
||||
#define R300_CMD_DMA_DISCARD 6
|
||||
#define R300_CMD_WAIT 7
|
||||
|
@ -232,13 +239,13 @@ typedef union {
|
|||
} packet3;
|
||||
struct {
|
||||
unsigned char cmd_type, packet;
|
||||
unsigned short count; /* amount of packet2 to emit */
|
||||
unsigned short count; /* amount of packet2 to emit */
|
||||
} delay;
|
||||
struct {
|
||||
unsigned char cmd_type, buf_idx, pad0, pad1;
|
||||
} dma;
|
||||
struct {
|
||||
unsigned char cmd_type, flags, pad0, pad1;
|
||||
unsigned char cmd_type, flags, pad0, pad1;
|
||||
} wait;
|
||||
} drm_r300_cmd_header_t;
|
||||
|
||||
|
@ -292,7 +299,7 @@ typedef union {
|
|||
#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
|
||||
#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
|
||||
|
||||
#endif /* __RADEON_SAREA_DEFINES__ */
|
||||
#endif /* __RADEON_SAREA_DEFINES__ */
|
||||
|
||||
typedef struct {
|
||||
unsigned int red;
|
||||
|
@ -303,7 +310,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
/* Context state */
|
||||
unsigned int pp_misc; /* 0x1c14 */
|
||||
unsigned int pp_misc; /* 0x1c14 */
|
||||
unsigned int pp_fog_color;
|
||||
unsigned int re_solid_color;
|
||||
unsigned int rb3d_blendcntl;
|
||||
|
@ -311,7 +318,7 @@ typedef struct {
|
|||
unsigned int rb3d_depthpitch;
|
||||
unsigned int rb3d_zstencilcntl;
|
||||
|
||||
unsigned int pp_cntl; /* 0x1c38 */
|
||||
unsigned int pp_cntl; /* 0x1c38 */
|
||||
unsigned int rb3d_cntl;
|
||||
unsigned int rb3d_coloroffset;
|
||||
unsigned int re_width_height;
|
||||
|
@ -319,27 +326,27 @@ typedef struct {
|
|||
unsigned int se_cntl;
|
||||
|
||||
/* Vertex format state */
|
||||
unsigned int se_coord_fmt; /* 0x1c50 */
|
||||
unsigned int se_coord_fmt; /* 0x1c50 */
|
||||
|
||||
/* Line state */
|
||||
unsigned int re_line_pattern; /* 0x1cd0 */
|
||||
unsigned int re_line_pattern; /* 0x1cd0 */
|
||||
unsigned int re_line_state;
|
||||
|
||||
unsigned int se_line_width; /* 0x1db8 */
|
||||
unsigned int se_line_width; /* 0x1db8 */
|
||||
|
||||
/* Bumpmap state */
|
||||
unsigned int pp_lum_matrix; /* 0x1d00 */
|
||||
unsigned int pp_lum_matrix; /* 0x1d00 */
|
||||
|
||||
unsigned int pp_rot_matrix_0; /* 0x1d58 */
|
||||
unsigned int pp_rot_matrix_0; /* 0x1d58 */
|
||||
unsigned int pp_rot_matrix_1;
|
||||
|
||||
/* Mask state */
|
||||
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
|
||||
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
|
||||
unsigned int rb3d_ropcntl;
|
||||
unsigned int rb3d_planemask;
|
||||
|
||||
/* Viewport state */
|
||||
unsigned int se_vport_xscale; /* 0x1d98 */
|
||||
unsigned int se_vport_xscale; /* 0x1d98 */
|
||||
unsigned int se_vport_xoffset;
|
||||
unsigned int se_vport_yscale;
|
||||
unsigned int se_vport_yoffset;
|
||||
|
@ -347,20 +354,19 @@ typedef struct {
|
|||
unsigned int se_vport_zoffset;
|
||||
|
||||
/* Setup state */
|
||||
unsigned int se_cntl_status; /* 0x2140 */
|
||||
unsigned int se_cntl_status; /* 0x2140 */
|
||||
|
||||
/* Misc state */
|
||||
unsigned int re_top_left; /* 0x26c0 */
|
||||
unsigned int re_top_left; /* 0x26c0 */
|
||||
unsigned int re_misc;
|
||||
} drm_radeon_context_regs_t;
|
||||
|
||||
typedef struct {
|
||||
/* Zbias state */
|
||||
unsigned int se_zbias_factor; /* 0x1dac */
|
||||
unsigned int se_zbias_factor; /* 0x1dac */
|
||||
unsigned int se_zbias_constant;
|
||||
} drm_radeon_context2_regs_t;
|
||||
|
||||
|
||||
/* Setup registers for each texture unit
|
||||
*/
|
||||
typedef struct {
|
||||
|
@ -378,11 +384,10 @@ typedef struct {
|
|||
unsigned int finish;
|
||||
unsigned int prim:8;
|
||||
unsigned int stateidx:8;
|
||||
unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
|
||||
unsigned int vc_format; /* vertex format */
|
||||
unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
|
||||
unsigned int vc_format; /* vertex format */
|
||||
} drm_radeon_prim_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
drm_radeon_context_regs_t context;
|
||||
drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
|
||||
|
@ -390,7 +395,6 @@ typedef struct {
|
|||
unsigned int dirty;
|
||||
} drm_radeon_state_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/* The channel for communication of state information to the
|
||||
* kernel on firing a vertex buffer with either of the
|
||||
|
@ -413,16 +417,16 @@ typedef struct {
|
|||
unsigned int last_dispatch;
|
||||
unsigned int last_clear;
|
||||
|
||||
drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
|
||||
drm_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS +
|
||||
1];
|
||||
unsigned int tex_age[RADEON_NR_TEX_HEAPS];
|
||||
int ctx_owner;
|
||||
int pfState; /* number of 3d windows (0,1,2ormore) */
|
||||
int pfCurrentPage; /* which buffer is being displayed? */
|
||||
int crtc2_base; /* CRTC2 frame offset */
|
||||
int pfState; /* number of 3d windows (0,1,2ormore) */
|
||||
int pfCurrentPage; /* which buffer is being displayed? */
|
||||
int crtc2_base; /* CRTC2 frame offset */
|
||||
int tiling_enabled; /* set by drm, read by 2d + 3d clients */
|
||||
} drm_radeon_sarea_t;
|
||||
|
||||
|
||||
/* WARNING: If you change any of these defines, make sure to change the
|
||||
* defines in the Xserver file (xf86drmRadeon.h)
|
||||
*
|
||||
|
@ -432,15 +436,15 @@ typedef struct {
|
|||
/* Radeon specific ioctls
|
||||
* The device specific ioctl range is 0x40 to 0x79.
|
||||
*/
|
||||
#define DRM_RADEON_CP_INIT 0x00
|
||||
#define DRM_RADEON_CP_START 0x01
|
||||
#define DRM_RADEON_CP_INIT 0x00
|
||||
#define DRM_RADEON_CP_START 0x01
|
||||
#define DRM_RADEON_CP_STOP 0x02
|
||||
#define DRM_RADEON_CP_RESET 0x03
|
||||
#define DRM_RADEON_CP_IDLE 0x04
|
||||
#define DRM_RADEON_RESET 0x05
|
||||
#define DRM_RADEON_RESET 0x05
|
||||
#define DRM_RADEON_FULLSCREEN 0x06
|
||||
#define DRM_RADEON_SWAP 0x07
|
||||
#define DRM_RADEON_CLEAR 0x08
|
||||
#define DRM_RADEON_SWAP 0x07
|
||||
#define DRM_RADEON_CLEAR 0x08
|
||||
#define DRM_RADEON_VERTEX 0x09
|
||||
#define DRM_RADEON_INDICES 0x0A
|
||||
#define DRM_RADEON_NOT_USED
|
||||
|
@ -491,7 +495,7 @@ typedef struct {
|
|||
|
||||
typedef struct drm_radeon_init {
|
||||
enum {
|
||||
RADEON_INIT_CP = 0x01,
|
||||
RADEON_INIT_CP = 0x01,
|
||||
RADEON_CLEANUP_CP = 0x02,
|
||||
RADEON_INIT_R200_CP = 0x03,
|
||||
RADEON_INIT_R300_CP = 0x04
|
||||
|
@ -524,7 +528,7 @@ typedef struct drm_radeon_cp_stop {
|
|||
|
||||
typedef struct drm_radeon_fullscreen {
|
||||
enum {
|
||||
RADEON_INIT_FULLSCREEN = 0x01,
|
||||
RADEON_INIT_FULLSCREEN = 0x01,
|
||||
RADEON_CLEANUP_FULLSCREEN = 0x02
|
||||
} func;
|
||||
} drm_radeon_fullscreen_t;
|
||||
|
@ -545,15 +549,15 @@ typedef struct drm_radeon_clear {
|
|||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
unsigned int color_mask;
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
drm_radeon_clear_rect_t __user *depth_boxes;
|
||||
} drm_radeon_clear_t;
|
||||
|
||||
typedef struct drm_radeon_vertex {
|
||||
int prim;
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int idx; /* Index of vertex buffer */
|
||||
int count; /* Number of vertices in buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_radeon_vertex_t;
|
||||
|
||||
typedef struct drm_radeon_indices {
|
||||
|
@ -561,7 +565,7 @@ typedef struct drm_radeon_indices {
|
|||
int idx;
|
||||
int start;
|
||||
int end;
|
||||
int discard; /* Client finished with buffer? */
|
||||
int discard; /* Client finished with buffer? */
|
||||
} drm_radeon_indices_t;
|
||||
|
||||
/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
|
||||
|
@ -569,8 +573,8 @@ typedef struct drm_radeon_indices {
|
|||
* - supports driver change to emit native primitives
|
||||
*/
|
||||
typedef struct drm_radeon_vertex2 {
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int nr_states;
|
||||
drm_radeon_state_t __user *state;
|
||||
int nr_prims;
|
||||
|
@ -578,10 +582,10 @@ typedef struct drm_radeon_vertex2 {
|
|||
} drm_radeon_vertex2_t;
|
||||
|
||||
/* v1.3 - obsoletes drm_radeon_vertex2
|
||||
* - allows arbitarily large cliprect list
|
||||
* - allows arbitarily large cliprect list
|
||||
* - allows updating of tcl packet, vector and scalar state
|
||||
* - allows memory-efficient description of state updates
|
||||
* - allows state to be emitted without a primitive
|
||||
* - allows state to be emitted without a primitive
|
||||
* (for clears, ctx switches)
|
||||
* - allows more than one dma buffer to be referenced per ioctl
|
||||
* - supports tcl driver
|
||||
|
@ -595,7 +599,7 @@ typedef struct drm_radeon_cmd_buffer {
|
|||
} drm_radeon_cmd_buffer_t;
|
||||
|
||||
typedef struct drm_radeon_tex_image {
|
||||
unsigned int x, y; /* Blit coordinates */
|
||||
unsigned int x, y; /* Blit coordinates */
|
||||
unsigned int width, height;
|
||||
const void __user *data;
|
||||
} drm_radeon_tex_image_t;
|
||||
|
@ -604,7 +608,7 @@ typedef struct drm_radeon_texture {
|
|||
unsigned int offset;
|
||||
int pitch;
|
||||
int format;
|
||||
int width; /* Texture image coordinates */
|
||||
int width; /* Texture image coordinates */
|
||||
int height;
|
||||
drm_radeon_tex_image_t __user *image;
|
||||
} drm_radeon_texture_t;
|
||||
|
@ -620,19 +624,18 @@ typedef struct drm_radeon_indirect {
|
|||
int discard;
|
||||
} drm_radeon_indirect_t;
|
||||
|
||||
|
||||
/* 1.3: An ioctl to get parameters that aren't available to the 3d
|
||||
* client any other way.
|
||||
* client any other way.
|
||||
*/
|
||||
#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
|
||||
#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
|
||||
#define RADEON_PARAM_LAST_FRAME 2
|
||||
#define RADEON_PARAM_LAST_DISPATCH 3
|
||||
#define RADEON_PARAM_LAST_CLEAR 4
|
||||
/* Added with DRM version 1.6. */
|
||||
#define RADEON_PARAM_IRQ_NR 5
|
||||
#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
|
||||
#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
|
||||
/* Added with DRM version 1.8. */
|
||||
#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
|
||||
#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
|
||||
#define RADEON_PARAM_STATUS_HANDLE 8
|
||||
#define RADEON_PARAM_SAREA_HANDLE 9
|
||||
#define RADEON_PARAM_GART_TEX_HANDLE 10
|
||||
|
@ -663,10 +666,9 @@ typedef struct drm_radeon_mem_free {
|
|||
typedef struct drm_radeon_mem_init_heap {
|
||||
int region;
|
||||
int size;
|
||||
int start;
|
||||
int start;
|
||||
} drm_radeon_mem_init_heap_t;
|
||||
|
||||
|
||||
/* 1.6: Userspace can request & wait on irq's:
|
||||
*/
|
||||
typedef struct drm_radeon_irq_emit {
|
||||
|
@ -677,18 +679,18 @@ typedef struct drm_radeon_irq_wait {
|
|||
int irq_seq;
|
||||
} drm_radeon_irq_wait_t;
|
||||
|
||||
|
||||
/* 1.10: Clients tell the DRM where they think the framebuffer is located in
|
||||
* the card's address space, via a new generic ioctl to set parameters
|
||||
*/
|
||||
|
||||
typedef struct drm_radeon_setparam {
|
||||
unsigned int param;
|
||||
int64_t value;
|
||||
int64_t value;
|
||||
} drm_radeon_setparam_t;
|
||||
|
||||
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
|
||||
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
|
||||
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
|
||||
|
||||
/* 1.14: Clients can allocate/free a surface
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/config.h>
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
@ -38,30 +37,33 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
int radeon_no_wb;
|
||||
|
||||
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
|
||||
module_param_named(no_wb, radeon_no_wb, int, 0444);
|
||||
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -69,11 +71,11 @@ static struct pci_device_id pciidlist[] = {
|
|||
radeon_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t radeon_ioctls[];
|
||||
extern int radeon_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
|
||||
DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
|
||||
DRIVER_IRQ_VBL,
|
||||
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
|
||||
.preinit = radeon_driver_preinit,
|
||||
.presetup = radeon_presetup,
|
||||
|
@ -95,21 +97,22 @@ static struct drm_driver driver = {
|
|||
.ioctls = radeon_ioctls,
|
||||
.dma_ioctl = radeon_cp_buffers,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = radeon_compat_ioctl,
|
||||
.compat_ioctl = radeon_compat_ioctl,
|
||||
#endif
|
||||
},
|
||||
}
|
||||
,
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init radeon_init(void)
|
||||
|
@ -126,6 +129,6 @@ static void __exit radeon_exit(void)
|
|||
module_init(radeon_init);
|
||||
module_exit(radeon_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define DRIVER_NAME "radeon"
|
||||
#define DRIVER_DESC "ATI Radeon"
|
||||
#define DRIVER_DATE "20050311"
|
||||
#define DRIVER_DATE "20050911"
|
||||
|
||||
/* Interface history:
|
||||
*
|
||||
|
@ -68,7 +68,7 @@
|
|||
* 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
|
||||
* Add texture rectangle support for r100.
|
||||
* 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
|
||||
* clients use to tell the DRM where they think the framebuffer is
|
||||
* clients use to tell the DRM where they think the framebuffer is
|
||||
* located in the card's address space
|
||||
* 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
|
||||
* and GL_EXT_blend_[func|equation]_separate on r200
|
||||
|
@ -83,9 +83,14 @@
|
|||
* 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
|
||||
* texture filtering on r200
|
||||
* 1.17- Add initial support for R300 (3D).
|
||||
* 1.18- Add support for GL_ATI_fragment_shader, new packets
|
||||
* R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces
|
||||
* R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
|
||||
* (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
|
||||
* 1.19- Add support for gart table in FB memory and PCIE r300
|
||||
*/
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 17
|
||||
#define DRIVER_MINOR 19
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
|
||||
#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
|
||||
|
@ -129,14 +134,15 @@ enum radeon_chip_flags {
|
|||
CHIP_IS_IGP = 0x00020000UL,
|
||||
CHIP_SINGLE_CRTC = 0x00040000UL,
|
||||
CHIP_IS_AGP = 0x00080000UL,
|
||||
CHIP_HAS_HIERZ = 0x00100000UL,
|
||||
CHIP_HAS_HIERZ = 0x00100000UL,
|
||||
CHIP_IS_PCIE = 0x00200000UL,
|
||||
};
|
||||
|
||||
typedef struct drm_radeon_freelist {
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
struct drm_radeon_freelist *next;
|
||||
struct drm_radeon_freelist *prev;
|
||||
unsigned int age;
|
||||
drm_buf_t *buf;
|
||||
struct drm_radeon_freelist *next;
|
||||
struct drm_radeon_freelist *prev;
|
||||
} drm_radeon_freelist_t;
|
||||
|
||||
typedef struct drm_radeon_ring_buffer {
|
||||
|
@ -198,8 +204,8 @@ typedef struct drm_radeon_private {
|
|||
int cp_mode;
|
||||
int cp_running;
|
||||
|
||||
drm_radeon_freelist_t *head;
|
||||
drm_radeon_freelist_t *tail;
|
||||
drm_radeon_freelist_t *head;
|
||||
drm_radeon_freelist_t *tail;
|
||||
int last_buf;
|
||||
volatile u32 *scratch;
|
||||
int writeback_works;
|
||||
|
@ -209,8 +215,6 @@ typedef struct drm_radeon_private {
|
|||
int microcode_version;
|
||||
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
dma_addr_t bus_pci_gart;
|
||||
|
||||
struct {
|
||||
u32 boxes;
|
||||
|
@ -242,7 +246,7 @@ typedef struct drm_radeon_private {
|
|||
u32 depth_pitch_offset;
|
||||
|
||||
drm_radeon_depth_clear_t depth_clear;
|
||||
|
||||
|
||||
unsigned long fb_offset;
|
||||
unsigned long mmio_offset;
|
||||
unsigned long ring_offset;
|
||||
|
@ -260,11 +264,14 @@ typedef struct drm_radeon_private {
|
|||
struct mem_block *fb_heap;
|
||||
|
||||
/* SW interrupt */
|
||||
wait_queue_head_t swi_queue;
|
||||
atomic_t swi_emitted;
|
||||
wait_queue_head_t swi_queue;
|
||||
atomic_t swi_emitted;
|
||||
|
||||
struct radeon_surface surfaces[RADEON_MAX_SURFACES];
|
||||
struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
|
||||
struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
|
||||
|
||||
unsigned long pcigart_offset;
|
||||
drm_ati_pcigart_info gart_info;
|
||||
|
||||
/* starting from here on, data is preserved accross an open */
|
||||
uint32_t flags; /* see radeon_chip_flags */
|
||||
|
@ -274,63 +281,76 @@ typedef struct drm_radeon_buf_priv {
|
|||
u32 age;
|
||||
} drm_radeon_buf_priv_t;
|
||||
|
||||
typedef struct drm_radeon_kcmd_buffer {
|
||||
int bufsz;
|
||||
char *buf;
|
||||
int nbox;
|
||||
drm_clip_rect_t __user *boxes;
|
||||
} drm_radeon_kcmd_buffer_t;
|
||||
|
||||
extern int radeon_no_wb;
|
||||
extern drm_ioctl_desc_t radeon_ioctls[];
|
||||
extern int radeon_max_ioctl;
|
||||
|
||||
/* radeon_cp.c */
|
||||
extern int radeon_cp_init( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_start( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_stop( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_reset( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_idle( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_resume( DRM_IOCTL_ARGS );
|
||||
extern int radeon_engine_reset( DRM_IOCTL_ARGS );
|
||||
extern int radeon_fullscreen( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_buffers( DRM_IOCTL_ARGS );
|
||||
extern int radeon_cp_init(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_start(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_stop(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_reset(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_idle(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_resume(DRM_IOCTL_ARGS);
|
||||
extern int radeon_engine_reset(DRM_IOCTL_ARGS);
|
||||
extern int radeon_fullscreen(DRM_IOCTL_ARGS);
|
||||
extern int radeon_cp_buffers(DRM_IOCTL_ARGS);
|
||||
|
||||
extern void radeon_freelist_reset( drm_device_t *dev );
|
||||
extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
|
||||
extern void radeon_freelist_reset(drm_device_t * dev);
|
||||
extern drm_buf_t *radeon_freelist_get(drm_device_t * dev);
|
||||
|
||||
extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
|
||||
extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
|
||||
|
||||
extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
|
||||
extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
|
||||
|
||||
extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
|
||||
extern int radeon_presetup(struct drm_device *dev);
|
||||
extern int radeon_driver_postcleanup(struct drm_device *dev);
|
||||
|
||||
extern int radeon_mem_alloc( DRM_IOCTL_ARGS );
|
||||
extern int radeon_mem_free( DRM_IOCTL_ARGS );
|
||||
extern int radeon_mem_init_heap( DRM_IOCTL_ARGS );
|
||||
extern void radeon_mem_takedown( struct mem_block **heap );
|
||||
extern void radeon_mem_release( DRMFILE filp, struct mem_block *heap );
|
||||
extern int radeon_mem_alloc(DRM_IOCTL_ARGS);
|
||||
extern int radeon_mem_free(DRM_IOCTL_ARGS);
|
||||
extern int radeon_mem_init_heap(DRM_IOCTL_ARGS);
|
||||
extern void radeon_mem_takedown(struct mem_block **heap);
|
||||
extern void radeon_mem_release(DRMFILE filp, struct mem_block *heap);
|
||||
|
||||
/* radeon_irq.c */
|
||||
extern int radeon_irq_emit( DRM_IOCTL_ARGS );
|
||||
extern int radeon_irq_wait( DRM_IOCTL_ARGS );
|
||||
extern int radeon_irq_emit(DRM_IOCTL_ARGS);
|
||||
extern int radeon_irq_wait(DRM_IOCTL_ARGS);
|
||||
|
||||
extern void radeon_do_release(drm_device_t *dev);
|
||||
extern int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence);
|
||||
extern irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS );
|
||||
extern void radeon_driver_irq_preinstall( drm_device_t *dev );
|
||||
extern void radeon_driver_irq_postinstall( drm_device_t *dev );
|
||||
extern void radeon_driver_irq_uninstall( drm_device_t *dev );
|
||||
extern void radeon_driver_prerelease(drm_device_t *dev, DRMFILE filp);
|
||||
extern void radeon_driver_pretakedown(drm_device_t *dev);
|
||||
extern int radeon_driver_open_helper(drm_device_t *dev, drm_file_t *filp_priv);
|
||||
extern void radeon_driver_free_filp_priv(drm_device_t *dev, drm_file_t *filp_priv);
|
||||
extern void radeon_do_release(drm_device_t * dev);
|
||||
extern int radeon_driver_vblank_wait(drm_device_t * dev,
|
||||
unsigned int *sequence);
|
||||
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
|
||||
extern void radeon_driver_irq_preinstall(drm_device_t * dev);
|
||||
extern void radeon_driver_irq_postinstall(drm_device_t * dev);
|
||||
extern void radeon_driver_irq_uninstall(drm_device_t * dev);
|
||||
extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
|
||||
extern void radeon_driver_pretakedown(drm_device_t * dev);
|
||||
extern int radeon_driver_open_helper(drm_device_t * dev,
|
||||
drm_file_t * filp_priv);
|
||||
extern void radeon_driver_free_filp_priv(drm_device_t * dev,
|
||||
drm_file_t * filp_priv);
|
||||
|
||||
extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
|
||||
extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
|
||||
extern int radeon_postcleanup( struct drm_device *dev );
|
||||
extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
|
||||
extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
|
||||
extern int radeon_postcleanup(struct drm_device *dev);
|
||||
|
||||
extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
|
||||
/* r300_cmdbuf.c */
|
||||
extern void r300_init_reg_flags(void);
|
||||
|
||||
extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
||||
drm_file_t* filp_priv,
|
||||
drm_radeon_cmd_buffer_t* cmdbuf);
|
||||
extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
|
||||
drm_file_t * filp_priv,
|
||||
drm_radeon_kcmd_buffer_t * cmdbuf);
|
||||
|
||||
/* Flags for stats.boxes
|
||||
*/
|
||||
|
@ -340,8 +360,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
#define RADEON_BOX_WAIT_IDLE 0x8
|
||||
#define RADEON_BOX_TEXTURE_LOAD 0x10
|
||||
|
||||
|
||||
|
||||
/* Register definitions, register access macros and drmAddMap constants
|
||||
* for Radeon kernel driver.
|
||||
*/
|
||||
|
@ -369,6 +387,25 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
#define RADEON_CRTC2_OFFSET 0x0324
|
||||
#define RADEON_CRTC2_OFFSET_CNTL 0x0328
|
||||
|
||||
#define RADEON_PCIE_INDEX 0x0030
|
||||
#define RADEON_PCIE_DATA 0x0034
|
||||
#define RADEON_PCIE_TX_GART_CNTL 0x10
|
||||
# define RADEON_PCIE_TX_GART_EN (1 << 0)
|
||||
# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
|
||||
# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1)
|
||||
# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1)
|
||||
# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3)
|
||||
# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3)
|
||||
# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5)
|
||||
# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8)
|
||||
#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
|
||||
#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
|
||||
#define RADEON_PCIE_TX_GART_BASE 0x13
|
||||
#define RADEON_PCIE_TX_GART_START_LO 0x14
|
||||
#define RADEON_PCIE_TX_GART_START_HI 0x15
|
||||
#define RADEON_PCIE_TX_GART_END_LO 0x16
|
||||
#define RADEON_PCIE_TX_GART_END_HI 0x17
|
||||
|
||||
#define RADEON_MPP_TB_CONFIG 0x01c0
|
||||
#define RADEON_MEM_CNTL 0x0140
|
||||
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
|
||||
|
@ -416,7 +453,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
|
||||
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
|
||||
|
||||
|
||||
#define RADEON_GEN_INT_CNTL 0x0040
|
||||
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
|
||||
# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
|
||||
|
@ -624,7 +660,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
|
||||
# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
|
||||
|
||||
|
||||
/* CP registers */
|
||||
#define RADEON_CP_ME_RAM_ADDR 0x07d4
|
||||
#define RADEON_CP_ME_RAM_RADDR 0x07d8
|
||||
|
@ -672,7 +707,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
# define RADEON_CP_NEXT_CHAR 0x00001900
|
||||
# define RADEON_CP_PLY_NEXTSCAN 0x00001D00
|
||||
# define RADEON_CP_SET_SCISSORS 0x00001E00
|
||||
/* GEN_INDX_PRIM is unsupported starting with R300 */
|
||||
/* GEN_INDX_PRIM is unsupported starting with R300 */
|
||||
# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
|
||||
# define RADEON_WAIT_FOR_IDLE 0x00002600
|
||||
# define RADEON_3D_DRAW_VBUF 0x00002800
|
||||
|
@ -756,19 +791,19 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
#define R200_PP_TXCBLEND_5 0x2f50
|
||||
#define R200_PP_TXCBLEND_6 0x2f60
|
||||
#define R200_PP_TXCBLEND_7 0x2f70
|
||||
#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
|
||||
#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
|
||||
#define R200_PP_TFACTOR_0 0x2ee0
|
||||
#define R200_SE_VTX_FMT_0 0x2088
|
||||
#define R200_SE_VAP_CNTL 0x2080
|
||||
#define R200_SE_TCL_MATRIX_SEL_0 0x2230
|
||||
#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
|
||||
#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
|
||||
#define R200_PP_TXFILTER_5 0x2ca0
|
||||
#define R200_PP_TXFILTER_4 0x2c80
|
||||
#define R200_PP_TXFILTER_3 0x2c60
|
||||
#define R200_PP_TXFILTER_2 0x2c40
|
||||
#define R200_PP_TXFILTER_1 0x2c20
|
||||
#define R200_PP_TXFILTER_0 0x2c00
|
||||
#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
|
||||
#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
|
||||
#define R200_PP_TXFILTER_5 0x2ca0
|
||||
#define R200_PP_TXFILTER_4 0x2c80
|
||||
#define R200_PP_TXFILTER_3 0x2c60
|
||||
#define R200_PP_TXFILTER_2 0x2c40
|
||||
#define R200_PP_TXFILTER_1 0x2c20
|
||||
#define R200_PP_TXFILTER_0 0x2c00
|
||||
#define R200_PP_TXOFFSET_5 0x2d78
|
||||
#define R200_PP_TXOFFSET_4 0x2d60
|
||||
#define R200_PP_TXOFFSET_3 0x2d48
|
||||
|
@ -822,13 +857,13 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
#define R200_RE_SCISSOR_TL_0 0x1cd8
|
||||
#define R200_RE_SCISSOR_TL_1 0x1ce0
|
||||
#define R200_RE_SCISSOR_TL_2 0x1ce8
|
||||
#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
|
||||
#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
|
||||
#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
|
||||
#define R200_SE_VTX_STATE_CNTL 0x2180
|
||||
#define R200_RE_POINTSIZE 0x2648
|
||||
#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
|
||||
|
||||
#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
|
||||
#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
|
||||
#define RADEON_PP_TEX_SIZE_1 0x1d0c
|
||||
#define RADEON_PP_TEX_SIZE_2 0x1d14
|
||||
|
||||
|
@ -849,7 +884,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b
|
||||
#define R200_3D_DRAW_IMMD_2 0xC0003500
|
||||
#define R200_SE_VTX_FMT_1 0x208c
|
||||
#define R200_RE_CNTL 0x1c50
|
||||
#define R200_RE_CNTL 0x1c50
|
||||
|
||||
#define R200_RB3D_BLENDCOLOR 0x3218
|
||||
|
||||
|
@ -857,6 +892,9 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
|
||||
#define R200_PP_TRI_PERF 0x2cf8
|
||||
|
||||
#define R200_PP_AFS_0 0x2f80
|
||||
#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
|
||||
|
||||
/* Constants */
|
||||
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
|
||||
|
||||
|
@ -871,6 +909,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t* dev, DRMFILE filp,
|
|||
|
||||
#define RADEON_RING_HIGH_MARK 128
|
||||
|
||||
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
|
||||
|
||||
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
|
||||
#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
|
||||
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
|
||||
|
@ -883,6 +923,13 @@ do { \
|
|||
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
|
||||
} while (0)
|
||||
|
||||
#define RADEON_WRITE_PCIE( addr, val ) \
|
||||
do { \
|
||||
RADEON_WRITE8( RADEON_PCIE_INDEX, \
|
||||
((addr) & 0xff)); \
|
||||
RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \
|
||||
} while (0)
|
||||
|
||||
#define CP_PACKET0( reg, n ) \
|
||||
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
|
||||
#define CP_PACKET0_TABLE( reg, n ) \
|
||||
|
@ -894,7 +941,6 @@ do { \
|
|||
#define CP_PACKET3( pkt, n ) \
|
||||
(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Engine control helper macros
|
||||
*/
|
||||
|
@ -943,12 +989,11 @@ do { \
|
|||
OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Misc helper macros
|
||||
*/
|
||||
|
||||
/* Perfbox functionality only.
|
||||
/* Perfbox functionality only.
|
||||
*/
|
||||
#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
|
||||
do { \
|
||||
|
@ -985,7 +1030,6 @@ do { \
|
|||
OUT_RING( age ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* ================================================================
|
||||
* Ring control
|
||||
*/
|
||||
|
@ -1046,7 +1090,6 @@ do { \
|
|||
OUT_RING( val ); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define OUT_RING_TABLE( tab, sz ) do { \
|
||||
int _size = (sz); \
|
||||
int *_tab = (int *)(tab); \
|
||||
|
@ -1071,5 +1114,4 @@ do { \
|
|||
write &= mask; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif /* __RADEON_DRV_H__ */
|
||||
#endif /* __RADEON_DRV_H__ */
|
||||
|
|
|
@ -94,7 +94,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
|
||||
DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_clear32 {
|
||||
|
@ -102,8 +102,8 @@ typedef struct drm_radeon_clear32 {
|
|||
unsigned int clear_color;
|
||||
unsigned int clear_depth;
|
||||
unsigned int color_mask;
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
u32 depth_boxes;
|
||||
unsigned int depth_mask; /* misnamed field: should be stencil */
|
||||
u32 depth_boxes;
|
||||
} drm_radeon_clear32_t;
|
||||
|
||||
static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
|
||||
|
@ -127,7 +127,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
|
||||
DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_stipple32 {
|
||||
|
@ -137,7 +137,7 @@ typedef struct drm_radeon_stipple32 {
|
|||
static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
drm_radeon_stipple32_t __user *argp = (void __user *) arg;
|
||||
drm_radeon_stipple32_t __user *argp = (void __user *)arg;
|
||||
drm_radeon_stipple_t __user *request;
|
||||
u32 mask;
|
||||
|
||||
|
@ -146,16 +146,16 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
|
|||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
|
||||
|| __put_user((unsigned int __user *)(unsigned long) mask,
|
||||
|| __put_user((unsigned int __user *)(unsigned long)mask,
|
||||
&request->mask))
|
||||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_tex_image32 {
|
||||
unsigned int x, y; /* Blit coordinates */
|
||||
unsigned int x, y; /* Blit coordinates */
|
||||
unsigned int width, height;
|
||||
u32 data;
|
||||
} drm_radeon_tex_image32_t;
|
||||
|
@ -164,7 +164,7 @@ typedef struct drm_radeon_texture32 {
|
|||
unsigned int offset;
|
||||
int pitch;
|
||||
int format;
|
||||
int width; /* Texture image coordinates */
|
||||
int width; /* Texture image coordinates */
|
||||
int height;
|
||||
u32 image;
|
||||
} drm_radeon_texture32_t;
|
||||
|
@ -177,7 +177,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
|
|||
drm_radeon_tex_image32_t img32;
|
||||
drm_radeon_tex_image_t __user *image;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
if (req32.image == 0)
|
||||
return -EINVAL;
|
||||
|
@ -206,12 +206,12 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_vertex2_32 {
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int idx; /* Index of vertex buffer */
|
||||
int discard; /* Client finished with buffer? */
|
||||
int nr_states;
|
||||
u32 state;
|
||||
int nr_prims;
|
||||
|
@ -224,7 +224,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
|
|||
drm_radeon_vertex2_32_t req32;
|
||||
drm_radeon_vertex2_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -240,7 +240,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_cmd_buffer32 {
|
||||
|
@ -256,7 +256,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
|
|||
drm_radeon_cmd_buffer32_t req32;
|
||||
drm_radeon_cmd_buffer_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -270,7 +270,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_getparam32 {
|
||||
|
@ -284,7 +284,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
|
|||
drm_radeon_getparam32_t req32;
|
||||
drm_radeon_getparam_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -295,7 +295,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_mem_alloc32 {
|
||||
|
@ -311,7 +311,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
|
|||
drm_radeon_mem_alloc32_t req32;
|
||||
drm_radeon_mem_alloc_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -324,7 +324,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
|
||||
}
|
||||
|
||||
typedef struct drm_radeon_irq_emit32 {
|
||||
|
@ -337,7 +337,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
|
|||
drm_radeon_irq_emit32_t req32;
|
||||
drm_radeon_irq_emit_t __user *request;
|
||||
|
||||
if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
|
||||
if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
|
||||
return -EFAULT;
|
||||
|
||||
request = compat_alloc_user_space(sizeof(*request));
|
||||
|
@ -347,7 +347,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
return drm_ioctl(file->f_dentry->d_inode, file,
|
||||
DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
|
||||
DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
|
||||
}
|
||||
|
||||
drm_ioctl_compat_t *radeon_compat_ioctls[] = {
|
||||
|
@ -371,8 +371,7 @@ drm_ioctl_compat_t *radeon_compat_ioctls[] = {
|
|||
* \param arg user argument.
|
||||
* \return zero on success or negative number on failure.
|
||||
*/
|
||||
long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
unsigned int nr = DRM_IOCTL_NR(cmd);
|
||||
drm_ioctl_compat_t *fn = NULL;
|
||||
|
@ -386,7 +385,7 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
|
|||
|
||||
lock_kernel(); /* XXX for now */
|
||||
if (fn != NULL)
|
||||
ret = (*fn)(filp, cmd, arg);
|
||||
ret = (*fn) (filp, cmd, arg);
|
||||
else
|
||||
ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
|
||||
unlock_kernel();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*-
|
||||
*
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
*
|
||||
* The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
* initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
* This notice must be preserved.
|
||||
|
@ -35,7 +35,8 @@
|
|||
#include "radeon_drm.h"
|
||||
#include "radeon_drv.h"
|
||||
|
||||
static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
|
||||
static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
|
||||
u32 mask)
|
||||
{
|
||||
u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
|
||||
if (irqs)
|
||||
|
@ -61,37 +62,37 @@ static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u3
|
|||
* tied to dma at all, this is just a hangover from dri prehistory.
|
||||
*/
|
||||
|
||||
irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
|
||||
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
drm_device_t *dev = (drm_device_t *) arg;
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
u32 stat;
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
u32 stat;
|
||||
|
||||
/* Only consider the bits we're interested in - others could be used
|
||||
* outside the DRM
|
||||
*/
|
||||
stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
|
||||
stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
|
||||
RADEON_CRTC_VBLANK_STAT));
|
||||
if (!stat)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* SW interrupt */
|
||||
if (stat & RADEON_SW_INT_TEST) {
|
||||
DRM_WAKEUP( &dev_priv->swi_queue );
|
||||
DRM_WAKEUP(&dev_priv->swi_queue);
|
||||
}
|
||||
|
||||
/* VBLANK interrupt */
|
||||
if (stat & RADEON_CRTC_VBLANK_STAT) {
|
||||
atomic_inc(&dev->vbl_received);
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals( dev );
|
||||
drm_vbl_send_signals(dev);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int radeon_emit_irq(drm_device_t *dev)
|
||||
static int radeon_emit_irq(drm_device_t * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
unsigned int ret;
|
||||
|
@ -100,42 +101,41 @@ static int radeon_emit_irq(drm_device_t *dev)
|
|||
atomic_inc(&dev_priv->swi_emitted);
|
||||
ret = atomic_read(&dev_priv->swi_emitted);
|
||||
|
||||
BEGIN_RING( 4 );
|
||||
OUT_RING_REG( RADEON_LAST_SWI_REG, ret );
|
||||
OUT_RING_REG( RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE );
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
BEGIN_RING(4);
|
||||
OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
|
||||
OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
|
||||
ADVANCE_RING();
|
||||
COMMIT_RING();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int radeon_wait_irq(drm_device_t *dev, int swi_nr)
|
||||
static int radeon_wait_irq(drm_device_t * dev, int swi_nr)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
int ret = 0;
|
||||
|
||||
if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)
|
||||
return 0;
|
||||
if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
|
||||
return 0;
|
||||
|
||||
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
|
||||
|
||||
DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ,
|
||||
RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );
|
||||
DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
|
||||
RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
||||
int radeon_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
unsigned int cur_vblank;
|
||||
int ret = 0;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -145,101 +145,100 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
|
|||
|
||||
/* Assume that the user has missed the current sequence number
|
||||
* by about a day rather than she wants to wait for years
|
||||
* using vertical blanks...
|
||||
* using vertical blanks...
|
||||
*/
|
||||
DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ,
|
||||
( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
|
||||
- *sequence ) <= (1<<23) ) );
|
||||
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
||||
(((cur_vblank = atomic_read(&dev->vbl_received))
|
||||
- *sequence) <= (1 << 23)));
|
||||
|
||||
*sequence = cur_vblank;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Needs the lock as it touches the ring.
|
||||
*/
|
||||
int radeon_irq_emit( DRM_IOCTL_ARGS )
|
||||
int radeon_irq_emit(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_irq_emit_t emit;
|
||||
int result;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev, filp );
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( emit, (drm_radeon_irq_emit_t __user *)data,
|
||||
sizeof(emit) );
|
||||
DRM_COPY_FROM_USER_IOCTL(emit, (drm_radeon_irq_emit_t __user *) data,
|
||||
sizeof(emit));
|
||||
|
||||
result = radeon_emit_irq( dev );
|
||||
result = radeon_emit_irq(dev);
|
||||
|
||||
if ( DRM_COPY_TO_USER( emit.irq_seq, &result, sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
|
||||
DRM_ERROR("copy_to_user\n");
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Doesn't need the hardware lock.
|
||||
*/
|
||||
int radeon_irq_wait( DRM_IOCTL_ARGS )
|
||||
int radeon_irq_wait(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_irq_wait_t irqwait;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( irqwait, (drm_radeon_irq_wait_t __user*)data,
|
||||
sizeof(irqwait) );
|
||||
DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_radeon_irq_wait_t __user *) data,
|
||||
sizeof(irqwait));
|
||||
|
||||
return radeon_wait_irq( dev, irqwait.irq_seq );
|
||||
return radeon_wait_irq(dev, irqwait.irq_seq);
|
||||
}
|
||||
|
||||
|
||||
/* drm_dma.h hooks
|
||||
*/
|
||||
void radeon_driver_irq_preinstall( drm_device_t *dev ) {
|
||||
void radeon_driver_irq_preinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
|
||||
/* Disable *all* interrupts */
|
||||
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
|
||||
|
||||
/* Clear bits if they're already high */
|
||||
radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
|
||||
RADEON_CRTC_VBLANK_STAT));
|
||||
}
|
||||
|
||||
void radeon_driver_irq_postinstall( drm_device_t *dev ) {
|
||||
void radeon_driver_irq_postinstall(drm_device_t * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
|
||||
atomic_set(&dev_priv->swi_emitted, 0);
|
||||
DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );
|
||||
atomic_set(&dev_priv->swi_emitted, 0);
|
||||
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
|
||||
|
||||
/* Turn on SW and VBL ints */
|
||||
RADEON_WRITE( RADEON_GEN_INT_CNTL,
|
||||
RADEON_CRTC_VBLANK_MASK |
|
||||
RADEON_SW_INT_ENABLE );
|
||||
RADEON_WRITE(RADEON_GEN_INT_CNTL,
|
||||
RADEON_CRTC_VBLANK_MASK | RADEON_SW_INT_ENABLE);
|
||||
}
|
||||
|
||||
void radeon_driver_irq_uninstall( drm_device_t *dev ) {
|
||||
void radeon_driver_irq_uninstall(drm_device_t * dev)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv =
|
||||
(drm_radeon_private_t *)dev->dev_private;
|
||||
(drm_radeon_private_t *) dev->dev_private;
|
||||
if (!dev_priv)
|
||||
return;
|
||||
|
||||
/* Disable *all* interrupts */
|
||||
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
|
||||
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*-
|
||||
*
|
||||
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
|
||||
*
|
||||
*
|
||||
* The Weather Channel (TM) funded Tungsten Graphics to develop the
|
||||
* initial release of the Radeon 8500 driver under the XFree86 license.
|
||||
* This notice must be preserved.
|
||||
|
@ -35,16 +35,17 @@
|
|||
#include "radeon_drv.h"
|
||||
|
||||
/* Very simple allocator for GART memory, working on a static range
|
||||
* already mapped into each client's address space.
|
||||
* already mapped into each client's address space.
|
||||
*/
|
||||
|
||||
static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
||||
DRMFILE filp )
|
||||
DRMFILE filp)
|
||||
{
|
||||
/* Maybe cut off the start of an existing block */
|
||||
if (start > p->start) {
|
||||
struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
|
||||
if (!newblock)
|
||||
struct mem_block *newblock =
|
||||
drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
|
||||
if (!newblock)
|
||||
goto out;
|
||||
newblock->start = start;
|
||||
newblock->size = p->size - (start - p->start);
|
||||
|
@ -56,10 +57,11 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
|||
p->size -= newblock->size;
|
||||
p = newblock;
|
||||
}
|
||||
|
||||
|
||||
/* Maybe cut off the end of an existing block */
|
||||
if (size < p->size) {
|
||||
struct mem_block *newblock = drm_alloc(sizeof(*newblock), DRM_MEM_BUFS );
|
||||
struct mem_block *newblock =
|
||||
drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
|
||||
if (!newblock)
|
||||
goto out;
|
||||
newblock->start = start + size;
|
||||
|
@ -72,40 +74,39 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size,
|
|||
p->size = size;
|
||||
}
|
||||
|
||||
out:
|
||||
out:
|
||||
/* Our block is in the middle */
|
||||
p->filp = filp;
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct mem_block *alloc_block( struct mem_block *heap, int size,
|
||||
int align2, DRMFILE filp )
|
||||
static struct mem_block *alloc_block(struct mem_block *heap, int size,
|
||||
int align2, DRMFILE filp)
|
||||
{
|
||||
struct mem_block *p;
|
||||
int mask = (1 << align2)-1;
|
||||
int mask = (1 << align2) - 1;
|
||||
|
||||
list_for_each(p, heap) {
|
||||
int start = (p->start + mask) & ~mask;
|
||||
if (p->filp == 0 && start + size <= p->start + p->size)
|
||||
return split_block( p, start, size, filp );
|
||||
return split_block(p, start, size, filp);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mem_block *find_block( struct mem_block *heap, int start )
|
||||
static struct mem_block *find_block(struct mem_block *heap, int start)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
list_for_each(p, heap)
|
||||
if (p->start == start)
|
||||
return p;
|
||||
if (p->start == start)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void free_block( struct mem_block *p )
|
||||
static void free_block(struct mem_block *p)
|
||||
{
|
||||
p->filp = NULL;
|
||||
|
||||
|
@ -117,7 +118,7 @@ static void free_block( struct mem_block *p )
|
|||
p->size += q->size;
|
||||
p->next = q->next;
|
||||
p->next->prev = p;
|
||||
drm_free(q, sizeof(*q), DRM_MEM_BUFS );
|
||||
drm_free(q, sizeof(*q), DRM_MEM_BUFS);
|
||||
}
|
||||
|
||||
if (p->prev->filp == 0) {
|
||||
|
@ -125,7 +126,7 @@ static void free_block( struct mem_block *p )
|
|||
q->size += p->size;
|
||||
q->next = p->next;
|
||||
q->next->prev = q;
|
||||
drm_free(p, sizeof(*q), DRM_MEM_BUFS );
|
||||
drm_free(p, sizeof(*q), DRM_MEM_BUFS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,14 +134,14 @@ static void free_block( struct mem_block *p )
|
|||
*/
|
||||
static int init_heap(struct mem_block **heap, int start, int size)
|
||||
{
|
||||
struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS );
|
||||
struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
|
||||
|
||||
if (!blocks)
|
||||
if (!blocks)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS );
|
||||
|
||||
*heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
|
||||
if (!*heap) {
|
||||
drm_free( blocks, sizeof(*blocks), DRM_MEM_BUFS );
|
||||
drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
|
@ -149,16 +150,15 @@ static int init_heap(struct mem_block **heap, int start, int size)
|
|||
blocks->filp = NULL;
|
||||
blocks->next = blocks->prev = *heap;
|
||||
|
||||
memset( *heap, 0, sizeof(**heap) );
|
||||
(*heap)->filp = (DRMFILE) -1;
|
||||
memset(*heap, 0, sizeof(**heap));
|
||||
(*heap)->filp = (DRMFILE) - 1;
|
||||
(*heap)->next = (*heap)->prev = blocks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free all blocks associated with the releasing file.
|
||||
*/
|
||||
void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
|
||||
void radeon_mem_release(DRMFILE filp, struct mem_block *heap)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
|
@ -166,7 +166,7 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
|
|||
return;
|
||||
|
||||
list_for_each(p, heap) {
|
||||
if (p->filp == filp)
|
||||
if (p->filp == filp)
|
||||
p->filp = NULL;
|
||||
}
|
||||
|
||||
|
@ -179,40 +179,37 @@ void radeon_mem_release( DRMFILE filp, struct mem_block *heap )
|
|||
p->size += q->size;
|
||||
p->next = q->next;
|
||||
p->next->prev = p;
|
||||
drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
|
||||
drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutdown.
|
||||
*/
|
||||
void radeon_mem_takedown( struct mem_block **heap )
|
||||
void radeon_mem_takedown(struct mem_block **heap)
|
||||
{
|
||||
struct mem_block *p;
|
||||
|
||||
|
||||
if (!*heap)
|
||||
return;
|
||||
|
||||
for (p = (*heap)->next ; p != *heap ; ) {
|
||||
for (p = (*heap)->next; p != *heap;) {
|
||||
struct mem_block *q = p;
|
||||
p = p->next;
|
||||
drm_free(q, sizeof(*q),DRM_MEM_DRIVER);
|
||||
drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
|
||||
}
|
||||
|
||||
drm_free( *heap, sizeof(**heap),DRM_MEM_DRIVER );
|
||||
drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
|
||||
*heap = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* IOCTL HANDLERS */
|
||||
|
||||
static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
|
||||
int region )
|
||||
static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region)
|
||||
{
|
||||
switch( region ) {
|
||||
switch (region) {
|
||||
case RADEON_MEM_REGION_GART:
|
||||
return &dev_priv->gart_heap;
|
||||
return &dev_priv->gart_heap;
|
||||
case RADEON_MEM_REGION_FB:
|
||||
return &dev_priv->fb_heap;
|
||||
default:
|
||||
|
@ -220,103 +217,98 @@ static struct mem_block **get_heap( drm_radeon_private_t *dev_priv,
|
|||
}
|
||||
}
|
||||
|
||||
int radeon_mem_alloc( DRM_IOCTL_ARGS )
|
||||
int radeon_mem_alloc(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_mem_alloc_t alloc;
|
||||
struct mem_block *block, **heap;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( alloc, (drm_radeon_mem_alloc_t __user *)data,
|
||||
sizeof(alloc) );
|
||||
DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_mem_alloc_t __user *) data,
|
||||
sizeof(alloc));
|
||||
|
||||
heap = get_heap( dev_priv, alloc.region );
|
||||
heap = get_heap(dev_priv, alloc.region);
|
||||
if (!heap || !*heap)
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
|
||||
/* Make things easier on ourselves: all allocations at least
|
||||
* 4k aligned.
|
||||
*/
|
||||
if (alloc.alignment < 12)
|
||||
alloc.alignment = 12;
|
||||
|
||||
block = alloc_block( *heap, alloc.size, alloc.alignment,
|
||||
filp );
|
||||
block = alloc_block(*heap, alloc.size, alloc.alignment, filp);
|
||||
|
||||
if (!block)
|
||||
if (!block)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
if ( DRM_COPY_TO_USER( alloc.region_offset, &block->start,
|
||||
sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
if (DRM_COPY_TO_USER(alloc.region_offset, &block->start, sizeof(int))) {
|
||||
DRM_ERROR("copy_to_user\n");
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int radeon_mem_free( DRM_IOCTL_ARGS )
|
||||
int radeon_mem_free(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_mem_free_t memfree;
|
||||
struct mem_block *block, **heap;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( memfree, (drm_radeon_mem_free_t __user *)data,
|
||||
sizeof(memfree) );
|
||||
DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
|
||||
sizeof(memfree));
|
||||
|
||||
heap = get_heap( dev_priv, memfree.region );
|
||||
heap = get_heap(dev_priv, memfree.region);
|
||||
if (!heap || !*heap)
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
block = find_block( *heap, memfree.region_offset );
|
||||
|
||||
block = find_block(*heap, memfree.region_offset);
|
||||
if (!block)
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
if (block->filp != filp)
|
||||
return DRM_ERR(EPERM);
|
||||
|
||||
free_block( block );
|
||||
free_block(block);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_mem_init_heap( DRM_IOCTL_ARGS )
|
||||
int radeon_mem_init_heap(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_mem_init_heap_t initheap;
|
||||
struct mem_block **heap;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
if (!dev_priv) {
|
||||
DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL( initheap, (drm_radeon_mem_init_heap_t __user *)data,
|
||||
sizeof(initheap) );
|
||||
DRM_COPY_FROM_USER_IOCTL(initheap,
|
||||
(drm_radeon_mem_init_heap_t __user *) data,
|
||||
sizeof(initheap));
|
||||
|
||||
heap = get_heap( dev_priv, initheap.region );
|
||||
if (!heap)
|
||||
heap = get_heap(dev_priv, initheap.region);
|
||||
if (!heap)
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
|
||||
if (*heap) {
|
||||
DRM_ERROR("heap already initialized?");
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
||||
return init_heap( heap, initheap.start, initheap.size );
|
||||
|
||||
return init_heap(heap, initheap.start, initheap.size);
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,12 +28,12 @@
|
|||
|
||||
/* Need a long timeout for shadow status updates can take a while
|
||||
* and so can waiting for events when the queue is full. */
|
||||
#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
|
||||
#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
|
||||
#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
|
||||
#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
|
||||
#define SAVAGE_FREELIST_DEBUG 0
|
||||
|
||||
static int
|
||||
savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
|
||||
savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n)
|
||||
{
|
||||
uint32_t mask = dev_priv->status_used_mask;
|
||||
uint32_t threshold = dev_priv->bci_threshold_hi;
|
||||
|
@ -62,7 +62,7 @@ savage_bci_wait_fifo_shadow(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
}
|
||||
|
||||
static int
|
||||
savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
|
||||
savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n)
|
||||
{
|
||||
uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
|
||||
uint32_t status;
|
||||
|
@ -83,7 +83,7 @@ savage_bci_wait_fifo_s3d(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
}
|
||||
|
||||
static int
|
||||
savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
|
||||
savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n)
|
||||
{
|
||||
uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
|
||||
uint32_t status;
|
||||
|
@ -115,7 +115,7 @@ savage_bci_wait_fifo_s4(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
* rule. Otherwise there may be glitches every 2^16 events.
|
||||
*/
|
||||
static int
|
||||
savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
|
||||
savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e)
|
||||
{
|
||||
uint32_t status;
|
||||
int i;
|
||||
|
@ -138,7 +138,7 @@ savage_bci_wait_event_shadow(drm_savage_private_t *dev_priv, uint16_t e)
|
|||
}
|
||||
|
||||
static int
|
||||
savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
|
||||
savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e)
|
||||
{
|
||||
uint32_t status;
|
||||
int i;
|
||||
|
@ -159,7 +159,7 @@ savage_bci_wait_event_reg(drm_savage_private_t *dev_priv, uint16_t e)
|
|||
return DRM_ERR(EBUSY);
|
||||
}
|
||||
|
||||
uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
|
||||
uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
|
||||
unsigned int flags)
|
||||
{
|
||||
uint16_t count;
|
||||
|
@ -175,12 +175,12 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
|
|||
}
|
||||
count = (count + 1) & 0xffff;
|
||||
if (count == 0) {
|
||||
count++; /* See the comment above savage_wait_event_*. */
|
||||
count++; /* See the comment above savage_wait_event_*. */
|
||||
dev_priv->event_wrap++;
|
||||
}
|
||||
dev_priv->event_counter = count;
|
||||
if (dev_priv->status_ptr)
|
||||
dev_priv->status_ptr[1023] = (uint32_t)count;
|
||||
dev_priv->status_ptr[1023] = (uint32_t) count;
|
||||
|
||||
if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) {
|
||||
unsigned int wait_cmd = BCI_CMD_WAIT;
|
||||
|
@ -193,7 +193,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
|
|||
} else {
|
||||
BEGIN_BCI(1);
|
||||
}
|
||||
BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t)count);
|
||||
BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
|
|||
/*
|
||||
* Freelist management
|
||||
*/
|
||||
static int savage_freelist_init(drm_device_t *dev)
|
||||
static int savage_freelist_init(drm_device_t * dev)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
|
@ -234,7 +234,7 @@ static int savage_freelist_init(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static drm_buf_t *savage_freelist_get(drm_device_t *dev)
|
||||
static drm_buf_t *savage_freelist_get(drm_device_t * dev)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
drm_savage_buf_priv_t *tail = dev_priv->tail.prev;
|
||||
|
@ -249,7 +249,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev)
|
|||
event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
|
||||
wrap = dev_priv->event_wrap;
|
||||
if (event > dev_priv->event_counter)
|
||||
wrap--; /* hardware hasn't passed the last wrap yet */
|
||||
wrap--; /* hardware hasn't passed the last wrap yet */
|
||||
|
||||
DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
|
||||
DRM_DEBUG(" head=0x%04x %d\n", event, wrap);
|
||||
|
@ -267,7 +267,7 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
|
||||
void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next;
|
||||
|
@ -290,15 +290,14 @@ void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf)
|
|||
/*
|
||||
* Command DMA
|
||||
*/
|
||||
static int savage_dma_init(drm_savage_private_t *dev_priv)
|
||||
static int savage_dma_init(drm_savage_private_t * dev_priv)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
dev_priv->nr_dma_pages = dev_priv->cmd_dma->size /
|
||||
(SAVAGE_DMA_PAGE_SIZE*4);
|
||||
(SAVAGE_DMA_PAGE_SIZE * 4);
|
||||
dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) *
|
||||
dev_priv->nr_dma_pages,
|
||||
DRM_MEM_DRIVER);
|
||||
dev_priv->nr_dma_pages, DRM_MEM_DRIVER);
|
||||
if (dev_priv->dma_pages == NULL)
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
||||
|
@ -315,7 +314,7 @@ static int savage_dma_init(drm_savage_private_t *dev_priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void savage_dma_reset(drm_savage_private_t *dev_priv)
|
||||
void savage_dma_reset(drm_savage_private_t * dev_priv)
|
||||
{
|
||||
uint16_t event;
|
||||
unsigned int wrap, i;
|
||||
|
@ -330,7 +329,7 @@ void savage_dma_reset(drm_savage_private_t *dev_priv)
|
|||
dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
|
||||
}
|
||||
|
||||
void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
|
||||
void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page)
|
||||
{
|
||||
uint16_t event;
|
||||
unsigned int wrap;
|
||||
|
@ -346,7 +345,7 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
|
|||
event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
|
||||
wrap = dev_priv->event_wrap;
|
||||
if (event > dev_priv->event_counter)
|
||||
wrap--; /* hardware hasn't passed the last wrap yet */
|
||||
wrap--; /* hardware hasn't passed the last wrap yet */
|
||||
|
||||
if (dev_priv->dma_pages[page].age.wrap > wrap ||
|
||||
(dev_priv->dma_pages[page].age.wrap == wrap &&
|
||||
|
@ -358,13 +357,13 @@ void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
|
||||
uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n)
|
||||
{
|
||||
unsigned int cur = dev_priv->current_dma_page;
|
||||
unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
|
||||
dev_priv->dma_pages[cur].used;
|
||||
unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE-1) /
|
||||
SAVAGE_DMA_PAGE_SIZE;
|
||||
dev_priv->dma_pages[cur].used;
|
||||
unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) /
|
||||
SAVAGE_DMA_PAGE_SIZE;
|
||||
uint32_t *dma_ptr;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -372,9 +371,8 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
|
||||
|
||||
if (cur + nr_pages < dev_priv->nr_dma_pages) {
|
||||
dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
|
||||
cur*SAVAGE_DMA_PAGE_SIZE +
|
||||
dev_priv->dma_pages[cur].used;
|
||||
dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
|
||||
cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
|
||||
if (n < rest)
|
||||
rest = n;
|
||||
dev_priv->dma_pages[cur].used += rest;
|
||||
|
@ -382,13 +380,14 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
cur++;
|
||||
} else {
|
||||
dev_priv->dma_flush(dev_priv);
|
||||
nr_pages = (n + SAVAGE_DMA_PAGE_SIZE-1) / SAVAGE_DMA_PAGE_SIZE;
|
||||
nr_pages =
|
||||
(n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE;
|
||||
for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
|
||||
dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
|
||||
dev_priv->dma_pages[i].used = 0;
|
||||
dev_priv->dma_pages[i].flushed = 0;
|
||||
}
|
||||
dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle;
|
||||
dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle;
|
||||
dev_priv->first_dma_page = cur = 0;
|
||||
}
|
||||
for (i = cur; nr_pages > 0; ++i, --nr_pages) {
|
||||
|
@ -414,7 +413,7 @@ uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv, unsigned int n)
|
|||
return dma_ptr;
|
||||
}
|
||||
|
||||
static void savage_dma_flush(drm_savage_private_t *dev_priv)
|
||||
static void savage_dma_flush(drm_savage_private_t * dev_priv)
|
||||
{
|
||||
unsigned int first = dev_priv->first_dma_page;
|
||||
unsigned int cur = dev_priv->current_dma_page;
|
||||
|
@ -439,11 +438,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
|
|||
|
||||
/* pad with noops */
|
||||
if (pad) {
|
||||
uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
|
||||
cur * SAVAGE_DMA_PAGE_SIZE +
|
||||
dev_priv->dma_pages[cur].used;
|
||||
uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
|
||||
cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
|
||||
dev_priv->dma_pages[cur].used += pad;
|
||||
while(pad != 0) {
|
||||
while (pad != 0) {
|
||||
*dma_ptr++ = BCI_CMD_WAIT;
|
||||
pad--;
|
||||
}
|
||||
|
@ -453,11 +451,10 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
|
|||
|
||||
/* do flush ... */
|
||||
phys_addr = dev_priv->cmd_dma->offset +
|
||||
(first * SAVAGE_DMA_PAGE_SIZE +
|
||||
dev_priv->dma_pages[first].flushed) * 4;
|
||||
(first * SAVAGE_DMA_PAGE_SIZE +
|
||||
dev_priv->dma_pages[first].flushed) * 4;
|
||||
len = (cur - first) * SAVAGE_DMA_PAGE_SIZE +
|
||||
dev_priv->dma_pages[cur].used -
|
||||
dev_priv->dma_pages[first].flushed;
|
||||
dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed;
|
||||
|
||||
DRM_DEBUG("phys_addr=%lx, len=%u\n",
|
||||
phys_addr | dev_priv->dma_type, len);
|
||||
|
@ -499,7 +496,7 @@ static void savage_dma_flush(drm_savage_private_t *dev_priv)
|
|||
dev_priv->dma_pages[cur].flushed);
|
||||
}
|
||||
|
||||
static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
|
||||
static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
|
||||
{
|
||||
unsigned int i, j;
|
||||
BCI_LOCALS;
|
||||
|
@ -515,8 +512,8 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
|
|||
for (i = dev_priv->first_dma_page;
|
||||
i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
|
||||
++i) {
|
||||
uint32_t *dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle +
|
||||
i * SAVAGE_DMA_PAGE_SIZE;
|
||||
uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
|
||||
i * SAVAGE_DMA_PAGE_SIZE;
|
||||
#if SAVAGE_DMA_DEBUG
|
||||
/* Sanity check: all pages except the last one must be full. */
|
||||
if (i < dev_priv->current_dma_page &&
|
||||
|
@ -543,7 +540,7 @@ static void savage_fake_dma_flush(drm_savage_private_t *dev_priv)
|
|||
* initialized. We also need to take care of deleting the MTRRs in
|
||||
* postcleanup.
|
||||
*/
|
||||
int savage_preinit(drm_device_t *dev, unsigned long chipset)
|
||||
int savage_preinit(drm_device_t * dev, unsigned long chipset)
|
||||
{
|
||||
drm_savage_private_t *dev_priv;
|
||||
unsigned long mmio_base, fb_base, fb_size, aperture_base;
|
||||
|
@ -578,19 +575,22 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
|
|||
* MTRRs. */
|
||||
dev_priv->mtrr[0].base = fb_base;
|
||||
dev_priv->mtrr[0].size = 0x01000000;
|
||||
dev_priv->mtrr[0].handle = mtrr_add(
|
||||
dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
dev_priv->mtrr[1].base = fb_base+0x02000000;
|
||||
dev_priv->mtrr[0].handle =
|
||||
mtrr_add(dev_priv->mtrr[0].base,
|
||||
dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
|
||||
1);
|
||||
dev_priv->mtrr[1].base = fb_base + 0x02000000;
|
||||
dev_priv->mtrr[1].size = 0x02000000;
|
||||
dev_priv->mtrr[1].handle = mtrr_add(
|
||||
dev_priv->mtrr[1].base, dev_priv->mtrr[1].size,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
dev_priv->mtrr[2].base = fb_base+0x04000000;
|
||||
dev_priv->mtrr[1].handle =
|
||||
mtrr_add(dev_priv->mtrr[1].base,
|
||||
dev_priv->mtrr[1].size, MTRR_TYPE_WRCOMB,
|
||||
1);
|
||||
dev_priv->mtrr[2].base = fb_base + 0x04000000;
|
||||
dev_priv->mtrr[2].size = 0x04000000;
|
||||
dev_priv->mtrr[2].handle = mtrr_add(
|
||||
dev_priv->mtrr[2].base, dev_priv->mtrr[2].size,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
dev_priv->mtrr[2].handle =
|
||||
mtrr_add(dev_priv->mtrr[2].base,
|
||||
dev_priv->mtrr[2].size, MTRR_TYPE_WRCOMB,
|
||||
1);
|
||||
} else {
|
||||
DRM_ERROR("strange pci_resource_len %08lx\n",
|
||||
drm_get_resource_len(dev, 0));
|
||||
|
@ -608,9 +608,10 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
|
|||
* aperture. */
|
||||
dev_priv->mtrr[0].base = fb_base;
|
||||
dev_priv->mtrr[0].size = 0x08000000;
|
||||
dev_priv->mtrr[0].handle = mtrr_add(
|
||||
dev_priv->mtrr[0].base, dev_priv->mtrr[0].size,
|
||||
MTRR_TYPE_WRCOMB, 1);
|
||||
dev_priv->mtrr[0].handle =
|
||||
mtrr_add(dev_priv->mtrr[0].base,
|
||||
dev_priv->mtrr[0].size, MTRR_TYPE_WRCOMB,
|
||||
1);
|
||||
} else {
|
||||
DRM_ERROR("strange pci_resource_len %08lx\n",
|
||||
drm_get_resource_len(dev, 1));
|
||||
|
@ -647,7 +648,7 @@ int savage_preinit(drm_device_t *dev, unsigned long chipset)
|
|||
/*
|
||||
* Delete MTRRs and free device-private data.
|
||||
*/
|
||||
int savage_postcleanup(drm_device_t *dev)
|
||||
int savage_postcleanup(drm_device_t * dev)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
@ -663,7 +664,7 @@ int savage_postcleanup(drm_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
||||
static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
|
@ -731,7 +732,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
}
|
||||
if (init->agp_textures_offset) {
|
||||
dev_priv->agp_textures =
|
||||
drm_core_findmap(dev, init->agp_textures_offset);
|
||||
drm_core_findmap(dev, init->agp_textures_offset);
|
||||
if (!dev_priv->agp_textures) {
|
||||
DRM_ERROR("could not find agp texture region!\n");
|
||||
savage_do_cleanup_bci(dev);
|
||||
|
@ -802,8 +803,8 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
}
|
||||
|
||||
dev_priv->sarea_priv =
|
||||
(drm_savage_sarea_t *)((uint8_t *)dev_priv->sarea->handle +
|
||||
init->sarea_priv_offset);
|
||||
(drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle +
|
||||
init->sarea_priv_offset);
|
||||
|
||||
/* setup bitmap descriptors */
|
||||
{
|
||||
|
@ -812,35 +813,36 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
unsigned int front_stride, back_stride, depth_stride;
|
||||
if (dev_priv->chipset <= S3_SAVAGE4) {
|
||||
color_tile_format = dev_priv->fb_bpp == 16 ?
|
||||
SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
|
||||
SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
|
||||
depth_tile_format = dev_priv->depth_bpp == 16 ?
|
||||
SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
|
||||
SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
|
||||
} else {
|
||||
color_tile_format = SAVAGE_BD_TILE_DEST;
|
||||
depth_tile_format = SAVAGE_BD_TILE_DEST;
|
||||
}
|
||||
front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp/8);
|
||||
back_stride = dev_priv-> back_pitch / (dev_priv->fb_bpp/8);
|
||||
depth_stride = dev_priv->depth_pitch / (dev_priv->depth_bpp/8);
|
||||
front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8);
|
||||
back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
|
||||
depth_stride =
|
||||
dev_priv->depth_pitch / (dev_priv->depth_bpp / 8);
|
||||
|
||||
dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE |
|
||||
(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(color_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(color_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
|
||||
dev_priv-> back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
|
||||
(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(color_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
|
||||
(dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(color_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
|
||||
dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE |
|
||||
(dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(depth_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
(dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
|
||||
(depth_tile_format << SAVAGE_BD_TILE_SHIFT);
|
||||
}
|
||||
|
||||
/* setup status and bci ptr */
|
||||
dev_priv->event_counter = 0;
|
||||
dev_priv->event_wrap = 0;
|
||||
dev_priv->bci_ptr = (volatile uint32_t *)
|
||||
((uint8_t *)dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
|
||||
((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
|
||||
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
|
||||
} else {
|
||||
|
@ -848,7 +850,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
}
|
||||
if (dev_priv->status != NULL) {
|
||||
dev_priv->status_ptr =
|
||||
(volatile uint32_t *)dev_priv->status->handle;
|
||||
(volatile uint32_t *)dev_priv->status->handle;
|
||||
dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
|
||||
dev_priv->wait_evnt = savage_bci_wait_event_shadow;
|
||||
dev_priv->status_ptr[1023] = dev_priv->event_counter;
|
||||
|
@ -874,7 +876,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
if (savage_dma_init(dev_priv) < 0) {
|
||||
if (savage_dma_init(dev_priv) < 0) {
|
||||
DRM_ERROR("could not initialize command DMA\n");
|
||||
savage_do_cleanup_bci(dev);
|
||||
return DRM_ERR(ENOMEM);
|
||||
|
@ -883,7 +885,7 @@ static int savage_do_init_bci(drm_device_t *dev, drm_savage_init_t *init)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int savage_do_cleanup_bci(drm_device_t *dev)
|
||||
int savage_do_cleanup_bci(drm_device_t * dev)
|
||||
{
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
|
||||
|
@ -907,7 +909,7 @@ int savage_do_cleanup_bci(drm_device_t *dev)
|
|||
|
||||
if (dev_priv->dma_pages)
|
||||
drm_free(dev_priv->dma_pages,
|
||||
sizeof(drm_savage_dma_page_t)*dev_priv->nr_dma_pages,
|
||||
sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages,
|
||||
DRM_MEM_DRIVER);
|
||||
|
||||
return 0;
|
||||
|
@ -920,7 +922,7 @@ static int savage_bci_init(DRM_IOCTL_ARGS)
|
|||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *)data,
|
||||
DRM_COPY_FROM_USER_IOCTL(init, (drm_savage_init_t __user *) data,
|
||||
sizeof(init));
|
||||
|
||||
switch (init.func) {
|
||||
|
@ -943,13 +945,13 @@ static int savage_bci_event_emit(DRM_IOCTL_ARGS)
|
|||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *)data,
|
||||
DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_emit_t __user *) data,
|
||||
sizeof(event));
|
||||
|
||||
event.count = savage_bci_emit_event(dev_priv, event.flags);
|
||||
event.count |= dev_priv->event_wrap << 16;
|
||||
DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count,
|
||||
event.count, sizeof(event.count));
|
||||
DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *) data)->
|
||||
count, event.count, sizeof(event.count));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -963,7 +965,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
|
|||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data,
|
||||
DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *) data,
|
||||
sizeof(event));
|
||||
|
||||
UPDATE_EVENT_COUNTER();
|
||||
|
@ -973,7 +975,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
|
|||
hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
|
||||
hw_w = dev_priv->event_wrap;
|
||||
if (hw_e > dev_priv->event_counter)
|
||||
hw_w--; /* hardware hasn't passed the last wrap yet */
|
||||
hw_w--; /* hardware hasn't passed the last wrap yet */
|
||||
|
||||
event_e = event.count & 0xffff;
|
||||
event_w = event.count >> 16;
|
||||
|
@ -982,7 +984,7 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
|
|||
* - event counter wrapped since the event was emitted or
|
||||
* - the hardware has advanced up to or over the event to wait for.
|
||||
*/
|
||||
if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e) )
|
||||
if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e))
|
||||
return 0;
|
||||
else
|
||||
return dev_priv->wait_evnt(dev_priv, event_e);
|
||||
|
@ -992,7 +994,8 @@ static int savage_bci_event_wait(DRM_IOCTL_ARGS)
|
|||
* DMA buffer management
|
||||
*/
|
||||
|
||||
static int savage_bci_get_buffers(DRMFILE filp, drm_device_t *dev, drm_dma_t *d)
|
||||
static int savage_bci_get_buffers(DRMFILE filp, drm_device_t * dev,
|
||||
drm_dma_t * d)
|
||||
{
|
||||
drm_buf_t *buf;
|
||||
int i;
|
||||
|
@ -1025,7 +1028,7 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
|
|||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *)data, sizeof(d));
|
||||
DRM_COPY_FROM_USER_IOCTL(d, (drm_dma_t __user *) data, sizeof(d));
|
||||
|
||||
/* Please don't send us buffers.
|
||||
*/
|
||||
|
@ -1049,12 +1052,13 @@ int savage_bci_buffers(DRM_IOCTL_ARGS)
|
|||
ret = savage_bci_get_buffers(filp, dev, &d);
|
||||
}
|
||||
|
||||
DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *)data, d, sizeof(d));
|
||||
DRM_COPY_TO_USER_IOCTL((drm_dma_t __user *) data, d, sizeof(d));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
|
||||
void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp)
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_savage_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
@ -1066,7 +1070,7 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
|
|||
if (!dma->buflist)
|
||||
return;
|
||||
|
||||
/*i830_flush_queue(dev);*/
|
||||
/*i830_flush_queue(dev); */
|
||||
|
||||
for (i = 0; i < dma->buf_count; i++) {
|
||||
drm_buf_t *buf = dma->buflist[i];
|
||||
|
@ -1085,7 +1089,6 @@ void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp) {
|
|||
drm_core_reclaim_buffers(dev, filp);
|
||||
}
|
||||
|
||||
|
||||
drm_ioctl_desc_t savage_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_SAVAGE_BCI_INIT)] = {savage_bci_init, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_SAVAGE_BCI_CMDBUF)] = {savage_bci_cmdbuf, 1, 0},
|
||||
|
|
|
@ -42,12 +42,13 @@
|
|||
#define SAVAGE_NR_TEX_REGIONS 16
|
||||
#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
|
||||
|
||||
#endif /* __SAVAGE_SAREA_DEFINES__ */
|
||||
#endif /* __SAVAGE_SAREA_DEFINES__ */
|
||||
|
||||
typedef struct _drm_savage_sarea {
|
||||
/* LRU lists for texture memory in agp space and on the card.
|
||||
*/
|
||||
drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1];
|
||||
drm_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS +
|
||||
1];
|
||||
unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
|
||||
|
||||
/* Mechanism to validate card state.
|
||||
|
@ -101,24 +102,24 @@ typedef struct drm_savage_init {
|
|||
|
||||
typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
|
||||
typedef struct drm_savage_cmdbuf {
|
||||
/* command buffer in client's address space */
|
||||
/* command buffer in client's address space */
|
||||
drm_savage_cmd_header_t __user *cmd_addr;
|
||||
unsigned int size; /* size of the command buffer in 64bit units */
|
||||
|
||||
unsigned int dma_idx; /* DMA buffer index to use */
|
||||
int discard; /* discard DMA buffer when done */
|
||||
/* vertex buffer in client's address space */
|
||||
/* vertex buffer in client's address space */
|
||||
unsigned int __user *vb_addr;
|
||||
unsigned int vb_size; /* size of client vertex buffer in bytes */
|
||||
unsigned int vb_stride; /* stride of vertices in 32bit words */
|
||||
/* boxes in client's address space */
|
||||
/* boxes in client's address space */
|
||||
drm_clip_rect_t __user *box_addr;
|
||||
unsigned int nbox; /* number of clipping boxes */
|
||||
} drm_savage_cmdbuf_t;
|
||||
|
||||
#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
|
||||
#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
|
||||
#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
|
||||
#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
|
||||
#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
|
||||
#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
|
||||
typedef struct drm_savage_event {
|
||||
unsigned int count;
|
||||
unsigned int flags;
|
||||
|
@ -126,21 +127,21 @@ typedef struct drm_savage_event {
|
|||
|
||||
/* Commands for the cmdbuf ioctl
|
||||
*/
|
||||
#define SAVAGE_CMD_STATE 0 /* a range of state registers */
|
||||
#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
|
||||
#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
|
||||
#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
|
||||
#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
|
||||
#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
|
||||
#define SAVAGE_CMD_SWAP 6 /* swap buffers */
|
||||
#define SAVAGE_CMD_STATE 0 /* a range of state registers */
|
||||
#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
|
||||
#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
|
||||
#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
|
||||
#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
|
||||
#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
|
||||
#define SAVAGE_CMD_SWAP 6 /* swap buffers */
|
||||
|
||||
/* Primitive types
|
||||
*/
|
||||
#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
|
||||
#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
|
||||
#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
|
||||
#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
|
||||
* shading on s3d */
|
||||
#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
|
||||
#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
|
||||
#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
|
||||
#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
|
||||
* shading on s3d */
|
||||
|
||||
/* Skip flags (vertex format)
|
||||
*/
|
||||
|
@ -172,38 +173,38 @@ union drm_savage_cmd_header {
|
|||
unsigned short pad1;
|
||||
unsigned short pad2;
|
||||
unsigned short pad3;
|
||||
} cmd; /* generic */
|
||||
} cmd; /* generic */
|
||||
struct {
|
||||
unsigned char cmd;
|
||||
unsigned char global; /* need idle engine? */
|
||||
unsigned short count; /* number of consecutive registers */
|
||||
unsigned short start; /* first register */
|
||||
unsigned short pad3;
|
||||
} state; /* SAVAGE_CMD_STATE */
|
||||
} state; /* SAVAGE_CMD_STATE */
|
||||
struct {
|
||||
unsigned char cmd;
|
||||
unsigned char prim; /* primitive type */
|
||||
unsigned short skip; /* vertex format (skip flags) */
|
||||
unsigned short count; /* number of vertices */
|
||||
unsigned short start; /* first vertex in DMA/vertex buffer */
|
||||
} prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
|
||||
} prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
|
||||
struct {
|
||||
unsigned char cmd;
|
||||
unsigned char prim;
|
||||
unsigned short skip;
|
||||
unsigned short count; /* number of indices that follow */
|
||||
unsigned short pad3;
|
||||
} idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
|
||||
} idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
|
||||
struct {
|
||||
unsigned char cmd;
|
||||
unsigned char pad0;
|
||||
unsigned short pad1;
|
||||
unsigned int flags;
|
||||
} clear0; /* SAVAGE_CMD_CLEAR */
|
||||
} clear0; /* SAVAGE_CMD_CLEAR */
|
||||
struct {
|
||||
unsigned int mask;
|
||||
unsigned int value;
|
||||
} clear1; /* SAVAGE_CMD_CLEAR data */
|
||||
} clear1; /* SAVAGE_CMD_CLEAR data */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,30 +30,28 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -61,13 +59,9 @@ static struct pci_device_id pciidlist[] = {
|
|||
savage_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t savage_ioctls[];
|
||||
extern int savage_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_USE_MTRR |
|
||||
DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
|
||||
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
|
||||
.dev_priv_size = sizeof(drm_savage_buf_priv_t),
|
||||
.preinit = savage_preinit,
|
||||
.postinit = postinit,
|
||||
|
@ -79,18 +73,19 @@ static struct drm_driver driver = {
|
|||
.ioctls = savage_ioctls,
|
||||
.dma_ioctl = savage_bci_buffers,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
}
|
||||
,
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init savage_init(void)
|
||||
|
@ -107,6 +102,6 @@ static void __exit savage_exit(void)
|
|||
module_init(savage_init);
|
||||
module_exit(savage_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -65,7 +65,7 @@ typedef struct drm_savage_dma_page {
|
|||
drm_savage_age_t age;
|
||||
unsigned int used, flushed;
|
||||
} drm_savage_dma_page_t;
|
||||
#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
|
||||
#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
|
||||
/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command
|
||||
* size of 16kbytes or 4k entries. Minimum requirement would be
|
||||
* 10kbytes for 255 40-byte vertices in one drawing command. */
|
||||
|
@ -104,6 +104,9 @@ enum savage_family {
|
|||
S3_LAST
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t savage_ioctls[];
|
||||
extern int savage_max_ioctl;
|
||||
|
||||
#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
|
||||
|
||||
#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
|
||||
|
@ -184,13 +187,13 @@ typedef struct drm_savage_private {
|
|||
unsigned int waiting;
|
||||
|
||||
/* config/hardware-dependent function pointers */
|
||||
int (*wait_fifo)(struct drm_savage_private *dev_priv, unsigned int n);
|
||||
int (*wait_evnt)(struct drm_savage_private *dev_priv, uint16_t e);
|
||||
int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n);
|
||||
int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e);
|
||||
/* Err, there is a macro wait_event in include/linux/wait.h.
|
||||
* Avoid unwanted macro expansion. */
|
||||
void (*emit_clip_rect)(struct drm_savage_private *dev_priv,
|
||||
drm_clip_rect_t *pbox);
|
||||
void (*dma_flush)(struct drm_savage_private *dev_priv);
|
||||
void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
|
||||
drm_clip_rect_t * pbox);
|
||||
void (*dma_flush) (struct drm_savage_private * dev_priv);
|
||||
} drm_savage_private_t;
|
||||
|
||||
/* ioctls */
|
||||
|
@ -198,23 +201,23 @@ extern int savage_bci_cmdbuf(DRM_IOCTL_ARGS);
|
|||
extern int savage_bci_buffers(DRM_IOCTL_ARGS);
|
||||
|
||||
/* BCI functions */
|
||||
extern uint16_t savage_bci_emit_event(drm_savage_private_t *dev_priv,
|
||||
extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
|
||||
unsigned int flags);
|
||||
extern void savage_freelist_put(drm_device_t *dev, drm_buf_t *buf);
|
||||
extern void savage_dma_reset(drm_savage_private_t *dev_priv);
|
||||
extern void savage_dma_wait(drm_savage_private_t *dev_priv, unsigned int page);
|
||||
extern uint32_t *savage_dma_alloc(drm_savage_private_t *dev_priv,
|
||||
extern void savage_freelist_put(drm_device_t * dev, drm_buf_t * buf);
|
||||
extern void savage_dma_reset(drm_savage_private_t * dev_priv);
|
||||
extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
|
||||
extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
|
||||
unsigned int n);
|
||||
extern int savage_preinit(drm_device_t *dev, unsigned long chipset);
|
||||
extern int savage_postcleanup(drm_device_t *dev);
|
||||
extern int savage_do_cleanup_bci(drm_device_t *dev);
|
||||
extern void savage_reclaim_buffers(drm_device_t *dev, DRMFILE filp);
|
||||
extern int savage_preinit(drm_device_t * dev, unsigned long chipset);
|
||||
extern int savage_postcleanup(drm_device_t * dev);
|
||||
extern int savage_do_cleanup_bci(drm_device_t * dev);
|
||||
extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
|
||||
|
||||
/* state functions */
|
||||
extern void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
|
||||
drm_clip_rect_t *pbox);
|
||||
extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
||||
drm_clip_rect_t *pbox);
|
||||
extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
|
||||
drm_clip_rect_t * pbox);
|
||||
extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
|
||||
drm_clip_rect_t * pbox);
|
||||
|
||||
#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
|
||||
#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
|
||||
|
@ -222,10 +225,10 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */
|
||||
#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */
|
||||
|
||||
#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
|
||||
#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
|
||||
* inside the MMIO region */
|
||||
#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
|
||||
* BCI FIFO */
|
||||
#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
|
||||
* BCI FIFO */
|
||||
|
||||
/*
|
||||
* MMIO registers
|
||||
|
@ -278,7 +281,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define SAVAGE_TEXADDR1_S4 0x23
|
||||
#define SAVAGE_TEXBLEND0_S4 0x24
|
||||
#define SAVAGE_TEXBLEND1_S4 0x25
|
||||
#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
|
||||
#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
|
||||
#define SAVAGE_TEXDESCR_S4 0x27
|
||||
#define SAVAGE_FOGTABLE_S4 0x28
|
||||
#define SAVAGE_FOGCTRL_S4 0x30
|
||||
|
@ -293,7 +296,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define SAVAGE_TEXBLENDCOLOR_S4 0x39
|
||||
/* Savage3D/MX/IX 3D registers */
|
||||
#define SAVAGE_TEXPALADDR_S3D 0x18
|
||||
#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
|
||||
#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
|
||||
#define SAVAGE_TEXADDR_S3D 0x1A
|
||||
#define SAVAGE_TEXDESCR_S3D 0x1B
|
||||
#define SAVAGE_TEXCTRL_S3D 0x1C
|
||||
|
@ -305,7 +308,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define SAVAGE_DESTCTRL_S3D 0x34
|
||||
#define SAVAGE_SCSTART_S3D 0x35
|
||||
#define SAVAGE_SCEND_S3D 0x36
|
||||
#define SAVAGE_ZWATERMARK_S3D 0x37
|
||||
#define SAVAGE_ZWATERMARK_S3D 0x37
|
||||
#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38
|
||||
/* common stuff */
|
||||
#define SAVAGE_VERTBUFADDR 0x3e
|
||||
|
@ -313,9 +316,9 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define SAVAGE_DMABUFADDR 0x51
|
||||
|
||||
/* texture enable bits (needed for tex addr checking) */
|
||||
#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
|
||||
#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
|
||||
#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
|
||||
#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
|
||||
#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
|
||||
#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
|
||||
|
||||
/* Global fields in Savage4/Twister/ProSavage 3D registers:
|
||||
*
|
||||
|
@ -576,4 +579,4 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
#define TEST_AGE( age, e, w ) \
|
||||
( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) )
|
||||
|
||||
#endif /* __SAVAGE_DRV_H__ */
|
||||
#endif /* __SAVAGE_DRV_H__ */
|
||||
|
|
|
@ -26,48 +26,48 @@
|
|||
#include "savage_drm.h"
|
||||
#include "savage_drv.h"
|
||||
|
||||
void savage_emit_clip_rect_s3d(drm_savage_private_t *dev_priv,
|
||||
drm_clip_rect_t *pbox)
|
||||
void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
|
||||
drm_clip_rect_t * pbox)
|
||||
{
|
||||
uint32_t scstart = dev_priv->state.s3d.new_scstart;
|
||||
uint32_t scend = dev_priv->state.s3d.new_scend;
|
||||
uint32_t scend = dev_priv->state.s3d.new_scend;
|
||||
scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
|
||||
((uint32_t)pbox->x1 & 0x000007ff) |
|
||||
(((uint32_t)pbox->y1 << 16) & 0x07ff0000);
|
||||
scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
|
||||
(((uint32_t)pbox->x2-1) & 0x000007ff) |
|
||||
((((uint32_t)pbox->y2-1) << 16) & 0x07ff0000);
|
||||
((uint32_t) pbox->x1 & 0x000007ff) |
|
||||
(((uint32_t) pbox->y1 << 16) & 0x07ff0000);
|
||||
scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
|
||||
(((uint32_t) pbox->x2 - 1) & 0x000007ff) |
|
||||
((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000);
|
||||
if (scstart != dev_priv->state.s3d.scstart ||
|
||||
scend != dev_priv->state.s3d.scend) {
|
||||
scend != dev_priv->state.s3d.scend) {
|
||||
DMA_LOCALS;
|
||||
BEGIN_DMA(4);
|
||||
DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
|
||||
DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
|
||||
DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
|
||||
DMA_WRITE(scstart);
|
||||
DMA_WRITE(scend);
|
||||
dev_priv->state.s3d.scstart = scstart;
|
||||
dev_priv->state.s3d.scend = scend;
|
||||
dev_priv->state.s3d.scend = scend;
|
||||
dev_priv->waiting = 1;
|
||||
DMA_COMMIT();
|
||||
}
|
||||
}
|
||||
|
||||
void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
||||
drm_clip_rect_t *pbox)
|
||||
void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
|
||||
drm_clip_rect_t * pbox)
|
||||
{
|
||||
uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
|
||||
uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
|
||||
drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) |
|
||||
((uint32_t)pbox->x1 & 0x000007ff) |
|
||||
(((uint32_t)pbox->y1 << 12) & 0x00fff000);
|
||||
((uint32_t) pbox->x1 & 0x000007ff) |
|
||||
(((uint32_t) pbox->y1 << 12) & 0x00fff000);
|
||||
drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
|
||||
(((uint32_t)pbox->x2-1) & 0x000007ff) |
|
||||
((((uint32_t)pbox->y2-1) << 12) & 0x00fff000);
|
||||
(((uint32_t) pbox->x2 - 1) & 0x000007ff) |
|
||||
((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000);
|
||||
if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
|
||||
drawctrl1 != dev_priv->state.s4.drawctrl1) {
|
||||
DMA_LOCALS;
|
||||
BEGIN_DMA(4);
|
||||
DMA_WRITE(BCI_CMD_WAIT|BCI_CMD_WAIT_3D);
|
||||
DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
|
||||
DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
|
||||
DMA_WRITE(drawctrl0);
|
||||
DMA_WRITE(drawctrl1);
|
||||
|
@ -78,22 +78,23 @@ void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
|
|||
}
|
||||
}
|
||||
|
||||
static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
|
||||
static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
|
||||
uint32_t addr)
|
||||
{
|
||||
if ((addr & 6) != 2) { /* reserved bits */
|
||||
if ((addr & 6) != 2) { /* reserved bits */
|
||||
DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (!(addr & 1)) { /* local */
|
||||
if (!(addr & 1)) { /* local */
|
||||
addr &= ~7;
|
||||
if (addr < dev_priv->texture_offset ||
|
||||
addr >= dev_priv->texture_offset+dev_priv->texture_size) {
|
||||
DRM_ERROR("bad texAddr%d %08x (local addr out of range)\n",
|
||||
unit, addr);
|
||||
if (addr < dev_priv->texture_offset ||
|
||||
addr >= dev_priv->texture_offset + dev_priv->texture_size) {
|
||||
DRM_ERROR
|
||||
("bad texAddr%d %08x (local addr out of range)\n",
|
||||
unit, addr);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
} else { /* AGP */
|
||||
} else { /* AGP */
|
||||
if (!dev_priv->agp_textures) {
|
||||
DRM_ERROR("bad texAddr%d %08x (AGP not available)\n",
|
||||
unit, addr);
|
||||
|
@ -103,8 +104,9 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
|
|||
if (addr < dev_priv->agp_textures->offset ||
|
||||
addr >= (dev_priv->agp_textures->offset +
|
||||
dev_priv->agp_textures->size)) {
|
||||
DRM_ERROR("bad texAddr%d %08x (AGP addr out of range)\n",
|
||||
unit, addr);
|
||||
DRM_ERROR
|
||||
("bad texAddr%d %08x (AGP addr out of range)\n",
|
||||
unit, addr);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -122,14 +124,14 @@ static int savage_verify_texaddr(drm_savage_private_t *dev_priv, int unit,
|
|||
(dev_priv->state.where & ~(mask)); \
|
||||
} \
|
||||
} while (0)
|
||||
static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
|
||||
static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
|
||||
unsigned int start, unsigned int count,
|
||||
const uint32_t __user *regs)
|
||||
const uint32_t __user * regs)
|
||||
{
|
||||
if (start < SAVAGE_TEXPALADDR_S3D ||
|
||||
start+count-1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
|
||||
start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
|
||||
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
|
||||
start, start+count-1);
|
||||
start, start + count - 1);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -140,28 +142,29 @@ static int savage_verify_state_s3d(drm_savage_private_t *dev_priv,
|
|||
|
||||
/* if any texture regs were changed ... */
|
||||
if (start <= SAVAGE_TEXCTRL_S3D &&
|
||||
start+count > SAVAGE_TEXPALADDR_S3D) {
|
||||
start + count > SAVAGE_TEXPALADDR_S3D) {
|
||||
/* ... check texture state */
|
||||
SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
|
||||
SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
|
||||
if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
|
||||
return savage_verify_texaddr(
|
||||
dev_priv, 0, dev_priv->state.s3d.texaddr);
|
||||
return savage_verify_texaddr(dev_priv, 0,
|
||||
dev_priv->state.s3d.
|
||||
texaddr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
|
||||
static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
|
||||
unsigned int start, unsigned int count,
|
||||
const uint32_t __user *regs)
|
||||
const uint32_t __user * regs)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
|
||||
start+count-1 > SAVAGE_TEXBLENDCOLOR_S4) {
|
||||
start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) {
|
||||
DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
|
||||
start, start+count-1);
|
||||
start, start + count - 1);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -171,28 +174,30 @@ static int savage_verify_state_s4(drm_savage_private_t *dev_priv,
|
|||
~SAVAGE_SCISSOR_MASK_S4);
|
||||
|
||||
/* if any texture regs were changed ... */
|
||||
if (start <= SAVAGE_TEXDESCR_S4 &&
|
||||
start+count > SAVAGE_TEXPALADDR_S4) {
|
||||
if (start <= SAVAGE_TEXDESCR_S4 && start + count > SAVAGE_TEXPALADDR_S4) {
|
||||
/* ... check texture state */
|
||||
SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
|
||||
SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
|
||||
SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
|
||||
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
|
||||
ret |= savage_verify_texaddr(
|
||||
dev_priv, 0, dev_priv->state.s4.texaddr0);
|
||||
ret |=
|
||||
savage_verify_texaddr(dev_priv, 0,
|
||||
dev_priv->state.s4.texaddr0);
|
||||
if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
|
||||
ret |= savage_verify_texaddr(
|
||||
dev_priv, 1, dev_priv->state.s4.texaddr1);
|
||||
ret |=
|
||||
savage_verify_texaddr(dev_priv, 1,
|
||||
dev_priv->state.s4.texaddr1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef SAVE_STATE
|
||||
#undef SAVE_STATE_MASK
|
||||
|
||||
static int savage_dispatch_state(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const uint32_t __user *regs)
|
||||
static int savage_dispatch_state(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const uint32_t __user * regs)
|
||||
{
|
||||
unsigned int count = cmd_header->state.count;
|
||||
unsigned int start = cmd_header->state.start;
|
||||
|
@ -204,7 +209,7 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
|
|||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (DRM_VERIFYAREA_READ(regs, count*4))
|
||||
if (DRM_VERIFYAREA_READ(regs, count * 4))
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
|
@ -213,14 +218,14 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
|
|||
return ret;
|
||||
/* scissor regs are emitted in savage_dispatch_draw */
|
||||
if (start < SAVAGE_SCSTART_S3D) {
|
||||
if (start+count > SAVAGE_SCEND_S3D+1)
|
||||
count2 = count - (SAVAGE_SCEND_S3D+1 - start);
|
||||
if (start+count > SAVAGE_SCSTART_S3D)
|
||||
if (start + count > SAVAGE_SCEND_S3D + 1)
|
||||
count2 = count - (SAVAGE_SCEND_S3D + 1 - start);
|
||||
if (start + count > SAVAGE_SCSTART_S3D)
|
||||
count = SAVAGE_SCSTART_S3D - start;
|
||||
} else if (start <= SAVAGE_SCEND_S3D) {
|
||||
if (start+count > SAVAGE_SCEND_S3D+1) {
|
||||
count -= SAVAGE_SCEND_S3D+1 - start;
|
||||
start = SAVAGE_SCEND_S3D+1;
|
||||
if (start + count > SAVAGE_SCEND_S3D + 1) {
|
||||
count -= SAVAGE_SCEND_S3D + 1 - start;
|
||||
start = SAVAGE_SCEND_S3D + 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
@ -230,23 +235,24 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
|
|||
return ret;
|
||||
/* scissor regs are emitted in savage_dispatch_draw */
|
||||
if (start < SAVAGE_DRAWCTRL0_S4) {
|
||||
if (start+count > SAVAGE_DRAWCTRL1_S4+1)
|
||||
count2 = count - (SAVAGE_DRAWCTRL1_S4+1 - start);
|
||||
if (start+count > SAVAGE_DRAWCTRL0_S4)
|
||||
if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
|
||||
count2 =
|
||||
count - (SAVAGE_DRAWCTRL1_S4 + 1 - start);
|
||||
if (start + count > SAVAGE_DRAWCTRL0_S4)
|
||||
count = SAVAGE_DRAWCTRL0_S4 - start;
|
||||
} else if (start <= SAVAGE_DRAWCTRL1_S4) {
|
||||
if (start+count > SAVAGE_DRAWCTRL1_S4+1) {
|
||||
count -= SAVAGE_DRAWCTRL1_S4+1 - start;
|
||||
start = SAVAGE_DRAWCTRL1_S4+1;
|
||||
if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) {
|
||||
count -= SAVAGE_DRAWCTRL1_S4 + 1 - start;
|
||||
start = SAVAGE_DRAWCTRL1_S4 + 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bci_size = count + (count+254)/255 + count2 + (count2+254)/255;
|
||||
bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255;
|
||||
|
||||
if (cmd_header->state.global) {
|
||||
BEGIN_DMA(bci_size+1);
|
||||
BEGIN_DMA(bci_size + 1);
|
||||
DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
|
||||
dev_priv->waiting = 1;
|
||||
} else {
|
||||
|
@ -273,9 +279,9 @@ static int savage_dispatch_state(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const drm_buf_t *dmabuf)
|
||||
static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const drm_buf_t * dmabuf)
|
||||
{
|
||||
unsigned char reorder = 0;
|
||||
unsigned int prim = cmd_header->prim.prim;
|
||||
|
@ -286,8 +292,8 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
BCI_LOCALS;
|
||||
|
||||
if (!dmabuf) {
|
||||
DRM_ERROR("called without dma buffers!\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
DRM_ERROR("called without dma buffers!\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (!n)
|
||||
|
@ -307,8 +313,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
case SAVAGE_PRIM_TRISTRIP:
|
||||
case SAVAGE_PRIM_TRIFAN:
|
||||
if (n < 3) {
|
||||
DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
DRM_ERROR
|
||||
("wrong number of vertices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
@ -319,17 +326,15 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
|
||||
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
if (skip != 0) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
|
||||
skip);
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
|
||||
(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
|
||||
(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
|
||||
(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
|
||||
(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
|
||||
if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
|
||||
skip);
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (reorder) {
|
||||
|
@ -338,9 +343,9 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
}
|
||||
}
|
||||
|
||||
if (start + n > dmabuf->total/32) {
|
||||
if (start + n > dmabuf->total / 32) {
|
||||
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
|
||||
start, start + n - 1, dmabuf->total/32);
|
||||
start, start + n - 1, dmabuf->total / 32);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -375,32 +380,33 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
/* Need to reorder indices for correct flat
|
||||
* shading while preserving the clock sense
|
||||
* for correct culling. Only on Savage3D. */
|
||||
int reorder[3] = {-1, -1, -1};
|
||||
reorder[start%3] = 2;
|
||||
int reorder[3] = { -1, -1, -1 };
|
||||
reorder[start % 3] = 2;
|
||||
|
||||
BEGIN_BCI((count+1+1)/2);
|
||||
BCI_DRAW_INDICES_S3D(count, prim, start+2);
|
||||
BEGIN_BCI((count + 1 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S3D(count, prim, start + 2);
|
||||
|
||||
for (i = start+1; i+1 < start+count; i += 2)
|
||||
for (i = start + 1; i + 1 < start + count; i += 2)
|
||||
BCI_WRITE((i + reorder[i % 3]) |
|
||||
((i+1 + reorder[(i+1) % 3]) << 16));
|
||||
if (i < start+count)
|
||||
BCI_WRITE(i + reorder[i%3]);
|
||||
((i + 1 +
|
||||
reorder[(i + 1) % 3]) << 16));
|
||||
if (i < start + count)
|
||||
BCI_WRITE(i + reorder[i % 3]);
|
||||
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
BEGIN_BCI((count+1+1)/2);
|
||||
BEGIN_BCI((count + 1 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S3D(count, prim, start);
|
||||
|
||||
for (i = start+1; i+1 < start+count; i += 2)
|
||||
BCI_WRITE(i | ((i+1) << 16));
|
||||
if (i < start+count)
|
||||
for (i = start + 1; i + 1 < start + count; i += 2)
|
||||
BCI_WRITE(i | ((i + 1) << 16));
|
||||
if (i < start + count)
|
||||
BCI_WRITE(i);
|
||||
} else {
|
||||
BEGIN_BCI((count+2+1)/2);
|
||||
BEGIN_BCI((count + 2 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S4(count, prim, skip);
|
||||
|
||||
for (i = start; i+1 < start+count; i += 2)
|
||||
BCI_WRITE(i | ((i+1) << 16));
|
||||
if (i < start+count)
|
||||
for (i = start; i + 1 < start + count; i += 2)
|
||||
BCI_WRITE(i | ((i + 1) << 16));
|
||||
if (i < start + count)
|
||||
BCI_WRITE(i);
|
||||
}
|
||||
|
||||
|
@ -413,11 +419,10 @@ static int savage_dispatch_dma_prim(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const uint32_t __user *vtxbuf,
|
||||
unsigned int vb_size,
|
||||
unsigned int vb_stride)
|
||||
static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const uint32_t __user * vtxbuf,
|
||||
unsigned int vb_size, unsigned int vb_stride)
|
||||
{
|
||||
unsigned char reorder = 0;
|
||||
unsigned int prim = cmd_header->prim.prim;
|
||||
|
@ -445,8 +450,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
|||
case SAVAGE_PRIM_TRISTRIP:
|
||||
case SAVAGE_PRIM_TRIFAN:
|
||||
if (n < 3) {
|
||||
DRM_ERROR("wrong number of vertices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
DRM_ERROR
|
||||
("wrong number of vertices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
@ -460,18 +466,18 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
|||
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
vtx_size = 8; /* full vertex */
|
||||
vtx_size = 8; /* full vertex */
|
||||
} else {
|
||||
if (skip > SAVAGE_SKIP_ALL_S4) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
vtx_size = 10; /* full vertex */
|
||||
vtx_size = 10; /* full vertex */
|
||||
}
|
||||
|
||||
vtx_size -= (skip & 1) + (skip >> 1 & 1) +
|
||||
(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
|
||||
(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
|
||||
(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
|
||||
(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
|
||||
|
||||
if (vtx_size > vb_stride) {
|
||||
DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
|
||||
|
@ -479,9 +485,9 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
|||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (start + n > vb_size / (vb_stride*4)) {
|
||||
if (start + n > vb_size / (vb_stride * 4)) {
|
||||
DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
|
||||
start, start + n - 1, vb_size / (vb_stride*4));
|
||||
start, start + n - 1, vb_size / (vb_stride * 4));
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
@ -493,31 +499,31 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
|||
/* Need to reorder vertices for correct flat
|
||||
* shading while preserving the clock sense
|
||||
* for correct culling. Only on Savage3D. */
|
||||
int reorder[3] = {-1, -1, -1};
|
||||
reorder[start%3] = 2;
|
||||
int reorder[3] = { -1, -1, -1 };
|
||||
reorder[start % 3] = 2;
|
||||
|
||||
BEGIN_DMA(count*vtx_size+1);
|
||||
BEGIN_DMA(count * vtx_size + 1);
|
||||
DMA_DRAW_PRIMITIVE(count, prim, skip);
|
||||
|
||||
for (i = start; i < start+count; ++i) {
|
||||
for (i = start; i < start + count; ++i) {
|
||||
unsigned int j = i + reorder[i % 3];
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
|
||||
vtx_size);
|
||||
}
|
||||
|
||||
DMA_COMMIT();
|
||||
} else {
|
||||
BEGIN_DMA(count*vtx_size+1);
|
||||
BEGIN_DMA(count * vtx_size + 1);
|
||||
DMA_DRAW_PRIMITIVE(count, prim, skip);
|
||||
|
||||
if (vb_stride == vtx_size) {
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride*start],
|
||||
vtx_size*count);
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride * start],
|
||||
vtx_size * count);
|
||||
} else {
|
||||
for (i = start; i < start+count; ++i) {
|
||||
DMA_COPY_FROM_USER(
|
||||
&vtxbuf[vb_stride*i],
|
||||
vtx_size);
|
||||
for (i = start; i < start + count; ++i) {
|
||||
DMA_COPY_FROM_USER(&vtxbuf
|
||||
[vb_stride * i],
|
||||
vtx_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,10 +539,10 @@ static int savage_dispatch_vb_prim(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const uint16_t __user *usr_idx,
|
||||
const drm_buf_t *dmabuf)
|
||||
static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const uint16_t __user * usr_idx,
|
||||
const drm_buf_t * dmabuf)
|
||||
{
|
||||
unsigned char reorder = 0;
|
||||
unsigned int prim = cmd_header->idx.prim;
|
||||
|
@ -546,8 +552,8 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
BCI_LOCALS;
|
||||
|
||||
if (!dmabuf) {
|
||||
DRM_ERROR("called without dma buffers!\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
DRM_ERROR("called without dma buffers!\n");
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (!n)
|
||||
|
@ -559,16 +565,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
prim = SAVAGE_PRIM_TRILIST;
|
||||
case SAVAGE_PRIM_TRILIST:
|
||||
if (n % 3 != 0) {
|
||||
DRM_ERROR("wrong number of indices %u in TRILIST\n",
|
||||
n);
|
||||
DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
case SAVAGE_PRIM_TRISTRIP:
|
||||
case SAVAGE_PRIM_TRIFAN:
|
||||
if (n < 3) {
|
||||
DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
DRM_ERROR
|
||||
("wrong number of indices %u in TRIFAN/STRIP\n", n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
@ -579,17 +584,15 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
|
||||
if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
if (skip != 0) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
|
||||
skip);
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
|
||||
(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
|
||||
(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
|
||||
(skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
|
||||
(skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
|
||||
if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n",
|
||||
skip);
|
||||
DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
if (reorder) {
|
||||
|
@ -629,11 +632,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
uint16_t idx[255];
|
||||
|
||||
/* Copy and check indices */
|
||||
DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
|
||||
DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (idx[i] > dmabuf->total/32) {
|
||||
if (idx[i] > dmabuf->total / 32) {
|
||||
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
|
||||
i, idx[i], dmabuf->total/32);
|
||||
i, idx[i], dmabuf->total / 32);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -642,30 +645,31 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
/* Need to reorder indices for correct flat
|
||||
* shading while preserving the clock sense
|
||||
* for correct culling. Only on Savage3D. */
|
||||
int reorder[3] = {2, -1, -1};
|
||||
int reorder[3] = { 2, -1, -1 };
|
||||
|
||||
BEGIN_BCI((count+1+1)/2);
|
||||
BEGIN_BCI((count + 1 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
|
||||
|
||||
for (i = 1; i+1 < count; i += 2)
|
||||
for (i = 1; i + 1 < count; i += 2)
|
||||
BCI_WRITE(idx[i + reorder[i % 3]] |
|
||||
(idx[i+1 + reorder[(i+1) % 3]] << 16));
|
||||
(idx[i + 1 + reorder[(i + 1) % 3]] <<
|
||||
16));
|
||||
if (i < count)
|
||||
BCI_WRITE(idx[i + reorder[i%3]]);
|
||||
BCI_WRITE(idx[i + reorder[i % 3]]);
|
||||
} else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
|
||||
BEGIN_BCI((count+1+1)/2);
|
||||
BEGIN_BCI((count + 1 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
|
||||
|
||||
for (i = 1; i+1 < count; i += 2)
|
||||
BCI_WRITE(idx[i] | (idx[i+1] << 16));
|
||||
for (i = 1; i + 1 < count; i += 2)
|
||||
BCI_WRITE(idx[i] | (idx[i + 1] << 16));
|
||||
if (i < count)
|
||||
BCI_WRITE(idx[i]);
|
||||
} else {
|
||||
BEGIN_BCI((count+2+1)/2);
|
||||
BEGIN_BCI((count + 2 + 1) / 2);
|
||||
BCI_DRAW_INDICES_S4(count, prim, skip);
|
||||
|
||||
for (i = 0; i+1 < count; i += 2)
|
||||
BCI_WRITE(idx[i] | (idx[i+1] << 16));
|
||||
for (i = 0; i + 1 < count; i += 2)
|
||||
BCI_WRITE(idx[i] | (idx[i + 1] << 16));
|
||||
if (i < count)
|
||||
BCI_WRITE(idx[i]);
|
||||
}
|
||||
|
@ -679,12 +683,11 @@ static int savage_dispatch_dma_idx(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const uint16_t __user *usr_idx,
|
||||
const uint32_t __user *vtxbuf,
|
||||
unsigned int vb_size,
|
||||
unsigned int vb_stride)
|
||||
static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const uint16_t __user * usr_idx,
|
||||
const uint32_t __user * vtxbuf,
|
||||
unsigned int vb_size, unsigned int vb_stride)
|
||||
{
|
||||
unsigned char reorder = 0;
|
||||
unsigned int prim = cmd_header->idx.prim;
|
||||
|
@ -703,16 +706,15 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
|||
prim = SAVAGE_PRIM_TRILIST;
|
||||
case SAVAGE_PRIM_TRILIST:
|
||||
if (n % 3 != 0) {
|
||||
DRM_ERROR("wrong number of indices %u in TRILIST\n",
|
||||
n);
|
||||
DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
case SAVAGE_PRIM_TRISTRIP:
|
||||
case SAVAGE_PRIM_TRIFAN:
|
||||
if (n < 3) {
|
||||
DRM_ERROR("wrong number of indices %u in TRIFAN/STRIP\n",
|
||||
n);
|
||||
DRM_ERROR
|
||||
("wrong number of indices %u in TRIFAN/STRIP\n", n);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
break;
|
||||
|
@ -726,18 +728,18 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
|||
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
vtx_size = 8; /* full vertex */
|
||||
vtx_size = 8; /* full vertex */
|
||||
} else {
|
||||
if (skip > SAVAGE_SKIP_ALL_S4) {
|
||||
DRM_ERROR("invalid skip flags 0x%04x\n", skip);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
vtx_size = 10; /* full vertex */
|
||||
vtx_size = 10; /* full vertex */
|
||||
}
|
||||
|
||||
vtx_size -= (skip & 1) + (skip >> 1 & 1) +
|
||||
(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
|
||||
(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
|
||||
(skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
|
||||
(skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
|
||||
|
||||
if (vtx_size > vb_stride) {
|
||||
DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
|
||||
|
@ -753,11 +755,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
|||
uint16_t idx[255];
|
||||
|
||||
/* Copy and check indices */
|
||||
DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count*2);
|
||||
DRM_COPY_FROM_USER_UNCHECKED(idx, usr_idx, count * 2);
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (idx[i] > vb_size / (vb_stride*4)) {
|
||||
if (idx[i] > vb_size / (vb_stride * 4)) {
|
||||
DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
|
||||
i, idx[i], vb_size / (vb_stride*4));
|
||||
i, idx[i], vb_size / (vb_stride * 4));
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -766,25 +768,25 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
|||
/* Need to reorder vertices for correct flat
|
||||
* shading while preserving the clock sense
|
||||
* for correct culling. Only on Savage3D. */
|
||||
int reorder[3] = {2, -1, -1};
|
||||
int reorder[3] = { 2, -1, -1 };
|
||||
|
||||
BEGIN_DMA(count*vtx_size+1);
|
||||
BEGIN_DMA(count * vtx_size + 1);
|
||||
DMA_DRAW_PRIMITIVE(count, prim, skip);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
unsigned int j = idx[i + reorder[i % 3]];
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
|
||||
vtx_size);
|
||||
}
|
||||
|
||||
DMA_COMMIT();
|
||||
} else {
|
||||
BEGIN_DMA(count*vtx_size+1);
|
||||
BEGIN_DMA(count * vtx_size + 1);
|
||||
DMA_DRAW_PRIMITIVE(count, prim, skip);
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
unsigned int j = idx[i];
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride*j],
|
||||
DMA_COPY_FROM_USER(&vtxbuf[vb_stride * j],
|
||||
vtx_size);
|
||||
}
|
||||
|
||||
|
@ -800,11 +802,11 @@ static int savage_dispatch_vb_idx(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t *cmd_header,
|
||||
const drm_savage_cmd_header_t __user *data,
|
||||
static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t * cmd_header,
|
||||
const drm_savage_cmd_header_t __user * data,
|
||||
unsigned int nbox,
|
||||
const drm_clip_rect_t __user *usr_boxes)
|
||||
const drm_clip_rect_t __user * usr_boxes)
|
||||
{
|
||||
unsigned int flags = cmd_header->clear0.flags, mask, value;
|
||||
unsigned int clear_cmd;
|
||||
|
@ -814,18 +816,15 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
|
|||
if (nbox == 0)
|
||||
return 0;
|
||||
|
||||
DRM_GET_USER_UNCHECKED(mask, &((const drm_savage_cmd_header_t*)data)
|
||||
->clear1.mask);
|
||||
DRM_GET_USER_UNCHECKED(value, &((const drm_savage_cmd_header_t*)data)
|
||||
->clear1.value);
|
||||
DRM_GET_USER_UNCHECKED(mask, &data->clear1.mask);
|
||||
DRM_GET_USER_UNCHECKED(value, &data->clear1.value);
|
||||
|
||||
clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
|
||||
BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
|
||||
BCI_CMD_SET_ROP(clear_cmd,0xCC);
|
||||
BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
|
||||
BCI_CMD_SET_ROP(clear_cmd, 0xCC);
|
||||
|
||||
nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +
|
||||
((flags & SAVAGE_BACK) ? 1 : 0) +
|
||||
((flags & SAVAGE_DEPTH) ? 1 : 0);
|
||||
((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0);
|
||||
if (nbufs == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -844,12 +843,12 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
|
|||
x = box.x1, y = box.y1;
|
||||
w = box.x2 - box.x1;
|
||||
h = box.y2 - box.y1;
|
||||
BEGIN_DMA(nbufs*6);
|
||||
BEGIN_DMA(nbufs * 6);
|
||||
for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
|
||||
if (!(flags & buf))
|
||||
continue;
|
||||
DMA_WRITE(clear_cmd);
|
||||
switch(buf) {
|
||||
switch (buf) {
|
||||
case SAVAGE_FRONT:
|
||||
DMA_WRITE(dev_priv->front_offset);
|
||||
DMA_WRITE(dev_priv->front_bd);
|
||||
|
@ -880,9 +879,9 @@ static int savage_dispatch_clear(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
|
||||
static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
|
||||
unsigned int nbox,
|
||||
const drm_clip_rect_t __user *usr_boxes)
|
||||
const drm_clip_rect_t __user * usr_boxes)
|
||||
{
|
||||
unsigned int swap_cmd;
|
||||
unsigned int i;
|
||||
|
@ -892,8 +891,8 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
|
|||
return 0;
|
||||
|
||||
swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
|
||||
BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
|
||||
BCI_CMD_SET_ROP(swap_cmd,0xCC);
|
||||
BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
|
||||
BCI_CMD_SET_ROP(swap_cmd, 0xCC);
|
||||
|
||||
for (i = 0; i < nbox; ++i) {
|
||||
drm_clip_rect_t box;
|
||||
|
@ -905,21 +904,21 @@ static int savage_dispatch_swap(drm_savage_private_t *dev_priv,
|
|||
DMA_WRITE(dev_priv->back_bd);
|
||||
DMA_WRITE(BCI_X_Y(box.x1, box.y1));
|
||||
DMA_WRITE(BCI_X_Y(box.x1, box.y1));
|
||||
DMA_WRITE(BCI_W_H(box.x2-box.x1, box.y2-box.y1));
|
||||
DMA_WRITE(BCI_W_H(box.x2 - box.x1, box.y2 - box.y1));
|
||||
DMA_COMMIT();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
|
||||
const drm_savage_cmd_header_t __user *start,
|
||||
const drm_savage_cmd_header_t __user *end,
|
||||
const drm_buf_t *dmabuf,
|
||||
const unsigned int __user *usr_vtxbuf,
|
||||
static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
|
||||
const drm_savage_cmd_header_t __user * start,
|
||||
const drm_savage_cmd_header_t __user * end,
|
||||
const drm_buf_t * dmabuf,
|
||||
const unsigned int __user * usr_vtxbuf,
|
||||
unsigned int vb_size, unsigned int vb_stride,
|
||||
unsigned int nbox,
|
||||
const drm_clip_rect_t __user *usr_boxes)
|
||||
const drm_clip_rect_t __user * usr_boxes)
|
||||
{
|
||||
unsigned int i, j;
|
||||
int ret;
|
||||
|
@ -938,32 +937,42 @@ static int savage_dispatch_draw(drm_savage_private_t *dev_priv,
|
|||
usr_cmdbuf++;
|
||||
switch (cmd_header.cmd.cmd) {
|
||||
case SAVAGE_CMD_DMA_PRIM:
|
||||
ret = savage_dispatch_dma_prim(
|
||||
dev_priv, &cmd_header, dmabuf);
|
||||
ret =
|
||||
savage_dispatch_dma_prim(dev_priv,
|
||||
&cmd_header,
|
||||
dmabuf);
|
||||
break;
|
||||
case SAVAGE_CMD_VB_PRIM:
|
||||
ret = savage_dispatch_vb_prim(
|
||||
dev_priv, &cmd_header,
|
||||
(const uint32_t __user *)usr_vtxbuf,
|
||||
vb_size, vb_stride);
|
||||
ret =
|
||||
savage_dispatch_vb_prim(dev_priv,
|
||||
&cmd_header,
|
||||
(const uint32_t
|
||||
__user *)
|
||||
usr_vtxbuf, vb_size,
|
||||
vb_stride);
|
||||
break;
|
||||
case SAVAGE_CMD_DMA_IDX:
|
||||
j = (cmd_header.idx.count + 3) / 4;
|
||||
/* j was check in savage_bci_cmdbuf */
|
||||
ret = savage_dispatch_dma_idx(
|
||||
dev_priv, &cmd_header,
|
||||
(const uint16_t __user *)usr_cmdbuf,
|
||||
dmabuf);
|
||||
ret =
|
||||
savage_dispatch_dma_idx(dev_priv,
|
||||
&cmd_header,
|
||||
(const uint16_t
|
||||
__user *)
|
||||
usr_cmdbuf, dmabuf);
|
||||
usr_cmdbuf += j;
|
||||
break;
|
||||
case SAVAGE_CMD_VB_IDX:
|
||||
j = (cmd_header.idx.count + 3) / 4;
|
||||
/* j was check in savage_bci_cmdbuf */
|
||||
ret = savage_dispatch_vb_idx(
|
||||
dev_priv, &cmd_header,
|
||||
(const uint16_t __user *)usr_cmdbuf,
|
||||
(const uint32_t __user *)usr_vtxbuf,
|
||||
vb_size, vb_stride);
|
||||
ret =
|
||||
savage_dispatch_vb_idx(dev_priv,
|
||||
&cmd_header,
|
||||
(const uint16_t
|
||||
__user *)usr_cmdbuf,
|
||||
(const uint32_t
|
||||
__user *)usr_vtxbuf,
|
||||
vb_size, vb_stride);
|
||||
usr_cmdbuf += j;
|
||||
break;
|
||||
default:
|
||||
|
@ -997,16 +1006,17 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
int ret = 0;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *)data,
|
||||
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_savage_cmdbuf_t __user *) data,
|
||||
sizeof(cmdbuf));
|
||||
|
||||
if (dma && dma->buflist) {
|
||||
if (cmdbuf.dma_idx > dma->buf_count) {
|
||||
DRM_ERROR("vertex buffer index %u out of range (0-%u)\n",
|
||||
cmdbuf.dma_idx, dma->buf_count-1);
|
||||
DRM_ERROR
|
||||
("vertex buffer index %u out of range (0-%u)\n",
|
||||
cmdbuf.dma_idx, dma->buf_count - 1);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
dmabuf = dma->buflist[cmdbuf.dma_idx];
|
||||
|
@ -1014,14 +1024,14 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
dmabuf = NULL;
|
||||
}
|
||||
|
||||
usr_cmdbuf = (drm_savage_cmd_header_t __user *)cmdbuf.cmd_addr;
|
||||
usr_cmdbuf = (drm_savage_cmd_header_t __user *) cmdbuf.cmd_addr;
|
||||
usr_vtxbuf = (unsigned int __user *)cmdbuf.vb_addr;
|
||||
usr_boxes = (drm_clip_rect_t __user *)cmdbuf.box_addr;
|
||||
if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size*8)) ||
|
||||
(cmdbuf.vb_size && DRM_VERIFYAREA_READ(
|
||||
usr_vtxbuf, cmdbuf.vb_size)) ||
|
||||
(cmdbuf.nbox && DRM_VERIFYAREA_READ(
|
||||
usr_boxes, cmdbuf.nbox*sizeof(drm_clip_rect_t))))
|
||||
usr_boxes = (drm_clip_rect_t __user *) cmdbuf.box_addr;
|
||||
if ((cmdbuf.size && DRM_VERIFYAREA_READ(usr_cmdbuf, cmdbuf.size * 8)) ||
|
||||
(cmdbuf.vb_size && DRM_VERIFYAREA_READ(usr_vtxbuf, cmdbuf.vb_size))
|
||||
|| (cmdbuf.nbox
|
||||
&& DRM_VERIFYAREA_READ(usr_boxes,
|
||||
cmdbuf.nbox * sizeof(drm_clip_rect_t))))
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
/* Make sure writes to DMA buffers are finished before sending
|
||||
|
@ -1058,17 +1068,21 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
case SAVAGE_CMD_DMA_PRIM:
|
||||
case SAVAGE_CMD_VB_PRIM:
|
||||
if (!first_draw_cmd)
|
||||
first_draw_cmd = usr_cmdbuf-1;
|
||||
first_draw_cmd = usr_cmdbuf - 1;
|
||||
usr_cmdbuf += j;
|
||||
i += j;
|
||||
break;
|
||||
default:
|
||||
if (first_draw_cmd) {
|
||||
ret = savage_dispatch_draw (
|
||||
dev_priv, first_draw_cmd, usr_cmdbuf-1,
|
||||
dmabuf, usr_vtxbuf, cmdbuf.vb_size,
|
||||
cmdbuf.vb_stride,
|
||||
cmdbuf.nbox, usr_boxes);
|
||||
ret =
|
||||
savage_dispatch_draw(dev_priv,
|
||||
first_draw_cmd,
|
||||
usr_cmdbuf - 1, dmabuf,
|
||||
usr_vtxbuf,
|
||||
cmdbuf.vb_size,
|
||||
cmdbuf.vb_stride,
|
||||
cmdbuf.nbox,
|
||||
usr_boxes);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
first_draw_cmd = NULL;
|
||||
|
@ -1086,9 +1100,9 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
DMA_FLUSH();
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
ret = savage_dispatch_state(
|
||||
dev_priv, &cmd_header,
|
||||
(uint32_t __user *)usr_cmdbuf);
|
||||
ret = savage_dispatch_state(dev_priv, &cmd_header,
|
||||
(uint32_t __user *)
|
||||
usr_cmdbuf);
|
||||
usr_cmdbuf += j;
|
||||
i += j;
|
||||
break;
|
||||
|
@ -1122,10 +1136,11 @@ int savage_bci_cmdbuf(DRM_IOCTL_ARGS)
|
|||
}
|
||||
|
||||
if (first_draw_cmd) {
|
||||
ret = savage_dispatch_draw (
|
||||
dev_priv, first_draw_cmd, usr_cmdbuf, dmabuf,
|
||||
usr_vtxbuf, cmdbuf.vb_size, cmdbuf.vb_stride,
|
||||
cmdbuf.nbox, usr_boxes);
|
||||
ret =
|
||||
savage_dispatch_draw(dev_priv, first_draw_cmd, usr_cmdbuf,
|
||||
dmabuf, usr_vtxbuf, cmdbuf.vb_size,
|
||||
cmdbuf.vb_stride, cmdbuf.nbox,
|
||||
usr_boxes);
|
||||
if (ret != 0) {
|
||||
DMA_FLUSH();
|
||||
return ret;
|
||||
|
|
|
@ -39,4 +39,4 @@ typedef struct {
|
|||
unsigned int offset, size;
|
||||
} drm_sis_fb_t;
|
||||
|
||||
#endif /* __SIS_DRM_H__ */
|
||||
#endif /* __SIS_DRM_H__ */
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -31,31 +31,29 @@
|
|||
#include "sis_drv.h"
|
||||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -63,9 +61,6 @@ static struct pci_device_id pciidlist[] = {
|
|||
sisdrv_PCI_IDS
|
||||
};
|
||||
|
||||
extern drm_ioctl_desc_t sis_ioctls[];
|
||||
extern int sis_max_ioctl;
|
||||
|
||||
static struct drm_driver driver = {
|
||||
.driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
|
||||
.context_ctor = sis_init_context,
|
||||
|
@ -77,18 +72,18 @@ static struct drm_driver driver = {
|
|||
.version = version,
|
||||
.ioctls = sis_ioctls,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init sis_init(void)
|
||||
|
@ -105,6 +100,6 @@ static void __exit sis_exit(void)
|
|||
module_init(sis_init);
|
||||
module_exit(sis_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -22,7 +22,7 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SIS_DRV_H_
|
||||
|
@ -46,7 +46,10 @@ typedef struct drm_sis_private {
|
|||
memHeap_t *FBHeap;
|
||||
} drm_sis_private_t;
|
||||
|
||||
extern int sis_init_context(drm_device_t *dev, int context);
|
||||
extern int sis_final_context(drm_device_t *dev, int context);
|
||||
extern int sis_init_context(drm_device_t * dev, int context);
|
||||
extern int sis_final_context(drm_device_t * dev, int context);
|
||||
|
||||
extern drm_ioctl_desc_t sis_ioctls[];
|
||||
extern int sis_max_ioctl;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -22,10 +22,10 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Sung-Ching Lin <sclin@sis.com.tw>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
@ -41,13 +41,13 @@ set_t *setInit(void)
|
|||
int i;
|
||||
set_t *set;
|
||||
|
||||
set = (set_t *)drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
|
||||
set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
|
||||
if (set != NULL) {
|
||||
for (i = 0; i < SET_SIZE; i++) {
|
||||
set->list[i].free_next = i + 1;
|
||||
set->list[i].free_next = i + 1;
|
||||
set->list[i].alloc_next = -1;
|
||||
}
|
||||
set->list[SET_SIZE-1].free_next = -1;
|
||||
set->list[SET_SIZE - 1].free_next = -1;
|
||||
set->free = 0;
|
||||
set->alloc = -1;
|
||||
set->trace = -1;
|
||||
|
@ -55,10 +55,10 @@ set_t *setInit(void)
|
|||
return set;
|
||||
}
|
||||
|
||||
int setAdd(set_t *set, ITEM_TYPE item)
|
||||
int setAdd(set_t * set, ITEM_TYPE item)
|
||||
{
|
||||
int free = set->free;
|
||||
|
||||
|
||||
if (free != -1) {
|
||||
set->list[free].val = item;
|
||||
set->free = set->list[free].free_next;
|
||||
|
@ -67,16 +67,16 @@ int setAdd(set_t *set, ITEM_TYPE item)
|
|||
}
|
||||
|
||||
set->list[free].alloc_next = set->alloc;
|
||||
set->alloc = free;
|
||||
set->list[free].free_next = -1;
|
||||
set->alloc = free;
|
||||
set->list[free].free_next = -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int setDel(set_t *set, ITEM_TYPE item)
|
||||
int setDel(set_t * set, ITEM_TYPE item)
|
||||
{
|
||||
int alloc = set->alloc;
|
||||
int prev = -1;
|
||||
int prev = -1;
|
||||
|
||||
while (alloc != -1) {
|
||||
if (set->list[alloc].val == item) {
|
||||
|
@ -103,7 +103,7 @@ int setDel(set_t *set, ITEM_TYPE item)
|
|||
|
||||
/* setFirst -> setAdd -> setNext is wrong */
|
||||
|
||||
int setFirst(set_t *set, ITEM_TYPE *item)
|
||||
int setFirst(set_t * set, ITEM_TYPE * item)
|
||||
{
|
||||
if (set->alloc == -1)
|
||||
return 0;
|
||||
|
@ -114,7 +114,7 @@ int setFirst(set_t *set, ITEM_TYPE *item)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int setNext(set_t *set, ITEM_TYPE *item)
|
||||
int setNext(set_t * set, ITEM_TYPE * item)
|
||||
{
|
||||
if (set->trace == -1)
|
||||
return 0;
|
||||
|
@ -125,7 +125,7 @@ int setNext(set_t *set, ITEM_TYPE *item)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int setDestroy(set_t *set)
|
||||
int setDestroy(set_t * set)
|
||||
{
|
||||
drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
|
||||
|
||||
|
@ -149,35 +149,34 @@ int setDestroy(set_t *set)
|
|||
* 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
|
||||
* WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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
|
||||
* WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define ISFREE(bptr) ((bptr)->free)
|
||||
|
||||
memHeap_t *mmInit(int ofs,
|
||||
int size)
|
||||
memHeap_t *mmInit(int ofs, int size)
|
||||
{
|
||||
PMemBlock blocks;
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
blocks = (TMemBlock *)drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
|
||||
blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
|
||||
if (blocks != NULL) {
|
||||
blocks->ofs = ofs;
|
||||
blocks->size = size;
|
||||
blocks->free = 1;
|
||||
return (memHeap_t *)blocks;
|
||||
return (memHeap_t *) blocks;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Checks if a pointer 'b' is part of the heap 'heap' */
|
||||
int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
|
||||
int mmBlockInHeap(memHeap_t * heap, PMemBlock b)
|
||||
{
|
||||
TMemBlock *p;
|
||||
|
||||
|
@ -194,16 +193,16 @@ int mmBlockInHeap(memHeap_t *heap, PMemBlock b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static TMemBlock* SliceBlock(TMemBlock *p,
|
||||
int startofs, int size,
|
||||
static TMemBlock *SliceBlock(TMemBlock * p,
|
||||
int startofs, int size,
|
||||
int reserved, int alignment)
|
||||
{
|
||||
TMemBlock *newblock;
|
||||
|
||||
/* break left */
|
||||
if (startofs > p->ofs) {
|
||||
newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
|
||||
DRM_MEM_DRIVER);
|
||||
newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
|
||||
DRM_MEM_DRIVER);
|
||||
newblock->ofs = startofs;
|
||||
newblock->size = p->size - (startofs - p->ofs);
|
||||
newblock->free = 1;
|
||||
|
@ -215,8 +214,8 @@ static TMemBlock* SliceBlock(TMemBlock *p,
|
|||
|
||||
/* break right */
|
||||
if (size < p->size) {
|
||||
newblock = (TMemBlock*) drm_calloc(1, sizeof(TMemBlock),
|
||||
DRM_MEM_DRIVER);
|
||||
newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
|
||||
DRM_MEM_DRIVER);
|
||||
newblock->ofs = startofs + size;
|
||||
newblock->size = p->size - size;
|
||||
newblock->free = 1;
|
||||
|
@ -232,37 +231,37 @@ static TMemBlock* SliceBlock(TMemBlock *p,
|
|||
return p;
|
||||
}
|
||||
|
||||
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch)
|
||||
PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
|
||||
{
|
||||
int mask,startofs, endofs;
|
||||
int mask, startofs, endofs;
|
||||
TMemBlock *p;
|
||||
|
||||
|
||||
if (heap == NULL || align2 < 0 || size <= 0)
|
||||
return NULL;
|
||||
|
||||
mask = (1 << align2)-1;
|
||||
mask = (1 << align2) - 1;
|
||||
startofs = 0;
|
||||
p = (TMemBlock *)heap;
|
||||
p = (TMemBlock *) heap;
|
||||
while (p != NULL) {
|
||||
if (ISFREE(p)) {
|
||||
startofs = (p->ofs + mask) & ~mask;
|
||||
if ( startofs < startSearch ) {
|
||||
if (startofs < startSearch) {
|
||||
startofs = startSearch;
|
||||
}
|
||||
endofs = startofs+size;
|
||||
if (endofs <= (p->ofs+p->size))
|
||||
endofs = startofs + size;
|
||||
if (endofs <= (p->ofs + p->size))
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
p = SliceBlock(p,startofs,size,0,mask+1);
|
||||
p = SliceBlock(p, startofs, size, 0, mask + 1);
|
||||
p->heap = heap;
|
||||
return p;
|
||||
}
|
||||
|
||||
static __inline__ int Join2Blocks(TMemBlock *p)
|
||||
static __inline__ int Join2Blocks(TMemBlock * p)
|
||||
{
|
||||
if (p->free && p->next && p->next->free) {
|
||||
TMemBlock *q = p->next;
|
||||
|
@ -295,7 +294,6 @@ int mmFreeMem(PMemBlock b)
|
|||
p->free = 1;
|
||||
Join2Blocks(p);
|
||||
if (prev)
|
||||
Join2Blocks(prev);
|
||||
Join2Blocks(prev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -22,10 +22,10 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Sung-Ching Lin <sclin@sis.com.tw>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SIS_DS_H__
|
||||
|
@ -50,11 +50,11 @@ typedef struct {
|
|||
} set_t;
|
||||
|
||||
set_t *setInit(void);
|
||||
int setAdd(set_t *set, ITEM_TYPE item);
|
||||
int setDel(set_t *set, ITEM_TYPE item);
|
||||
int setFirst(set_t *set, ITEM_TYPE *item);
|
||||
int setNext(set_t *set, ITEM_TYPE *item);
|
||||
int setDestroy(set_t *set);
|
||||
int setAdd(set_t * set, ITEM_TYPE item);
|
||||
int setDel(set_t * set, ITEM_TYPE item);
|
||||
int setFirst(set_t * set, ITEM_TYPE * item);
|
||||
int setNext(set_t * set, ITEM_TYPE * item);
|
||||
int setDestroy(set_t * set);
|
||||
|
||||
/*
|
||||
* GLX Hardware Device Driver common code
|
||||
|
@ -73,9 +73,9 @@ int setDestroy(set_t *set);
|
|||
* 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
|
||||
* WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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
|
||||
* WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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.
|
||||
*
|
||||
*/
|
||||
|
@ -83,7 +83,7 @@ int setDestroy(set_t *set);
|
|||
struct mem_block_t {
|
||||
struct mem_block_t *next;
|
||||
struct mem_block_t *heap;
|
||||
int ofs,size;
|
||||
int ofs, size;
|
||||
int align;
|
||||
unsigned int free:1;
|
||||
unsigned int reserved:1;
|
||||
|
@ -109,11 +109,11 @@ static __inline__ void mmMarkReserved(PMemBlock b)
|
|||
b->reserved = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* input: total size in bytes
|
||||
* return: a heap pointer if OK, NULL if error
|
||||
*/
|
||||
memHeap_t *mmInit( int ofs, int size );
|
||||
memHeap_t *mmInit(int ofs, int size);
|
||||
|
||||
/*
|
||||
* Allocate 'size' bytes with 2^align2 bytes alignment,
|
||||
|
@ -125,21 +125,21 @@ memHeap_t *mmInit( int ofs, int size );
|
|||
* startSearch = linear offset from start of heap to begin search
|
||||
* return: pointer to the allocated block, 0 if error
|
||||
*/
|
||||
PMemBlock mmAllocMem( memHeap_t *heap, int size, int align2, int startSearch );
|
||||
PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch);
|
||||
|
||||
/*
|
||||
* Returns 1 if the block 'b' is part of the heap 'heap'
|
||||
*/
|
||||
int mmBlockInHeap( PMemBlock heap, PMemBlock b );
|
||||
int mmBlockInHeap(PMemBlock heap, PMemBlock b);
|
||||
|
||||
/*
|
||||
* Free block starts at offset
|
||||
* input: pointer to a block
|
||||
* return: 0 if OK, -1 if error
|
||||
*/
|
||||
int mmFreeMem( PMemBlock b );
|
||||
int mmFreeMem(PMemBlock b);
|
||||
|
||||
/* For debuging purpose. */
|
||||
void mmDumpMemInfo( memHeap_t *mmInit );
|
||||
void mmDumpMemInfo(memHeap_t * mmInit);
|
||||
|
||||
#endif /* __SIS_DS_H__ */
|
||||
#endif /* __SIS_DS_H__ */
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
|
@ -22,10 +22,10 @@
|
|||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* Authors:
|
||||
* Sung-Ching Lin <sclin@sis.com.tw>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
@ -37,25 +37,23 @@
|
|||
#endif
|
||||
|
||||
#define MAX_CONTEXT 100
|
||||
#define VIDEO_TYPE 0
|
||||
#define VIDEO_TYPE 0
|
||||
#define AGP_TYPE 1
|
||||
|
||||
typedef struct {
|
||||
int used;
|
||||
int context;
|
||||
set_t *sets[2]; /* 0 for video, 1 for AGP */
|
||||
set_t *sets[2]; /* 0 for video, 1 for AGP */
|
||||
} sis_context_t;
|
||||
|
||||
static sis_context_t global_ppriv[MAX_CONTEXT];
|
||||
|
||||
|
||||
static int add_alloc_set(int context, int type, unsigned int val)
|
||||
{
|
||||
int i, retval = 0;
|
||||
|
||||
|
||||
for (i = 0; i < MAX_CONTEXT; i++) {
|
||||
if (global_ppriv[i].used && global_ppriv[i].context == context)
|
||||
{
|
||||
if (global_ppriv[i].used && global_ppriv[i].context == context) {
|
||||
retval = setAdd(global_ppriv[i].sets[type], val);
|
||||
break;
|
||||
}
|
||||
|
@ -64,12 +62,11 @@ static int add_alloc_set(int context, int type, unsigned int val)
|
|||
}
|
||||
|
||||
static int del_alloc_set(int context, int type, unsigned int val)
|
||||
{
|
||||
{
|
||||
int i, retval = 0;
|
||||
|
||||
for (i = 0; i < MAX_CONTEXT; i++) {
|
||||
if (global_ppriv[i].used && global_ppriv[i].context == context)
|
||||
{
|
||||
if (global_ppriv[i].used && global_ppriv[i].context == context) {
|
||||
retval = setDel(global_ppriv[i].sets[type], val);
|
||||
break;
|
||||
}
|
||||
|
@ -77,15 +74,15 @@ static int del_alloc_set(int context, int type, unsigned int val)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* fb management via fb device */
|
||||
/* fb management via fb device */
|
||||
#if defined(__linux__) && defined(CONFIG_FB_SIS)
|
||||
|
||||
static int sis_fb_init( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_init(DRM_IOCTL_ARGS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_alloc(DRM_IOCTL_ARGS)
|
||||
{
|
||||
drm_sis_mem_t fb;
|
||||
struct sis_memreq req;
|
||||
|
@ -105,7 +102,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
|||
sis_free(req.offset);
|
||||
retval = DRM_ERR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
fb.offset = 0;
|
||||
fb.size = 0;
|
||||
fb.free = 0;
|
||||
|
@ -118,19 +115,19 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int sis_fb_free( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_free(DRM_IOCTL_ARGS)
|
||||
{
|
||||
drm_sis_mem_t fb;
|
||||
int retval = 0;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
|
||||
|
||||
if (!fb.free)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
|
||||
retval = DRM_ERR(EINVAL);
|
||||
sis_free((u32)fb.free);
|
||||
sis_free((u32) fb.free);
|
||||
|
||||
DRM_DEBUG("free fb, offset = %lu\n", fb.free);
|
||||
|
||||
|
@ -149,17 +146,17 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
|
|||
* X driver/sisfb HW- Command-
|
||||
* framebuffer memory DRI heap Cursor queue
|
||||
*/
|
||||
static int sis_fb_init( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_init(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
drm_sis_fb_t fb;
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *)data, sizeof(fb));
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t __user *) data, sizeof(fb));
|
||||
|
||||
if (dev_priv == NULL) {
|
||||
dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
DRM_MEM_DRIVER);
|
||||
dev_priv = dev->dev_private;
|
||||
if (dev_priv == NULL)
|
||||
return ENOMEM;
|
||||
|
@ -175,7 +172,7 @@ static int sis_fb_init( DRM_IOCTL_ARGS )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_alloc(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -186,9 +183,9 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
|||
|
||||
if (dev_priv == NULL || dev_priv->FBHeap == NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, argp, sizeof(fb));
|
||||
|
||||
|
||||
block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
|
||||
if (block) {
|
||||
/* TODO */
|
||||
|
@ -196,7 +193,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
|||
fb.free = (unsigned long)block;
|
||||
if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
|
||||
DRM_DEBUG("adding to allocation set fails\n");
|
||||
mmFreeMem((PMemBlock)fb.free);
|
||||
mmFreeMem((PMemBlock) fb.free);
|
||||
retval = DRM_ERR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
|
@ -212,7 +209,7 @@ static int sis_fb_alloc( DRM_IOCTL_ARGS )
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int sis_fb_free( DRM_IOCTL_ARGS )
|
||||
static int sis_fb_free(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -221,14 +218,14 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
|
|||
if (dev_priv == NULL || dev_priv->FBHeap == NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *)data, sizeof(fb));
|
||||
DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t __user *) data, sizeof(fb));
|
||||
|
||||
if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free))
|
||||
if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock) fb.free))
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
|
||||
return DRM_ERR(EINVAL);
|
||||
mmFreeMem((PMemBlock)fb.free);
|
||||
mmFreeMem((PMemBlock) fb.free);
|
||||
|
||||
DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
|
||||
|
||||
|
@ -237,9 +234,9 @@ static int sis_fb_free( DRM_IOCTL_ARGS )
|
|||
|
||||
#endif
|
||||
|
||||
/* agp memory management */
|
||||
/* agp memory management */
|
||||
|
||||
static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
|
||||
static int sis_ioctl_agp_init(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -247,7 +244,7 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
|
|||
|
||||
if (dev_priv == NULL) {
|
||||
dev->dev_private = drm_calloc(1, sizeof(drm_sis_private_t),
|
||||
DRM_MEM_DRIVER);
|
||||
DRM_MEM_DRIVER);
|
||||
dev_priv = dev->dev_private;
|
||||
if (dev_priv == NULL)
|
||||
return ENOMEM;
|
||||
|
@ -256,16 +253,17 @@ static int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
|
|||
if (dev_priv->AGPHeap != NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *)data, sizeof(agp));
|
||||
DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t __user *) data,
|
||||
sizeof(agp));
|
||||
|
||||
dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
|
||||
|
||||
DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
|
||||
static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -273,12 +271,12 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
|
|||
drm_sis_mem_t agp;
|
||||
PMemBlock block;
|
||||
int retval = 0;
|
||||
|
||||
|
||||
if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(agp, argp, sizeof(agp));
|
||||
|
||||
|
||||
block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
|
||||
if (block) {
|
||||
/* TODO */
|
||||
|
@ -286,10 +284,10 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
|
|||
agp.free = (unsigned long)block;
|
||||
if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
|
||||
DRM_DEBUG("adding to allocation set fails\n");
|
||||
mmFreeMem((PMemBlock)agp.free);
|
||||
mmFreeMem((PMemBlock) agp.free);
|
||||
retval = -1;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
agp.offset = 0;
|
||||
agp.size = 0;
|
||||
agp.free = 0;
|
||||
|
@ -302,7 +300,7 @@ static int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
|
||||
static int sis_ioctl_agp_free(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||
|
@ -311,12 +309,13 @@ static int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
|
|||
if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *)data, sizeof(agp));
|
||||
DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t __user *) data,
|
||||
sizeof(agp));
|
||||
|
||||
if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free))
|
||||
if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock) agp.free))
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
mmFreeMem((PMemBlock)agp.free);
|
||||
mmFreeMem((PMemBlock) agp.free);
|
||||
if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
|
||||
return DRM_ERR(EINVAL);
|
||||
|
||||
|
@ -329,31 +328,30 @@ int sis_init_context(struct drm_device *dev, int context)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CONTEXT ; i++) {
|
||||
for (i = 0; i < MAX_CONTEXT; i++) {
|
||||
if (global_ppriv[i].used &&
|
||||
(global_ppriv[i].context == context))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= MAX_CONTEXT) {
|
||||
for (i = 0; i < MAX_CONTEXT ; i++) {
|
||||
for (i = 0; i < MAX_CONTEXT; i++) {
|
||||
if (!global_ppriv[i].used) {
|
||||
global_ppriv[i].context = context;
|
||||
global_ppriv[i].used = 1;
|
||||
global_ppriv[i].sets[0] = setInit();
|
||||
global_ppriv[i].sets[1] = setInit();
|
||||
DRM_DEBUG("init allocation set, socket=%d, "
|
||||
"context = %d\n", i, context);
|
||||
"context = %d\n", i, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
|
||||
(global_ppriv[i].sets[1] == NULL))
|
||||
{
|
||||
(global_ppriv[i].sets[1] == NULL)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -361,7 +359,7 @@ int sis_final_context(struct drm_device *dev, int context)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_CONTEXT; i++) {
|
||||
for (i = 0; i < MAX_CONTEXT; i++) {
|
||||
if (global_ppriv[i].used &&
|
||||
(global_ppriv[i].context == context))
|
||||
break;
|
||||
|
@ -382,7 +380,7 @@ int sis_final_context(struct drm_device *dev, int context)
|
|||
#if defined(__linux__) && defined(CONFIG_FB_SIS)
|
||||
sis_free(item);
|
||||
#else
|
||||
mmFreeMem((PMemBlock)item);
|
||||
mmFreeMem((PMemBlock) item);
|
||||
#endif
|
||||
retval = setNext(set, &item);
|
||||
}
|
||||
|
@ -393,25 +391,24 @@ int sis_final_context(struct drm_device *dev, int context)
|
|||
retval = setFirst(set, &item);
|
||||
while (retval) {
|
||||
DRM_DEBUG("free agp memory 0x%x\n", item);
|
||||
mmFreeMem((PMemBlock)item);
|
||||
mmFreeMem((PMemBlock) item);
|
||||
retval = setNext(set, &item);
|
||||
}
|
||||
setDestroy(set);
|
||||
|
||||
global_ppriv[i].used = 0;
|
||||
}
|
||||
|
||||
global_ppriv[i].used = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
drm_ioctl_desc_t sis_ioctls[] = {
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = { sis_fb_alloc, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = { sis_fb_free, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = { sis_ioctl_agp_init, 1, 1 },
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = { sis_ioctl_agp_alloc, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = { sis_ioctl_agp_free, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = { sis_fb_init, 1, 1 }
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_ALLOC)] = {sis_fb_alloc, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_FREE)] = {sis_fb_free, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_INIT)] = {sis_ioctl_agp_init, 1, 1},
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_ALLOC)] = {sis_ioctl_agp_alloc, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_SIS_AGP_FREE)] = {sis_ioctl_agp_free, 1, 0},
|
||||
[DRM_IOCTL_NR(DRM_SIS_FB_INIT)] = {sis_fb_init, 1, 1}
|
||||
};
|
||||
|
||||
int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
|
||||
|
||||
|
|
|
@ -36,30 +36,28 @@
|
|||
|
||||
#include "drm_pciids.h"
|
||||
|
||||
static int postinit( struct drm_device *dev, unsigned long flags )
|
||||
static int postinit(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE,
|
||||
dev->primary.minor,
|
||||
pci_pretty_name(dev->pdev)
|
||||
);
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
|
||||
DRIVER_NAME,
|
||||
DRIVER_MAJOR,
|
||||
DRIVER_MINOR,
|
||||
DRIVER_PATCHLEVEL,
|
||||
DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version( drm_version_t *version )
|
||||
static int version(drm_version_t * version)
|
||||
{
|
||||
int len;
|
||||
|
||||
version->version_major = DRIVER_MAJOR;
|
||||
version->version_minor = DRIVER_MINOR;
|
||||
version->version_patchlevel = DRIVER_PATCHLEVEL;
|
||||
DRM_COPY( version->name, DRIVER_NAME );
|
||||
DRM_COPY( version->date, DRIVER_DATE );
|
||||
DRM_COPY( version->desc, DRIVER_DESC );
|
||||
DRM_COPY(version->name, DRIVER_NAME);
|
||||
DRM_COPY(version->date, DRIVER_DATE);
|
||||
DRM_COPY(version->desc, DRIVER_DESC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -75,18 +73,18 @@ static struct drm_driver driver = {
|
|||
.postinit = postinit,
|
||||
.version = version,
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init tdfx_init(void)
|
||||
|
@ -102,6 +100,6 @@ static void __exit tdfx_exit(void)
|
|||
module_init(tdfx_init);
|
||||
module_exit(tdfx_exit);
|
||||
|
||||
MODULE_AUTHOR( DRIVER_AUTHOR );
|
||||
MODULE_DESCRIPTION( DRIVER_DESC );
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
|
|
@ -1643,7 +1643,6 @@
|
|||
#define HC_HAGPBpID_STOP 0x00000002
|
||||
#define HC_HAGPBpH_MASK 0x00ffffff
|
||||
|
||||
|
||||
#define VIA_VIDEO_HEADER5 0xFE040000
|
||||
#define VIA_VIDEO_HEADER6 0xFE050000
|
||||
#define VIA_VIDEO_HEADER7 0xFE060000
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* via_dma.c -- DMA support for the VIA Unichrome/Pro
|
||||
*
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*
|
||||
* Copyright 2004 The Unichrome project.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
|
@ -23,14 +23,14 @@
|
|||
* 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS 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
|
||||
* THE COPYRIGHT HOLDERS, AUTHORS 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:
|
||||
* Tungsten Graphics,
|
||||
* Erdi Chen,
|
||||
* Authors:
|
||||
* Tungsten Graphics,
|
||||
* Erdi Chen,
|
||||
* Thomas Hellstrom.
|
||||
*/
|
||||
|
||||
|
@ -61,34 +61,31 @@
|
|||
dev_priv->dma_low +=8; \
|
||||
}
|
||||
|
||||
#define via_flush_write_combine() DRM_MEMORYBARRIER()
|
||||
#define via_flush_write_combine() DRM_MEMORYBARRIER()
|
||||
|
||||
#define VIA_OUT_RING_QW(w1,w2) \
|
||||
*vb++ = (w1); \
|
||||
*vb++ = (w2); \
|
||||
dev_priv->dma_low += 8;
|
||||
dev_priv->dma_low += 8;
|
||||
|
||||
static void via_cmdbuf_start(drm_via_private_t * dev_priv);
|
||||
static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
|
||||
static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
|
||||
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
|
||||
static int via_wait_idle(drm_via_private_t * dev_priv);
|
||||
static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
|
||||
|
||||
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
|
||||
|
||||
/*
|
||||
* Free space in command buffer.
|
||||
*/
|
||||
|
||||
static uint32_t
|
||||
via_cmdbuf_space(drm_via_private_t *dev_priv)
|
||||
static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
|
||||
{
|
||||
uint32_t agp_base = dev_priv->dma_offset +
|
||||
(uint32_t) dev_priv->agpAddr;
|
||||
uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
|
||||
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
|
||||
|
||||
return ((hw_addr <= dev_priv->dma_low) ?
|
||||
(dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
|
||||
|
||||
return ((hw_addr <= dev_priv->dma_low) ?
|
||||
(dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
|
||||
(hw_addr - dev_priv->dma_low));
|
||||
}
|
||||
|
||||
|
@ -96,15 +93,13 @@ via_cmdbuf_space(drm_via_private_t *dev_priv)
|
|||
* How much does the command regulator lag behind?
|
||||
*/
|
||||
|
||||
static uint32_t
|
||||
via_cmdbuf_lag(drm_via_private_t *dev_priv)
|
||||
static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
|
||||
{
|
||||
uint32_t agp_base = dev_priv->dma_offset +
|
||||
(uint32_t) dev_priv->agpAddr;
|
||||
uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
|
||||
uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
|
||||
|
||||
return ((hw_addr <= dev_priv->dma_low) ?
|
||||
(dev_priv->dma_low - hw_addr) :
|
||||
|
||||
return ((hw_addr <= dev_priv->dma_low) ?
|
||||
(dev_priv->dma_low - hw_addr) :
|
||||
(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
|
||||
}
|
||||
|
||||
|
@ -121,20 +116,20 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
|
|||
uint32_t count;
|
||||
hw_addr_ptr = dev_priv->hw_addr_ptr;
|
||||
cur_addr = dev_priv->dma_low;
|
||||
next_addr = cur_addr + size + 512*1024;
|
||||
next_addr = cur_addr + size + 512 * 1024;
|
||||
count = 1000000;
|
||||
do {
|
||||
hw_addr = *hw_addr_ptr - agp_base;
|
||||
hw_addr = *hw_addr_ptr - agp_base;
|
||||
if (count-- == 0) {
|
||||
DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
|
||||
hw_addr, cur_addr, next_addr);
|
||||
DRM_ERROR
|
||||
("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
|
||||
hw_addr, cur_addr, next_addr);
|
||||
return -1;
|
||||
}
|
||||
} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Checks whether buffer head has reach the end. Rewind the ring buffer
|
||||
* when necessary.
|
||||
|
@ -145,7 +140,8 @@ via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
|
|||
static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
|
||||
unsigned int size)
|
||||
{
|
||||
if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
|
||||
if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
|
||||
dev_priv->dma_high) {
|
||||
via_cmdbuf_rewind(dev_priv);
|
||||
}
|
||||
if (via_cmdbuf_wait(dev_priv, size) != 0) {
|
||||
|
@ -159,7 +155,7 @@ int via_dma_cleanup(drm_device_t * dev)
|
|||
{
|
||||
if (dev->dev_private) {
|
||||
drm_via_private_t *dev_priv =
|
||||
(drm_via_private_t *) dev->dev_private;
|
||||
(drm_via_private_t *) dev->dev_private;
|
||||
|
||||
if (dev_priv->ring.virtual_start) {
|
||||
via_cmdbuf_reset(dev_priv);
|
||||
|
@ -189,7 +185,7 @@ static int via_initialize(drm_device_t * dev,
|
|||
}
|
||||
|
||||
if (!dev->agp || !dev->agp->base) {
|
||||
DRM_ERROR("%s called with no agp memory available\n",
|
||||
DRM_ERROR("%s called with no agp memory available\n",
|
||||
__FUNCTION__);
|
||||
return DRM_ERR(EFAULT);
|
||||
}
|
||||
|
@ -247,10 +243,10 @@ int via_dma_init(DRM_IOCTL_ARGS)
|
|||
else
|
||||
retcode = via_dma_cleanup(dev);
|
||||
break;
|
||||
case VIA_DMA_INITIALIZED:
|
||||
retcode = (dev_priv->ring.virtual_start != NULL) ?
|
||||
0: DRM_ERR( EFAULT );
|
||||
break;
|
||||
case VIA_DMA_INITIALIZED:
|
||||
retcode = (dev_priv->ring.virtual_start != NULL) ?
|
||||
0 : DRM_ERR(EFAULT);
|
||||
break;
|
||||
default:
|
||||
retcode = DRM_ERR(EINVAL);
|
||||
break;
|
||||
|
@ -259,8 +255,6 @@ int via_dma_init(DRM_IOCTL_ARGS)
|
|||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
|
||||
{
|
||||
drm_via_private_t *dev_priv;
|
||||
|
@ -277,8 +271,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
|
|||
|
||||
if (cmd->size > VIA_PCI_BUF_SIZE) {
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
|
||||
return DRM_ERR(EFAULT);
|
||||
|
@ -289,19 +282,19 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
|
|||
* copy it to AGP memory when ready.
|
||||
*/
|
||||
|
||||
|
||||
if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) {
|
||||
if ((ret =
|
||||
via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
|
||||
cmd->size, dev, 1))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
|
||||
if (vb == NULL) {
|
||||
return DRM_ERR(EAGAIN);
|
||||
}
|
||||
|
||||
memcpy(vb, dev_priv->pci_buf, cmd->size);
|
||||
|
||||
|
||||
dev_priv->dma_low += cmd->size;
|
||||
|
||||
/*
|
||||
|
@ -310,7 +303,7 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
|
|||
*/
|
||||
|
||||
if (cmd->size < 0x100)
|
||||
via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3);
|
||||
via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
|
||||
via_cmdbuf_pause(dev_priv);
|
||||
|
||||
return 0;
|
||||
|
@ -330,7 +323,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS)
|
|||
{
|
||||
DRM_DEVICE;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev, filp );
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
return via_driver_dma_quiescent(dev);
|
||||
}
|
||||
|
@ -341,7 +334,7 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
|
|||
drm_via_cmdbuffer_t cmdbuf;
|
||||
int ret;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev, filp );
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
|
||||
sizeof(cmdbuf));
|
||||
|
@ -356,8 +349,9 @@ int via_cmdbuffer(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern int
|
||||
via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size);
|
||||
extern int
|
||||
via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
|
||||
unsigned int size);
|
||||
static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
|
||||
drm_via_cmdbuffer_t * cmd)
|
||||
{
|
||||
|
@ -366,15 +360,19 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
|
|||
|
||||
if (cmd->size > VIA_PCI_BUF_SIZE) {
|
||||
return DRM_ERR(ENOMEM);
|
||||
}
|
||||
}
|
||||
if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
|
||||
return DRM_ERR(EFAULT);
|
||||
|
||||
if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) {
|
||||
|
||||
if ((ret =
|
||||
via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
|
||||
cmd->size, dev, 0))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size);
|
||||
|
||||
ret =
|
||||
via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
|
||||
cmd->size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -384,7 +382,7 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
|
|||
drm_via_cmdbuffer_t cmdbuf;
|
||||
int ret;
|
||||
|
||||
LOCK_TEST_WITH_RETURN( dev, filp );
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
|
||||
sizeof(cmdbuf));
|
||||
|
@ -400,17 +398,15 @@ int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
|
||||
uint32_t * vb, int qw_count)
|
||||
{
|
||||
for (; qw_count > 0; --qw_count) {
|
||||
for (; qw_count > 0; --qw_count) {
|
||||
VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
|
||||
}
|
||||
return vb;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is used internally by ring buffer mangement code.
|
||||
*
|
||||
|
@ -426,7 +422,7 @@ static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
|
|||
* modifying the pause address stored in the buffer itself. If
|
||||
* the regulator has already paused, restart it.
|
||||
*/
|
||||
static int via_hook_segment(drm_via_private_t *dev_priv,
|
||||
static int via_hook_segment(drm_via_private_t * dev_priv,
|
||||
uint32_t pause_addr_hi, uint32_t pause_addr_lo,
|
||||
int no_pci_fire)
|
||||
{
|
||||
|
@ -434,7 +430,7 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
|
|||
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
|
||||
|
||||
via_flush_write_combine();
|
||||
while(! *(via_get_dma(dev_priv)-1));
|
||||
while (!*(via_get_dma(dev_priv) - 1)) ;
|
||||
*dev_priv->last_pause_ptr = pause_addr_lo;
|
||||
via_flush_write_combine();
|
||||
|
||||
|
@ -443,55 +439,53 @@ static int via_hook_segment(drm_via_private_t *dev_priv,
|
|||
* Not sure it is needed.
|
||||
*/
|
||||
|
||||
while(! *dev_priv->last_pause_ptr);
|
||||
while (!*dev_priv->last_pause_ptr) ;
|
||||
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
|
||||
while(! *dev_priv->last_pause_ptr);
|
||||
|
||||
while (!*dev_priv->last_pause_ptr) ;
|
||||
|
||||
paused = 0;
|
||||
count = 20;
|
||||
count = 20;
|
||||
|
||||
while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
|
||||
while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ;
|
||||
if ((count <= 8) && (count >= 0)) {
|
||||
uint32_t rgtr, ptr;
|
||||
rgtr = *(dev_priv->hw_addr_ptr);
|
||||
ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
|
||||
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
|
||||
CMDBUF_ALIGNMENT_SIZE;
|
||||
ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
|
||||
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 -
|
||||
CMDBUF_ALIGNMENT_SIZE;
|
||||
if (rgtr <= ptr) {
|
||||
DRM_ERROR("Command regulator\npaused at count %d, address %x, "
|
||||
"while current pause address is %x.\n"
|
||||
"Please mail this message to "
|
||||
"<unichrome-devel@lists.sourceforge.net>\n",
|
||||
count, rgtr, ptr);
|
||||
DRM_ERROR
|
||||
("Command regulator\npaused at count %d, address %x, "
|
||||
"while current pause address is %x.\n"
|
||||
"Please mail this message to "
|
||||
"<unichrome-devel@lists.sourceforge.net>\n", count,
|
||||
rgtr, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (paused && !no_pci_fire) {
|
||||
uint32_t rgtr,ptr;
|
||||
uint32_t rgtr, ptr;
|
||||
uint32_t ptr_low;
|
||||
|
||||
count = 1000000;
|
||||
while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
|
||||
|
||||
rgtr = *(dev_priv->hw_addr_ptr);
|
||||
ptr = ((char *)paused_at - dev_priv->dma_ptr) +
|
||||
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
|
||||
|
||||
while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY)
|
||||
&& count--) ;
|
||||
|
||||
ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ?
|
||||
ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
|
||||
rgtr = *(dev_priv->hw_addr_ptr);
|
||||
ptr = ((char *)paused_at - dev_priv->dma_ptr) +
|
||||
dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
|
||||
|
||||
ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
|
||||
ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0;
|
||||
if (rgtr <= ptr && rgtr >= ptr_low) {
|
||||
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return paused;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int via_wait_idle(drm_via_private_t * dev_priv)
|
||||
{
|
||||
int count = 10000000;
|
||||
|
@ -502,9 +496,8 @@ static int via_wait_idle(drm_via_private_t * dev_priv)
|
|||
}
|
||||
|
||||
static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
|
||||
uint32_t addr, uint32_t *cmd_addr_hi,
|
||||
uint32_t *cmd_addr_lo,
|
||||
int skip_wait)
|
||||
uint32_t addr, uint32_t * cmd_addr_hi,
|
||||
uint32_t * cmd_addr_lo, int skip_wait)
|
||||
{
|
||||
uint32_t agp_base;
|
||||
uint32_t cmd_addr, addr_lo, addr_hi;
|
||||
|
@ -512,31 +505,26 @@ static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
|
|||
uint32_t qw_pad_count;
|
||||
|
||||
if (!skip_wait)
|
||||
via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
|
||||
via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
|
||||
|
||||
vb = via_get_dma(dev_priv);
|
||||
VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
|
||||
(VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
|
||||
VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
|
||||
(VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
|
||||
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
|
||||
qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
|
||||
((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
|
||||
((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
|
||||
|
||||
|
||||
cmd_addr = (addr) ? addr :
|
||||
agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
|
||||
cmd_addr = (addr) ? addr :
|
||||
agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
|
||||
addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
|
||||
(cmd_addr & HC_HAGPBpL_MASK));
|
||||
addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
|
||||
|
||||
vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
|
||||
VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi,
|
||||
*cmd_addr_lo = addr_lo);
|
||||
VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
|
||||
return vb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void via_cmdbuf_start(drm_via_private_t * dev_priv)
|
||||
{
|
||||
uint32_t pause_addr_lo, pause_addr_hi;
|
||||
|
@ -545,7 +533,6 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
|
|||
uint32_t command;
|
||||
uint32_t agp_base;
|
||||
|
||||
|
||||
dev_priv->dma_low = 0;
|
||||
|
||||
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
|
||||
|
@ -557,12 +544,12 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
|
|||
command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
|
||||
((end_addr & 0xff000000) >> 16));
|
||||
|
||||
dev_priv->last_pause_ptr =
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
|
||||
&pause_addr_hi, & pause_addr_lo, 1) - 1;
|
||||
dev_priv->last_pause_ptr =
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
|
||||
&pause_addr_hi, &pause_addr_lo, 1) - 1;
|
||||
|
||||
via_flush_write_combine();
|
||||
while(! *dev_priv->last_pause_ptr);
|
||||
while (!*dev_priv->last_pause_ptr) ;
|
||||
|
||||
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
|
||||
VIA_WRITE(VIA_REG_TRANSPACE, command);
|
||||
|
@ -575,14 +562,14 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
|
|||
VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
|
||||
}
|
||||
|
||||
static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
|
||||
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
|
||||
{
|
||||
uint32_t *vb;
|
||||
|
||||
via_cmdbuf_wait(dev_priv, qwords + 2);
|
||||
vb = via_get_dma(dev_priv);
|
||||
VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
|
||||
via_align_buffer(dev_priv,vb,qwords);
|
||||
VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
|
||||
via_align_buffer(dev_priv, vb, qwords);
|
||||
}
|
||||
|
||||
static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
|
||||
|
@ -590,10 +577,9 @@ static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
|
|||
uint32_t *vb = via_get_dma(dev_priv);
|
||||
SetReg2DAGP(0x0C, (0 | (0 << 16)));
|
||||
SetReg2DAGP(0x10, 0 | (0 << 16));
|
||||
SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
|
||||
SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
|
||||
}
|
||||
|
||||
|
||||
static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
|
||||
{
|
||||
uint32_t agp_base;
|
||||
|
@ -603,11 +589,10 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
|
|||
uint32_t dma_low_save1, dma_low_save2;
|
||||
|
||||
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
|
||||
&jump_addr_lo, 0);
|
||||
|
||||
dev_priv->dma_wrap = dev_priv->dma_low;
|
||||
|
||||
dev_priv->dma_wrap = dev_priv->dma_low;
|
||||
|
||||
/*
|
||||
* Wrap command buffer to the beginning.
|
||||
|
@ -619,11 +604,12 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
|
|||
}
|
||||
|
||||
via_dummy_bitblt(dev_priv);
|
||||
via_dummy_bitblt(dev_priv);
|
||||
via_dummy_bitblt(dev_priv);
|
||||
|
||||
last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0) -1;
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
last_pause_ptr =
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0) - 1;
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0);
|
||||
|
||||
*last_pause_ptr = pause_addr_lo;
|
||||
|
@ -638,23 +624,23 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
|
|||
* does not seem to get updated immediately when a jump occurs.
|
||||
*/
|
||||
|
||||
last_pause_ptr = via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0) -1;
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
last_pause_ptr =
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0) - 1;
|
||||
via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
|
||||
&pause_addr_lo, 0);
|
||||
*last_pause_ptr = pause_addr_lo;
|
||||
|
||||
dma_low_save2 = dev_priv->dma_low;
|
||||
dev_priv->dma_low = dma_low_save1;
|
||||
via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
|
||||
dev_priv->dma_low = dma_low_save1;
|
||||
via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
|
||||
dev_priv->dma_low = dma_low_save2;
|
||||
via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
|
||||
via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
|
||||
}
|
||||
|
||||
|
||||
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
|
||||
{
|
||||
via_cmdbuf_jump(dev_priv);
|
||||
via_cmdbuf_jump(dev_priv);
|
||||
}
|
||||
|
||||
static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
|
||||
|
@ -662,10 +648,9 @@ static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
|
|||
uint32_t pause_addr_lo, pause_addr_hi;
|
||||
|
||||
via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
|
||||
via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
|
||||
via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
|
||||
}
|
||||
|
||||
|
||||
static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
|
||||
{
|
||||
via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
|
||||
|
@ -681,8 +666,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
|
|||
* User interface to the space and lag functions.
|
||||
*/
|
||||
|
||||
int
|
||||
via_cmdbuf_size(DRM_IOCTL_ARGS)
|
||||
int via_cmdbuf_size(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_via_cmdbuf_size_t d_siz;
|
||||
|
@ -691,7 +675,7 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
|
|||
drm_via_private_t *dev_priv;
|
||||
|
||||
DRM_DEBUG("via cmdbuf_size\n");
|
||||
LOCK_TEST_WITH_RETURN( dev, filp );
|
||||
LOCK_TEST_WITH_RETURN(dev, filp);
|
||||
|
||||
dev_priv = (drm_via_private_t *) dev->dev_private;
|
||||
|
||||
|
@ -704,12 +688,12 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
|
|||
DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data,
|
||||
sizeof(d_siz));
|
||||
|
||||
|
||||
count = 1000000;
|
||||
tmp_size = d_siz.size;
|
||||
switch(d_siz.func) {
|
||||
switch (d_siz.func) {
|
||||
case VIA_CMDBUF_SPACE:
|
||||
while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) {
|
||||
while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size)
|
||||
&& count--) {
|
||||
if (!d_siz.wait) {
|
||||
break;
|
||||
}
|
||||
|
@ -720,7 +704,8 @@ via_cmdbuf_size(DRM_IOCTL_ARGS)
|
|||
}
|
||||
break;
|
||||
case VIA_CMDBUF_LAG:
|
||||
while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) {
|
||||
while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size)
|
||||
&& count--) {
|
||||
if (!d_siz.wait) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ typedef struct _drm_via_dma_init {
|
|||
enum {
|
||||
VIA_INIT_DMA = 0x01,
|
||||
VIA_CLEANUP_DMA = 0x02,
|
||||
VIA_DMA_INITIALIZED = 0x03
|
||||
VIA_DMA_INITIALIZED = 0x03
|
||||
} func;
|
||||
|
||||
unsigned long offset;
|
||||
|
@ -212,7 +212,7 @@ typedef enum {
|
|||
|
||||
#define VIA_IRQ_FLAGS_MASK 0xF0000000
|
||||
|
||||
struct drm_via_wait_irq_request{
|
||||
struct drm_via_wait_irq_request {
|
||||
unsigned irq;
|
||||
via_irq_seq_type_t type;
|
||||
uint32_t sequence;
|
||||
|
|
|
@ -93,18 +93,18 @@ static struct drm_driver driver = {
|
|||
.ioctls = ioctls,
|
||||
.num_ioctls = DRM_ARRAY_SIZE(ioctls),
|
||||
.fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.owner = THIS_MODULE,
|
||||
.open = drm_open,
|
||||
.release = drm_release,
|
||||
.ioctl = drm_ioctl,
|
||||
.mmap = drm_mmap,
|
||||
.poll = drm_poll,
|
||||
.fasync = drm_fasync,
|
||||
},
|
||||
.pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = pciidlist,
|
||||
}
|
||||
};
|
||||
|
||||
static int __init via_init(void)
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
#define VIA_FIRE_BUF_SIZE 1024
|
||||
#define VIA_NUM_IRQS 2
|
||||
|
||||
|
||||
|
||||
typedef struct drm_via_ring_buffer {
|
||||
drm_map_t map;
|
||||
char *virtual_start;
|
||||
|
@ -55,7 +53,7 @@ typedef struct drm_via_irq {
|
|||
uint32_t enable_mask;
|
||||
wait_queue_head_t irq_queue;
|
||||
} drm_via_irq_t;
|
||||
|
||||
|
||||
typedef struct drm_via_private {
|
||||
drm_via_sarea_t *sarea_priv;
|
||||
drm_map_t *sarea;
|
||||
|
@ -71,9 +69,9 @@ typedef struct drm_via_private {
|
|||
volatile uint32_t *last_pause_ptr;
|
||||
volatile uint32_t *hw_addr_ptr;
|
||||
drm_via_ring_buffer_t ring;
|
||||
struct timeval last_vblank;
|
||||
int last_vblank_valid;
|
||||
unsigned usec_per_vblank;
|
||||
struct timeval last_vblank;
|
||||
int last_vblank_valid;
|
||||
unsigned usec_per_vblank;
|
||||
drm_via_state_t hc_state;
|
||||
char pci_buf[VIA_PCI_BUF_SIZE];
|
||||
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
|
||||
|
@ -82,8 +80,8 @@ typedef struct drm_via_private {
|
|||
drm_via_irq_t via_irqs[VIA_NUM_IRQS];
|
||||
unsigned num_irqs;
|
||||
maskarray_t *irq_masks;
|
||||
uint32_t irq_enable_mask;
|
||||
uint32_t irq_pending_mask;
|
||||
uint32_t irq_enable_mask;
|
||||
uint32_t irq_pending_mask;
|
||||
} drm_via_private_t;
|
||||
|
||||
/* VIA MMIO register access */
|
||||
|
@ -110,9 +108,11 @@ extern void via_driver_irq_uninstall(drm_device_t * dev);
|
|||
extern int via_dma_cleanup(drm_device_t * dev);
|
||||
extern void via_init_command_verifier(void);
|
||||
extern int via_driver_dma_quiescent(drm_device_t * dev);
|
||||
extern void via_init_futex(drm_via_private_t *dev_priv);
|
||||
extern void via_cleanup_futex(drm_via_private_t *dev_priv);
|
||||
extern void via_release_futex(drm_via_private_t *dev_priv, int context);
|
||||
extern void via_init_futex(drm_via_private_t * dev_priv);
|
||||
extern void via_cleanup_futex(drm_via_private_t * dev_priv);
|
||||
extern void via_release_futex(drm_via_private_t * dev_priv, int context);
|
||||
|
||||
extern int via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
|
||||
unsigned int size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,23 +54,26 @@
|
|||
/*
|
||||
* Device-specific IRQs go here. This type might need to be extended with
|
||||
* the register if there are multiple IRQ control registers.
|
||||
* Currently we activate the HQV interrupts of Unichrome Pro group A.
|
||||
* Currently we activate the HQV interrupts of Unichrome Pro group A.
|
||||
*/
|
||||
|
||||
static maskarray_t via_pro_group_a_irqs[] = {
|
||||
{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 },
|
||||
{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }};
|
||||
static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
|
||||
{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
|
||||
0x00000000},
|
||||
{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
|
||||
0x00000000}
|
||||
};
|
||||
static int via_num_pro_group_a =
|
||||
sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
|
||||
|
||||
static maskarray_t via_unichrome_irqs[] = {};
|
||||
static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
|
||||
static maskarray_t via_unichrome_irqs[] = { };
|
||||
static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
|
||||
|
||||
|
||||
static unsigned time_diff(struct timeval *now,struct timeval *then)
|
||||
static unsigned time_diff(struct timeval *now, struct timeval *then)
|
||||
{
|
||||
return (now->tv_usec >= then->tv_usec) ?
|
||||
now->tv_usec - then->tv_usec :
|
||||
1000000 - (then->tv_usec - now->tv_usec);
|
||||
return (now->tv_usec >= then->tv_usec) ?
|
||||
now->tv_usec - then->tv_usec :
|
||||
1000000 - (then->tv_usec - now->tv_usec);
|
||||
}
|
||||
|
||||
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
|
||||
|
@ -86,38 +89,37 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
|
|||
status = VIA_READ(VIA_REG_INTERRUPT);
|
||||
if (status & VIA_IRQ_VBLANK_PENDING) {
|
||||
atomic_inc(&dev->vbl_received);
|
||||
if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
|
||||
if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
|
||||
do_gettimeofday(&cur_vblank);
|
||||
if (dev_priv->last_vblank_valid) {
|
||||
dev_priv->usec_per_vblank =
|
||||
time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4;
|
||||
if (dev_priv->last_vblank_valid) {
|
||||
dev_priv->usec_per_vblank =
|
||||
time_diff(&cur_vblank,
|
||||
&dev_priv->last_vblank) >> 4;
|
||||
}
|
||||
dev_priv->last_vblank = cur_vblank;
|
||||
dev_priv->last_vblank_valid = 1;
|
||||
}
|
||||
if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
|
||||
}
|
||||
if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
|
||||
DRM_DEBUG("US per vblank is: %u\n",
|
||||
dev_priv->usec_per_vblank);
|
||||
dev_priv->usec_per_vblank);
|
||||
}
|
||||
DRM_WAKEUP(&dev->vbl_queue);
|
||||
drm_vbl_send_signals(dev);
|
||||
handled = 1;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<dev_priv->num_irqs; ++i) {
|
||||
for (i = 0; i < dev_priv->num_irqs; ++i) {
|
||||
if (status & cur_irq->pending_mask) {
|
||||
atomic_inc( &cur_irq->irq_received );
|
||||
DRM_WAKEUP( &cur_irq->irq_queue );
|
||||
atomic_inc(&cur_irq->irq_received);
|
||||
DRM_WAKEUP(&cur_irq->irq_queue);
|
||||
handled = 1;
|
||||
}
|
||||
cur_irq++;
|
||||
}
|
||||
|
||||
|
||||
/* Acknowlege interrupts */
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status);
|
||||
|
||||
|
||||
if (handled)
|
||||
return IRQ_HANDLED;
|
||||
else
|
||||
|
@ -131,7 +133,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
|
|||
if (dev_priv) {
|
||||
/* Acknowlege interrupts */
|
||||
status = VIA_READ(VIA_REG_INTERRUPT);
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status |
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status |
|
||||
dev_priv->irq_pending_mask);
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +160,12 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
|
|||
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
|
||||
(((cur_vblank = atomic_read(&dev->vbl_received)) -
|
||||
*sequence) <= (1 << 23)));
|
||||
|
||||
|
||||
*sequence = cur_vblank;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
|
||||
unsigned int *sequence)
|
||||
{
|
||||
|
@ -180,27 +182,29 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
|
|||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
if (irq >= dev_priv->num_irqs ) {
|
||||
DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq);
|
||||
if (irq >= dev_priv->num_irqs) {
|
||||
DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
|
||||
irq);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
||||
|
||||
cur_irq += irq;
|
||||
|
||||
if (masks[irq][2] && !force_sequence) {
|
||||
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
|
||||
((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4]));
|
||||
((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
|
||||
masks[irq][4]));
|
||||
cur_irq_sequence = atomic_read(&cur_irq->irq_received);
|
||||
} else {
|
||||
DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
|
||||
(((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) -
|
||||
*sequence) <= (1 << 23)));
|
||||
(((cur_irq_sequence =
|
||||
atomic_read(&cur_irq->irq_received)) -
|
||||
*sequence) <= (1 << 23)));
|
||||
}
|
||||
*sequence = cur_irq_sequence;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* drm_dma.h hooks
|
||||
*/
|
||||
|
@ -219,29 +223,29 @@ void via_driver_irq_preinstall(drm_device_t * dev)
|
|||
dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
|
||||
|
||||
dev_priv->irq_masks = (dev_priv->pro_group_a) ?
|
||||
via_pro_group_a_irqs : via_unichrome_irqs;
|
||||
via_pro_group_a_irqs : via_unichrome_irqs;
|
||||
dev_priv->num_irqs = (dev_priv->pro_group_a) ?
|
||||
via_num_pro_group_a : via_num_unichrome;
|
||||
|
||||
for(i=0; i < dev_priv->num_irqs; ++i) {
|
||||
via_num_pro_group_a : via_num_unichrome;
|
||||
|
||||
for (i = 0; i < dev_priv->num_irqs; ++i) {
|
||||
atomic_set(&cur_irq->irq_received, 0);
|
||||
cur_irq->enable_mask = dev_priv->irq_masks[i][0];
|
||||
cur_irq->enable_mask = dev_priv->irq_masks[i][0];
|
||||
cur_irq->pending_mask = dev_priv->irq_masks[i][1];
|
||||
DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
|
||||
DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
|
||||
dev_priv->irq_enable_mask |= cur_irq->enable_mask;
|
||||
dev_priv->irq_pending_mask |= cur_irq->pending_mask;
|
||||
cur_irq++;
|
||||
|
||||
|
||||
DRM_DEBUG("Initializing IRQ %d\n", i);
|
||||
}
|
||||
|
||||
dev_priv->last_vblank_valid = 0;
|
||||
|
||||
dev_priv->last_vblank_valid = 0;
|
||||
|
||||
// Clear VSync interrupt regs
|
||||
status = VIA_READ(VIA_REG_INTERRUPT);
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status &
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status &
|
||||
~(dev_priv->irq_enable_mask));
|
||||
|
||||
|
||||
/* Clear bits if they're already high */
|
||||
viadrv_acknowledge_irqs(dev_priv);
|
||||
}
|
||||
|
@ -262,7 +266,7 @@ void via_driver_irq_postinstall(drm_device_t * dev)
|
|||
|
||||
VIA_WRITE8(0x83d4, 0x11);
|
||||
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,7 +284,7 @@ void via_driver_irq_uninstall(drm_device_t * dev)
|
|||
VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
|
||||
|
||||
status = VIA_READ(VIA_REG_INTERRUPT);
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status &
|
||||
VIA_WRITE(VIA_REG_INTERRUPT, status &
|
||||
~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +306,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
|
|||
|
||||
DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait));
|
||||
if (irqwait.request.irq >= dev_priv->num_irqs) {
|
||||
DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
|
||||
DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
|
||||
irqwait.request.irq);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
@ -320,7 +324,7 @@ int via_wait_irq(DRM_IOCTL_ARGS)
|
|||
}
|
||||
|
||||
if (irqwait.request.type & VIA_IRQ_SIGNAL) {
|
||||
DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
|
||||
DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
|
||||
__FUNCTION__);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
|
|||
|
||||
dev_priv->agpAddr = init->agpAddr;
|
||||
|
||||
via_init_futex( dev_priv );
|
||||
via_init_futex(dev_priv);
|
||||
dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
|
||||
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
|
@ -107,5 +107,3 @@ int via_map_init(DRM_IOCTL_ARGS)
|
|||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -81,7 +81,8 @@ int via_agp_init(DRM_IOCTL_ARGS)
|
|||
|
||||
AgpHeap = via_mmInit(agp.offset, agp.size);
|
||||
|
||||
DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size);
|
||||
DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset,
|
||||
(unsigned long)agp.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -97,7 +98,8 @@ int via_fb_init(DRM_IOCTL_ARGS)
|
|||
|
||||
FBHeap = via_mmInit(fb.offset, fb.size);
|
||||
|
||||
DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size);
|
||||
DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset,
|
||||
(unsigned long)fb.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -134,8 +136,8 @@ int via_init_context(struct drm_device *dev, int context)
|
|||
}
|
||||
|
||||
int via_final_context(struct drm_device *dev, int context)
|
||||
{
|
||||
int i;
|
||||
{
|
||||
int i;
|
||||
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
|
||||
|
||||
for (i = 0; i < MAX_CONTEXT; i++)
|
||||
|
@ -171,14 +173,13 @@ int via_final_context(struct drm_device *dev, int context)
|
|||
via_setDestroy(set);
|
||||
global_ppriv[i].used = 0;
|
||||
}
|
||||
via_release_futex(dev_priv, context);
|
||||
|
||||
|
||||
via_release_futex(dev_priv, context);
|
||||
|
||||
#if defined(__linux__)
|
||||
/* Linux specific until context tracking code gets ported to BSD */
|
||||
/* Last context, perform cleanup */
|
||||
if (dev->ctx_count == 1 && dev->dev_private) {
|
||||
DRM_DEBUG("Last Context\n");
|
||||
DRM_DEBUG("Last Context\n");
|
||||
if (dev->irq)
|
||||
drm_irq_uninstall(dev);
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
* be very slow.
|
||||
*/
|
||||
|
||||
|
||||
#include "via_3d_reg.h"
|
||||
#include "drmP.h"
|
||||
#include "drm.h"
|
||||
|
@ -36,7 +35,7 @@
|
|||
#include "via_verifier.h"
|
||||
#include "via_drv.h"
|
||||
|
||||
typedef enum{
|
||||
typedef enum {
|
||||
state_command,
|
||||
state_header2,
|
||||
state_header1,
|
||||
|
@ -45,8 +44,7 @@ typedef enum{
|
|||
state_error
|
||||
} verifier_state_t;
|
||||
|
||||
|
||||
typedef enum{
|
||||
typedef enum {
|
||||
no_check = 0,
|
||||
check_for_header2,
|
||||
check_for_header1,
|
||||
|
@ -74,16 +72,16 @@ typedef enum{
|
|||
check_for_vertex_count,
|
||||
check_number_texunits,
|
||||
forbidden_command
|
||||
}hazard_t;
|
||||
} hazard_t;
|
||||
|
||||
/*
|
||||
* Associates each hazard above with a possible multi-command
|
||||
* sequence. For example an address that is split over multiple
|
||||
* commands and that needs to be checked at the first command
|
||||
* commands and that needs to be checked at the first command
|
||||
* that does not include any part of the address.
|
||||
*/
|
||||
|
||||
static drm_via_sequence_t seqs[] = {
|
||||
static drm_via_sequence_t seqs[] = {
|
||||
no_sequence,
|
||||
no_sequence,
|
||||
no_sequence,
|
||||
|
@ -110,14 +108,12 @@ static drm_via_sequence_t seqs[] = {
|
|||
tex_address,
|
||||
no_sequence
|
||||
};
|
||||
|
||||
typedef struct{
|
||||
|
||||
typedef struct {
|
||||
unsigned int code;
|
||||
hazard_t hz;
|
||||
} hz_init_t;
|
||||
|
||||
|
||||
|
||||
static hz_init_t init_table1[] = {
|
||||
{0xf2, check_for_header2_err},
|
||||
{0xf0, check_for_header1_err},
|
||||
|
@ -169,8 +165,6 @@ static hz_init_t init_table1[] = {
|
|||
{0x7D, check_for_vertex_count}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static hz_init_t init_table2[] = {
|
||||
{0xf2, check_for_header2_err},
|
||||
{0xf0, check_for_header1_err},
|
||||
|
@ -235,49 +229,49 @@ static hz_init_t init_table3[] = {
|
|||
{0xcc, check_for_dummy},
|
||||
{0x00, check_number_texunits}
|
||||
};
|
||||
|
||||
|
||||
static hazard_t table1[256];
|
||||
static hazard_t table2[256];
|
||||
static hazard_t table3[256];
|
||||
|
||||
|
||||
static hazard_t table1[256];
|
||||
static hazard_t table2[256];
|
||||
static hazard_t table3[256];
|
||||
|
||||
static __inline__ int
|
||||
eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
|
||||
eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
|
||||
{
|
||||
if ((*buf - buf_end) >= num_words) {
|
||||
*buf += num_words;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DRM_ERROR("Illegal termination of DMA command buffer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Partially stolen from drm_memory.h
|
||||
*/
|
||||
|
||||
static __inline__ drm_map_t *
|
||||
via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size,
|
||||
drm_device_t *dev)
|
||||
static __inline__ drm_map_t *via_drm_lookup_agp_map(drm_via_state_t * seq,
|
||||
unsigned long offset,
|
||||
unsigned long size,
|
||||
drm_device_t * dev)
|
||||
{
|
||||
struct list_head *list;
|
||||
drm_map_list_t *r_list;
|
||||
drm_map_t *map = seq->map_cache;
|
||||
|
||||
if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) {
|
||||
if (map && map->offset <= offset
|
||||
&& (offset + size) <= (map->offset + map->size)) {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *) list;
|
||||
map = r_list->map;
|
||||
if (!map)
|
||||
continue;
|
||||
if (map->offset <= offset && (offset + size) <= (map->offset + map->size) &&
|
||||
!(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) {
|
||||
if (map->offset <= offset
|
||||
&& (offset + size) <= (map->offset + map->size)
|
||||
&& !(map->flags & _DRM_RESTRICTED)
|
||||
&& (map->type == _DRM_AGP)) {
|
||||
seq->map_cache = map;
|
||||
return map;
|
||||
}
|
||||
|
@ -285,54 +279,60 @@ via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned lon
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Require that all AGP texture levels reside in the same AGP map which should
|
||||
* Require that all AGP texture levels reside in the same AGP map which should
|
||||
* be mappable by the client. This is not a big restriction.
|
||||
* FIXME: To actually enforce this security policy strictly, drm_rmmap
|
||||
* would have to wait for dma quiescent before removing an AGP map.
|
||||
* FIXME: To actually enforce this security policy strictly, drm_rmmap
|
||||
* would have to wait for dma quiescent before removing an AGP map.
|
||||
* The via_drm_lookup_agp_map call in reality seems to take
|
||||
* very little CPU time.
|
||||
*/
|
||||
|
||||
|
||||
static __inline__ int
|
||||
finish_current_sequence(drm_via_state_t *cur_seq)
|
||||
static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
|
||||
{
|
||||
switch(cur_seq->unfinished) {
|
||||
switch (cur_seq->unfinished) {
|
||||
case z_address:
|
||||
DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
|
||||
break;
|
||||
case dest_address:
|
||||
DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr);
|
||||
DRM_DEBUG("Destination start address is 0x%x\n",
|
||||
cur_seq->d_addr);
|
||||
break;
|
||||
case tex_address:
|
||||
if (cur_seq->agp_texture) {
|
||||
unsigned start = cur_seq->tex_level_lo[cur_seq->texture];
|
||||
if (cur_seq->agp_texture) {
|
||||
unsigned start =
|
||||
cur_seq->tex_level_lo[cur_seq->texture];
|
||||
unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
|
||||
unsigned long lo=~0, hi=0, tmp;
|
||||
unsigned long lo = ~0, hi = 0, tmp;
|
||||
uint32_t *addr, *pitch, *height, tex;
|
||||
unsigned i;
|
||||
|
||||
if (end > 9) end = 9;
|
||||
if (start > 9) start = 9;
|
||||
if (end > 9)
|
||||
end = 9;
|
||||
if (start > 9)
|
||||
start = 9;
|
||||
|
||||
addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]);
|
||||
addr =
|
||||
&(cur_seq->t_addr[tex = cur_seq->texture][start]);
|
||||
pitch = &(cur_seq->pitch[tex][start]);
|
||||
height = &(cur_seq->height[tex][start]);
|
||||
|
||||
for (i=start; i<= end; ++i) {
|
||||
for (i = start; i <= end; ++i) {
|
||||
tmp = *addr++;
|
||||
if (tmp < lo) lo = tmp;
|
||||
if (tmp < lo)
|
||||
lo = tmp;
|
||||
tmp += (*height++ << *pitch++);
|
||||
if (tmp > hi) hi = tmp;
|
||||
if (tmp > hi)
|
||||
hi = tmp;
|
||||
}
|
||||
|
||||
if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) {
|
||||
DRM_ERROR("AGP texture is not in allowed map\n");
|
||||
if (!via_drm_lookup_agp_map
|
||||
(cur_seq, lo, hi - lo, cur_seq->dev)) {
|
||||
DRM_ERROR
|
||||
("AGP texture is not in allowed map\n");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -341,73 +341,84 @@ finish_current_sequence(drm_via_state_t *cur_seq)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
|
||||
static __inline__ int
|
||||
investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
|
||||
{
|
||||
register uint32_t tmp, *tmp_addr;
|
||||
|
||||
if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
|
||||
int ret;
|
||||
if ((ret = finish_current_sequence(cur_seq))) return ret;
|
||||
if ((ret = finish_current_sequence(cur_seq)))
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch(hz) {
|
||||
switch (hz) {
|
||||
case check_for_header2:
|
||||
if (cmd == HALCYON_HEADER2) return 1;
|
||||
if (cmd == HALCYON_HEADER2)
|
||||
return 1;
|
||||
return 0;
|
||||
case check_for_header1:
|
||||
if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
|
||||
if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
return 1;
|
||||
return 0;
|
||||
case check_for_header2_err:
|
||||
if (cmd == HALCYON_HEADER2) return 1;
|
||||
if (cmd == HALCYON_HEADER2)
|
||||
return 1;
|
||||
DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
|
||||
break;
|
||||
case check_for_header1_err:
|
||||
if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
|
||||
if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
return 1;
|
||||
DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
|
||||
break;
|
||||
case check_for_fire:
|
||||
if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1;
|
||||
if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD)
|
||||
return 1;
|
||||
DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
|
||||
break;
|
||||
case check_for_dummy:
|
||||
if (HC_DUMMY == cmd) return 0;
|
||||
if (HC_DUMMY == cmd)
|
||||
return 0;
|
||||
DRM_ERROR("Illegal DMA HC_DUMMY command\n");
|
||||
break;
|
||||
case check_for_dd:
|
||||
if (0xdddddddd == cmd) return 0;
|
||||
if (0xdddddddd == cmd)
|
||||
return 0;
|
||||
DRM_ERROR("Illegal DMA 0xdddddddd command\n");
|
||||
break;
|
||||
case check_z_buffer_addr0:
|
||||
cur_seq->unfinished = z_address;
|
||||
cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
|
||||
(cmd & 0x00FFFFFF);
|
||||
(cmd & 0x00FFFFFF);
|
||||
return 0;
|
||||
case check_z_buffer_addr1:
|
||||
cur_seq->unfinished = z_address;
|
||||
cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
|
||||
((cmd & 0xFF) << 24);
|
||||
((cmd & 0xFF) << 24);
|
||||
return 0;
|
||||
case check_z_buffer_addr_mode:
|
||||
cur_seq->unfinished = z_address;
|
||||
if ((cmd & 0x0000C000) == 0) return 0;
|
||||
if ((cmd & 0x0000C000) == 0)
|
||||
return 0;
|
||||
DRM_ERROR("Attempt to place Z buffer in system memory\n");
|
||||
return 2;
|
||||
case check_destination_addr0:
|
||||
cur_seq->unfinished = dest_address;
|
||||
cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
|
||||
(cmd & 0x00FFFFFF);
|
||||
(cmd & 0x00FFFFFF);
|
||||
return 0;
|
||||
case check_destination_addr1:
|
||||
cur_seq->unfinished = dest_address;
|
||||
cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
|
||||
((cmd & 0xFF) << 24);
|
||||
((cmd & 0xFF) << 24);
|
||||
return 0;
|
||||
case check_destination_addr_mode:
|
||||
cur_seq->unfinished = dest_address;
|
||||
if ((cmd & 0x0000C000) == 0) return 0;
|
||||
DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n");
|
||||
return 2;
|
||||
if ((cmd & 0x0000C000) == 0)
|
||||
return 0;
|
||||
DRM_ERROR
|
||||
("Attempt to place 3D drawing buffer in system memory\n");
|
||||
return 2;
|
||||
case check_texture_addr0:
|
||||
cur_seq->unfinished = tex_address;
|
||||
tmp = (cmd >> 24);
|
||||
|
@ -433,9 +444,11 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
|
|||
case check_texture_addr3:
|
||||
cur_seq->unfinished = tex_address;
|
||||
tmp = ((cmd >> 24) - 0x2B);
|
||||
cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20;
|
||||
cur_seq->pitch[cur_seq->texture][tmp] =
|
||||
(cmd & 0x00F00000) >> 20;
|
||||
if (!tmp && (cmd & 0x000FFFFF)) {
|
||||
DRM_ERROR("Unimplemented texture level 0 pitch mode.\n");
|
||||
DRM_ERROR
|
||||
("Unimplemented texture level 0 pitch mode.\n");
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
@ -449,7 +462,7 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
|
|||
cur_seq->unfinished = tex_address;
|
||||
/*
|
||||
* Texture width. We don't care since we have the pitch.
|
||||
*/
|
||||
*/
|
||||
return 0;
|
||||
case check_texture_addr7:
|
||||
cur_seq->unfinished = tex_address;
|
||||
|
@ -465,25 +478,26 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
|
|||
cur_seq->unfinished = tex_address;
|
||||
tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
|
||||
tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
|
||||
tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
|
||||
tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
|
||||
tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
|
||||
tmp_addr[6] = 1 << (cmd & 0x0000000F);
|
||||
return 0;
|
||||
case check_texture_addr_mode:
|
||||
cur_seq->unfinished = tex_address;
|
||||
if ( 2 == (tmp = cmd & 0x00000003)) {
|
||||
DRM_ERROR("Attempt to fetch texture from system memory.\n");
|
||||
if (2 == (tmp = cmd & 0x00000003)) {
|
||||
DRM_ERROR
|
||||
("Attempt to fetch texture from system memory.\n");
|
||||
return 2;
|
||||
}
|
||||
cur_seq->agp_texture = (tmp == 3);
|
||||
cur_seq->tex_palette_size[cur_seq->texture] =
|
||||
(cmd >> 16) & 0x000000007;
|
||||
cur_seq->tex_palette_size[cur_seq->texture] =
|
||||
(cmd >> 16) & 0x000000007;
|
||||
return 0;
|
||||
case check_for_vertex_count:
|
||||
cur_seq->vertex_count = cmd & 0x0000FFFF;
|
||||
return 0;
|
||||
case check_number_texunits:
|
||||
cur_seq->multitex = (cmd >> 3) & 1;
|
||||
cur_seq->multitex = (cmd >> 3) & 1;
|
||||
return 0;
|
||||
default:
|
||||
DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
|
||||
|
@ -492,25 +506,27 @@ investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
|
|||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ int
|
||||
via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
|
||||
drm_via_state_t *cur_seq)
|
||||
via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
|
||||
drm_via_state_t * cur_seq)
|
||||
{
|
||||
drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private;
|
||||
uint32_t a_fire, bcmd , dw_count;
|
||||
drm_via_private_t *dev_priv =
|
||||
(drm_via_private_t *) cur_seq->dev->dev_private;
|
||||
uint32_t a_fire, bcmd, dw_count;
|
||||
int ret = 0;
|
||||
int have_fire;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
||||
while(buf < buf_end) {
|
||||
have_fire = 0;
|
||||
while (buf < buf_end) {
|
||||
have_fire = 0;
|
||||
if ((buf_end - buf) < 2) {
|
||||
DRM_ERROR("Unexpected termination of primitive list.\n");
|
||||
DRM_ERROR
|
||||
("Unexpected termination of primitive list.\n");
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break;
|
||||
if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB)
|
||||
break;
|
||||
bcmd = *buf++;
|
||||
if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
|
||||
DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
|
||||
|
@ -518,43 +534,56 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
|
|||
ret = 1;
|
||||
break;
|
||||
}
|
||||
a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;
|
||||
|
||||
a_fire =
|
||||
*buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK |
|
||||
HC_HE3Fire_MASK;
|
||||
|
||||
/*
|
||||
* How many dwords per vertex ?
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
|
||||
DRM_ERROR("Illegal B command vertex data for AGP.\n");
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dw_count = 0;
|
||||
if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1;
|
||||
if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1;
|
||||
if (bcmd & (1 << 9)) dw_count++;
|
||||
if (bcmd & (1 << 10)) dw_count++;
|
||||
if (bcmd & (1 << 11)) dw_count++;
|
||||
if (bcmd & (1 << 12)) dw_count++;
|
||||
if (bcmd & (1 << 13)) dw_count++;
|
||||
if (bcmd & (1 << 14)) dw_count++;
|
||||
if (bcmd & (1 << 7))
|
||||
dw_count += (cur_seq->multitex) ? 2 : 1;
|
||||
if (bcmd & (1 << 8))
|
||||
dw_count += (cur_seq->multitex) ? 2 : 1;
|
||||
if (bcmd & (1 << 9))
|
||||
dw_count++;
|
||||
if (bcmd & (1 << 10))
|
||||
dw_count++;
|
||||
if (bcmd & (1 << 11))
|
||||
dw_count++;
|
||||
if (bcmd & (1 << 12))
|
||||
dw_count++;
|
||||
if (bcmd & (1 << 13))
|
||||
dw_count++;
|
||||
if (bcmd & (1 << 14))
|
||||
dw_count++;
|
||||
|
||||
while(buf < buf_end) {
|
||||
while (buf < buf_end) {
|
||||
if (*buf == a_fire) {
|
||||
if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) {
|
||||
if (dev_priv->num_fire_offsets >=
|
||||
VIA_FIRE_BUF_SIZE) {
|
||||
DRM_ERROR("Fire offset buffer full.\n");
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf;
|
||||
have_fire = 1;
|
||||
dev_priv->fire_offsets[dev_priv->
|
||||
num_fire_offsets++] =
|
||||
buf;
|
||||
have_fire = 1;
|
||||
buf++;
|
||||
if (buf < buf_end && *buf == a_fire)
|
||||
if (buf < buf_end && *buf == a_fire)
|
||||
buf++;
|
||||
break;
|
||||
}
|
||||
if ((*buf == HALCYON_HEADER2) ||
|
||||
if ((*buf == HALCYON_HEADER2) ||
|
||||
((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
|
||||
DRM_ERROR("Missing Vertex Fire command, "
|
||||
"Stray Vertex Fire command or verifier "
|
||||
|
@ -576,18 +605,14 @@ via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
|
|||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*buffer = buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
|
||||
drm_via_state_t *hc_state)
|
||||
via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
|
||||
drm_via_state_t * hc_state)
|
||||
{
|
||||
uint32_t cmd;
|
||||
int hz_mode;
|
||||
|
@ -595,17 +620,17 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
|
|||
const uint32_t *buf = *buffer;
|
||||
const hazard_t *hz_table;
|
||||
|
||||
|
||||
if ((buf_end - buf) < 2) {
|
||||
DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
|
||||
DRM_ERROR
|
||||
("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
|
||||
return state_error;
|
||||
}
|
||||
buf++;
|
||||
cmd = (*buf++ & 0xFFFF0000) >> 16;
|
||||
|
||||
switch(cmd) {
|
||||
switch (cmd) {
|
||||
case HC_ParaType_CmdVdata:
|
||||
if (via_check_prim_list(&buf, buf_end, hc_state ))
|
||||
if (via_check_prim_list(&buf, buf_end, hc_state))
|
||||
return state_error;
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
|
@ -650,13 +675,13 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
|
|||
*/
|
||||
|
||||
DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
|
||||
"DMA subcommand: 0x%x. Previous dword: 0x%x\n",
|
||||
cmd, *(buf -2));
|
||||
"DMA subcommand: 0x%x. Previous dword: 0x%x\n",
|
||||
cmd, *(buf - 2));
|
||||
*buffer = buf;
|
||||
return state_error;
|
||||
}
|
||||
|
||||
while(buf < buf_end) {
|
||||
while (buf < buf_end) {
|
||||
cmd = *buf++;
|
||||
if ((hz = hz_table[cmd >> 24])) {
|
||||
if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
|
||||
|
@ -666,7 +691,7 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
|
|||
}
|
||||
return state_error;
|
||||
}
|
||||
} else if (hc_state->unfinished &&
|
||||
} else if (hc_state->unfinished &&
|
||||
finish_current_sequence(hc_state)) {
|
||||
return state_error;
|
||||
}
|
||||
|
@ -679,64 +704,65 @@ via_check_header2( uint32_t const **buffer, const uint32_t *buf_end,
|
|||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end,
|
||||
int *fire_count)
|
||||
via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer,
|
||||
const uint32_t * buf_end, int *fire_count)
|
||||
{
|
||||
uint32_t cmd;
|
||||
const uint32_t *buf = *buffer;
|
||||
const uint32_t *next_fire;
|
||||
const uint32_t *next_fire;
|
||||
int burst = 0;
|
||||
|
||||
next_fire = dev_priv->fire_offsets[*fire_count];
|
||||
buf++;
|
||||
cmd = (*buf & 0xFFFF0000) >> 16;
|
||||
VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
|
||||
switch(cmd) {
|
||||
switch (cmd) {
|
||||
case HC_ParaType_CmdVdata:
|
||||
while ((buf < buf_end) &&
|
||||
(*fire_count < dev_priv->num_fire_offsets) &&
|
||||
(*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) {
|
||||
while(buf <= next_fire) {
|
||||
VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
|
||||
(*fire_count < dev_priv->num_fire_offsets) &&
|
||||
(*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) {
|
||||
while (buf <= next_fire) {
|
||||
VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
|
||||
(burst & 63), *buf++);
|
||||
burst += 4;
|
||||
}
|
||||
if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
|
||||
if ((buf < buf_end)
|
||||
&& ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
|
||||
buf++;
|
||||
|
||||
if (++(*fire_count) < dev_priv->num_fire_offsets)
|
||||
if (++(*fire_count) < dev_priv->num_fire_offsets)
|
||||
next_fire = dev_priv->fire_offsets[*fire_count];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
while(buf < buf_end) {
|
||||
|
||||
if ( *buf == HC_HEADER2 ||
|
||||
(*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
|
||||
(*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
|
||||
(*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break;
|
||||
|
||||
VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
|
||||
burst +=4;
|
||||
while (buf < buf_end) {
|
||||
|
||||
if (*buf == HC_HEADER2 ||
|
||||
(*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
|
||||
(*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
|
||||
(*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
|
||||
break;
|
||||
|
||||
VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
|
||||
(burst & 63), *buf++);
|
||||
burst += 4;
|
||||
}
|
||||
}
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static __inline__ int
|
||||
verify_mmio_address( uint32_t address)
|
||||
static __inline__ int verify_mmio_address(uint32_t address)
|
||||
{
|
||||
if ((address > 0x3FF) && (address < 0xC00 )) {
|
||||
if ((address > 0x3FF) && (address < 0xC00)) {
|
||||
DRM_ERROR("Invalid VIDEO DMA command. "
|
||||
"Attempt to access 3D- or command burst area.\n");
|
||||
return 1;
|
||||
} else if ((address > 0xCFF) && (address < 0x1300)) {
|
||||
DRM_ERROR("Invalid VIDEO DMA command. "
|
||||
"Attempt to access PCI DMA area.\n");
|
||||
return 1;
|
||||
} else if (address > 0x13FF ) {
|
||||
return 1;
|
||||
} else if (address > 0x13FF) {
|
||||
DRM_ERROR("Invalid VIDEO DMA command. "
|
||||
"Attempt to access VGA registers.\n");
|
||||
return 1;
|
||||
|
@ -745,7 +771,8 @@ verify_mmio_address( uint32_t address)
|
|||
}
|
||||
|
||||
static __inline__ int
|
||||
verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords)
|
||||
verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end,
|
||||
uint32_t dwords)
|
||||
{
|
||||
const uint32_t *buf = *buffer;
|
||||
|
||||
|
@ -762,10 +789,9 @@ verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dw
|
|||
*buffer = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_check_header1(uint32_t const **buffer, const uint32_t * buf_end)
|
||||
{
|
||||
uint32_t cmd;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
@ -774,21 +800,21 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
|
|||
while (buf < buf_end) {
|
||||
cmd = *buf;
|
||||
if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
|
||||
(cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
|
||||
(cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
|
||||
break;
|
||||
DRM_ERROR("Invalid HALCYON_HEADER1 command. "
|
||||
"Attempt to access 3D- or command burst area.\n");
|
||||
ret = state_error;
|
||||
break;
|
||||
} else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
|
||||
break;
|
||||
DRM_ERROR("Invalid HALCYON_HEADER1 command. "
|
||||
"Attempt to access VGA registers.\n");
|
||||
ret = state_error;
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
} else {
|
||||
buf += 2;
|
||||
}
|
||||
}
|
||||
|
@ -797,15 +823,17 @@ via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
|
|||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
|
||||
const uint32_t * buf_end)
|
||||
{
|
||||
register uint32_t cmd;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
||||
while (buf < buf_end) {
|
||||
cmd = *buf;
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break;
|
||||
VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
|
||||
if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
|
||||
break;
|
||||
VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
|
||||
buf++;
|
||||
}
|
||||
*buffer = buf;
|
||||
|
@ -813,7 +841,7 @@ via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const u
|
|||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
|
||||
{
|
||||
uint32_t data;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
@ -836,41 +864,41 @@ via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
|
|||
DRM_ERROR("Illegal header5 header data\n");
|
||||
return state_error;
|
||||
}
|
||||
if (eat_words(&buf, buf_end, data))
|
||||
if (eat_words(&buf, buf_end, data))
|
||||
return state_error;
|
||||
if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
|
||||
if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
|
||||
return state_error;
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
|
||||
const uint32_t * buf_end)
|
||||
{
|
||||
uint32_t addr, count, i;
|
||||
uint32_t addr, count, i;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
||||
|
||||
addr = *buf++ & ~VIA_VIDEOMASK;
|
||||
i = count = *buf;
|
||||
buf += 3;
|
||||
while(i--) {
|
||||
while (i--) {
|
||||
VIA_WRITE(addr, *buf++);
|
||||
}
|
||||
if (count & 3) buf += 4 - (count & 3);
|
||||
if (count & 3)
|
||||
buf += 4 - (count & 3);
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
}
|
||||
|
||||
return state_command;
|
||||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end)
|
||||
{
|
||||
uint32_t data;
|
||||
const uint32_t *buf = *buffer;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
if (buf_end - buf < 4) {
|
||||
DRM_ERROR("Illegal termination of video header6 command\n");
|
||||
return state_error;
|
||||
|
@ -889,7 +917,7 @@ via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
|
|||
DRM_ERROR("Illegal termination of video header6 command\n");
|
||||
return state_error;
|
||||
}
|
||||
for (i=0; i<data; ++i) {
|
||||
for (i = 0; i < data; ++i) {
|
||||
if (verify_mmio_address(*buf++))
|
||||
return state_error;
|
||||
buf++;
|
||||
|
@ -899,42 +927,42 @@ via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
|
|||
return state_error;
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ verifier_state_t
|
||||
via_parse_vheader6( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
|
||||
via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer,
|
||||
const uint32_t * buf_end)
|
||||
{
|
||||
|
||||
uint32_t addr, count, i;
|
||||
uint32_t addr, count, i;
|
||||
const uint32_t *buf = *buffer;
|
||||
|
||||
i = count = *++buf;
|
||||
buf += 3;
|
||||
while(i--) {
|
||||
while (i--) {
|
||||
addr = *buf++;
|
||||
VIA_WRITE(addr, *buf++);
|
||||
}
|
||||
count <<= 1;
|
||||
if (count & 3) buf += 4 - (count & 3);
|
||||
if (count & 3)
|
||||
buf += 4 - (count & 3);
|
||||
*buffer = buf;
|
||||
return state_command;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
|
||||
int agp)
|
||||
int
|
||||
via_verify_command_stream(const uint32_t * buf, unsigned int size,
|
||||
drm_device_t * dev, int agp)
|
||||
{
|
||||
|
||||
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
|
||||
drm_via_state_t *hc_state = &dev_priv->hc_state;
|
||||
drm_via_state_t saved_state = *hc_state;
|
||||
uint32_t cmd;
|
||||
const uint32_t *buf_end = buf + ( size >> 2 );
|
||||
const uint32_t *buf_end = buf + (size >> 2);
|
||||
verifier_state_t state = state_command;
|
||||
int pro_group_a = dev_priv->pro_group_a;
|
||||
|
||||
|
||||
hc_state->dev = dev;
|
||||
hc_state->unfinished = no_sequence;
|
||||
hc_state->map_cache = NULL;
|
||||
|
@ -946,38 +974,41 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t
|
|||
|
||||
switch (state) {
|
||||
case state_header2:
|
||||
state = via_check_header2( &buf, buf_end, hc_state );
|
||||
state = via_check_header2(&buf, buf_end, hc_state);
|
||||
break;
|
||||
case state_header1:
|
||||
state = via_check_header1( &buf, buf_end );
|
||||
state = via_check_header1(&buf, buf_end);
|
||||
break;
|
||||
case state_vheader5:
|
||||
state = via_check_vheader5( &buf, buf_end );
|
||||
state = via_check_vheader5(&buf, buf_end);
|
||||
break;
|
||||
case state_vheader6:
|
||||
state = via_check_vheader6( &buf, buf_end );
|
||||
state = via_check_vheader6(&buf, buf_end);
|
||||
break;
|
||||
case state_command:
|
||||
if (HALCYON_HEADER2 == (cmd = *buf))
|
||||
if (HALCYON_HEADER2 == (cmd = *buf))
|
||||
state = state_header2;
|
||||
else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
state = state_header1;
|
||||
else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
|
||||
else if (pro_group_a
|
||||
&& (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
|
||||
state = state_vheader5;
|
||||
else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
|
||||
else if (pro_group_a
|
||||
&& (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
|
||||
state = state_vheader6;
|
||||
else {
|
||||
DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
|
||||
cmd);
|
||||
DRM_ERROR
|
||||
("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
|
||||
cmd);
|
||||
state = state_error;
|
||||
}
|
||||
break;
|
||||
case state_error:
|
||||
default:
|
||||
*hc_state = saved_state;
|
||||
return DRM_ERR(EINVAL);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state == state_error) {
|
||||
*hc_state = saved_state;
|
||||
return DRM_ERR(EINVAL);
|
||||
|
@ -985,77 +1016,81 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size)
|
||||
int
|
||||
via_parse_command_stream(drm_device_t * dev, const uint32_t * buf,
|
||||
unsigned int size)
|
||||
{
|
||||
|
||||
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
|
||||
uint32_t cmd;
|
||||
const uint32_t *buf_end = buf + ( size >> 2 );
|
||||
const uint32_t *buf_end = buf + (size >> 2);
|
||||
verifier_state_t state = state_command;
|
||||
int fire_count = 0;
|
||||
|
||||
|
||||
while (buf < buf_end) {
|
||||
|
||||
switch (state) {
|
||||
case state_header2:
|
||||
state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count );
|
||||
state =
|
||||
via_parse_header2(dev_priv, &buf, buf_end,
|
||||
&fire_count);
|
||||
break;
|
||||
case state_header1:
|
||||
state = via_parse_header1( dev_priv, &buf, buf_end );
|
||||
state = via_parse_header1(dev_priv, &buf, buf_end);
|
||||
break;
|
||||
case state_vheader5:
|
||||
state = via_parse_vheader5( dev_priv, &buf, buf_end );
|
||||
state = via_parse_vheader5(dev_priv, &buf, buf_end);
|
||||
break;
|
||||
case state_vheader6:
|
||||
state = via_parse_vheader6( dev_priv, &buf, buf_end );
|
||||
state = via_parse_vheader6(dev_priv, &buf, buf_end);
|
||||
break;
|
||||
case state_command:
|
||||
if (HALCYON_HEADER2 == (cmd = *buf))
|
||||
if (HALCYON_HEADER2 == (cmd = *buf))
|
||||
state = state_header2;
|
||||
else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
|
||||
state = state_header1;
|
||||
else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
|
||||
state = state_vheader5;
|
||||
else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
|
||||
state = state_vheader6;
|
||||
else {
|
||||
DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
|
||||
cmd);
|
||||
DRM_ERROR
|
||||
("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
|
||||
cmd);
|
||||
state = state_error;
|
||||
}
|
||||
break;
|
||||
case state_error:
|
||||
default:
|
||||
return DRM_ERR(EINVAL);
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state == state_error) {
|
||||
return DRM_ERR(EINVAL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
static void
|
||||
setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<256; ++i) {
|
||||
for (i = 0; i < 256; ++i) {
|
||||
table[i] = forbidden_command;
|
||||
}
|
||||
|
||||
for(i=0; i<size; ++i) {
|
||||
for (i = 0; i < size; ++i) {
|
||||
table[init_table[i].code] = init_table[i].hz;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
via_init_command_verifier( void )
|
||||
void via_init_command_verifier(void)
|
||||
{
|
||||
setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
|
||||
setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
|
||||
setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
|
||||
setup_hazard_table(init_table1, table1,
|
||||
sizeof(init_table1) / sizeof(hz_init_t));
|
||||
setup_hazard_table(init_table2, table2,
|
||||
sizeof(init_table2) / sizeof(hz_init_t));
|
||||
setup_hazard_table(init_table3, table3,
|
||||
sizeof(init_table3) / sizeof(hz_init_t));
|
||||
}
|
||||
|
|
|
@ -26,23 +26,21 @@
|
|||
#ifndef _VIA_VERIFIER_H_
|
||||
#define _VIA_VERIFIER_H_
|
||||
|
||||
typedef enum{
|
||||
no_sequence = 0,
|
||||
typedef enum {
|
||||
no_sequence = 0,
|
||||
z_address,
|
||||
dest_address,
|
||||
tex_address
|
||||
}drm_via_sequence_t;
|
||||
} drm_via_sequence_t;
|
||||
|
||||
|
||||
|
||||
typedef struct{
|
||||
typedef struct {
|
||||
unsigned texture;
|
||||
uint32_t z_addr;
|
||||
uint32_t d_addr;
|
||||
uint32_t t_addr[2][10];
|
||||
uint32_t z_addr;
|
||||
uint32_t d_addr;
|
||||
uint32_t t_addr[2][10];
|
||||
uint32_t pitch[2][10];
|
||||
uint32_t height[2][10];
|
||||
uint32_t tex_level_lo[2];
|
||||
uint32_t tex_level_lo[2];
|
||||
uint32_t tex_level_hi[2];
|
||||
uint32_t tex_palette_size[2];
|
||||
drm_via_sequence_t unfinished;
|
||||
|
@ -55,7 +53,7 @@ typedef struct{
|
|||
const uint32_t *buf_start;
|
||||
} drm_via_state_t;
|
||||
|
||||
extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
|
||||
drm_device_t *dev, int agp);
|
||||
extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
|
||||
drm_device_t * dev, int agp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,8 +29,7 @@
|
|||
#include "via_drm.h"
|
||||
#include "via_drv.h"
|
||||
|
||||
void
|
||||
via_init_futex(drm_via_private_t *dev_priv)
|
||||
void via_init_futex(drm_via_private_t * dev_priv)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
@ -42,30 +41,28 @@ via_init_futex(drm_via_private_t *dev_priv)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
via_cleanup_futex(drm_via_private_t *dev_priv)
|
||||
void via_cleanup_futex(drm_via_private_t * dev_priv)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
via_release_futex(drm_via_private_t *dev_priv, int context)
|
||||
void via_release_futex(drm_via_private_t * dev_priv, int context)
|
||||
{
|
||||
unsigned int i;
|
||||
volatile int *lock;
|
||||
|
||||
for (i=0; i < VIA_NR_XVMC_LOCKS; ++i) {
|
||||
lock = (int *) XVMCLOCKPTR(dev_priv->sarea_priv, i);
|
||||
if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) {
|
||||
if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) {
|
||||
DRM_WAKEUP( &(dev_priv->decoder_queue[i]));
|
||||
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
|
||||
lock = (int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
|
||||
if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
|
||||
if (_DRM_LOCK_IS_HELD(*lock)
|
||||
&& (*lock & _DRM_LOCK_CONT)) {
|
||||
DRM_WAKEUP(&(dev_priv->decoder_queue[i]));
|
||||
}
|
||||
*lock = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
via_decoder_futex(DRM_IOCTL_ARGS)
|
||||
int via_decoder_futex(DRM_IOCTL_ARGS)
|
||||
{
|
||||
DRM_DEVICE;
|
||||
drm_via_futex_t fx;
|
||||
|
@ -95,4 +92,3 @@ via_decoder_futex(DRM_IOCTL_ARGS)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue