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