1674 lines · 54.5 KB · C
RawDownload
/** * \file drmP.h * Private header for Direct Rendering Manager * * \author Rickard E. (Rik) Faith <faith@valinux.com> * \author Gareth Hughes <gareth@valinux.com> */ /* * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * Copyright (c) 2009-2010, Code Aurora Forum. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _DRM_P_H_#define _DRM_P_H_ #ifdef __KERNEL__#ifdef __alpha__/* add include of current.h so that "current" is defined * before static inline funcs in wait.h. Doing this so we * can build the DRM (part of PI DRI). 4/21/2000 S + B */#include <asm/current.h>#endif				/* __alpha__ */#include <linux/kernel.h>#include <linux/miscdevice.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/file.h>#include <linux/platform_device.h>#include <linux/pci.h>#include <linux/jiffies.h>#include <linux/dma-mapping.h>#include <linux/mm.h>#include <linux/cdev.h>#include <linux/mutex.h>#include <linux/io.h>#include <linux/slab.h>#if defined(__alpha__) || defined(__powerpc__)#include <asm/pgtable.h>	/* For pte_wrprotect */#endif#include <asm/mman.h>#include <asm/uaccess.h>#include <linux/types.h>#include <linux/agp_backend.h>#include <linux/workqueue.h>#include <linux/poll.h>#include <asm/pgalloc.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))) struct module; struct drm_file;struct drm_device; 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#define DRM_UT_PRIME		0x08/* * 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 definition 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". * * 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" * * 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" * * 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. */ extern __printf(4, 5)void drm_ut_debug_printk(unsigned int request_level,			 const char *prefix,			 const char *function_name,			 const char *format, ...);extern __printf(2, 3)int drm_err(const char *func, 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_PCI_DMA     0x8#define DRIVER_SG          0x10#define DRIVER_HAVE_DMA    0x20#define DRIVER_HAVE_IRQ    0x40#define DRIVER_IRQ_SHARED  0x80#define DRIVER_GEM         0x1000#define DRIVER_MODESET     0x2000#define DRIVER_PRIME       0x4000#define DRIVER_RENDER      0x8000 #define DRIVER_BUS_PCI 0x1#define DRIVER_BUS_PLATFORM 0x2#define DRIVER_BUS_USB 0x3#define DRIVER_BUS_HOST1X 0x4 /***********************************************************************//** \name Begin the DRM... *//*@{*/ #define DRM_DEBUG_CODE 2	  /**< Include debugging code if > 1, then				     also include looping detection. */ #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_MAP_HASH_OFFSET 0x10000000 /*@}*/ /***********************************************************************//** \name Macros to make printk easier *//*@{*/ /** * Error output. * * \param fmt printf() like format string. * \param arg arguments */#define DRM_ERROR(fmt, ...)				\	drm_err(__func__, fmt, ##__VA_ARGS__) #define DRM_INFO(fmt, ...)				\	printk(KERN_INFO "[" DRM_NAME "] " fmt, ##__VA_ARGS__) /** * Debug output. * * \param fmt printf() like format string. * \param arg arguments */#if DRM_DEBUG_CODE#define DRM_DEBUG(fmt, args...)						\	do {								\		drm_ut_debug_printk(DRM_UT_CORE, DRM_NAME, 		\					__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_DEBUG_PRIME(fmt, args...)					\	do {								\		drm_ut_debug_printk(DRM_UT_PRIME, 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);		\	} while (0)#define DRM_LOG_MODE(fmt, args...)					\	do {								\		drm_ut_debug_printk(DRM_UT_MODE, NULL,			\					NULL, fmt, ##args);		\	} while (0)#define DRM_LOG_DRIVER(fmt, args...)					\	do {								\		drm_ut_debug_printk(DRM_UT_DRIVER, NULL,		\					NULL, 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 /*@}*/ /***********************************************************************//** \name Internal types and structures *//*@{*/ #define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) #define DRM_IF_VERSION(maj, min) (maj << 16 | min) /** * Test that the hardware lock is held by the caller, returning otherwise. * * \param dev DRM device. * \param filp file pointer of the caller. */#define LOCK_TEST_WITH_RETURN( dev, _file_priv )				\do {										\	if (!_DRM_LOCK_IS_HELD(_file_priv->master->lock.hw_lock->lock) ||	\	    _file_priv->master->lock.file_priv != _file_priv)	{		\		DRM_ERROR( "%s called without lock held, held  %d owner %p %p\n",\			   __func__, _DRM_LOCK_IS_HELD(_file_priv->master->lock.hw_lock->lock),\			   _file_priv->master->lock.file_priv, _file_priv);	\		return -EINVAL;							\	}									\} while (0) /** * Ioctl function type. * * \param inode device inode. * \param file_priv DRM file private pointer. * \param cmd command. * \param arg argument. */typedef int drm_ioctl_t(struct drm_device *dev, void *data,			struct drm_file *file_priv); typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,			       unsigned long arg); #define DRM_IOCTL_NR(n)                _IOC_NR(n)#define DRM_MAJOR       226 #define DRM_AUTH	0x1#define	DRM_MASTER	0x2#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;}; /** * Creates a driver or general drm_ioctl_desc array entry for the given * ioctl, for use by drm_ioctl(). */ #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, .name = #ioctl} struct drm_magic_entry {	struct list_head head;	struct drm_hash_item hash_item;	struct drm_file *priv;}; struct drm_vma_entry {	struct list_head head;	struct vm_area_struct *vma;	pid_t pid;}; /** * DMA buffer. */struct drm_buf {	int idx;		       /**< Index into master buflist */	int total;		       /**< Buffer size */	int order;		       /**< log-base-2(total) */	int used;		       /**< Amount of buffer in use (for DMA) */	unsigned long offset;	       /**< Byte offset (used internally) */	void *address;		       /**< Address of buffer */	unsigned long bus_address;     /**< Bus address of buffer */	struct drm_buf *next;	       /**< Kernel-only: used for free list */	__volatile__ int waiting;      /**< On kernel DMA queue */	__volatile__ int pending;      /**< On hardware DMA queue */	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 */	enum {		DRM_LIST_NONE = 0,		DRM_LIST_FREE = 1,		DRM_LIST_WAIT = 2,		DRM_LIST_PEND = 3,		DRM_LIST_PRIO = 4,		DRM_LIST_RECLAIM = 5	} list;			       /**< Which list we're on */ 	int dev_priv_size;		 /**< Size of buffer private storage */	void *dev_private;		 /**< Per-buffer private storage */}; /** bufs is one longer than it has to be */struct drm_waitlist {	int count;			/**< Number of possible buffers */	struct drm_buf **bufs;		/**< List of pointers to buffers */	struct drm_buf **rp;			/**< Read pointer */	struct drm_buf **wp;			/**< Write pointer */	struct drm_buf **end;		/**< End pointer */	spinlock_t read_lock;	spinlock_t write_lock;}; struct drm_freelist {	int initialized;	       /**< Freelist in use */	atomic_t count;		       /**< Number of free buffers */	struct drm_buf *next;	       /**< End pointer */ 	wait_queue_head_t waiting;     /**< Processes waiting on free bufs */	int low_mark;		       /**< Low water mark */	int high_mark;		       /**< High water mark */	atomic_t wfh;		       /**< If waiting for high mark */	spinlock_t lock;}; typedef struct drm_dma_handle {	dma_addr_t busaddr;	void *vaddr;	size_t size;} drm_dma_handle_t; /** * Buffer entry.  There is one of this for each buffer size order. */struct drm_buf_entry {	int buf_size;			/**< size */	int buf_count;			/**< number of buffers */	struct drm_buf *buflist;		/**< buffer list */	int seg_count;	int page_order;	struct drm_dma_handle **seglist; 	struct drm_freelist freelist;}; /* Event queued up for userspace to read */struct drm_pending_event {	struct drm_event *event;	struct list_head link;	struct drm_file *file_priv;	pid_t pid; /* pid of requester, no guarantee it's valid by the time		      we deliver the event, for tracing only */	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 {	unsigned always_authenticated :1;	unsigned authenticated :1;	unsigned is_master :1; /* this file private is a master for a minor */	/* true when the client has asked us to expose stereo 3D mode flags */	unsigned stereo_allowed :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; 	/** Mapping of mm object handles to object pointers. */	struct idr object_idr;	/** Lock for synchronization of access to object_idr. */	spinlock_t table_lock; 	struct file *filp;	void *driver_priv; 	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 */struct drm_queue {	atomic_t use_count;		/**< Outstanding uses (+1) */	atomic_t finalization;		/**< Finalization in progress */	atomic_t block_count;		/**< Count of processes waiting */	atomic_t block_read;		/**< Queue blocked for reads */	wait_queue_head_t read_queue;	/**< Processes waiting on block_read */	atomic_t block_write;		/**< Queue blocked for writes */	wait_queue_head_t write_queue;	/**< Processes waiting on block_write */	atomic_t total_queued;		/**< Total queued statistic */	atomic_t total_flushed;		/**< Total flushes statistic */	atomic_t total_locks;		/**< Total locks statistics */	enum drm_ctx_flags flags;	/**< Context preserving and 2D-only */	struct drm_waitlist waitlist;	/**< Pending buffers */	wait_queue_head_t flush_queue;	/**< Processes waiting until flush */}; /** * Lock data. */struct drm_lock_data {	struct drm_hw_lock *hw_lock;	/**< Hardware lock */	/** Private of lock holder's file (NULL=kernel) */	struct drm_file *file_priv;	wait_queue_head_t lock_queue;	/**< Queue of blocked processes */	unsigned long lock_time;	/**< Time of last lock in jiffies */	spinlock_t spinlock;	uint32_t kernel_waiters;	uint32_t user_waiters;	int idle_has_lock;}; /** * DMA data. */struct drm_device_dma { 	struct drm_buf_entry bufs[DRM_MAX_ORDER + 1];	/**< buffers, grouped by their size order */	int buf_count;			/**< total number of buffers */	struct drm_buf **buflist;		/**< Vector of pointers into drm_device_dma::bufs */	int seg_count;	int page_count;			/**< number of pages */	unsigned long *pagelist;	/**< page list */	unsigned long byte_count;	enum {

Lines 1–500 of 1674.