diff options
Diffstat (limited to 'include/drm/drmP.h')
| -rw-r--r-- | include/drm/drmP.h | 1023 | 
1 files changed, 558 insertions, 465 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 274eaaa15c3..8af71a8e2c0 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -42,11 +42,10 @@   * can build the DRM (part of PI DRI). 4/21/2000 S + B */  #include <asm/current.h>  #endif				/* __alpha__ */ -#include <linux/module.h>  #include <linux/kernel.h> +#include <linux/kref.h>  #include <linux/miscdevice.h>  #include <linux/fs.h> -#include <linux/proc_fs.h>  #include <linux/init.h>  #include <linux/file.h>  #include <linux/platform_device.h> @@ -56,96 +55,93 @@  #include <linux/mm.h>  #include <linux/cdev.h>  #include <linux/mutex.h> +#include <linux/io.h>  #include <linux/slab.h> +#include <linux/ratelimit.h>  #if defined(__alpha__) || defined(__powerpc__)  #include <asm/pgtable.h>	/* For pte_wrprotect */  #endif -#include <asm/io.h>  #include <asm/mman.h>  #include <asm/uaccess.h> -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif -#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)  #include <linux/types.h>  #include <linux/agp_backend.h> -#endif  #include <linux/workqueue.h>  #include <linux/poll.h>  #include <asm/pgalloc.h> -#include "drm.h" +#include <drm/drm.h> +#include <drm/drm_sarea.h> +#include <drm/drm_vma_manager.h>  #include <linux/idr.h>  #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE))) -#define __OS_HAS_MTRR (defined(CONFIG_MTRR)) + +struct module;  struct drm_file;  struct drm_device; -#include "drm_os_linux.h" -#include "drm_hashtab.h" -#include "drm_mm.h" +struct device_node; +struct videomode; + +#include <drm/drm_os_linux.h> +#include <drm/drm_hashtab.h> +#include <drm/drm_mm.h> -#define DRM_UT_CORE 		0x01 -#define DRM_UT_DRIVER		0x02 -#define DRM_UT_KMS		0x04  /* - * Three debug levels are defined. - * drm_core, drm_driver, drm_kms - * drm_core level can be used in the generic drm code. For example: - * 	drm_ioctl, drm_mm, drm_memory - * The macro definiton of DRM_DEBUG is used. - * 	DRM_DEBUG(fmt, args...) - * 	The debug info by using the DRM_DEBUG can be obtained by adding - * 	the boot option of "drm.debug=1". + * 4 debug categories are defined: + * + * CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c, drm_memory.c, ... + *	 This is the category used by the DRM_DEBUG() macro.   * - * drm_driver level can be used in the specific drm driver. It is used - * to add the debug info related with the drm driver. For example: - * i915_drv, i915_dma, i915_gem, radeon_drv, - * 	The macro definition of DRM_DEBUG_DRIVER can be used. - * 	DRM_DEBUG_DRIVER(fmt, args...) - * 	The debug info by using the DRM_DEBUG_DRIVER can be obtained by - * 	adding the boot option of "drm.debug=0x02" + * DRIVER: Used in the vendor specific part of the driver: i915, radeon, ... + *	   This is the category used by the DRM_DEBUG_DRIVER() macro.   * - * drm_kms level can be used in the KMS code related with specific drm driver. - * It is used to add the debug info related with KMS mode. For example: - * the connector/crtc , - * 	The macro definition of DRM_DEBUG_KMS can be used. - * 	DRM_DEBUG_KMS(fmt, args...) - * 	The debug info by using the DRM_DEBUG_KMS can be obtained by - * 	adding the boot option of "drm.debug=0x04" + * KMS: used in the modesetting code. + *	This is the category used by the DRM_DEBUG_KMS() macro.   * - * If we add the boot option of "drm.debug=0x06", we can get the debug info by - * using the DRM_DEBUG_KMS and DRM_DEBUG_DRIVER. - * If we add the boot option of "drm.debug=0x05", we can get the debug info by - * using the DRM_DEBUG_KMS and DRM_DEBUG. + * PRIME: used in the prime code. + *	  This is the category used by the DRM_DEBUG_PRIME() macro. + * + * Enabling verbose debug messages is done through the drm.debug parameter, + * each category being enabled by a bit. + * + * drm.debug=0x1 will enable CORE messages + * drm.debug=0x2 will enable DRIVER messages + * drm.debug=0x3 will enable CORE and DRIVER messages + * ... + * drm.debug=0xf will enable all messages + * + * An interesting feature is that it's possible to enable verbose logging at + * run-time by echoing the debug value in its sysfs node: + *   # echo 0xf > /sys/module/drm/parameters/debug   */ +#define DRM_UT_CORE 		0x01 +#define DRM_UT_DRIVER		0x02 +#define DRM_UT_KMS		0x04 +#define DRM_UT_PRIME		0x08 + +extern __printf(2, 3) +void drm_ut_debug_printk(const char *function_name, +			 const char *format, ...); +extern __printf(2, 3) +int drm_err(const char *func, const char *format, ...); -extern void drm_ut_debug_printk(unsigned int request_level, -				const char *prefix, -				const char *function_name, -				const char *format, ...);  /***********************************************************************/  /** \name DRM template customization defaults */  /*@{*/  /* driver capabilities and requirements mask */  #define DRIVER_USE_AGP     0x1 -#define DRIVER_REQUIRE_AGP 0x2 -#define DRIVER_USE_MTRR    0x4  #define DRIVER_PCI_DMA     0x8  #define DRIVER_SG          0x10  #define DRIVER_HAVE_DMA    0x20  #define DRIVER_HAVE_IRQ    0x40  #define DRIVER_IRQ_SHARED  0x80 -#define DRIVER_IRQ_VBL     0x100 -#define DRIVER_DMA_QUEUE   0x200 -#define DRIVER_FB_DMA      0x400 -#define DRIVER_IRQ_VBL2    0x800  #define DRIVER_GEM         0x1000  #define DRIVER_MODESET     0x2000 -#define DRIVER_USE_PLATFORM_DEVICE  0x4000 +#define DRIVER_PRIME       0x4000 +#define DRIVER_RENDER      0x8000  /***********************************************************************/  /** \name Begin the DRM... */ @@ -157,13 +153,7 @@ extern void drm_ut_debug_printk(unsigned int request_level,  #define DRM_MAGIC_HASH_ORDER  4  /**< Size of key hash table. Must be power of 2. */  #define DRM_KERNEL_CONTEXT    0	 /**< Change drm_resctx if changed */  #define DRM_RESERVED_CONTEXTS 1	 /**< Change drm_resctx if changed */ -#define DRM_LOOPING_LIMIT     5000000 -#define DRM_TIME_SLICE	      (HZ/20)  /**< Time slice for GLXContexts */ -#define DRM_LOCK_SLICE	      1	/**< Time slice for lock, in jiffies */ -#define DRM_FLAG_DEBUG	  0x01 - -#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)  #define DRM_MAP_HASH_OFFSET 0x10000000  /*@}*/ @@ -178,21 +168,30 @@ extern void drm_ut_debug_printk(unsigned int request_level,   * \param fmt printf() like format string.   * \param arg arguments   */ -#define DRM_ERROR(fmt, arg...) \ -	printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg) +#define DRM_ERROR(fmt, ...)				\ +	drm_err(__func__, fmt, ##__VA_ARGS__)  /** - * Memory error output. + * Rate limited error output.  Like DRM_ERROR() but won't flood the log.   * - * \param area memory area where the error occurred.   * \param fmt printf() like format string.   * \param arg arguments   */ -#define DRM_MEM_ERROR(area, fmt, arg...) \ -	printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __func__, \ -	       drm_mem_stats[area].name , ##arg) - -#define DRM_INFO(fmt, arg...)  printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg) +#define DRM_ERROR_RATELIMITED(fmt, ...)				\ +({									\ +	static DEFINE_RATELIMIT_STATE(_rs,				\ +				      DEFAULT_RATELIMIT_INTERVAL,	\ +				      DEFAULT_RATELIMIT_BURST);		\ +									\ +	if (__ratelimit(&_rs))						\ +		drm_err(__func__, fmt, ##__VA_ARGS__);			\ +}) + +#define DRM_INFO(fmt, ...)				\ +	printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__) + +#define DRM_INFO_ONCE(fmt, ...)				\ +	printk_once(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__)  /**   * Debug output. @@ -203,49 +202,30 @@ extern void drm_ut_debug_printk(unsigned int request_level,  #if DRM_DEBUG_CODE  #define DRM_DEBUG(fmt, args...)						\  	do {								\ -		drm_ut_debug_printk(DRM_UT_CORE, DRM_NAME, 		\ -					__func__, fmt, ##args);		\ +		if (unlikely(drm_debug & DRM_UT_CORE))			\ +			drm_ut_debug_printk(__func__, fmt, ##args);	\  	} while (0)  #define DRM_DEBUG_DRIVER(fmt, args...)					\  	do {								\ -		drm_ut_debug_printk(DRM_UT_DRIVER, DRM_NAME,		\ -					__func__, fmt, ##args);		\ -	} while (0) -#define DRM_DEBUG_KMS(fmt, args...)				\ -	do {								\ -		drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, 		\ -					 __func__, fmt, ##args);	\ -	} while (0) -#define DRM_LOG(fmt, args...)						\ -	do {								\ -		drm_ut_debug_printk(DRM_UT_CORE, NULL,			\ -					NULL, fmt, ##args);		\ -	} while (0) -#define DRM_LOG_KMS(fmt, args...)					\ -	do {								\ -		drm_ut_debug_printk(DRM_UT_KMS, NULL,			\ -					NULL, fmt, ##args);		\ +		if (unlikely(drm_debug & DRM_UT_DRIVER))		\ +			drm_ut_debug_printk(__func__, fmt, ##args);	\  	} while (0) -#define DRM_LOG_MODE(fmt, args...)					\ +#define DRM_DEBUG_KMS(fmt, args...)					\  	do {								\ -		drm_ut_debug_printk(DRM_UT_MODE, NULL,			\ -					NULL, fmt, ##args);		\ +		if (unlikely(drm_debug & DRM_UT_KMS))			\ +			drm_ut_debug_printk(__func__, fmt, ##args);	\  	} while (0) -#define DRM_LOG_DRIVER(fmt, args...)					\ +#define DRM_DEBUG_PRIME(fmt, args...)					\  	do {								\ -		drm_ut_debug_printk(DRM_UT_DRIVER, NULL,		\ -					NULL, fmt, ##args);		\ +		if (unlikely(drm_debug & DRM_UT_PRIME))			\ +			drm_ut_debug_printk(__func__, fmt, ##args);	\  	} while (0)  #else  #define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)  #define DRM_DEBUG_KMS(fmt, args...)	do { } while (0) +#define DRM_DEBUG_PRIME(fmt, args...)	do { } while (0)  #define DRM_DEBUG(fmt, arg...)		 do { } while (0) -#define DRM_LOG(fmt, arg...)		do { } while (0) -#define DRM_LOG_KMS(fmt, args...) do { } while (0) -#define DRM_LOG_MODE(fmt, arg...) do { } while (0) -#define DRM_LOG_DRIVER(fmt, arg...) do { } while (0) -  #endif  /*@}*/ @@ -254,11 +234,6 @@ extern void drm_ut_debug_printk(unsigned int request_level,  /** \name Internal types and structures */  /*@{*/ -#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) - -#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) -#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) -  #define DRM_IF_VERSION(maj, min) (maj << 16 | min)  /** @@ -300,12 +275,14 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,  #define DRM_ROOT_ONLY	0x4  #define DRM_CONTROL_ALLOW 0x8  #define DRM_UNLOCKED	0x10 +#define DRM_RENDER_ALLOW 0x20  struct drm_ioctl_desc {  	unsigned int cmd;  	int flags;  	drm_ioctl_t *func;  	unsigned int cmd_drv; +	const char *name;  };  /** @@ -314,7 +291,7 @@ struct drm_ioctl_desc {   */  #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags)			\ -	[DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl} +	[DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl}  struct drm_magic_entry {  	struct list_head head; @@ -342,7 +319,6 @@ struct drm_buf {  	struct drm_buf *next;	       /**< Kernel-only: used for free list */  	__volatile__ int waiting;      /**< On kernel DMA queue */  	__volatile__ int pending;      /**< On hardware DMA queue */ -	wait_queue_head_t dma_wait;    /**< Processes waiting */  	struct drm_file *file_priv;    /**< Private of holding file descr */  	int context;		       /**< Kernel queue for this buffer */  	int while_locked;	       /**< Dispatch this buffer while locked */ @@ -412,13 +388,29 @@ struct drm_pending_event {  	void (*destroy)(struct drm_pending_event *event);  }; +/* initial implementaton using a linked list - todo hashtab */ +struct drm_prime_file_private { +	struct list_head head; +	struct mutex lock; +}; +  /** File private data */  struct drm_file { -	int authenticated; -	pid_t pid; -	uid_t uid; +	unsigned always_authenticated :1; +	unsigned authenticated :1; +	/* Whether we're master for a minor. Protected by master_mutex */ +	unsigned is_master :1; +	/* true when the client has asked us to expose stereo 3D mode flags */ +	unsigned stereo_allowed :1; +	/* +	 * true if client understands CRTC primary planes and cursor planes +	 * in the plane list +	 */ +	unsigned universal_planes:1; + +	struct pid *pid; +	kuid_t uid;  	drm_magic_t magic; -	unsigned long ioctl_count;  	struct list_head lhead;  	struct drm_minor *minor;  	unsigned long lock_count; @@ -431,14 +423,22 @@ struct drm_file {  	struct file *filp;  	void *driver_priv; -	int is_master; /* this file private is a master for a minor */  	struct drm_master *master; /* master this node is currently associated with  				      N.B. not always minor->master */ +	/** +	 * fbs - List of framebuffers associated with this file. +	 * +	 * Protected by fbs_lock. Note that the fbs list holds a reference on +	 * the fb object to prevent it from untimely disappearing. +	 */  	struct list_head fbs; +	struct mutex fbs_lock;  	wait_queue_head_t event_wait;  	struct list_head event_list;  	int event_space; + +	struct drm_prime_file_private prime;  };  /** Wait queue */ @@ -499,7 +499,7 @@ struct drm_device_dma {   */  struct drm_agp_mem {  	unsigned long handle;		/**< handle */ -	DRM_AGP_MEM *memory; +	struct agp_memory *memory;  	unsigned long bound;		/**< address */  	int pages;  	struct list_head head; @@ -511,7 +511,7 @@ struct drm_agp_mem {   * \sa drm_agp_init() and drm_device::agp.   */  struct drm_agp_head { -	DRM_AGP_KERN agp_info;		/**< AGP device information */ +	struct agp_kern_info agp_info;		/**< AGP device information */  	struct list_head memory;  	unsigned long mode;		/**< AGP mode */  	struct agp_bridge_data *bridge; @@ -564,7 +564,6 @@ struct drm_map_list {  	struct drm_local_map *map;	/**< mapping */  	uint64_t user_token;  	struct drm_master *master; -	struct drm_mm_node *file_offset_node;	/**< fake offset */  };  /** @@ -596,14 +595,6 @@ struct drm_ati_pcigart_info {  };  /** - * GEM specific mm private for tracking GEM objects - */ -struct drm_gem_mm { -	struct drm_mm offset_manager;	/**< Offset mgmt for buffer objects */ -	struct drm_open_hash offset_hash; /**< User token hash table for maps */ -}; - -/**   * This structure defines the drm_mm memory object, which will be used by the   * DRM for its buffer objects.   */ @@ -611,8 +602,16 @@ struct drm_gem_object {  	/** Reference count of this object */  	struct kref refcount; -	/** Handle count of this object. Each handle also holds a reference */ -	atomic_t handle_count; /* number of handles on this object */ +	/** +	 * handle_count - gem file_priv handle count of this object +	 * +	 * Each handle also holds a reference. Note that when the handle_count +	 * drops to 0 any global names (e.g. the id in the flink namespace) will +	 * be cleared. +	 * +	 * Protected by dev->object_name_lock. +	 * */ +	unsigned handle_count;  	/** Related drm device */  	struct drm_device *dev; @@ -621,7 +620,7 @@ struct drm_gem_object {  	struct file *filp;  	/* Mapping info for this object */ -	struct drm_map_list map_list; +	struct drm_vma_offset_node vma_node;  	/**  	 * Size of the object, in bytes.  Immutable over the object's @@ -653,34 +652,79 @@ struct drm_gem_object {  	uint32_t pending_read_domains;  	uint32_t pending_write_domain; -	void *driver_private; +	/** +	 * dma_buf - dma buf associated with this GEM object +	 * +	 * Pointer to the dma-buf associated with this gem object (either +	 * through importing or exporting). We break the resulting reference +	 * loop when the last gem handle for this object is released. +	 * +	 * Protected by obj->object_name_lock +	 */ +	struct dma_buf *dma_buf; + +	/** +	 * import_attach - dma buf attachment backing this object +	 * +	 * Any foreign dma_buf imported as a gem object has this set to the +	 * attachment point for the device. This is invariant over the lifetime +	 * of a gem object. +	 * +	 * The driver's ->gem_free_object callback is responsible for cleaning +	 * up the dma_buf attachment and references acquired at import time. +	 * +	 * Note that the drm gem/prime core does not depend upon drivers setting +	 * this field any more. So for drivers where this doesn't make sense +	 * (e.g. virtual devices or a displaylink behind an usb bus) they can +	 * simply leave it as NULL. +	 */ +	struct dma_buf_attachment *import_attach;  }; -#include "drm_crtc.h" +#include <drm/drm_crtc.h> -/* per-master structure */ +/** + * struct drm_master - drm master structure + * + * @refcount: Refcount for this master object. + * @minor: Link back to minor char device we are master for. Immutable. + * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex. + * @unique_len: Length of unique field. Protected by drm_global_mutex. + * @unique_size: Amount allocated. Protected by drm_global_mutex. + * @magiclist: Hash of used authentication tokens. Protected by struct_mutex. + * @magicfree: List of used authentication tokens. Protected by struct_mutex. + * @lock: DRI lock information. + * @driver_priv: Pointer to driver-private information. + */  struct drm_master { - -	struct kref refcount; /* refcount for this master */ - -	struct list_head head; /**< each minor contains a list of masters */ -	struct drm_minor *minor; /**< link back to minor we are a master for */ - -	char *unique;			/**< Unique identifier: e.g., busid */ -	int unique_len;			/**< Length of unique field */ -	int unique_size;		/**< amount allocated */ - -	int blocked;			/**< Blocked due to VC switch? */ - -	/** \name Authentication */ -	/*@{ */ +	struct kref refcount; +	struct drm_minor *minor; +	char *unique; +	int unique_len; +	int unique_size;  	struct drm_open_hash magiclist;  	struct list_head magicfree; -	/*@} */ +	struct drm_lock_data lock; +	void *driver_priv; +}; -	struct drm_lock_data lock;	/**< Information on hardware lock */ +/* Size of ringbuffer for vblank timestamps. Just double-buffer + * in initial implementation. + */ +#define DRM_VBLANKTIME_RBSIZE 2 -	void *driver_priv; /**< Private structure for driver to use */ +/* Flags and return codes for get_vblank_timestamp() driver function. */ +#define DRM_CALLED_FROM_VBLIRQ 1 +#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) +#define DRM_VBLANKTIME_INVBL             (1 << 1) + +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID        (1 << 0) +#define DRM_SCANOUTPOS_INVBL        (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE     (1 << 2) + +struct drm_bus { +	int (*set_busid)(struct drm_device *dev, struct drm_master *master);  };  /** @@ -707,11 +751,11 @@ struct drm_driver {  	 * @dev: DRM device  	 * @crtc: counter to fetch  	 * -	 * Driver callback for fetching a raw hardware vblank counter -	 * for @crtc.  If a device doesn't have a hardware counter, the -	 * driver can simply return the value of drm_vblank_count and -	 * make the enable_vblank() and disable_vblank() hooks into no-ops, -	 * leaving interrupts enabled at all times. +	 * Driver callback for fetching a raw hardware vblank counter for @crtc. +	 * If a device doesn't have a hardware counter, the driver can simply +	 * return the value of drm_vblank_count. The DRM core will account for +	 * missed vblank events while interrupts where disabled based on system +	 * timestamps.  	 *  	 * Wraparound handling and loss of events due to modesetting is dealt  	 * with in the DRM core code. @@ -760,20 +804,82 @@ struct drm_driver {  	 */  	int (*device_is_agp) (struct drm_device *dev); +	/** +	 * Called by vblank timestamping code. +	 * +	 * Return the current display scanout position from a crtc, and an +	 * optional accurate ktime_get timestamp of when position was measured. +	 * +	 * \param dev  DRM device. +	 * \param crtc Id of the crtc to query. +	 * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). +	 * \param *vpos Target location for current vertical scanout position. +	 * \param *hpos Target location for current horizontal scanout position. +	 * \param *stime Target location for timestamp taken immediately before +	 *               scanout position query. Can be NULL to skip timestamp. +	 * \param *etime Target location for timestamp taken immediately after +	 *               scanout position query. Can be NULL to skip timestamp. +	 * +	 * Returns vpos as a positive number while in active scanout area. +	 * Returns vpos as a negative number inside vblank, counting the number +	 * of scanlines to go until end of vblank, e.g., -1 means "one scanline +	 * until start of active scanout / end of vblank." +	 * +	 * \return Flags, or'ed together as follows: +	 * +	 * DRM_SCANOUTPOS_VALID = Query successful. +	 * DRM_SCANOUTPOS_INVBL = Inside vblank. +	 * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of +	 * this flag means that returned position may be offset by a constant +	 * but unknown small number of scanlines wrt. real scanout position. +	 * +	 */ +	int (*get_scanout_position) (struct drm_device *dev, int crtc, +				     unsigned int flags, +				     int *vpos, int *hpos, ktime_t *stime, +				     ktime_t *etime); + +	/** +	 * Called by \c drm_get_last_vbltimestamp. Should return a precise +	 * timestamp when the most recent VBLANK interval ended or will end. +	 * +	 * Specifically, the timestamp in @vblank_time should correspond as +	 * closely as possible to the time when the first video scanline of +	 * the video frame after the end of VBLANK will start scanning out, +	 * the time immediately after end of the VBLANK interval. If the +	 * @crtc is currently inside VBLANK, this will be a time in the future. +	 * If the @crtc is currently scanning out a frame, this will be the +	 * past start time of the current scanout. This is meant to adhere +	 * to the OpenML OML_sync_control extension specification. +	 * +	 * \param dev dev DRM device handle. +	 * \param crtc crtc for which timestamp should be returned. +	 * \param *max_error Maximum allowable timestamp error in nanoseconds. +	 *                   Implementation should strive to provide timestamp +	 *                   with an error of at most *max_error nanoseconds. +	 *                   Returns true upper bound on error for timestamp. +	 * \param *vblank_time Target location for returned vblank timestamp. +	 * \param flags 0 = Defaults, no special treatment needed. +	 * \param       DRM_CALLED_FROM_VBLIRQ = Function is called from vblank +	 *	        irq handler. Some drivers need to apply some workarounds +	 *              for gpu-specific vblank irq quirks if flag is set. +	 * +	 * \returns +	 * Zero if timestamping isn't supported in current display mode or a +	 * negative number on failure. A positive status code on success, +	 * which describes how the vblank_time timestamp was computed. +	 */ +	int (*get_vblank_timestamp) (struct drm_device *dev, int crtc, +				     int *max_error, +				     struct timeval *vblank_time, +				     unsigned flags); +  	/* these have to be filled in */ -	irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); +	irqreturn_t(*irq_handler) (int irq, void *arg);  	void (*irq_preinstall) (struct drm_device *dev);  	int (*irq_postinstall) (struct drm_device *dev);  	void (*irq_uninstall) (struct drm_device *dev); -	void (*reclaim_buffers) (struct drm_device *dev, -				 struct drm_file * file_priv); -	void (*reclaim_buffers_locked) (struct drm_device *dev, -					struct drm_file *file_priv); -	void (*reclaim_buffers_idlelocked) (struct drm_device *dev, -					    struct drm_file *file_priv); -	void (*set_version) (struct drm_device *dev, -			     struct drm_set_version *sv);  	/* Master routines */  	int (*master_create)(struct drm_device *dev, struct drm_master *master); @@ -797,14 +903,51 @@ struct drm_driver {  	 *  	 * Returns 0 on success.  	 */ -	int (*gem_init_object) (struct drm_gem_object *obj);  	void (*gem_free_object) (struct drm_gem_object *obj); +	int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); +	void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); + +	/* prime: */ +	/* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ +	int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, +				uint32_t handle, uint32_t flags, int *prime_fd); +	/* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */ +	int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, +				int prime_fd, uint32_t *handle); +	/* export GEM -> dmabuf */ +	struct dma_buf * (*gem_prime_export)(struct drm_device *dev, +				struct drm_gem_object *obj, int flags); +	/* import dmabuf -> GEM */ +	struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, +				struct dma_buf *dma_buf); +	/* low-level interface used by drm_gem_prime_{import,export} */ +	int (*gem_prime_pin)(struct drm_gem_object *obj); +	void (*gem_prime_unpin)(struct drm_gem_object *obj); +	struct sg_table *(*gem_prime_get_sg_table)(struct drm_gem_object *obj); +	struct drm_gem_object *(*gem_prime_import_sg_table)( +				struct drm_device *dev, size_t size, +				struct sg_table *sgt); +	void *(*gem_prime_vmap)(struct drm_gem_object *obj); +	void (*gem_prime_vunmap)(struct drm_gem_object *obj, void *vaddr); +	int (*gem_prime_mmap)(struct drm_gem_object *obj, +				struct vm_area_struct *vma);  	/* vga arb irq handler */  	void (*vgaarb_irq)(struct drm_device *dev, bool state); +	/* dumb alloc support */ +	int (*dumb_create)(struct drm_file *file_priv, +			   struct drm_device *dev, +			   struct drm_mode_create_dumb *args); +	int (*dumb_map_offset)(struct drm_file *file_priv, +			       struct drm_device *dev, uint32_t handle, +			       uint64_t *offset); +	int (*dumb_destroy)(struct drm_file *file_priv, +			    struct drm_device *dev, +			    uint32_t handle); +  	/* Driver private ops for this object */ -	struct vm_operations_struct *gem_vm_ops; +	const struct vm_operations_struct *gem_vm_ops;  	int major;  	int minor; @@ -815,39 +958,20 @@ struct drm_driver {  	u32 driver_features;  	int dev_priv_size; -	struct drm_ioctl_desc *ioctls; +	const struct drm_ioctl_desc *ioctls;  	int num_ioctls; -	struct file_operations fops; -	struct pci_driver pci_driver; -	struct platform_device *platform_device; -	/* List of devices hanging off this driver */ -	struct list_head device_list; -}; +	const struct file_operations *fops; +	struct drm_bus *bus; -#define DRM_MINOR_UNASSIGNED 0 -#define DRM_MINOR_LEGACY 1 -#define DRM_MINOR_CONTROL 2 -#define DRM_MINOR_RENDER 3 - - -/** - * debugfs node list. This structure represents a debugfs file to - * be created by the drm core - */ -struct drm_debugfs_list { -	const char *name; /** file name */ -	int (*show)(struct seq_file*, void*); /** show callback */ -	u32 driver_features; /**< Required driver features for this entry */ +	/* List of devices hanging off this driver with stealth attach. */ +	struct list_head legacy_dev_list;  }; -/** - * debugfs node structure. This structure represents a debugfs file. - */ -struct drm_debugfs_node { -	struct list_head list; -	struct drm_minor *minor; -	struct drm_debugfs_list *debugfs_ent; -	struct dentry *dent; +enum drm_minor_type { +	DRM_MINOR_LEGACY, +	DRM_MINOR_CONTROL, +	DRM_MINOR_RENDER, +	DRM_MINOR_CNT,  };  /** @@ -867,7 +991,7 @@ struct drm_info_list {  struct drm_info_node {  	struct list_head list;  	struct drm_minor *minor; -	struct drm_info_list *info_ent; +	const struct drm_info_list *info_ent;  	struct dentry *dent;  }; @@ -877,69 +1001,88 @@ struct drm_info_node {  struct drm_minor {  	int index;			/**< Minor device number */  	int type;                       /**< Control or render */ -	dev_t device;			/**< Device number for mknod */ -	struct device kdev;		/**< Linux device */ +	struct device *kdev;		/**< Linux device */  	struct drm_device *dev; -	struct proc_dir_entry *proc_root;  /**< proc directory entry */ -	struct drm_info_node proc_nodes;  	struct dentry *debugfs_root; -	struct drm_info_node debugfs_nodes; -	struct drm_master *master; /* currently active master for this node */ -	struct list_head master_list; +	struct list_head debugfs_list; +	struct mutex debugfs_lock; /* Protects debugfs_list. */ + +	/* currently active master for this node. Protected by master_mutex */ +	struct drm_master *master;  	struct drm_mode_group mode_group;  }; +  struct drm_pending_vblank_event {  	struct drm_pending_event base;  	int pipe;  	struct drm_event_vblank event;  }; +struct drm_vblank_crtc { +	struct drm_device *dev;		/* pointer to the drm_device */ +	wait_queue_head_t queue;	/**< VBLANK wait queue */ +	struct timeval time[DRM_VBLANKTIME_RBSIZE];	/**< timestamp of current count */ +	struct timer_list disable_timer;		/* delayed disable timer */ +	atomic_t count;			/**< number of VBLANK interrupts */ +	atomic_t refcount;		/* number of users of vblank interruptsper crtc */ +	u32 last;			/* protected by dev->vbl_lock, used */ +					/* for wraparound handling */ +	u32 last_wait;			/* Last vblank seqno waited per CRTC */ +	unsigned int inmodeset;		/* Display driver is setting mode */ +	int crtc;			/* crtc index */ +	bool enabled;			/* so we don't call enable more than +					   once per disable */ +}; +  /**   * DRM device structure. This structure represent a complete card that   * may contain multiple heads.   */  struct drm_device { -	struct list_head driver_item;	/**< list of devices per driver */ -	char *devname;			/**< For /proc/interrupts */ +	struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */  	int if_version;			/**< Highest interface version set */ +	/** \name Lifetime Management */ +	/*@{ */ +	struct kref ref;		/**< Object ref-count */ +	struct device *dev;		/**< Device structure of bus-device */ +	struct drm_driver *driver;	/**< DRM driver managing the device */ +	void *dev_private;		/**< DRM driver private data */ +	struct drm_minor *control;		/**< Control node */ +	struct drm_minor *primary;		/**< Primary node */ +	struct drm_minor *render;		/**< Render node */ +	atomic_t unplugged;			/**< Flag whether dev is dead */ +	struct inode *anon_inode;		/**< inode for private address-space */ +	char *unique;				/**< unique name of the device */ +	/*@} */ +  	/** \name Locks */  	/*@{ */ -	spinlock_t count_lock;		/**< For inuse, drm_device::open_count, drm_device::buf_use */  	struct mutex struct_mutex;	/**< For others */ +	struct mutex master_mutex;      /**< For drm_minor::master and drm_file::is_master */  	/*@} */  	/** \name Usage Counters */  	/*@{ */ -	int open_count;			/**< Outstanding files open */ -	atomic_t ioctl_count;		/**< Outstanding IOCTLs pending */ -	atomic_t vma_count;		/**< Outstanding vma areas open */ +	int open_count;			/**< Outstanding files open, protected by drm_global_mutex. */ +	spinlock_t buf_lock;		/**< For drm_device::buf_use and a few other things. */  	int buf_use;			/**< Buffers in use -- cannot alloc */  	atomic_t buf_alloc;		/**< Buffer allocation in progress */  	/*@} */ -	/** \name Performance counters */ -	/*@{ */ -	unsigned long counters; -	enum drm_stat_type types[15]; -	atomic_t counts[15]; -	/*@} */ -  	struct list_head filelist;  	/** \name Memory management */  	/*@{ */  	struct list_head maplist;	/**< Linked list of regions */ -	int map_count;			/**< Number of mappable regions */  	struct drm_open_hash map_hash;	/**< User token hash table for maps */  	/** \name Context handle management */  	/*@{ */  	struct list_head ctxlist;	/**< Linked list of context handles */ -	int ctx_count;			/**< Number of context handles */  	struct mutex ctxlist_mutex;	/**< For ctxlist */  	struct idr ctx_idr; @@ -948,28 +1091,20 @@ struct drm_device {  	/*@} */ -	/** \name DMA queues (contexts) */ +	/** \name DMA support */  	/*@{ */ -	int queue_count;		/**< Number of active DMA queues */ -	int queue_reserved;		  /**< Number of reserved DMA queues */ -	int queue_slots;		/**< Actual length of queuelist */ -	struct drm_queue **queuelist;	/**< Vector of pointers to DMA queues */  	struct drm_device_dma *dma;		/**< Optional pointer for DMA support */  	/*@} */  	/** \name Context support */  	/*@{ */ -	int irq_enabled;		/**< True if irq handler is enabled */ +	bool irq_enabled;		/**< True if irq handler is enabled */ +	int irq; +  	__volatile__ long context_flag;	/**< Context swapping flag */ -	__volatile__ long interrupt_flag; /**< Interruption handler flag */ -	__volatile__ long dma_flag;	/**< DMA dispatch flag */ -	wait_queue_head_t context_wait;	/**< Processes waiting on ctx switch */ -	int last_checked;		/**< Last context checked for DMA */  	int last_context;		/**< Last current context */ -	unsigned long last_switch;	/**< jiffies at last context switch */  	/*@} */ -	struct work_struct work;  	/** \name VBLANK IRQ support */  	/*@{ */ @@ -979,19 +1114,13 @@ struct drm_device {  	 * Once the modeset ioctl *has* been called though, we can safely  	 * disable them when unused.  	 */ -	int vblank_disable_allowed; +	bool vblank_disable_allowed; -	wait_queue_head_t *vbl_queue;   /**< VBLANK wait queue */ -	atomic_t *_vblank_count;        /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ +	/* array of size num_crtcs */ +	struct drm_vblank_crtc *vblank; + +	spinlock_t vblank_time_lock;    /**< Protects vblank count and time updates during vblank enable/disable */  	spinlock_t vbl_lock; -	atomic_t *vblank_refcount;      /* number of users of vblank interruptsper crtc */ -	u32 *last_vblank;               /* protected by dev->vbl_lock, used */ -					/* for wraparound handling */ -	int *vblank_enabled;            /* so we don't call enable more than -					   once per disable */ -	int *vblank_inmodeset;          /* Display driver is setting mode */ -	u32 *last_vblank_wait;		/* Last vblank seqno waited per CRTC */ -	struct timer_list vblank_disable_timer;  	u32 max_vblank_count;           /**< size of vblank counter register */ @@ -1002,147 +1131,91 @@ struct drm_device {  	spinlock_t event_lock;  	/*@} */ -	cycles_t ctx_start; -	cycles_t lck_start; - -	struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */ -	wait_queue_head_t buf_readers;	/**< Processes waiting to read */ -	wait_queue_head_t buf_writers;	/**< Processes waiting to ctx switch */  	struct drm_agp_head *agp;	/**< AGP data */ -	struct device *dev;             /**< Device structure */  	struct pci_dev *pdev;		/**< PCI device structure */ -	int pci_vendor;			/**< PCI vendor id */ -	int pci_device;			/**< PCI device id */  #ifdef __alpha__  	struct pci_controller *hose;  #endif  	struct platform_device *platformdev; /**< Platform device struture */ +	struct usb_device *usbdev;  	struct drm_sg_mem *sg;	/**< Scatter gather memory */ -	int num_crtcs;                  /**< Number of CRTCs on this device */ -	void *dev_private;		/**< device private data */ -	void *mm_private; -	struct address_space *dev_mapping; +	unsigned int num_crtcs;                  /**< Number of CRTCs on this device */  	struct drm_sigdata sigdata;	   /**< For block_all_signals */  	sigset_t sigmask; -	struct drm_driver *driver;  	struct drm_local_map *agp_buffer_map;  	unsigned int agp_buffer_token; -	struct drm_minor *control;		/**< Control node for card */ -	struct drm_minor *primary;		/**< render type primary screen head */          struct drm_mode_config mode_config;	/**< Current mode config */  	/** \name GEM information */  	/*@{ */ -	spinlock_t object_name_lock; +	struct mutex object_name_lock;  	struct idr object_name_idr; -	uint32_t invalidate_domains;    /* domains pending invalidation */ -	uint32_t flush_domains;         /* domains pending flush */ +	struct drm_vma_offset_manager *vma_offset_manager;  	/*@} */ - +	int switch_power_state;  }; +#define DRM_SWITCH_POWER_ON 0 +#define DRM_SWITCH_POWER_OFF 1 +#define DRM_SWITCH_POWER_CHANGING 2 +#define DRM_SWITCH_POWER_DYNAMIC_OFF 3 +  static __inline__ int drm_core_check_feature(struct drm_device *dev,  					     int feature)  {  	return ((dev->driver->driver_features & feature) ? 1 : 0);  } -static inline int drm_dev_to_irq(struct drm_device *dev) +static inline void drm_device_set_unplugged(struct drm_device *dev)  { -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) -		return platform_get_irq(dev->platformdev, 0); -	else -		return dev->pdev->irq; +	smp_wmb(); +	atomic_set(&dev->unplugged, 1);  } -static inline int drm_get_pci_domain(struct drm_device *dev) +static inline int drm_device_is_unplugged(struct drm_device *dev)  { -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) -		return 0; - -#ifndef __alpha__ -	/* For historical reasons, drm_get_pci_domain() is busticated -	 * on most archs and has to remain so for userspace interface -	 * < 1.4, except on alpha which was right from the beginning -	 */ -	if (dev->if_version < 0x10004) -		return 0; -#endif /* __alpha__ */ - -	return pci_domain_nr(dev->pdev->bus); +	int ret = atomic_read(&dev->unplugged); +	smp_rmb(); +	return ret;  } -#if __OS_HAS_AGP -static inline int drm_core_has_AGP(struct drm_device *dev) +static inline bool drm_is_render_client(const struct drm_file *file_priv)  { -	return drm_core_check_feature(dev, DRIVER_USE_AGP); +	return file_priv->minor->type == DRM_MINOR_RENDER;  } -#else -#define drm_core_has_AGP(dev) (0) -#endif -#if __OS_HAS_MTRR -static inline int drm_core_has_MTRR(struct drm_device *dev) +static inline bool drm_is_control_client(const struct drm_file *file_priv)  { -	return drm_core_check_feature(dev, DRIVER_USE_MTRR); +	return file_priv->minor->type == DRM_MINOR_CONTROL;  } -#define DRM_MTRR_WC		MTRR_TYPE_WRCOMB - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, -			       unsigned int flags) -{ -	return mtrr_add(offset, size, flags, 1); -} - -static inline int drm_mtrr_del(int handle, unsigned long offset, -			       unsigned long size, unsigned int flags) -{ -	return mtrr_del(handle, offset, size); -} - -#else -#define drm_core_has_MTRR(dev) (0) - -#define DRM_MTRR_WC		0 - -static inline int drm_mtrr_add(unsigned long offset, unsigned long size, -			       unsigned int flags) +static inline bool drm_is_primary_client(const struct drm_file *file_priv)  { -	return 0; +	return file_priv->minor->type == DRM_MINOR_LEGACY;  } -static inline int drm_mtrr_del(int handle, unsigned long offset, -			       unsigned long size, unsigned int flags) -{ -	return 0; -} -#endif -  /******************************************************************/  /** \name Internal function definitions */  /*@{*/  				/* Driver support (drm_drv.h) */ -extern int drm_init(struct drm_driver *driver); -extern void drm_exit(struct drm_driver *driver);  extern long drm_ioctl(struct file *filp,  		      unsigned int cmd, unsigned long arg);  extern long drm_compat_ioctl(struct file *filp,  			     unsigned int cmd, unsigned long arg);  extern int drm_lastclose(struct drm_device *dev); +extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);  				/* Device support (drm_fops.h) */  extern struct mutex drm_global_mutex;  extern int drm_open(struct inode *inode, struct file *filp);  extern int drm_stub_open(struct inode *inode, struct file *filp); -extern int drm_fasync(int fd, struct file *filp, int on);  extern ssize_t drm_read(struct file *filp, char __user *buffer,  			size_t count, loff_t *offset);  extern int drm_release(struct inode *inode, struct file *filp); @@ -1150,25 +1223,13 @@ extern int drm_release(struct inode *inode, struct file *filp);  				/* Mapping support (drm_vm.h) */  extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);  extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); -extern void drm_vm_open_locked(struct vm_area_struct *vma); -extern void drm_vm_close_locked(struct vm_area_struct *vma); +extern void drm_vm_open_locked(struct drm_device *dev, struct vm_area_struct *vma); +extern void drm_vm_close_locked(struct drm_device *dev, struct vm_area_struct *vma);  extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);  				/* Memory management support (drm_memory.h) */ -#include "drm_memory.h" -extern void drm_mem_init(void); -extern int drm_mem_info(char *buf, char **start, off_t offset, -			int request, int *eof, void *data); -extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); - -extern void drm_free_agp(DRM_AGP_MEM * handle, int pages); -extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start); -extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev, -				       struct page **pages, -				       unsigned long num_pages, -				       uint32_t gtt_offset, -				       uint32_t type); -extern int drm_unbind_agp(DRM_AGP_MEM * handle); +#include <drm/drm_memory.h> +  				/* Misc. IOCTL support (drm_ioctl.h) */  extern int drm_irq_by_busid(struct drm_device *dev, void *data, @@ -1183,6 +1244,10 @@ extern int drm_getclient(struct drm_device *dev, void *data,  			 struct drm_file *file_priv);  extern int drm_getstats(struct drm_device *dev, void *data,  			struct drm_file *file_priv); +extern int drm_getcap(struct drm_device *dev, void *data, +		      struct drm_file *file_priv); +extern int drm_setclientcap(struct drm_device *dev, void *data, +			    struct drm_file *file_priv);  extern int drm_setversion(struct drm_device *dev, void *data,  			  struct drm_file *file_priv);  extern int drm_noop(struct drm_device *dev, void *data, @@ -1193,8 +1258,6 @@ extern int drm_resctx(struct drm_device *dev, void *data,  		      struct drm_file *file_priv);  extern int drm_addctx(struct drm_device *dev, void *data,  		      struct drm_file *file_priv); -extern int drm_modctx(struct drm_device *dev, void *data, -		      struct drm_file *file_priv);  extern int drm_getctx(struct drm_device *dev, void *data,  		      struct drm_file *file_priv);  extern int drm_switchctx(struct drm_device *dev, void *data, @@ -1218,9 +1281,12 @@ extern int drm_getmagic(struct drm_device *dev, void *data,  			struct drm_file *file_priv);  extern int drm_authmagic(struct drm_device *dev, void *data,  			 struct drm_file *file_priv); +extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);  /* Cache management (drm_cache.c) */  void drm_clflush_pages(struct page *pages[], unsigned long num_pages); +void drm_clflush_sg(struct sg_table *st); +void drm_clflush_virt_range(void *addr, unsigned long length);  				/* Locking IOCTL support (drm_lock.h) */  extern int drm_lock(struct drm_device *dev, void *data, @@ -1260,11 +1326,12 @@ extern int drm_freebufs(struct drm_device *dev, void *data,  			struct drm_file *file_priv);  extern int drm_mapbufs(struct drm_device *dev, void *data,  		       struct drm_file *file_priv); -extern int drm_order(unsigned long size); +extern int drm_dma_ioctl(struct drm_device *dev, void *data, +			 struct drm_file *file_priv);  				/* DMA support (drm_dma.h) */ -extern int drm_dma_setup(struct drm_device *dev); -extern void drm_dma_takedown(struct drm_device *dev); +extern int drm_legacy_dma_setup(struct drm_device *dev); +extern void drm_legacy_dma_takedown(struct drm_device *dev);  extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);  extern void drm_core_reclaim_buffers(struct drm_device *dev,  				     struct drm_file *filp); @@ -1272,23 +1339,40 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev,  				/* IRQ support (drm_irq.h) */  extern int drm_control(struct drm_device *dev, void *data,  		       struct drm_file *file_priv); -extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); -extern int drm_irq_install(struct drm_device *dev); +extern int drm_irq_install(struct drm_device *dev, int irq);  extern int drm_irq_uninstall(struct drm_device *dev); -extern void drm_driver_irq_preinstall(struct drm_device *dev); -extern void drm_driver_irq_postinstall(struct drm_device *dev); -extern void drm_driver_irq_uninstall(struct drm_device *dev);  extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);  extern int drm_wait_vblank(struct drm_device *dev, void *data,  			   struct drm_file *filp); -extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);  extern u32 drm_vblank_count(struct drm_device *dev, int crtc); -extern void drm_handle_vblank(struct drm_device *dev, int crtc); +extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, +				     struct timeval *vblanktime); +extern void drm_send_vblank_event(struct drm_device *dev, int crtc, +				     struct drm_pending_vblank_event *e); +extern bool drm_handle_vblank(struct drm_device *dev, int crtc);  extern int drm_vblank_get(struct drm_device *dev, int crtc);  extern void drm_vblank_put(struct drm_device *dev, int crtc); +extern int drm_crtc_vblank_get(struct drm_crtc *crtc); +extern void drm_crtc_vblank_put(struct drm_crtc *crtc);  extern void drm_vblank_off(struct drm_device *dev, int crtc); +extern void drm_vblank_on(struct drm_device *dev, int crtc); +extern void drm_crtc_vblank_off(struct drm_crtc *crtc); +extern void drm_crtc_vblank_on(struct drm_crtc *crtc);  extern void drm_vblank_cleanup(struct drm_device *dev); + +extern u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, +				     struct timeval *tvblank, unsigned flags); +extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, +						 int crtc, int *max_error, +						 struct timeval *vblank_time, +						 unsigned flags, +						 const struct drm_crtc *refcrtc, +						 const struct drm_display_mode *mode); +extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, +					    const struct drm_display_mode *mode); + +  /* Modesetting support */  extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);  extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc); @@ -1296,32 +1380,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data,  			   struct drm_file *file_priv);  				/* AGP/GART support (drm_agpsupport.h) */ -extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); -extern int drm_agp_acquire(struct drm_device *dev); -extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, -				 struct drm_file *file_priv); -extern int drm_agp_release(struct drm_device *dev); -extern int drm_agp_release_ioctl(struct drm_device *dev, void *data, -				 struct drm_file *file_priv); -extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode); -extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data, -				struct drm_file *file_priv); -extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info); -extern int drm_agp_info_ioctl(struct drm_device *dev, void *data, -			struct drm_file *file_priv); -extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request); -extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data, -			 struct drm_file *file_priv); -extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request); -extern int drm_agp_free_ioctl(struct drm_device *dev, void *data, -			struct drm_file *file_priv); -extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request); -extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, -			  struct drm_file *file_priv); -extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); -extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data, -			struct drm_file *file_priv); -extern void drm_agp_chipset_flush(struct drm_device *dev); + +#include <drm/drm_agpsupport.h>  				/* Stub support (drm_stub.h) */  extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, @@ -1331,57 +1391,106 @@ extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data,  struct drm_master *drm_master_create(struct drm_minor *minor);  extern struct drm_master *drm_master_get(struct drm_master *master);  extern void drm_master_put(struct drm_master **master); -extern int drm_get_pci_dev(struct pci_dev *pdev, -			   const struct pci_device_id *ent, -			   struct drm_driver *driver); -extern int drm_get_platform_dev(struct platform_device *pdev, -				struct drm_driver *driver); +  extern void drm_put_dev(struct drm_device *dev); -extern int drm_put_minor(struct drm_minor **minor); +extern void drm_unplug_dev(struct drm_device *dev);  extern unsigned int drm_debug; +extern unsigned int drm_rnodes; +extern unsigned int drm_universal_planes; + +extern unsigned int drm_vblank_offdelay; +extern unsigned int drm_timestamp_precision; +extern unsigned int drm_timestamp_monotonic;  extern struct class *drm_class; -extern struct proc_dir_entry *drm_proc_root;  extern struct dentry *drm_debugfs_root;  extern struct idr drm_minors_idr;  extern struct drm_local_map *drm_getsarea(struct drm_device *dev); -				/* Proc support (drm_proc.h) */ -extern int drm_proc_init(struct drm_minor *minor, int minor_id, -			 struct proc_dir_entry *root); -extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); -  				/* Debugfs support */  #if defined(CONFIG_DEBUG_FS)  extern int drm_debugfs_init(struct drm_minor *minor, int minor_id,  			    struct dentry *root); -extern int drm_debugfs_create_files(struct drm_info_list *files, int count, -				    struct dentry *root, struct drm_minor *minor); -extern int drm_debugfs_remove_files(struct drm_info_list *files, int count, -                                    struct drm_minor *minor); +extern int drm_debugfs_create_files(const struct drm_info_list *files, +				    int count, struct dentry *root, +				    struct drm_minor *minor); +extern int drm_debugfs_remove_files(const struct drm_info_list *files, +				    int count, struct drm_minor *minor);  extern int drm_debugfs_cleanup(struct drm_minor *minor); +#else +static inline int drm_debugfs_init(struct drm_minor *minor, int minor_id, +				   struct dentry *root) +{ +	return 0; +} + +static inline int drm_debugfs_create_files(const struct drm_info_list *files, +					   int count, struct dentry *root, +					   struct drm_minor *minor) +{ +	return 0; +} + +static inline int drm_debugfs_remove_files(const struct drm_info_list *files, +					   int count, struct drm_minor *minor) +{ +	return 0; +} + +static inline int drm_debugfs_cleanup(struct drm_minor *minor) +{ +	return 0; +}  #endif  				/* Info file support */  extern int drm_name_info(struct seq_file *m, void *data);  extern int drm_vm_info(struct seq_file *m, void *data); -extern int drm_queues_info(struct seq_file *m, void *data);  extern int drm_bufs_info(struct seq_file *m, void *data);  extern int drm_vblank_info(struct seq_file *m, void *data);  extern int drm_clients_info(struct seq_file *m, void* data);  extern int drm_gem_name_info(struct seq_file *m, void *data); + +extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev, +		struct drm_gem_object *obj, int flags); +extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, +		struct drm_file *file_priv, uint32_t handle, uint32_t flags, +		int *prime_fd); +extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, +		struct dma_buf *dma_buf); +extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, +		struct drm_file *file_priv, int prime_fd, uint32_t *handle); +extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf); + +extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, +					struct drm_file *file_priv); +extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, +					struct drm_file *file_priv); + +extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, +					    dma_addr_t *addrs, int max_pages); +extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages); +extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); + +int drm_gem_dumb_destroy(struct drm_file *file, +			 struct drm_device *dev, +			 uint32_t handle); + +void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); +void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); +void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf); +  #if DRM_DEBUG_CODE  extern int drm_vma_info(struct seq_file *m, void *data);  #endif  				/* Scatter Gather Support (drm_scatter.h) */ -extern void drm_sg_cleanup(struct drm_sg_mem * entry); -extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data, +extern void drm_legacy_sg_cleanup(struct drm_device *dev); +extern int drm_sg_alloc(struct drm_device *dev, void *data,  			struct drm_file *file_priv); -extern int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request);  extern int drm_sg_free(struct drm_device *dev, void *data,  		       struct drm_file *file_priv); @@ -1395,6 +1504,9 @@ extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,  				       size_t align);  extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);  extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah); +extern int drm_pci_set_unique(struct drm_device *dev, +			      struct drm_master *master, +			      struct drm_unique *u);  			       /* sysfs support (drm_sysfs.c) */  struct drm_sysfs_class; @@ -1403,7 +1515,6 @@ extern void drm_sysfs_destroy(void);  extern int drm_sysfs_device_add(struct drm_minor *minor);  extern void drm_sysfs_hotplug_event(struct drm_device *dev);  extern void drm_sysfs_device_remove(struct drm_minor *minor); -extern char *drm_get_connector_status_name(enum drm_connector_status status);  extern int drm_sysfs_connector_add(struct drm_connector *connector);  extern void drm_sysfs_connector_remove(struct drm_connector *connector); @@ -1412,16 +1523,17 @@ int drm_gem_init(struct drm_device *dev);  void drm_gem_destroy(struct drm_device *dev);  void drm_gem_object_release(struct drm_gem_object *obj);  void drm_gem_object_free(struct kref *kref); -struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, -					    size_t size);  int drm_gem_object_init(struct drm_device *dev,  			struct drm_gem_object *obj, size_t size); -void drm_gem_object_handle_free(struct drm_gem_object *obj); +void drm_gem_private_object_init(struct drm_device *dev, +				 struct drm_gem_object *obj, size_t size);  void drm_gem_vm_open(struct vm_area_struct *vma);  void drm_gem_vm_close(struct vm_area_struct *vma); +int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, +		     struct vm_area_struct *vma);  int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); -#include "drm_global.h" +#include <drm/drm_global.h>  static inline void  drm_gem_object_reference(struct drm_gem_object *obj) @@ -1439,62 +1551,32 @@ drm_gem_object_unreference(struct drm_gem_object *obj)  static inline void  drm_gem_object_unreference_unlocked(struct drm_gem_object *obj)  { -	if (obj != NULL) { +	if (obj && !atomic_add_unless(&obj->refcount.refcount, -1, 1)) {  		struct drm_device *dev = obj->dev; +  		mutex_lock(&dev->struct_mutex); -		kref_put(&obj->refcount, drm_gem_object_free); +		if (likely(atomic_dec_and_test(&obj->refcount.refcount))) +			drm_gem_object_free(&obj->refcount);  		mutex_unlock(&dev->struct_mutex);  	}  } +int drm_gem_handle_create_tail(struct drm_file *file_priv, +			       struct drm_gem_object *obj, +			       u32 *handlep);  int drm_gem_handle_create(struct drm_file *file_priv,  			  struct drm_gem_object *obj,  			  u32 *handlep); +int drm_gem_handle_delete(struct drm_file *filp, u32 handle); -static inline void -drm_gem_object_handle_reference(struct drm_gem_object *obj) -{ -	drm_gem_object_reference(obj); -	atomic_inc(&obj->handle_count); -} -static inline void -drm_gem_object_handle_unreference(struct drm_gem_object *obj) -{ -	if (obj == NULL) -		return; +void drm_gem_free_mmap_offset(struct drm_gem_object *obj); +int drm_gem_create_mmap_offset(struct drm_gem_object *obj); +int drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size); -	if (atomic_read(&obj->handle_count) == 0) -		return; -	/* -	 * Must bump handle count first as this may be the last -	 * ref, in which case the object would disappear before we -	 * checked for a name -	 */ -	if (atomic_dec_and_test(&obj->handle_count)) -		drm_gem_object_handle_free(obj); -	drm_gem_object_unreference(obj); -} - -static inline void -drm_gem_object_handle_unreference_unlocked(struct drm_gem_object *obj) -{ -	if (obj == NULL) -		return; - -	if (atomic_read(&obj->handle_count) == 0) -		return; - -	/* -	* Must bump handle count first as this may be the last -	* ref, in which case the object would disappear before we -	* checked for a name -	*/ - -	if (atomic_dec_and_test(&obj->handle_count)) -		drm_gem_object_handle_free(obj); -	drm_gem_object_unreference_unlocked(obj); -} +struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); +void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, +		bool dirty, bool accessed);  struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,  					     struct drm_file *filp, @@ -1522,11 +1604,28 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev,  	return NULL;  } -static __inline__ int drm_device_is_agp(struct drm_device *dev) +static __inline__ void drm_core_dropmap(struct drm_local_map *map)  { -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) -		return 0; +} + +#include <drm/drm_mem_util.h> + +struct drm_device *drm_dev_alloc(struct drm_driver *driver, +				 struct device *parent); +void drm_dev_ref(struct drm_device *dev); +void drm_dev_unref(struct drm_device *dev); +int drm_dev_register(struct drm_device *dev, unsigned long flags); +void drm_dev_unregister(struct drm_device *dev); +int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...); + +struct drm_minor *drm_minor_acquire(unsigned int minor_id); +void drm_minor_release(struct drm_minor *minor); + +/*@}*/ +/* PCI section */ +static __inline__ int drm_pci_device_is_agp(struct drm_device *dev) +{  	if (dev->driver->device_is_agp != NULL) {  		int err = (*dev->driver->device_is_agp) (dev); @@ -1537,36 +1636,30 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev)  	return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);  } +void drm_pci_agp_destroy(struct drm_device *dev); -static __inline__ int drm_device_is_pcie(struct drm_device *dev) -{ -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) -		return 0; -	else -		return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP); -} +extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver); +extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver); +extern int drm_get_pci_dev(struct pci_dev *pdev, +			   const struct pci_device_id *ent, +			   struct drm_driver *driver); -static __inline__ void drm_core_dropmap(struct drm_local_map *map) -{ -} +#define DRM_PCIE_SPEED_25 1 +#define DRM_PCIE_SPEED_50 2 +#define DRM_PCIE_SPEED_80 4 -#include "drm_mem_util.h" +extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask); -static inline void *drm_get_device(struct drm_device *dev) +/* platform section */ +extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); + +/* returns true if currently okay to sleep */ +static __inline__ bool drm_can_sleep(void)  { -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) -		return dev->platformdev; -	else -		return dev->pdev; +	if (in_atomic() || in_dbg_master() || irqs_disabled()) +		return false; +	return true;  } -extern int drm_platform_init(struct drm_driver *driver); -extern int drm_pci_init(struct drm_driver *driver); -extern int drm_fill_in_dev(struct drm_device *dev, -			   const struct pci_device_id *ent, -			   struct drm_driver *driver); -int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type); -/*@}*/ -  #endif				/* __KERNEL__ */  #endif  | 
