From c182be37ed7cb04c344501b88b8fdb747016e6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sat, 12 Sep 2009 04:33:34 +1000 Subject: drm: Add async event synchronization for drmWaitVblank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a new flag to the drmWaitVblank ioctl, which asks the drm to return immediately and notify userspace when the specified vblank sequence happens by sending an event back on the drm fd. The event mechanism works with the other flags supported by the ioctls, specifically, the vblank sequence can be specified relatively or absolutely, and works for primary and seconday crtc. The signal field of the vblank request is used to provide user data, which will be sent back to user space in the vblank event. Signed-off-by: Kristian Høgsberg Reviewed-by: Jesse Barnes Signed-off-by: Dave Airlie --- include/drm/drmP.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index eeefb6369e19..fe52254df60c 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -426,6 +426,14 @@ struct drm_buf_entry { 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; + void (*destroy)(struct drm_pending_event *event); +}; + /** File private data */ struct drm_file { int authenticated; @@ -449,6 +457,10 @@ struct drm_file { struct drm_master *master; /* master this node is currently associated with N.B. not always minor->master */ struct list_head fbs; + + wait_queue_head_t event_wait; + struct list_head event_list; + int event_space; }; /** Wait queue */ @@ -897,6 +909,12 @@ struct drm_minor { struct drm_mode_group mode_group; }; +struct drm_pending_vblank_event { + struct drm_pending_event base; + int pipe; + struct drm_event_vblank event; +}; + /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. @@ -996,6 +1014,12 @@ struct drm_device { u32 max_vblank_count; /**< size of vblank counter register */ + /** + * List of events + */ + struct list_head vblank_event_list; + spinlock_t event_lock; + /*@} */ cycles_t ctx_start; cycles_t lck_start; @@ -1132,6 +1156,8 @@ extern int drm_lastclose(struct drm_device *dev); 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); /* Mapping support (drm_vm.h) */ -- cgit v1.2.2 From c9a9c5e02aedc1a2815877b0268f886d2640b771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sat, 12 Sep 2009 04:33:34 +1000 Subject: drm: Add async event synchronization for drmWaitVblank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a new flag to the drmWaitVblank ioctl, which asks the drm to return immediately and notify userspace when the specified vblank sequence happens by sending an event back on the drm fd. The event mechanism works with the other flags supported by the ioctls, specifically, the vblank sequence can be specified relatively or absolutely, and works for primary and seconday crtc. The signal field of the vblank request is used to provide user data, which will be sent back to user space in the vblank event. Signed-off-by: Kristian Høgsberg Reviewed-by: Jesse Barnes Signed-off-by: Dave Airlie --- include/drm/drmP.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c8e64bbadbcf..b0b36838ab11 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -426,6 +426,14 @@ struct drm_buf_entry { 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; + void (*destroy)(struct drm_pending_event *event); +}; + /** File private data */ struct drm_file { int authenticated; @@ -449,6 +457,10 @@ struct drm_file { struct drm_master *master; /* master this node is currently associated with N.B. not always minor->master */ struct list_head fbs; + + wait_queue_head_t event_wait; + struct list_head event_list; + int event_space; }; /** Wait queue */ @@ -900,6 +912,12 @@ struct drm_minor { struct drm_mode_group mode_group; }; +struct drm_pending_vblank_event { + struct drm_pending_event base; + int pipe; + struct drm_event_vblank event; +}; + /** * DRM device structure. This structure represent a complete card that * may contain multiple heads. @@ -999,6 +1017,12 @@ struct drm_device { u32 max_vblank_count; /**< size of vblank counter register */ + /** + * List of events + */ + struct list_head vblank_event_list; + spinlock_t event_lock; + /*@} */ cycles_t ctx_start; cycles_t lck_start; @@ -1135,6 +1159,8 @@ extern int drm_lastclose(struct drm_device *dev); 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); /* Mapping support (drm_vm.h) */ -- cgit v1.2.2 From 420a457088669e055e767dfb8468909cd1799cf9 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 17 Nov 2009 14:41:23 -0800 Subject: drm: kill some unused DRM_PROC macros from drmP.h i915_gem_proc.c appears to have been the last user of the DRM_PROC_* macros, and it has gone away. The macros should die as well. Signed-off-by: Andres Salomon Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- include/drm/drmP.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index b0b36838ab11..4977fa9038d9 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -245,16 +245,6 @@ extern void drm_ut_debug_printk(unsigned int request_level, #endif -#define DRM_PROC_LIMIT (PAGE_SIZE-80) - -#define DRM_PROC_PRINT(fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; } - -#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \ - len += sprintf(&buf[len], fmt , ##arg); \ - if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } - /*@}*/ /***********************************************************************/ -- cgit v1.2.2 From 156822f7175d9ceb9d7e808502d3c5de8841e047 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Tue, 17 Nov 2009 14:41:23 -0800 Subject: drm: kill more unused DRM macros There are a few more macros in drmP.h that are unused; DRM_GET_PRIV_SAREA, DRM_ARRAY_SIZE, and DRM_WAITCOUNT can go away completely. Unfortunately, DRM_COPY is still used in one place, but we can at least move it to where it's used. It's an awful looking macro.. [akpm: fix overeagerness] Signed-off-by: Andres Salomon Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie --- include/drm/drmP.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 4977fa9038d9..1b72a526ba64 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -255,19 +255,8 @@ extern void drm_ut_debug_printk(unsigned int request_level, #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) -#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist) #define DRM_IF_VERSION(maj, min) (maj << 16 | min) -/** - * Get the private SAREA mapping. - * - * \param _dev DRM device. - * \param _ctx context number. - * \param _map output mapping. - */ -#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \ - (_map) = (_dev)->context_sareas[_ctx]; \ -} while(0) /** * Test that the hardware lock is held by the caller, returning otherwise. @@ -286,18 +275,6 @@ do { \ } \ } while (0) -/** - * Copy and IOCTL return string to user space - */ -#define DRM_COPY( name, value ) \ - len = strlen( value ); \ - if ( len > name##_len ) len = name##_len; \ - name##_len = strlen( value ); \ - if ( len && name ) { \ - if ( copy_to_user( name, value, len ) ) \ - return -EFAULT; \ - } - /** * Ioctl function type. * -- cgit v1.2.2 From c8e0f93a381d1d76135e567f13a4418fce66fd95 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 22 Nov 2009 03:49:37 +0100 Subject: drm/i915: Replace a calloc followed by copying data over it with malloc. Execbufs involve quite a bit of payload, to the extent that cache misses show up in the profiles here, and a suspicion that some of those cachelines may get evicted and then reloaded in the subsequent copy. This is still abstracted like drm_calloc_large since we want to check for size overflow, and because we want to choose between kmalloc and vmalloc on the fly. cairo's interface for malloc-with-calloc's-args was used as the model. Signed-off-by: Eric Anholt --- include/drm/drmP.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index b0b36838ab11..1b807d0f6cdb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1545,14 +1545,27 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) { + if (size != 0 && nmemb > ULONG_MAX / size) + return NULL; + if (size * nmemb <= PAGE_SIZE) return kcalloc(nmemb, size, GFP_KERNEL); + return __vmalloc(size * nmemb, + GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); +} + +/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */ +static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size) +{ if (size != 0 && nmemb > ULONG_MAX / size) return NULL; + if (size * nmemb <= PAGE_SIZE) + return kmalloc(nmemb * size, GFP_KERNEL); + return __vmalloc(size * nmemb, - GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL); + GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); } static __inline void drm_free_large(void *ptr) -- cgit v1.2.2 From 778c902640530371a169ad1c03566e7c51b09874 Mon Sep 17 00:00:00 2001 From: Li Peng Date: Mon, 9 Nov 2009 12:51:22 +0800 Subject: drm/i915: Fix sync to vblank when VGA output is turned off In current vblank-wait implementation, if we turn off VGA output, drm_wait_vblank will still wait on the disabled pipe until timeout, because vblank on the pipe is assumed be enabled. This would cause slow system response on some system such as moblin. This patch resolve the issue by adding a drm helper function drm_vblank_off which explicitly clear vblank_enabled[crtc], wake up any waiting queue and save last vblank counter before turning off crtc. It also slightly change drm_vblank_get to ensure that we will will return immediately if trying to wait on a disabled pipe. Signed-off-by: Li Peng Reviewed-by: Jesse Barnes [anholt: hand-applied for conflicts with overlay changes] Signed-off-by: Eric Anholt --- include/drm/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index febf6c530c66..fd919959d146 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1288,6 +1288,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc); extern void 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 void drm_vblank_off(struct drm_device *dev, int crtc); extern void drm_vblank_cleanup(struct drm_device *dev); /* Modesetting support */ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); -- cgit v1.2.2 From 862302ffe422378a5213f558fc5cdf62c37050a9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 2 Dec 2009 18:15:25 +0000 Subject: drm: Add support for drm master_[set|drop] callbacks. The vmwgfx driver has a per master rw lock around TTM, to guarantee mutual exclusion when needed. This is typically when all evictable buffers are evicted due to 1) vt switch 2) master switch 3) suspend / resume. In the multi-master case, on master switch the new master takes the previously active master lock in write mode, and then evicts all buffers. Any clients to previous masters will then block on that lock when trying to validate a buffer. fbdev also acts as a virtual master wrt this. Signed-off-by: Thomas Hellstrom Signed-off-by: Jakob Bornecrantz Signed-off-by: Dave Airlie --- include/drm/drmP.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 1b72a526ba64..770772c014aa 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -774,6 +774,15 @@ struct drm_driver { /* Master routines */ int (*master_create)(struct drm_device *dev, struct drm_master *master); void (*master_destroy)(struct drm_device *dev, struct drm_master *master); + /** + * master_set is called whenever the minor master is set. + * master_drop is called whenever the minor master is dropped. + */ + + int (*master_set)(struct drm_device *dev, struct drm_file *file_priv, + bool from_open); + void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv, + bool from_release); int (*proc_init)(struct drm_minor *minor); void (*proc_cleanup)(struct drm_minor *minor); -- cgit v1.2.2 From 1a95916f5465ad6c91398f17924949db7e0b5c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Dec 2009 12:13:48 -0500 Subject: drm: Add compatibility #ifdefs for *BSD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This let's use use the linux drm headers as the canonical source for libdrm on all platforms. Signed-off-by: Kristian Høgsberg Signed-off-by: Dave Airlie --- include/drm/drmP.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/drm/drmP.h') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 770772c014aa..db56a6add5de 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -289,6 +289,9 @@ typedef int drm_ioctl_t(struct drm_device *dev, void *data, 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 -- cgit v1.2.2