drm: Move master pointer from drm_minor to drm_device
[cascardo/linux.git] / include / drm / drmP.h
index 84f1a8e..3d9a782 100644 (file)
 #include <linux/poll.h>
 #include <linux/ratelimit.h>
 #include <linux/sched.h>
+#include <linux/seqlock.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/workqueue.h>
+#include <linux/fence.h>
 
 #include <asm/mman.h>
 #include <asm/pgalloc.h>
@@ -66,6 +68,7 @@
 
 #include <drm/drm_agpsupport.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
 #include <drm/drm_global.h>
 #include <drm/drm_hashtab.h>
 #include <drm/drm_mem_util.h>
@@ -281,13 +284,14 @@ struct drm_ioctl_desc {
 
 /* Event queued up for userspace to read */
 struct drm_pending_event {
+       struct completion *completion;
        struct drm_event *event;
+       struct fence *fence;
        struct list_head link;
        struct list_head pending_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 */
@@ -332,7 +336,7 @@ struct drm_file {
        void *driver_priv;
 
        struct drm_master *master; /* master this node is currently associated with
-                                     N.B. not always minor->master */
+                                     N.B. not always dev->master */
        /**
         * fbs - List of framebuffers associated with this file.
         *
@@ -375,16 +379,19 @@ struct drm_lock_data {
  * struct drm_master - drm master structure
  *
  * @refcount: Refcount for this master object.
- * @minor: Link back to minor char device we are master for. Immutable.
+ * @dev: Link back to the DRM device
  * @unique: Unique identifier: e.g. busid. Protected by drm_global_mutex.
  * @unique_len: Length of unique field. Protected by drm_global_mutex.
  * @magic_map: Map of used authentication tokens. Protected by struct_mutex.
  * @lock: DRI lock information.
  * @driver_priv: Pointer to driver-private information.
+ *
+ * Note that master structures are only relevant for the legacy/primary device
+ * nodes, hence there can only be one per device, not one per drm_minor.
  */
 struct drm_master {
        struct kref refcount;
-       struct drm_minor *minor;
+       struct drm_device *dev;
        char *unique;
        int unique_len;
        struct idr magic_map;
@@ -392,11 +399,6 @@ struct drm_master {
        void *driver_priv;
 };
 
-/* Size of ringbuffer for vblank timestamps. Just double-buffer
- * in initial implementation.
- */
-#define DRM_VBLANKTIME_RBSIZE 2
-
 /* Flags and return codes for get_vblank_timestamp() driver function. */
 #define DRM_CALLED_FROM_VBLIRQ 1
 #define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
@@ -420,8 +422,6 @@ struct drm_driver {
        void (*postclose) (struct drm_device *, struct drm_file *);
        void (*lastclose) (struct drm_device *);
        int (*unload) (struct drm_device *);
-       int (*suspend) (struct drm_device *, pm_message_t state);
-       int (*resume) (struct drm_device *);
        int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
        int (*dma_quiescent) (struct drm_device *);
        int (*context_dtor) (struct drm_device *dev, int context);
@@ -434,7 +434,7 @@ struct drm_driver {
         *
         * 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
+        * use drm_vblank_no_hw_counter() function. The DRM core will account for
         * missed vblank events while interrupts where disabled based on system
         * timestamps.
         *
@@ -452,8 +452,8 @@ struct drm_driver {
         * @pipe: which irq to enable
         *
         * Enable vblank interrupts for @crtc.  If the device doesn't have
-        * a hardware vblank counter, this routine should be a no-op, since
-        * interrupts will have to stay on to keep the count accurate.
+        * a hardware vblank counter, the driver should use the
+        * drm_vblank_no_hw_counter() function that keeps a virtual counter.
         *
         * RETURNS
         * Zero on success, appropriate errno if the given @crtc's vblank
@@ -467,8 +467,8 @@ struct drm_driver {
         * @pipe: which irq to enable
         *
         * Disable vblank interrupts for @crtc.  If the device doesn't have
-        * a hardware vblank counter, this routine should be a no-op, since
-        * interrupts will have to stay on to keep the count accurate.
+        * a hardware vblank counter, the driver should use the
+        * drm_vblank_no_hw_counter() function that keeps a virtual counter.
         */
        void (*disable_vblank) (struct drm_device *dev, unsigned int pipe);
 
@@ -708,9 +708,6 @@ struct drm_minor {
 
        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;
 };
 
 
@@ -725,10 +722,10 @@ struct drm_vblank_crtc {
        wait_queue_head_t queue;        /**< VBLANK wait queue */
        struct timer_list disable_timer;                /* delayed disable timer */
 
-       /* vblank counter, protected by dev->vblank_time_lock for writes */
-       u32 count;
-       /* vblank timestamps, protected by dev->vblank_time_lock for writes */
-       struct timeval time[DRM_VBLANKTIME_RBSIZE];
+       seqlock_t seqlock;              /* protects vblank count and time */
+
+       u32 count;                      /* vblank counter */
+       struct timeval time;            /* vblank timestamp */
 
        atomic_t refcount;              /* number of users of vblank interruptsper crtc */
        u32 last;                       /* protected by dev->vbl_lock, used */
@@ -759,6 +756,10 @@ struct drm_device {
        struct drm_minor *control;              /**< Control node */
        struct drm_minor *primary;              /**< Primary node */
        struct drm_minor *render;               /**< Render node */
+
+       /* currently active master for this device. Protected by master_mutex */
+       struct drm_master *master;
+
        atomic_t unplugged;                     /**< Flag whether dev is dead */
        struct inode *anon_inode;               /**< inode for private address-space */
        char *unique;                           /**< unique name of the device */
@@ -928,7 +929,6 @@ int drm_open(struct inode *inode, struct file *filp);
 ssize_t drm_read(struct file *filp, char __user *buffer,
                 size_t count, loff_t *offset);
 int drm_release(struct inode *inode, struct file *filp);
-int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
 int drm_event_reserve_init_locked(struct drm_device *dev,
                                  struct drm_file *file_priv,
@@ -972,18 +972,12 @@ extern u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
                                     struct timeval *vblanktime);
 extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
                                          struct timeval *vblanktime);
-extern void drm_send_vblank_event(struct drm_device *dev, unsigned int pipe,
-                                 struct drm_pending_vblank_event *e);
 extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
                                       struct drm_pending_vblank_event *e);
-extern void drm_arm_vblank_event(struct drm_device *dev, unsigned int pipe,
-                                struct drm_pending_vblank_event *e);
 extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,
                                      struct drm_pending_vblank_event *e);
 extern bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
 extern bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
-extern int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
-extern void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
 extern int drm_crtc_vblank_get(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_put(struct drm_crtc *crtc);
 extern void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
@@ -994,6 +988,7 @@ extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
 extern void drm_crtc_vblank_reset(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_accurate_vblank_count(struct drm_crtc *crtc);
 extern u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe);
 
 extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
@@ -1078,6 +1073,9 @@ extern void drm_sysfs_hotplug_event(struct drm_device *dev);
 
 struct drm_device *drm_dev_alloc(struct drm_driver *driver,
                                 struct device *parent);
+int drm_dev_init(struct drm_device *dev,
+                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);