]>
Commit | Line | Data |
---|---|---|
739e1c91 GKH |
1 | From 48764bf43f746113fc77877d7e80f2df23ca4cbb Mon Sep 17 00:00:00 2001 |
2 | From: Daniel Vetter <daniel.vetter@ffwll.ch> | |
3 | Date: Tue, 15 Sep 2009 22:57:32 +0200 | |
4 | Subject: drm/i915: add i915_lp_ring_sync helper | |
5 | ||
6 | From: Daniel Vetter <daniel.vetter@ffwll.ch> | |
7 | ||
8 | commit 48764bf43f746113fc77877d7e80f2df23ca4cbb upstream. | |
9 | ||
10 | This just waits until the hw passed the current ring position with | |
11 | cmd execution. This slightly changes the existing i915_wait_request | |
12 | function to make uninterruptible waiting possible - no point in | |
13 | returning to userspace while mucking around with the overlay, that | |
14 | piece of hw is just too fragile. | |
15 | ||
16 | Also replace a magic 0 with the symbolic constant (and kill the then | |
17 | superflous comment) while I was looking at the code. | |
18 | ||
19 | Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> | |
20 | Signed-off-by: Eric Anholt <eric@anholt.net> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
22 | ||
23 | --- | |
24 | drivers/gpu/drm/i915/i915_drv.h | 1 | |
25 | drivers/gpu/drm/i915/i915_gem.c | 49 +++++++++++++++++++++++++++++++--------- | |
26 | include/drm/drm_os_linux.h | 2 - | |
27 | 3 files changed, 41 insertions(+), 11 deletions(-) | |
28 | ||
29 | --- a/drivers/gpu/drm/i915/i915_drv.h | |
30 | +++ b/drivers/gpu/drm/i915/i915_drv.h | |
31 | @@ -825,6 +825,7 @@ void i915_gem_cleanup_ringbuffer(struct | |
32 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | |
33 | unsigned long end); | |
34 | int i915_gem_idle(struct drm_device *dev); | |
35 | +int i915_lp_ring_sync(struct drm_device *dev); | |
36 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | |
37 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | |
38 | int write); | |
39 | --- a/drivers/gpu/drm/i915/i915_gem.c | |
40 | +++ b/drivers/gpu/drm/i915/i915_gem.c | |
41 | @@ -1809,12 +1809,8 @@ i915_gem_retire_work_handler(struct work | |
42 | mutex_unlock(&dev->struct_mutex); | |
43 | } | |
44 | ||
45 | -/** | |
46 | - * Waits for a sequence number to be signaled, and cleans up the | |
47 | - * request and object lists appropriately for that event. | |
48 | - */ | |
49 | static int | |
50 | -i915_wait_request(struct drm_device *dev, uint32_t seqno) | |
51 | +i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |
52 | { | |
53 | drm_i915_private_t *dev_priv = dev->dev_private; | |
54 | u32 ier; | |
55 | @@ -1841,10 +1837,15 @@ i915_wait_request(struct drm_device *dev | |
56 | ||
57 | dev_priv->mm.waiting_gem_seqno = seqno; | |
58 | i915_user_irq_get(dev); | |
59 | - ret = wait_event_interruptible(dev_priv->irq_queue, | |
60 | - i915_seqno_passed(i915_get_gem_seqno(dev), | |
61 | - seqno) || | |
62 | - atomic_read(&dev_priv->mm.wedged)); | |
63 | + if (interruptible) | |
64 | + ret = wait_event_interruptible(dev_priv->irq_queue, | |
65 | + i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | |
66 | + atomic_read(&dev_priv->mm.wedged)); | |
67 | + else | |
68 | + wait_event(dev_priv->irq_queue, | |
69 | + i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | |
70 | + atomic_read(&dev_priv->mm.wedged)); | |
71 | + | |
72 | i915_user_irq_put(dev); | |
73 | dev_priv->mm.waiting_gem_seqno = 0; | |
74 | ||
75 | @@ -1868,6 +1869,34 @@ i915_wait_request(struct drm_device *dev | |
76 | return ret; | |
77 | } | |
78 | ||
79 | +/** | |
80 | + * Waits for a sequence number to be signaled, and cleans up the | |
81 | + * request and object lists appropriately for that event. | |
82 | + */ | |
83 | +static int | |
84 | +i915_wait_request(struct drm_device *dev, uint32_t seqno) | |
85 | +{ | |
86 | + return i915_do_wait_request(dev, seqno, 1); | |
87 | +} | |
88 | + | |
89 | +/** | |
90 | + * Waits for the ring to finish up to the latest request. Usefull for waiting | |
91 | + * for flip events, e.g for the overlay support. */ | |
92 | +int i915_lp_ring_sync(struct drm_device *dev) | |
93 | +{ | |
94 | + uint32_t seqno; | |
95 | + int ret; | |
96 | + | |
97 | + seqno = i915_add_request(dev, NULL, 0); | |
98 | + | |
99 | + if (seqno == 0) | |
100 | + return -ENOMEM; | |
101 | + | |
102 | + ret = i915_do_wait_request(dev, seqno, 0); | |
103 | + BUG_ON(ret == -ERESTARTSYS); | |
104 | + return ret; | |
105 | +} | |
106 | + | |
107 | static void | |
108 | i915_gem_flush(struct drm_device *dev, | |
109 | uint32_t invalidate_domains, | |
110 | @@ -1936,7 +1965,7 @@ i915_gem_flush(struct drm_device *dev, | |
111 | #endif | |
112 | BEGIN_LP_RING(2); | |
113 | OUT_RING(cmd); | |
114 | - OUT_RING(0); /* noop */ | |
115 | + OUT_RING(MI_NOOP); | |
116 | ADVANCE_LP_RING(); | |
117 | } | |
118 | } | |
119 | --- a/include/drm/drm_os_linux.h | |
120 | +++ b/include/drm/drm_os_linux.h | |
121 | @@ -123,5 +123,5 @@ do { \ | |
122 | remove_wait_queue(&(queue), &entry); \ | |
123 | } while (0) | |
124 | ||
125 | -#define DRM_WAKEUP( queue ) wake_up_interruptible( queue ) | |
126 | +#define DRM_WAKEUP( queue ) wake_up( queue ) | |
127 | #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue ) |