OSDN Git Service

Merge commit 'origin/master' into modesetting-gem
[android-x86/external-libdrm.git] / linux-core / drmP.h
index 19168cd..1e5838e 100644 (file)
@@ -54,6 +54,8 @@
 #include <linux/smp_lock.h>    /* For (un)lock_kernel */
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/kref.h>
 #include <linux/pagemap.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
 #include <linux/mutex.h>
 struct drm_device;
 struct drm_file;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+typedef unsigned long uintptr_t;
+#endif
+
 /* If you want the memory alloc debug functionality, change define below */
 /* #define DEBUG_MEMORY */
 
@@ -107,7 +113,8 @@ struct drm_file;
 #define DRIVER_IRQ_SHARED  0x80
 #define DRIVER_DMA_QUEUE   0x100
 #define DRIVER_FB_DMA      0x200
-
+#define DRIVER_MODESET     0x400
+#define DRIVER_GEM        0x800
 
 /*@}*/
 
@@ -261,11 +268,11 @@ struct drm_file;
  */
 #define LOCK_TEST_WITH_RETURN( dev, file_priv )                                \
 do {                                                                   \
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||           \
-            dev->lock.file_priv != file_priv ) {                       \
+       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",\
-                          __FUNCTION__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
-                          dev->lock.file_priv, file_priv );            \
+                          __FUNCTION__, _DRM_LOCK_IS_HELD( file_priv->master->lock.hw_lock->lock ),\
+                          file_priv->master->lock.file_priv, file_priv );              \
                return -EINVAL;                                         \
        }                                                               \
 } while (0)
@@ -299,6 +306,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
 #define DRM_AUTH        0x1
 #define DRM_MASTER      0x2
 #define DRM_ROOT_ONLY   0x4
+#define DRM_CONTROL_ALLOW 0x8 // allow ioctl to operate on control node 
 
 struct drm_ioctl_desc {
        unsigned int cmd;
@@ -408,14 +416,12 @@ enum drm_ref_type {
 /** File private data */
 struct drm_file {
        int authenticated;
-       int master;
        pid_t pid;
        uid_t uid;
        drm_magic_t magic;
        unsigned long ioctl_count;
        struct list_head lhead;
        struct drm_minor *minor;
-       int remove_auth_on_close;
        unsigned long lock_count;
 
        /*
@@ -427,9 +433,19 @@ struct drm_file {
 
        struct list_head refd_objects;
 
+       /** 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 drm_open_hash refd_object_hash[_DRM_NO_REF_TYPES];
        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 */
+       struct list_head fbs;
 };
 
 /** Wait queue */
@@ -464,6 +480,11 @@ struct drm_lock_data {
        uint32_t kernel_waiters;
        uint32_t user_waiters;
        int idle_has_lock;
+       /**
+        * Boolean signaling that the lock is held on behalf of the
+        * file_priv client by the kernel in an ioctl handler.
+        */
+       int kernel_held;
 };
 
 /**
@@ -539,17 +560,17 @@ struct drm_sigdata {
  * Generic memory manager structs
  */
 
-struct drm_mm_node {
+struct drm_memrange_node {
        struct list_head fl_entry;
        struct list_head ml_entry;
        int free;
        unsigned long start;
        unsigned long size;
-       struct drm_mm *mm;
+       struct drm_memrange *mm;
        void *private;
 };
 
-struct drm_mm {
+struct drm_memrange {
        struct list_head fl_entry;
        struct list_head ml_entry;
 };
@@ -563,7 +584,9 @@ struct drm_map_list {
        struct drm_hash_item hash;
        struct drm_map *map;                    /**< mapping */
        uint64_t user_token;
-       struct drm_mm_node *file_offset_node;
+       struct drm_master *master; /** if this map is associated with a specific
+                                      master */
+       struct drm_memrange_node *file_offset_node;
 };
 
 typedef struct drm_map drm_local_map_t;
@@ -584,6 +607,13 @@ struct drm_vbl_sig {
        struct task_struct *task;
 };
 
+struct drm_hotplug_sig {
+       struct list_head head;
+       unsigned int counter;
+       struct siginfo info;
+       struct task_struct *task;
+};
+
 /* location of GART table */
 #define DRM_ATI_GART_MAIN 1
 #define DRM_ATI_GART_FB   2
@@ -604,7 +634,80 @@ struct drm_ati_pcigart_info {
        int table_size;
 };
 
+/**
+ * This structure defines the drm_mm memory object, which will be used by the
+ * DRM for its buffer objects.
+ */
+struct drm_gem_object {
+       /** Reference count of this object */
+       struct kref refcount;
+
+       /** Handle count of this object. Each handle also holds a reference */
+       struct kref handlecount;
+
+       /** Related drm device */
+       struct drm_device *dev;
+       
+       /** File representing the shmem storage */
+       struct file *filp;
+
+       /**
+        * Size of the object, in bytes.  Immutable over the object's
+        * lifetime.
+        */
+       size_t size;
+
+       /**
+        * Global name for this object, starts at 1. 0 means unnamed.
+        * Access is covered by the object_name_lock in the related drm_device
+        */
+       int name;
+
+       /**
+        * Memory domains. These monitor which caches contain read/write data
+        * related to the object. When transitioning from one set of domains
+        * to another, the driver is called to ensure that caches are suitably
+        * flushed and invalidated
+        */
+       uint32_t        read_domains;
+       uint32_t        write_domain;
+
+       /**
+        * While validating an exec operation, the
+        * new read/write domain values are computed here.
+        * They will be transferred to the above values
+        * at the point that any cache flushing occurs
+        */
+       uint32_t        pending_read_domains;
+       uint32_t        pending_write_domain;
+
+       void *driver_private;
+};
+
 #include "drm_objects.h"
+#include "drm_crtc.h"
+
+/* per-master structure */
+struct drm_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 blocked;                    /**< Blocked due to VC switch? */
+
+       /** \name Authentication */
+       /*@{ */
+       struct drm_open_hash magiclist;
+       struct list_head magicfree;
+       /*@} */
+
+       struct drm_lock_data lock;              /**< Information on hardware lock */
+
+       void *driver_priv; /**< Private structure for driver to use */
+};
 
 /**
  * DRM driver structure. This structure represent the common code for
@@ -705,6 +808,22 @@ struct drm_driver {
        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);
+       void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
+
+       int (*proc_init)(struct drm_minor *minor);
+       void (*proc_cleanup)(struct drm_minor *minor);
+
+       /**
+        * Driver-specific constructor for drm_gem_objects, to set up
+        * obj->driver_private.
+        *
+        * Returns 0 on success.
+        */
+       int (*gem_init_object) (struct drm_gem_object *obj);
+       void (*gem_free_object) (struct drm_gem_object *obj);
+
        struct drm_fence_driver *fence_driver;
        struct drm_bo_driver *bo_driver;
 
@@ -726,6 +845,8 @@ struct drm_driver {
 
 #define DRM_MINOR_UNASSIGNED 0
 #define DRM_MINOR_LEGACY 1
+#define DRM_MINOR_CONTROL 2
+#define DRM_MINOR_RENDER 3
 
 /**
  * DRM minor structure. This structure represents a drm minor number.
@@ -736,8 +857,15 @@ struct drm_minor {
        dev_t device;                   /**< Device number for mknod */
        struct device kdev;             /**< Linux device */
        struct drm_device *dev;
+       /* for render nodes */
        struct proc_dir_entry *dev_root;  /**< proc directory entry */
        struct class_device *dev_class;
+
+       /* for control nodes - a pointer to the current master for this control node */
+       struct drm_master *master; /* currently active master for this node */
+       struct list_head master_list;
+
+       struct drm_mode_group mode_group;
 };
 
 
@@ -746,13 +874,9 @@ struct drm_minor {
  * may contain multiple heads.
  */
 struct drm_device {
-       char *unique;                   /**< Unique identifier: e.g., busid */
-       int unique_len;                 /**< Length of unique field */
        char *devname;                  /**< For /proc/interrupts */
        int if_version;                 /**< Highest interface version set */
 
-       int blocked;                    /**< Blocked due to VC switch? */
-
        /** \name Locks */
        /*@{ */
        spinlock_t count_lock;          /**< For inuse, drm_device::open_count, drm_device::buf_use */
@@ -775,19 +899,13 @@ struct drm_device {
        atomic_t counts[15];
        /*@} */
 
-       /** \name Authentication */
-       /*@{ */
-       struct list_head filelist;
-       struct drm_open_hash magiclist;
-       struct list_head magicfree;
-       /*@} */
 
        /** \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 */
-       struct drm_mm offset_manager;        /**< User token manager */
+       struct drm_memrange offset_manager;  /**< User token manager */
        struct drm_open_hash object_hash;    /**< User token hash table for objects */
        struct address_space *dev_mapping;  /**< For unmap_mapping_range() */
        struct page *ttm_dummy_page;
@@ -801,7 +919,9 @@ struct drm_device {
        struct idr ctx_idr;
 
        struct list_head vmalist;       /**< List of vmas (for debugging) */
-       struct drm_lock_data lock;              /**< Information on hardware lock */
+
+       struct list_head filelist;
+
        /*@} */
 
        /** \name DMA queues (contexts) */
@@ -813,6 +933,7 @@ struct drm_device {
        struct drm_device_dma *dma;             /**< Optional pointer for DMA support */
        /*@} */
 
+
        /** \name Context support */
        /*@{ */
        int irq;                        /**< Interrupt used by board */
@@ -829,6 +950,15 @@ struct drm_device {
 
        struct work_struct work;
 
+       /** \name HOTPLUG IRQ support */
+       /*@{ */
+       wait_queue_head_t hotplug_queue;        /**< HOTPLUG wait queue */
+       spinlock_t hotplug_lock;
+       struct list_head *hotplug_sigs;         /**< signal list to send on HOTPLUG */
+       atomic_t hotplug_signal_pending;        /* number of signals pending on all crtcs*/
+
+       /*@} */
+
        /** \name VBLANK IRQ support */
        /*@{ */
 
@@ -882,6 +1012,9 @@ struct drm_device {
        struct drm_driver *driver;
        drm_local_map_t *agp_buffer_map;
        unsigned int agp_buffer_token;
+
+       /* minor number for control node */
+       struct drm_minor *control;
        struct drm_minor *primary;              /**< render type primary screen head */
 
        struct drm_fence_manager fm;
@@ -892,6 +1025,24 @@ struct drm_device {
        spinlock_t drw_lock;
        struct idr drw_idr;
        /*@} */
+
+       /* DRM mode setting */
+       struct drm_mode_config mode_config;
+
+       /** \name GEM information */
+       /*@{ */
+       spinlock_t object_name_lock;
+       struct idr object_name_idr;
+       atomic_t object_count;
+       atomic_t object_memory;
+       atomic_t pin_count;
+       atomic_t pin_memory;
+       atomic_t gtt_count;
+       atomic_t gtt_memory;
+       uint32_t gtt_total;
+       uint32_t invalidate_domains;    /* domains pending invalidation */
+       uint32_t flush_domains;         /* domains pending flush */
+       /*@} */
 };
 
 #if __OS_HAS_AGP
@@ -902,7 +1053,18 @@ struct drm_agp_ttm_backend {
        int populated;
 };
 #endif
-
+struct ati_pcigart_ttm_backend {
+       struct drm_ttm_backend backend;
+       int populated;
+       void (*gart_flush_fn)(struct drm_device *dev);
+       struct drm_ati_pcigart_info *gart_info;
+       unsigned long offset;
+       struct page **pages;
+       int num_pages;
+       int bound;
+       struct drm_device *dev;
+};
+extern struct drm_ttm_backend *ati_pcigart_init_ttm(struct drm_device *dev, struct drm_ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev));
 
 static __inline__ int drm_core_check_feature(struct drm_device *dev,
                                             int feature)
@@ -1007,6 +1169,10 @@ extern void drm_free_pages(unsigned long address, int order, int area);
 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
 extern int 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);
 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
 
 extern void drm_free_memctl(size_t size);
@@ -1147,12 +1313,16 @@ 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_hotplug_init(struct drm_device *dev);
+extern int drm_wait_hotplug(struct drm_device *dev, void *data, struct drm_file *filp);
 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_wait_hotplug(struct drm_device *dev, void *data, struct drm_file *filp);
 extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
 extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
 extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
 extern void drm_handle_vblank(struct drm_device *dev, int crtc);
+extern void drm_handle_hotplug(struct drm_device *dev);
 extern int drm_vblank_get(struct drm_device *dev, int crtc);
 extern void drm_vblank_put(struct drm_device *dev, int crtc);
 
@@ -1197,10 +1367,16 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
 extern struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev);
 extern void drm_agp_chipset_flush(struct drm_device *dev);
                                /* Stub support (drm_stub.h) */
+extern int drm_setmaster_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv);
+extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
+                               struct drm_file *file_priv);
+extern struct drm_master *drm_get_master(struct drm_minor *minor);
+extern void drm_put_master(struct drm_master *master);
 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                     struct drm_driver *driver);
 extern int drm_put_dev(struct drm_device *dev);
-extern int drm_put_minor(struct drm_minor **minor);
+extern int drm_put_minor(struct drm_device *dev, struct drm_minor **p);
 extern unsigned int drm_debug; /* 1 to enable debug output */
 
 extern struct class *drm_class;
@@ -1226,6 +1402,8 @@ extern int drm_sg_free(struct drm_device *dev, void *data,
                               /* ATI PCIGART support (ati_pcigart.h) */
 extern int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
 extern int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+extern int drm_ati_alloc_pcigart_table(struct drm_device *dev,
+                                      struct drm_ati_pcigart_info *gart_info);
 
 extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,
                           size_t align, dma_addr_t maxaddr);
@@ -1237,29 +1415,101 @@ struct drm_sysfs_class;
 extern struct class *drm_sysfs_create(struct module *owner, char *name);
 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);
 
 /*
- * Basic memory manager support (drm_mm.c)
+ * Basic memory manager support (drm_memrange.c)
  */
 
-extern struct drm_mm_node * drm_mm_get_block(struct drm_mm_node * parent, unsigned long size,
-                                              unsigned alignment);
-extern void drm_mm_put_block(struct drm_mm_node *cur);
-extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size,
-                                               unsigned alignment, int best_match);
-extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size);
-extern void drm_mm_takedown(struct drm_mm *mm);
-extern int drm_mm_clean(struct drm_mm *mm);
-extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
-extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
-extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
-
-static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
+extern struct drm_memrange_node *drm_memrange_get_block(struct drm_memrange_node * parent,
+                                                       unsigned long size,
+                                                       unsigned alignment);
+extern void drm_memrange_put_block(struct drm_memrange_node *cur);
+extern struct drm_memrange_node *drm_memrange_search_free(const struct drm_memrange *mm,
+                                                         unsigned long size,
+                                                         unsigned alignment, int best_match);
+extern int drm_memrange_init(struct drm_memrange *mm,
+                            unsigned long start, unsigned long size);
+extern void drm_memrange_takedown(struct drm_memrange *mm);
+extern int drm_memrange_clean(struct drm_memrange *mm);
+extern unsigned long drm_memrange_tail_space(struct drm_memrange *mm);
+extern int drm_memrange_remove_space_from_tail(struct drm_memrange *mm,
+                                              unsigned long size);
+extern int drm_memrange_add_space_to_tail(struct drm_memrange *mm,
+                                         unsigned long size);
+static inline struct drm_memrange *drm_get_mm(struct drm_memrange_node *block)
 {
        return block->mm;
 }
 
+/* Graphics Execution Manager library functions (drm_gem.c) */
+int
+drm_gem_init (struct drm_device *dev);
+
+void
+drm_gem_object_free (struct kref *kref);
+
+struct drm_gem_object *
+drm_gem_object_alloc(struct drm_device *dev, size_t size);
+
+void
+drm_gem_object_handle_free (struct kref *kref);
+    
+static inline void drm_gem_object_reference(struct drm_gem_object *obj)
+{
+       kref_get(&obj->refcount);
+}
+
+static inline void drm_gem_object_unreference(struct drm_gem_object *obj)
+{
+       if (obj == NULL)
+               return;
+
+       kref_put (&obj->refcount, drm_gem_object_free);
+}
+
+int
+drm_gem_handle_create(struct drm_file *file_priv,
+                     struct drm_gem_object *obj,
+                     int *handlep);
+
+static inline void drm_gem_object_handle_reference (struct drm_gem_object *obj)
+{
+       drm_gem_object_reference (obj);
+       kref_get(&obj->handlecount);
+}
+
+static inline void drm_gem_object_handle_unreference (struct drm_gem_object *obj)
+{
+       if (obj == NULL)
+               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
+        */
+       kref_put (&obj->handlecount, drm_gem_object_handle_free);
+       drm_gem_object_unreference (obj);
+}
+
+struct drm_gem_object *
+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
+                     int handle);
+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
+                       struct drm_file *file_priv);
+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
+                      struct drm_file *file_priv);
+
+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
+
 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);