xf86drm.h revision 22944501
122944501Smrg/** 222944501Smrg * \file xf86drm.h 322944501Smrg * OS-independent header for DRM user-level library interface. 422944501Smrg * 522944501Smrg * \author Rickard E. (Rik) Faith <faith@valinux.com> 622944501Smrg */ 722944501Smrg 822944501Smrg/* 922944501Smrg * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. 1022944501Smrg * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 1122944501Smrg * All Rights Reserved. 1222944501Smrg * 1322944501Smrg * Permission is hereby granted, free of charge, to any person obtaining a 1422944501Smrg * copy of this software and associated documentation files (the "Software"), 1522944501Smrg * to deal in the Software without restriction, including without limitation 1622944501Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1722944501Smrg * and/or sell copies of the Software, and to permit persons to whom the 1822944501Smrg * Software is furnished to do so, subject to the following conditions: 1922944501Smrg * 2022944501Smrg * The above copyright notice and this permission notice (including the next 2122944501Smrg * paragraph) shall be included in all copies or substantial portions of the 2222944501Smrg * Software. 2322944501Smrg * 2422944501Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2522944501Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2622944501Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2722944501Smrg * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 2822944501Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2922944501Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 3022944501Smrg * DEALINGS IN THE SOFTWARE. 3122944501Smrg * 3222944501Smrg */ 3322944501Smrg 3422944501Smrg#ifndef _XF86DRM_H_ 3522944501Smrg#define _XF86DRM_H_ 3622944501Smrg 3722944501Smrg#include <stdarg.h> 3822944501Smrg#include <sys/types.h> 3922944501Smrg#include <stdint.h> 4022944501Smrg#include <drm.h> 4122944501Smrg 4222944501Smrg#ifndef DRM_MAX_MINOR 4322944501Smrg#define DRM_MAX_MINOR 16 4422944501Smrg#endif 4522944501Smrg 4622944501Smrg#if defined(__linux__) 4722944501Smrg 4822944501Smrg#define DRM_IOCTL_NR(n) _IOC_NR(n) 4922944501Smrg#define DRM_IOC_VOID _IOC_NONE 5022944501Smrg#define DRM_IOC_READ _IOC_READ 5122944501Smrg#define DRM_IOC_WRITE _IOC_WRITE 5222944501Smrg#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE 5322944501Smrg#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) 5422944501Smrg 5522944501Smrg#else /* One of the *BSDs */ 5622944501Smrg 5722944501Smrg#include <sys/ioccom.h> 5822944501Smrg#define DRM_IOCTL_NR(n) ((n) & 0xff) 5922944501Smrg#define DRM_IOC_VOID IOC_VOID 6022944501Smrg#define DRM_IOC_READ IOC_OUT 6122944501Smrg#define DRM_IOC_WRITE IOC_IN 6222944501Smrg#define DRM_IOC_READWRITE IOC_INOUT 6322944501Smrg#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) 6422944501Smrg 6522944501Smrg#endif 6622944501Smrg 6722944501Smrg /* Defaults, if nothing set in xf86config */ 6822944501Smrg#define DRM_DEV_UID 0 6922944501Smrg#define DRM_DEV_GID 0 7022944501Smrg/* Default /dev/dri directory permissions 0755 */ 7122944501Smrg#define DRM_DEV_DIRMODE \ 7222944501Smrg (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 7322944501Smrg#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) 7422944501Smrg 7522944501Smrg#define DRM_DIR_NAME "/dev/dri" 7622944501Smrg#define DRM_DEV_NAME "%s/card%d" 7722944501Smrg#define DRM_CONTROL_DEV_NAME "%s/controlD%d" 7822944501Smrg#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ 7922944501Smrg 8022944501Smrg#define DRM_ERR_NO_DEVICE (-1001) 8122944501Smrg#define DRM_ERR_NO_ACCESS (-1002) 8222944501Smrg#define DRM_ERR_NOT_ROOT (-1003) 8322944501Smrg#define DRM_ERR_INVALID (-1004) 8422944501Smrg#define DRM_ERR_NO_FD (-1005) 8522944501Smrg 8622944501Smrg#define DRM_AGP_NO_HANDLE 0 8722944501Smrg 8822944501Smrgtypedef unsigned int drmSize, *drmSizePtr; /**< For mapped regions */ 8922944501Smrgtypedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */ 9022944501Smrg 9122944501Smrgtypedef struct _drmServerInfo { 9222944501Smrg int (*debug_print)(const char *format, va_list ap); 9322944501Smrg int (*load_module)(const char *name); 9422944501Smrg void (*get_perms)(gid_t *, mode_t *); 9522944501Smrg} drmServerInfo, *drmServerInfoPtr; 9622944501Smrg 9722944501Smrgtypedef struct drmHashEntry { 9822944501Smrg int fd; 9922944501Smrg void (*f)(int, void *, void *); 10022944501Smrg void *tagTable; 10122944501Smrg} drmHashEntry; 10222944501Smrg 10322944501Smrgextern int drmIoctl(int fd, unsigned long request, void *arg); 10422944501Smrgextern void *drmGetHashTable(void); 10522944501Smrgextern drmHashEntry *drmGetEntry(int fd); 10622944501Smrg 10722944501Smrg/** 10822944501Smrg * Driver version information. 10922944501Smrg * 11022944501Smrg * \sa drmGetVersion() and drmSetVersion(). 11122944501Smrg */ 11222944501Smrgtypedef struct _drmVersion { 11322944501Smrg int version_major; /**< Major version */ 11422944501Smrg int version_minor; /**< Minor version */ 11522944501Smrg int version_patchlevel; /**< Patch level */ 11622944501Smrg int name_len; /**< Length of name buffer */ 11722944501Smrg char *name; /**< Name of driver */ 11822944501Smrg int date_len; /**< Length of date buffer */ 11922944501Smrg char *date; /**< User-space buffer to hold date */ 12022944501Smrg int desc_len; /**< Length of desc buffer */ 12122944501Smrg char *desc; /**< User-space buffer to hold desc */ 12222944501Smrg} drmVersion, *drmVersionPtr; 12322944501Smrg 12422944501Smrgtypedef struct _drmStats { 12522944501Smrg unsigned long count; /**< Number of data */ 12622944501Smrg struct { 12722944501Smrg unsigned long value; /**< Value from kernel */ 12822944501Smrg const char *long_format; /**< Suggested format for long_name */ 12922944501Smrg const char *long_name; /**< Long name for value */ 13022944501Smrg const char *rate_format; /**< Suggested format for rate_name */ 13122944501Smrg const char *rate_name; /**< Short name for value per second */ 13222944501Smrg int isvalue; /**< True if value (vs. counter) */ 13322944501Smrg const char *mult_names; /**< Multiplier names (e.g., "KGM") */ 13422944501Smrg int mult; /**< Multiplier value (e.g., 1024) */ 13522944501Smrg int verbose; /**< Suggest only in verbose output */ 13622944501Smrg } data[15]; 13722944501Smrg} drmStatsT; 13822944501Smrg 13922944501Smrg 14022944501Smrg /* All of these enums *MUST* match with the 14122944501Smrg kernel implementation -- so do *NOT* 14222944501Smrg change them! (The drmlib implementation 14322944501Smrg will just copy the flags instead of 14422944501Smrg translating them.) */ 14522944501Smrgtypedef enum { 14622944501Smrg DRM_FRAME_BUFFER = 0, /**< WC, no caching, no core dump */ 14722944501Smrg DRM_REGISTERS = 1, /**< no caching, no core dump */ 14822944501Smrg DRM_SHM = 2, /**< shared, cached */ 14922944501Smrg DRM_AGP = 3, /**< AGP/GART */ 15022944501Smrg DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */ 15122944501Smrg DRM_CONSISTENT = 5 /**< PCI consistent */ 15222944501Smrg} drmMapType; 15322944501Smrg 15422944501Smrgtypedef enum { 15522944501Smrg DRM_RESTRICTED = 0x0001, /**< Cannot be mapped to client-virtual */ 15622944501Smrg DRM_READ_ONLY = 0x0002, /**< Read-only in client-virtual */ 15722944501Smrg DRM_LOCKED = 0x0004, /**< Physical pages locked */ 15822944501Smrg DRM_KERNEL = 0x0008, /**< Kernel requires access */ 15922944501Smrg DRM_WRITE_COMBINING = 0x0010, /**< Use write-combining, if available */ 16022944501Smrg DRM_CONTAINS_LOCK = 0x0020, /**< SHM page that contains lock */ 16122944501Smrg DRM_REMOVABLE = 0x0040 /**< Removable mapping */ 16222944501Smrg} drmMapFlags; 16322944501Smrg 16422944501Smrg/** 16522944501Smrg * \warning These values *MUST* match drm.h 16622944501Smrg */ 16722944501Smrgtypedef enum { 16822944501Smrg /** \name Flags for DMA buffer dispatch */ 16922944501Smrg /*@{*/ 17022944501Smrg DRM_DMA_BLOCK = 0x01, /**< 17122944501Smrg * Block until buffer dispatched. 17222944501Smrg * 17322944501Smrg * \note the buffer may not yet have been 17422944501Smrg * processed by the hardware -- getting a 17522944501Smrg * hardware lock with the hardware quiescent 17622944501Smrg * will ensure that the buffer has been 17722944501Smrg * processed. 17822944501Smrg */ 17922944501Smrg DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ 18022944501Smrg DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ 18122944501Smrg /*@}*/ 18222944501Smrg 18322944501Smrg /** \name Flags for DMA buffer request */ 18422944501Smrg /*@{*/ 18522944501Smrg DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ 18622944501Smrg DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ 18722944501Smrg DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ 18822944501Smrg /*@}*/ 18922944501Smrg} drmDMAFlags; 19022944501Smrg 19122944501Smrgtypedef enum { 19222944501Smrg DRM_PAGE_ALIGN = 0x01, 19322944501Smrg DRM_AGP_BUFFER = 0x02, 19422944501Smrg DRM_SG_BUFFER = 0x04, 19522944501Smrg DRM_FB_BUFFER = 0x08, 19622944501Smrg DRM_PCI_BUFFER_RO = 0x10 19722944501Smrg} drmBufDescFlags; 19822944501Smrg 19922944501Smrgtypedef enum { 20022944501Smrg DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ 20122944501Smrg DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ 20222944501Smrg DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ 20322944501Smrg DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ 20422944501Smrg /* These *HALT* flags aren't supported yet 20522944501Smrg -- they will be used to support the 20622944501Smrg full-screen DGA-like mode. */ 20722944501Smrg DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ 20822944501Smrg DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ 20922944501Smrg} drmLockFlags; 21022944501Smrg 21122944501Smrgtypedef enum { 21222944501Smrg DRM_CONTEXT_PRESERVED = 0x01, /**< This context is preserved and 21322944501Smrg never swapped. */ 21422944501Smrg DRM_CONTEXT_2DONLY = 0x02 /**< This context is for 2D rendering only. */ 21522944501Smrg} drm_context_tFlags, *drm_context_tFlagsPtr; 21622944501Smrg 21722944501Smrgtypedef struct _drmBufDesc { 21822944501Smrg int count; /**< Number of buffers of this size */ 21922944501Smrg int size; /**< Size in bytes */ 22022944501Smrg int low_mark; /**< Low water mark */ 22122944501Smrg int high_mark; /**< High water mark */ 22222944501Smrg} drmBufDesc, *drmBufDescPtr; 22322944501Smrg 22422944501Smrgtypedef struct _drmBufInfo { 22522944501Smrg int count; /**< Number of buffers described in list */ 22622944501Smrg drmBufDescPtr list; /**< List of buffer descriptions */ 22722944501Smrg} drmBufInfo, *drmBufInfoPtr; 22822944501Smrg 22922944501Smrgtypedef struct _drmBuf { 23022944501Smrg int idx; /**< Index into the master buffer list */ 23122944501Smrg int total; /**< Buffer size */ 23222944501Smrg int used; /**< Amount of buffer in use (for DMA) */ 23322944501Smrg drmAddress address; /**< Address */ 23422944501Smrg} drmBuf, *drmBufPtr; 23522944501Smrg 23622944501Smrg/** 23722944501Smrg * Buffer mapping information. 23822944501Smrg * 23922944501Smrg * Used by drmMapBufs() and drmUnmapBufs() to store information about the 24022944501Smrg * mapped buffers. 24122944501Smrg */ 24222944501Smrgtypedef struct _drmBufMap { 24322944501Smrg int count; /**< Number of buffers mapped */ 24422944501Smrg drmBufPtr list; /**< Buffers */ 24522944501Smrg} drmBufMap, *drmBufMapPtr; 24622944501Smrg 24722944501Smrgtypedef struct _drmLock { 24822944501Smrg volatile unsigned int lock; 24922944501Smrg char padding[60]; 25022944501Smrg /* This is big enough for most current (and future?) architectures: 25122944501Smrg DEC Alpha: 32 bytes 25222944501Smrg Intel Merced: ? 25322944501Smrg Intel P5/PPro/PII/PIII: 32 bytes 25422944501Smrg Intel StrongARM: 32 bytes 25522944501Smrg Intel i386/i486: 16 bytes 25622944501Smrg MIPS: 32 bytes (?) 25722944501Smrg Motorola 68k: 16 bytes 25822944501Smrg Motorola PowerPC: 32 bytes 25922944501Smrg Sun SPARC: 32 bytes 26022944501Smrg */ 26122944501Smrg} drmLock, *drmLockPtr; 26222944501Smrg 26322944501Smrg/** 26422944501Smrg * Indices here refer to the offset into 26522944501Smrg * list in drmBufInfo 26622944501Smrg */ 26722944501Smrgtypedef struct _drmDMAReq { 26822944501Smrg drm_context_t context; /**< Context handle */ 26922944501Smrg int send_count; /**< Number of buffers to send */ 27022944501Smrg int *send_list; /**< List of handles to buffers */ 27122944501Smrg int *send_sizes; /**< Lengths of data to send, in bytes */ 27222944501Smrg drmDMAFlags flags; /**< Flags */ 27322944501Smrg int request_count; /**< Number of buffers requested */ 27422944501Smrg int request_size; /**< Desired size of buffers requested */ 27522944501Smrg int *request_list; /**< Buffer information */ 27622944501Smrg int *request_sizes; /**< Minimum acceptable sizes */ 27722944501Smrg int granted_count; /**< Number of buffers granted at this size */ 27822944501Smrg} drmDMAReq, *drmDMAReqPtr; 27922944501Smrg 28022944501Smrgtypedef struct _drmRegion { 28122944501Smrg drm_handle_t handle; 28222944501Smrg unsigned int offset; 28322944501Smrg drmSize size; 28422944501Smrg drmAddress map; 28522944501Smrg} drmRegion, *drmRegionPtr; 28622944501Smrg 28722944501Smrgtypedef struct _drmTextureRegion { 28822944501Smrg unsigned char next; 28922944501Smrg unsigned char prev; 29022944501Smrg unsigned char in_use; 29122944501Smrg unsigned char padding; /**< Explicitly pad this out */ 29222944501Smrg unsigned int age; 29322944501Smrg} drmTextureRegion, *drmTextureRegionPtr; 29422944501Smrg 29522944501Smrg 29622944501Smrgtypedef enum { 29722944501Smrg DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ 29822944501Smrg DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ 29922944501Smrg DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ 30022944501Smrg DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ 30122944501Smrg DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ 30222944501Smrg DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ 30322944501Smrg DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ 30422944501Smrg} drmVBlankSeqType; 30522944501Smrg 30622944501Smrgtypedef struct _drmVBlankReq { 30722944501Smrg drmVBlankSeqType type; 30822944501Smrg unsigned int sequence; 30922944501Smrg unsigned long signal; 31022944501Smrg} drmVBlankReq, *drmVBlankReqPtr; 31122944501Smrg 31222944501Smrgtypedef struct _drmVBlankReply { 31322944501Smrg drmVBlankSeqType type; 31422944501Smrg unsigned int sequence; 31522944501Smrg long tval_sec; 31622944501Smrg long tval_usec; 31722944501Smrg} drmVBlankReply, *drmVBlankReplyPtr; 31822944501Smrg 31922944501Smrgtypedef union _drmVBlank { 32022944501Smrg drmVBlankReq request; 32122944501Smrg drmVBlankReply reply; 32222944501Smrg} drmVBlank, *drmVBlankPtr; 32322944501Smrg 32422944501Smrgtypedef struct _drmSetVersion { 32522944501Smrg int drm_di_major; 32622944501Smrg int drm_di_minor; 32722944501Smrg int drm_dd_major; 32822944501Smrg int drm_dd_minor; 32922944501Smrg} drmSetVersion, *drmSetVersionPtr; 33022944501Smrg 33122944501Smrg#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) 33222944501Smrg 33322944501Smrg#define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ 33422944501Smrg#define DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ 33522944501Smrg 33622944501Smrg#if defined(__GNUC__) && (__GNUC__ >= 2) 33722944501Smrg# if defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__) 33822944501Smrg /* Reflect changes here to drmP.h */ 33922944501Smrg#define DRM_CAS(lock,old,new,__ret) \ 34022944501Smrg do { \ 34122944501Smrg int __dummy; /* Can't mark eax as clobbered */ \ 34222944501Smrg __asm__ __volatile__( \ 34322944501Smrg "lock ; cmpxchg %4,%1\n\t" \ 34422944501Smrg "setnz %0" \ 34522944501Smrg : "=d" (__ret), \ 34622944501Smrg "=m" (__drm_dummy_lock(lock)), \ 34722944501Smrg "=a" (__dummy) \ 34822944501Smrg : "2" (old), \ 34922944501Smrg "r" (new)); \ 35022944501Smrg } while (0) 35122944501Smrg 35222944501Smrg#elif defined(__alpha__) 35322944501Smrg 35422944501Smrg#define DRM_CAS(lock, old, new, ret) \ 35522944501Smrg do { \ 35622944501Smrg int tmp, old32; \ 35722944501Smrg __asm__ __volatile__( \ 35822944501Smrg " addl $31, %5, %3\n" \ 35922944501Smrg "1: ldl_l %0, %2\n" \ 36022944501Smrg " cmpeq %0, %3, %1\n" \ 36122944501Smrg " beq %1, 2f\n" \ 36222944501Smrg " mov %4, %0\n" \ 36322944501Smrg " stl_c %0, %2\n" \ 36422944501Smrg " beq %0, 3f\n" \ 36522944501Smrg " mb\n" \ 36622944501Smrg "2: cmpeq %1, 0, %1\n" \ 36722944501Smrg ".subsection 2\n" \ 36822944501Smrg "3: br 1b\n" \ 36922944501Smrg ".previous" \ 37022944501Smrg : "=&r"(tmp), "=&r"(ret), \ 37122944501Smrg "=m"(__drm_dummy_lock(lock)), \ 37222944501Smrg "=&r"(old32) \ 37322944501Smrg : "r"(new), "r"(old) \ 37422944501Smrg : "memory"); \ 37522944501Smrg } while (0) 37622944501Smrg 37722944501Smrg#elif defined(__sparc__) 37822944501Smrg 37922944501Smrg#define DRM_CAS(lock,old,new,__ret) \ 38022944501Smrgdo { register unsigned int __old __asm("o0"); \ 38122944501Smrg register unsigned int __new __asm("o1"); \ 38222944501Smrg register volatile unsigned int *__lock __asm("o2"); \ 38322944501Smrg __old = old; \ 38422944501Smrg __new = new; \ 38522944501Smrg __lock = (volatile unsigned int *)lock; \ 38622944501Smrg __asm__ __volatile__( \ 38722944501Smrg /*"cas [%2], %3, %0"*/ \ 38822944501Smrg ".word 0xd3e29008\n\t" \ 38922944501Smrg /*"membar #StoreStore | #StoreLoad"*/ \ 39022944501Smrg ".word 0x8143e00a" \ 39122944501Smrg : "=&r" (__new) \ 39222944501Smrg : "0" (__new), \ 39322944501Smrg "r" (__lock), \ 39422944501Smrg "r" (__old) \ 39522944501Smrg : "memory"); \ 39622944501Smrg __ret = (__new != __old); \ 39722944501Smrg} while(0) 39822944501Smrg 39922944501Smrg#elif defined(__ia64__) 40022944501Smrg 40122944501Smrg#ifdef __INTEL_COMPILER 40222944501Smrg/* this currently generates bad code (missing stop bits)... */ 40322944501Smrg#include <ia64intrin.h> 40422944501Smrg 40522944501Smrg#define DRM_CAS(lock,old,new,__ret) \ 40622944501Smrg do { \ 40722944501Smrg unsigned long __result, __old = (old) & 0xffffffff; \ 40822944501Smrg __mf(); \ 40922944501Smrg __result = _InterlockedCompareExchange_acq(&__drm_dummy_lock(lock), (new), __old);\ 41022944501Smrg __ret = (__result) != (__old); \ 41122944501Smrg/* __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \ 41222944501Smrg (old), (new)) \ 41322944501Smrg != (old)); */\ 41422944501Smrg } while (0) 41522944501Smrg 41622944501Smrg#else 41722944501Smrg#define DRM_CAS(lock,old,new,__ret) \ 41822944501Smrg do { \ 41922944501Smrg unsigned int __result, __old = (old); \ 42022944501Smrg __asm__ __volatile__( \ 42122944501Smrg "mf\n" \ 42222944501Smrg "mov ar.ccv=%2\n" \ 42322944501Smrg ";;\n" \ 42422944501Smrg "cmpxchg4.acq %0=%1,%3,ar.ccv" \ 42522944501Smrg : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \ 42622944501Smrg : "r" ((unsigned long)__old), "r" (new) \ 42722944501Smrg : "memory"); \ 42822944501Smrg __ret = (__result) != (__old); \ 42922944501Smrg } while (0) 43022944501Smrg 43122944501Smrg#endif 43222944501Smrg 43322944501Smrg#elif defined(__powerpc__) 43422944501Smrg 43522944501Smrg#define DRM_CAS(lock,old,new,__ret) \ 43622944501Smrg do { \ 43722944501Smrg __asm__ __volatile__( \ 43822944501Smrg "sync;" \ 43922944501Smrg "0: lwarx %0,0,%1;" \ 44022944501Smrg " xor. %0,%3,%0;" \ 44122944501Smrg " bne 1f;" \ 44222944501Smrg " stwcx. %2,0,%1;" \ 44322944501Smrg " bne- 0b;" \ 44422944501Smrg "1: " \ 44522944501Smrg "sync;" \ 44622944501Smrg : "=&r"(__ret) \ 44722944501Smrg : "r"(lock), "r"(new), "r"(old) \ 44822944501Smrg : "cr0", "memory"); \ 44922944501Smrg } while (0) 45022944501Smrg 45122944501Smrg#endif /* architecture */ 45222944501Smrg#endif /* __GNUC__ >= 2 */ 45322944501Smrg 45422944501Smrg#ifndef DRM_CAS 45522944501Smrg#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */ 45622944501Smrg#endif 45722944501Smrg 45822944501Smrg#if defined(__alpha__) 45922944501Smrg#define DRM_CAS_RESULT(_result) long _result 46022944501Smrg#elif defined(__powerpc__) 46122944501Smrg#define DRM_CAS_RESULT(_result) int _result 46222944501Smrg#else 46322944501Smrg#define DRM_CAS_RESULT(_result) char _result 46422944501Smrg#endif 46522944501Smrg 46622944501Smrg#define DRM_LIGHT_LOCK(fd,lock,context) \ 46722944501Smrg do { \ 46822944501Smrg DRM_CAS_RESULT(__ret); \ 46922944501Smrg DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ 47022944501Smrg if (__ret) drmGetLock(fd,context,0); \ 47122944501Smrg } while(0) 47222944501Smrg 47322944501Smrg /* This one counts fast locks -- for 47422944501Smrg benchmarking only. */ 47522944501Smrg#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \ 47622944501Smrg do { \ 47722944501Smrg DRM_CAS_RESULT(__ret); \ 47822944501Smrg DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ 47922944501Smrg if (__ret) drmGetLock(fd,context,0); \ 48022944501Smrg else ++count; \ 48122944501Smrg } while(0) 48222944501Smrg 48322944501Smrg#define DRM_LOCK(fd,lock,context,flags) \ 48422944501Smrg do { \ 48522944501Smrg if (flags) drmGetLock(fd,context,flags); \ 48622944501Smrg else DRM_LIGHT_LOCK(fd,lock,context); \ 48722944501Smrg } while(0) 48822944501Smrg 48922944501Smrg#define DRM_UNLOCK(fd,lock,context) \ 49022944501Smrg do { \ 49122944501Smrg DRM_CAS_RESULT(__ret); \ 49222944501Smrg DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \ 49322944501Smrg if (__ret) drmUnlock(fd,context); \ 49422944501Smrg } while(0) 49522944501Smrg 49622944501Smrg /* Simple spin locks */ 49722944501Smrg#define DRM_SPINLOCK(spin,val) \ 49822944501Smrg do { \ 49922944501Smrg DRM_CAS_RESULT(__ret); \ 50022944501Smrg do { \ 50122944501Smrg DRM_CAS(spin,0,val,__ret); \ 50222944501Smrg if (__ret) while ((spin)->lock); \ 50322944501Smrg } while (__ret); \ 50422944501Smrg } while(0) 50522944501Smrg 50622944501Smrg#define DRM_SPINLOCK_TAKE(spin,val) \ 50722944501Smrg do { \ 50822944501Smrg DRM_CAS_RESULT(__ret); \ 50922944501Smrg int cur; \ 51022944501Smrg do { \ 51122944501Smrg cur = (*spin).lock; \ 51222944501Smrg DRM_CAS(spin,cur,val,__ret); \ 51322944501Smrg } while (__ret); \ 51422944501Smrg } while(0) 51522944501Smrg 51622944501Smrg#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \ 51722944501Smrg do { \ 51822944501Smrg int __i; \ 51922944501Smrg __ret = 1; \ 52022944501Smrg for (__i = 0; __ret && __i < count; __i++) { \ 52122944501Smrg DRM_CAS(spin,0,val,__ret); \ 52222944501Smrg if (__ret) for (;__i < count && (spin)->lock; __i++); \ 52322944501Smrg } \ 52422944501Smrg } while(0) 52522944501Smrg 52622944501Smrg#define DRM_SPINUNLOCK(spin,val) \ 52722944501Smrg do { \ 52822944501Smrg DRM_CAS_RESULT(__ret); \ 52922944501Smrg if ((*spin).lock == val) { /* else server stole lock */ \ 53022944501Smrg do { \ 53122944501Smrg DRM_CAS(spin,val,0,__ret); \ 53222944501Smrg } while (__ret); \ 53322944501Smrg } \ 53422944501Smrg } while(0) 53522944501Smrg 53622944501Smrg 53722944501Smrg 53822944501Smrg/* General user-level programmer's API: unprivileged */ 53922944501Smrgextern int drmAvailable(void); 54022944501Smrgextern int drmOpen(const char *name, const char *busid); 54122944501Smrgextern int drmOpenControl(int minor); 54222944501Smrgextern int drmClose(int fd); 54322944501Smrgextern drmVersionPtr drmGetVersion(int fd); 54422944501Smrgextern drmVersionPtr drmGetLibVersion(int fd); 54522944501Smrgextern void drmFreeVersion(drmVersionPtr); 54622944501Smrgextern int drmGetMagic(int fd, drm_magic_t * magic); 54722944501Smrgextern char *drmGetBusid(int fd); 54822944501Smrgextern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, 54922944501Smrg int funcnum); 55022944501Smrgextern int drmGetMap(int fd, int idx, drm_handle_t *offset, 55122944501Smrg drmSize *size, drmMapType *type, 55222944501Smrg drmMapFlags *flags, drm_handle_t *handle, 55322944501Smrg int *mtrr); 55422944501Smrgextern int drmGetClient(int fd, int idx, int *auth, int *pid, 55522944501Smrg int *uid, unsigned long *magic, 55622944501Smrg unsigned long *iocs); 55722944501Smrgextern int drmGetStats(int fd, drmStatsT *stats); 55822944501Smrgextern int drmSetInterfaceVersion(int fd, drmSetVersion *version); 55922944501Smrgextern int drmCommandNone(int fd, unsigned long drmCommandIndex); 56022944501Smrgextern int drmCommandRead(int fd, unsigned long drmCommandIndex, 56122944501Smrg void *data, unsigned long size); 56222944501Smrgextern int drmCommandWrite(int fd, unsigned long drmCommandIndex, 56322944501Smrg void *data, unsigned long size); 56422944501Smrgextern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, 56522944501Smrg void *data, unsigned long size); 56622944501Smrg 56722944501Smrg/* General user-level programmer's API: X server (root) only */ 56822944501Smrgextern void drmFreeBusid(const char *busid); 56922944501Smrgextern int drmSetBusid(int fd, const char *busid); 57022944501Smrgextern int drmAuthMagic(int fd, drm_magic_t magic); 57122944501Smrgextern int drmAddMap(int fd, 57222944501Smrg drm_handle_t offset, 57322944501Smrg drmSize size, 57422944501Smrg drmMapType type, 57522944501Smrg drmMapFlags flags, 57622944501Smrg drm_handle_t * handle); 57722944501Smrgextern int drmRmMap(int fd, drm_handle_t handle); 57822944501Smrgextern int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, 57922944501Smrg drm_handle_t handle); 58022944501Smrg 58122944501Smrgextern int drmAddBufs(int fd, int count, int size, 58222944501Smrg drmBufDescFlags flags, 58322944501Smrg int agp_offset); 58422944501Smrgextern int drmMarkBufs(int fd, double low, double high); 58522944501Smrgextern int drmCreateContext(int fd, drm_context_t * handle); 58622944501Smrgextern int drmSetContextFlags(int fd, drm_context_t context, 58722944501Smrg drm_context_tFlags flags); 58822944501Smrgextern int drmGetContextFlags(int fd, drm_context_t context, 58922944501Smrg drm_context_tFlagsPtr flags); 59022944501Smrgextern int drmAddContextTag(int fd, drm_context_t context, void *tag); 59122944501Smrgextern int drmDelContextTag(int fd, drm_context_t context); 59222944501Smrgextern void *drmGetContextTag(int fd, drm_context_t context); 59322944501Smrgextern drm_context_t * drmGetReservedContextList(int fd, int *count); 59422944501Smrgextern void drmFreeReservedContextList(drm_context_t *); 59522944501Smrgextern int drmSwitchToContext(int fd, drm_context_t context); 59622944501Smrgextern int drmDestroyContext(int fd, drm_context_t handle); 59722944501Smrgextern int drmCreateDrawable(int fd, drm_drawable_t * handle); 59822944501Smrgextern int drmDestroyDrawable(int fd, drm_drawable_t handle); 59922944501Smrgextern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, 60022944501Smrg drm_drawable_info_type_t type, 60122944501Smrg unsigned int num, void *data); 60222944501Smrgextern int drmCtlInstHandler(int fd, int irq); 60322944501Smrgextern int drmCtlUninstHandler(int fd); 60422944501Smrg 60522944501Smrg/* General user-level programmer's API: authenticated client and/or X */ 60622944501Smrgextern int drmMap(int fd, 60722944501Smrg drm_handle_t handle, 60822944501Smrg drmSize size, 60922944501Smrg drmAddressPtr address); 61022944501Smrgextern int drmUnmap(drmAddress address, drmSize size); 61122944501Smrgextern drmBufInfoPtr drmGetBufInfo(int fd); 61222944501Smrgextern drmBufMapPtr drmMapBufs(int fd); 61322944501Smrgextern int drmUnmapBufs(drmBufMapPtr bufs); 61422944501Smrgextern int drmDMA(int fd, drmDMAReqPtr request); 61522944501Smrgextern int drmFreeBufs(int fd, int count, int *list); 61622944501Smrgextern int drmGetLock(int fd, 61722944501Smrg drm_context_t context, 61822944501Smrg drmLockFlags flags); 61922944501Smrgextern int drmUnlock(int fd, drm_context_t context); 62022944501Smrgextern int drmFinish(int fd, int context, drmLockFlags flags); 62122944501Smrgextern int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, 62222944501Smrg drm_handle_t * handle); 62322944501Smrg 62422944501Smrg/* AGP/GART support: X server (root) only */ 62522944501Smrgextern int drmAgpAcquire(int fd); 62622944501Smrgextern int drmAgpRelease(int fd); 62722944501Smrgextern int drmAgpEnable(int fd, unsigned long mode); 62822944501Smrgextern int drmAgpAlloc(int fd, unsigned long size, 62922944501Smrg unsigned long type, unsigned long *address, 63022944501Smrg drm_handle_t *handle); 63122944501Smrgextern int drmAgpFree(int fd, drm_handle_t handle); 63222944501Smrgextern int drmAgpBind(int fd, drm_handle_t handle, 63322944501Smrg unsigned long offset); 63422944501Smrgextern int drmAgpUnbind(int fd, drm_handle_t handle); 63522944501Smrg 63622944501Smrg/* AGP/GART info: authenticated client and/or X */ 63722944501Smrgextern int drmAgpVersionMajor(int fd); 63822944501Smrgextern int drmAgpVersionMinor(int fd); 63922944501Smrgextern unsigned long drmAgpGetMode(int fd); 64022944501Smrgextern unsigned long drmAgpBase(int fd); /* Physical location */ 64122944501Smrgextern unsigned long drmAgpSize(int fd); /* Bytes */ 64222944501Smrgextern unsigned long drmAgpMemoryUsed(int fd); 64322944501Smrgextern unsigned long drmAgpMemoryAvail(int fd); 64422944501Smrgextern unsigned int drmAgpVendorId(int fd); 64522944501Smrgextern unsigned int drmAgpDeviceId(int fd); 64622944501Smrg 64722944501Smrg/* PCI scatter/gather support: X server (root) only */ 64822944501Smrgextern int drmScatterGatherAlloc(int fd, unsigned long size, 64922944501Smrg drm_handle_t *handle); 65022944501Smrgextern int drmScatterGatherFree(int fd, drm_handle_t handle); 65122944501Smrg 65222944501Smrgextern int drmWaitVBlank(int fd, drmVBlankPtr vbl); 65322944501Smrg 65422944501Smrg/* Support routines */ 65522944501Smrgextern void drmSetServerInfo(drmServerInfoPtr info); 65622944501Smrgextern int drmError(int err, const char *label); 65722944501Smrgextern void *drmMalloc(int size); 65822944501Smrgextern void drmFree(void *pt); 65922944501Smrg 66022944501Smrg/* Hash table routines */ 66122944501Smrgextern void *drmHashCreate(void); 66222944501Smrgextern int drmHashDestroy(void *t); 66322944501Smrgextern int drmHashLookup(void *t, unsigned long key, void **value); 66422944501Smrgextern int drmHashInsert(void *t, unsigned long key, void *value); 66522944501Smrgextern int drmHashDelete(void *t, unsigned long key); 66622944501Smrgextern int drmHashFirst(void *t, unsigned long *key, void **value); 66722944501Smrgextern int drmHashNext(void *t, unsigned long *key, void **value); 66822944501Smrg 66922944501Smrg/* PRNG routines */ 67022944501Smrgextern void *drmRandomCreate(unsigned long seed); 67122944501Smrgextern int drmRandomDestroy(void *state); 67222944501Smrgextern unsigned long drmRandom(void *state); 67322944501Smrgextern double drmRandomDouble(void *state); 67422944501Smrg 67522944501Smrg/* Skip list routines */ 67622944501Smrg 67722944501Smrgextern void *drmSLCreate(void); 67822944501Smrgextern int drmSLDestroy(void *l); 67922944501Smrgextern int drmSLLookup(void *l, unsigned long key, void **value); 68022944501Smrgextern int drmSLInsert(void *l, unsigned long key, void *value); 68122944501Smrgextern int drmSLDelete(void *l, unsigned long key); 68222944501Smrgextern int drmSLNext(void *l, unsigned long *key, void **value); 68322944501Smrgextern int drmSLFirst(void *l, unsigned long *key, void **value); 68422944501Smrgextern void drmSLDump(void *l); 68522944501Smrgextern int drmSLLookupNeighbors(void *l, unsigned long key, 68622944501Smrg unsigned long *prev_key, void **prev_value, 68722944501Smrg unsigned long *next_key, void **next_value); 68822944501Smrg 68922944501Smrgextern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened); 69022944501Smrgextern void drmCloseOnce(int fd); 69122944501Smrgextern void drmMsg(const char *format, ...); 69222944501Smrg 69322944501Smrgextern int drmSetMaster(int fd); 69422944501Smrgextern int drmDropMaster(int fd); 69522944501Smrg 69622944501Smrg#define DRM_EVENT_CONTEXT_VERSION 2 69722944501Smrg 69822944501Smrgtypedef struct _drmEventContext { 69922944501Smrg 70022944501Smrg /* This struct is versioned so we can add more pointers if we 70122944501Smrg * add more events. */ 70222944501Smrg int version; 70322944501Smrg 70422944501Smrg void (*vblank_handler)(int fd, 70522944501Smrg unsigned int sequence, 70622944501Smrg unsigned int tv_sec, 70722944501Smrg unsigned int tv_usec, 70822944501Smrg void *user_data); 70922944501Smrg 71022944501Smrg void (*page_flip_handler)(int fd, 71122944501Smrg unsigned int sequence, 71222944501Smrg unsigned int tv_sec, 71322944501Smrg unsigned int tv_usec, 71422944501Smrg void *user_data); 71522944501Smrg 71622944501Smrg} drmEventContext, *drmEventContextPtr; 71722944501Smrg 71822944501Smrgextern int drmHandleEvent(int fd, drmEventContextPtr evctx); 71922944501Smrg 72022944501Smrgextern char *drmGetDeviceNameFromFd(int fd); 72122944501Smrg 72222944501Smrg#endif 723