diff options
author | Jakob Bornecrantz <jakob@vmware.com> | 2011-10-04 14:13:21 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-05 05:17:13 -0400 |
commit | d991ef0395596c4aeabcded322011d3f5fa9e74e (patch) | |
tree | d9e1b3ab4ad8454f9c6512a2257b07174460d7b1 /drivers/gpu/drm/vmwgfx | |
parent | 626ab771c2f2d060d29470f18b3f7d710ba909dc (diff) |
vmwgfx: Add dmabuf helper functions for pinning
Signed-off-by: Jakob Bornecrantz <jakob@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | 292 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 66 |
7 files changed, 379 insertions, 107 deletions
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile index 7d8e9d5d498..e13a118b2ee 100644 --- a/drivers/gpu/drm/vmwgfx/Makefile +++ b/drivers/gpu/drm/vmwgfx/Makefile | |||
@@ -5,6 +5,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ | |||
5 | vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \ | 5 | vmwgfx_fb.o vmwgfx_ioctl.o vmwgfx_resource.o vmwgfx_buffer.o \ |
6 | vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ | 6 | vmwgfx_fifo.o vmwgfx_irq.o vmwgfx_ldu.o vmwgfx_ttm_glue.o \ |
7 | vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \ | 7 | vmwgfx_overlay.o vmwgfx_marker.o vmwgfx_gmrid_manager.o \ |
8 | vmwgfx_fence.o | 8 | vmwgfx_fence.o vmwgfx_dmabuf.o |
9 | 9 | ||
10 | obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o | 10 | obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c index 5d665ce8cbe..98a5d7e9054 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | |||
@@ -42,6 +42,10 @@ static uint32_t sys_placement_flags = TTM_PL_FLAG_SYSTEM | | |||
42 | static uint32_t gmr_placement_flags = VMW_PL_FLAG_GMR | | 42 | static uint32_t gmr_placement_flags = VMW_PL_FLAG_GMR | |
43 | TTM_PL_FLAG_CACHED; | 43 | TTM_PL_FLAG_CACHED; |
44 | 44 | ||
45 | static uint32_t gmr_ne_placement_flags = VMW_PL_FLAG_GMR | | ||
46 | TTM_PL_FLAG_CACHED | | ||
47 | TTM_PL_FLAG_NO_EVICT; | ||
48 | |||
45 | struct ttm_placement vmw_vram_placement = { | 49 | struct ttm_placement vmw_vram_placement = { |
46 | .fpfn = 0, | 50 | .fpfn = 0, |
47 | .lpfn = 0, | 51 | .lpfn = 0, |
@@ -65,6 +69,20 @@ struct ttm_placement vmw_vram_gmr_placement = { | |||
65 | .busy_placement = &gmr_placement_flags | 69 | .busy_placement = &gmr_placement_flags |
66 | }; | 70 | }; |
67 | 71 | ||
72 | static uint32_t vram_gmr_ne_placement_flags[] = { | ||
73 | TTM_PL_FLAG_VRAM | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT, | ||
74 | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED | TTM_PL_FLAG_NO_EVICT | ||
75 | }; | ||
76 | |||
77 | struct ttm_placement vmw_vram_gmr_ne_placement = { | ||
78 | .fpfn = 0, | ||
79 | .lpfn = 0, | ||
80 | .num_placement = 2, | ||
81 | .placement = vram_gmr_ne_placement_flags, | ||
82 | .num_busy_placement = 1, | ||
83 | .busy_placement = &gmr_ne_placement_flags | ||
84 | }; | ||
85 | |||
68 | struct ttm_placement vmw_vram_sys_placement = { | 86 | struct ttm_placement vmw_vram_sys_placement = { |
69 | .fpfn = 0, | 87 | .fpfn = 0, |
70 | .lpfn = 0, | 88 | .lpfn = 0, |
@@ -92,6 +110,21 @@ struct ttm_placement vmw_sys_placement = { | |||
92 | .busy_placement = &sys_placement_flags | 110 | .busy_placement = &sys_placement_flags |
93 | }; | 111 | }; |
94 | 112 | ||
113 | static uint32_t evictable_placement_flags[] = { | ||
114 | TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED, | ||
115 | TTM_PL_FLAG_VRAM | TTM_PL_FLAG_CACHED, | ||
116 | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED | ||
117 | }; | ||
118 | |||
119 | struct ttm_placement vmw_evictable_placement = { | ||
120 | .fpfn = 0, | ||
121 | .lpfn = 0, | ||
122 | .num_placement = 3, | ||
123 | .placement = evictable_placement_flags, | ||
124 | .num_busy_placement = 1, | ||
125 | .busy_placement = &sys_placement_flags | ||
126 | }; | ||
127 | |||
95 | struct vmw_ttm_backend { | 128 | struct vmw_ttm_backend { |
96 | struct ttm_backend backend; | 129 | struct ttm_backend backend; |
97 | struct page **pages; | 130 | struct page **pages; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c new file mode 100644 index 00000000000..5668ad980cb --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /************************************************************************** | ||
2 | * | ||
3 | * Copyright © 2011 VMware, Inc., Palo Alto, CA., USA | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the | ||
8 | * "Software"), to deal in the Software without restriction, including | ||
9 | * without limitation the rights to use, copy, modify, merge, publish, | ||
10 | * distribute, sub license, and/or sell copies of the Software, and to | ||
11 | * permit persons to whom the Software is furnished to do so, subject to | ||
12 | * the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice (including the | ||
15 | * next paragraph) shall be included in all copies or substantial portions | ||
16 | * of the Software. | ||
17 | * | ||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
21 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
22 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
23 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
25 | * | ||
26 | **************************************************************************/ | ||
27 | |||
28 | #include "ttm/ttm_placement.h" | ||
29 | |||
30 | #include "drmP.h" | ||
31 | #include "vmwgfx_drv.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Validate a buffer to placement. | ||
36 | * | ||
37 | * May only be called by the current master as this function takes the | ||
38 | * its lock in write mode. | ||
39 | * | ||
40 | * Returns | ||
41 | * -ERESTARTSYS if interrupted by a signal. | ||
42 | */ | ||
43 | int vmw_dmabuf_to_placement(struct vmw_private *dev_priv, | ||
44 | struct vmw_dma_buffer *buf, | ||
45 | struct ttm_placement *placement, | ||
46 | bool interruptible) | ||
47 | { | ||
48 | struct vmw_master *vmaster = dev_priv->active_master; | ||
49 | struct ttm_buffer_object *bo = &buf->base; | ||
50 | int ret; | ||
51 | |||
52 | ret = ttm_write_lock(&vmaster->lock, interruptible); | ||
53 | if (unlikely(ret != 0)) | ||
54 | return ret; | ||
55 | |||
56 | ret = ttm_bo_reserve(bo, interruptible, false, false, 0); | ||
57 | if (unlikely(ret != 0)) | ||
58 | goto err; | ||
59 | |||
60 | ret = ttm_bo_validate(bo, placement, interruptible, false, false); | ||
61 | |||
62 | ttm_bo_unreserve(bo); | ||
63 | |||
64 | err: | ||
65 | ttm_write_unlock(&vmaster->lock); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * Move a buffer to vram or gmr. | ||
71 | * | ||
72 | * May only be called by the current master as this function takes the | ||
73 | * its lock in write mode. | ||
74 | * | ||
75 | * @dev_priv: Driver private. | ||
76 | * @buf: DMA buffer to move. | ||
77 | * @pin: Pin buffer if true. | ||
78 | * @interruptible: Use interruptible wait. | ||
79 | * | ||
80 | * Returns | ||
81 | * -ERESTARTSYS if interrupted by a signal. | ||
82 | */ | ||
83 | int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv, | ||
84 | struct vmw_dma_buffer *buf, | ||
85 | bool pin, bool interruptible) | ||
86 | { | ||
87 | struct vmw_master *vmaster = dev_priv->active_master; | ||
88 | struct ttm_buffer_object *bo = &buf->base; | ||
89 | struct ttm_placement *placement; | ||
90 | int ret; | ||
91 | |||
92 | ret = ttm_write_lock(&vmaster->lock, interruptible); | ||
93 | if (unlikely(ret != 0)) | ||
94 | return ret; | ||
95 | |||
96 | ret = ttm_bo_reserve(bo, interruptible, false, false, 0); | ||
97 | if (unlikely(ret != 0)) | ||
98 | goto err; | ||
99 | |||
100 | /** | ||
101 | * Put BO in VRAM if there is space, otherwise as a GMR. | ||
102 | * If there is no space in VRAM and GMR ids are all used up, | ||
103 | * start evicting GMRs to make room. If the DMA buffer can't be | ||
104 | * used as a GMR, this will return -ENOMEM. | ||
105 | */ | ||
106 | |||
107 | if (pin) | ||
108 | placement = &vmw_vram_gmr_ne_placement; | ||
109 | else | ||
110 | placement = &vmw_vram_gmr_placement; | ||
111 | |||
112 | ret = ttm_bo_validate(bo, placement, interruptible, false, false); | ||
113 | if (likely(ret == 0) || ret == -ERESTARTSYS) | ||
114 | goto err_unreserve; | ||
115 | |||
116 | |||
117 | /** | ||
118 | * If that failed, try VRAM again, this time evicting | ||
119 | * previous contents. | ||
120 | */ | ||
121 | |||
122 | if (pin) | ||
123 | placement = &vmw_vram_ne_placement; | ||
124 | else | ||
125 | placement = &vmw_vram_placement; | ||
126 | |||
127 | ret = ttm_bo_validate(bo, placement, interruptible, false, false); | ||
128 | |||
129 | err_unreserve: | ||
130 | ttm_bo_unreserve(bo); | ||
131 | err: | ||
132 | ttm_write_unlock(&vmaster->lock); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * Move a buffer to vram. | ||
138 | * | ||
139 | * May only be called by the current master as this function takes the | ||
140 | * its lock in write mode. | ||
141 | * | ||
142 | * @dev_priv: Driver private. | ||
143 | * @buf: DMA buffer to move. | ||
144 | * @pin: Pin buffer in vram if true. | ||
145 | * @interruptible: Use interruptible wait. | ||
146 | * | ||
147 | * Returns | ||
148 | * -ERESTARTSYS if interrupted by a signal. | ||
149 | */ | ||
150 | int vmw_dmabuf_to_vram(struct vmw_private *dev_priv, | ||
151 | struct vmw_dma_buffer *buf, | ||
152 | bool pin, bool interruptible) | ||
153 | { | ||
154 | struct ttm_placement *placement; | ||
155 | |||
156 | if (pin) | ||
157 | placement = &vmw_vram_ne_placement; | ||
158 | else | ||
159 | placement = &vmw_vram_placement; | ||
160 | |||
161 | return vmw_dmabuf_to_placement(dev_priv, buf, | ||
162 | placement, | ||
163 | interruptible); | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * Move a buffer to start of vram. | ||
168 | * | ||
169 | * May only be called by the current master as this function takes the | ||
170 | * its lock in write mode. | ||
171 | * | ||
172 | * @dev_priv: Driver private. | ||
173 | * @buf: DMA buffer to move. | ||
174 | * @pin: Pin buffer in vram if true. | ||
175 | * @interruptible: Use interruptible wait. | ||
176 | * | ||
177 | * Returns | ||
178 | * -ERESTARTSYS if interrupted by a signal. | ||
179 | */ | ||
180 | int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv, | ||
181 | struct vmw_dma_buffer *buf, | ||
182 | bool pin, bool interruptible) | ||
183 | { | ||
184 | struct vmw_master *vmaster = dev_priv->active_master; | ||
185 | struct ttm_buffer_object *bo = &buf->base; | ||
186 | struct ttm_placement placement; | ||
187 | int ret = 0; | ||
188 | |||
189 | if (pin) | ||
190 | placement = vmw_vram_ne_placement; | ||
191 | else | ||
192 | placement = vmw_vram_placement; | ||
193 | placement.lpfn = bo->num_pages; | ||
194 | |||
195 | ret = ttm_write_lock(&vmaster->lock, interruptible); | ||
196 | if (unlikely(ret != 0)) | ||
197 | return ret; | ||
198 | |||
199 | ret = ttm_bo_reserve(bo, interruptible, false, false, 0); | ||
200 | if (unlikely(ret != 0)) | ||
201 | goto err_unlock; | ||
202 | |||
203 | /* Is this buffer already in vram but not at the start of it? */ | ||
204 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
205 | bo->mem.start < bo->num_pages && | ||
206 | bo->mem.start > 0) | ||
207 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
208 | false, false); | ||
209 | |||
210 | ret = ttm_bo_validate(bo, &placement, interruptible, false, false); | ||
211 | |||
212 | /* For some reason we didn't up at the start of vram */ | ||
213 | WARN_ON(ret == 0 && bo->offset != 0); | ||
214 | |||
215 | ttm_bo_unreserve(bo); | ||
216 | err_unlock: | ||
217 | ttm_write_unlock(&vmaster->lock); | ||
218 | |||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * Unpin the buffer given buffer, does not move the buffer. | ||
224 | * | ||
225 | * May only be called by the current master as this function takes the | ||
226 | * its lock in write mode. | ||
227 | * | ||
228 | * @dev_priv: Driver private. | ||
229 | * @buf: DMA buffer to unpin. | ||
230 | * @interruptible: Use interruptible wait. | ||
231 | * | ||
232 | * Returns | ||
233 | * -ERESTARTSYS if interrupted by a signal. | ||
234 | */ | ||
235 | int vmw_dmabuf_unpin(struct vmw_private *dev_priv, | ||
236 | struct vmw_dma_buffer *buf, | ||
237 | bool interruptible) | ||
238 | { | ||
239 | /* | ||
240 | * We could in theory early out if the buffer is | ||
241 | * unpinned but we need to lock and reserve the buffer | ||
242 | * anyways so we don't gain much by that. | ||
243 | */ | ||
244 | return vmw_dmabuf_to_placement(dev_priv, buf, | ||
245 | &vmw_evictable_placement, | ||
246 | interruptible); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * Move a buffer to system memory, does not pin the buffer. | ||
251 | * | ||
252 | * May only be called by the current master as this function takes the | ||
253 | * its lock in write mode. | ||
254 | * | ||
255 | * @dev_priv: Driver private. | ||
256 | * @buf: DMA buffer to move. | ||
257 | * @interruptible: Use interruptible wait. | ||
258 | * | ||
259 | * Returns | ||
260 | * -ERESTARTSYS if interrupted by a signal. | ||
261 | */ | ||
262 | int vmw_dmabuf_to_system(struct vmw_private *dev_priv, | ||
263 | struct vmw_dma_buffer *buf, | ||
264 | bool interruptible) | ||
265 | { | ||
266 | return vmw_dmabuf_to_placement(dev_priv, buf, | ||
267 | &vmw_sys_placement, | ||
268 | interruptible); | ||
269 | } | ||
270 | |||
271 | void vmw_dmabuf_get_id_offset(struct vmw_dma_buffer *buf, | ||
272 | uint32_t *gmrId, uint32_t *offset) | ||
273 | { | ||
274 | if (buf->base.mem.mem_type == TTM_PL_VRAM) { | ||
275 | *gmrId = SVGA_GMR_FRAMEBUFFER; | ||
276 | *offset = buf->base.offset; | ||
277 | } else { | ||
278 | *gmrId = buf->base.mem.start; | ||
279 | *offset = 0; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | void vmw_dmabuf_get_guest_ptr(struct vmw_dma_buffer *buf, SVGAGuestPtr *ptr) | ||
284 | { | ||
285 | if (buf->base.mem.mem_type == TTM_PL_VRAM) { | ||
286 | ptr->gmrId = SVGA_GMR_FRAMEBUFFER; | ||
287 | ptr->offset = buf->base.offset; | ||
288 | } else { | ||
289 | ptr->gmrId = buf->base.mem.start; | ||
290 | ptr->offset = 0; | ||
291 | } | ||
292 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index edd1e8362f3..5acf1f2c498 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -385,10 +385,6 @@ extern uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo, | |||
385 | extern void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo); | 385 | extern void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo); |
386 | extern int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile, | 386 | extern int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile, |
387 | uint32_t id, struct vmw_dma_buffer **out); | 387 | uint32_t id, struct vmw_dma_buffer **out); |
388 | extern int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | ||
389 | struct vmw_dma_buffer *bo); | ||
390 | extern int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv, | ||
391 | struct vmw_dma_buffer *bo); | ||
392 | extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, | 388 | extern int vmw_stream_claim_ioctl(struct drm_device *dev, void *data, |
393 | struct drm_file *file_priv); | 389 | struct drm_file *file_priv); |
394 | extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, | 390 | extern int vmw_stream_unref_ioctl(struct drm_device *dev, void *data, |
@@ -398,6 +394,32 @@ extern int vmw_user_stream_lookup(struct vmw_private *dev_priv, | |||
398 | uint32_t *inout_id, | 394 | uint32_t *inout_id, |
399 | struct vmw_resource **out); | 395 | struct vmw_resource **out); |
400 | 396 | ||
397 | /** | ||
398 | * DMA buffer helper routines - vmwgfx_dmabuf.c | ||
399 | */ | ||
400 | extern int vmw_dmabuf_to_placement(struct vmw_private *vmw_priv, | ||
401 | struct vmw_dma_buffer *bo, | ||
402 | struct ttm_placement *placement, | ||
403 | bool interruptible); | ||
404 | extern int vmw_dmabuf_to_vram(struct vmw_private *dev_priv, | ||
405 | struct vmw_dma_buffer *buf, | ||
406 | bool pin, bool interruptible); | ||
407 | extern int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv, | ||
408 | struct vmw_dma_buffer *buf, | ||
409 | bool pin, bool interruptible); | ||
410 | extern int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | ||
411 | struct vmw_dma_buffer *bo, | ||
412 | bool pin, bool interruptible); | ||
413 | extern int vmw_dmabuf_unpin(struct vmw_private *vmw_priv, | ||
414 | struct vmw_dma_buffer *bo, | ||
415 | bool interruptible); | ||
416 | extern int vmw_dmabuf_to_system(struct vmw_private *vmw_priv, | ||
417 | struct vmw_dma_buffer *bo, | ||
418 | bool interruptible); | ||
419 | extern void vmw_dmabuf_get_id_offset(struct vmw_dma_buffer *buf, | ||
420 | uint32_t *gmrId, uint32_t *offset); | ||
421 | extern void vmw_dmabuf_get_guest_ptr(struct vmw_dma_buffer *buf, | ||
422 | SVGAGuestPtr *ptr); | ||
401 | 423 | ||
402 | /** | 424 | /** |
403 | * Misc Ioctl functionality - vmwgfx_ioctl.c | 425 | * Misc Ioctl functionality - vmwgfx_ioctl.c |
@@ -440,7 +462,9 @@ extern struct ttm_placement vmw_vram_placement; | |||
440 | extern struct ttm_placement vmw_vram_ne_placement; | 462 | extern struct ttm_placement vmw_vram_ne_placement; |
441 | extern struct ttm_placement vmw_vram_sys_placement; | 463 | extern struct ttm_placement vmw_vram_sys_placement; |
442 | extern struct ttm_placement vmw_vram_gmr_placement; | 464 | extern struct ttm_placement vmw_vram_gmr_placement; |
465 | extern struct ttm_placement vmw_vram_gmr_ne_placement; | ||
443 | extern struct ttm_placement vmw_sys_placement; | 466 | extern struct ttm_placement vmw_sys_placement; |
467 | extern struct ttm_placement vmw_evictable_placement; | ||
444 | extern struct ttm_bo_driver vmw_bo_driver; | 468 | extern struct ttm_bo_driver vmw_bo_driver; |
445 | extern int vmw_dma_quiescent(struct drm_device *dev); | 469 | extern int vmw_dma_quiescent(struct drm_device *dev); |
446 | 470 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index b1888e801e2..191f1b2a2a2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -592,58 +592,6 @@ int vmw_fb_close(struct vmw_private *vmw_priv) | |||
592 | return 0; | 592 | return 0; |
593 | } | 593 | } |
594 | 594 | ||
595 | int vmw_dmabuf_from_vram(struct vmw_private *vmw_priv, | ||
596 | struct vmw_dma_buffer *vmw_bo) | ||
597 | { | ||
598 | struct ttm_buffer_object *bo = &vmw_bo->base; | ||
599 | int ret = 0; | ||
600 | |||
601 | ret = ttm_bo_reserve(bo, false, false, false, 0); | ||
602 | if (unlikely(ret != 0)) | ||
603 | return ret; | ||
604 | |||
605 | ret = ttm_bo_validate(bo, &vmw_sys_placement, false, false, false); | ||
606 | ttm_bo_unreserve(bo); | ||
607 | |||
608 | return ret; | ||
609 | } | ||
610 | |||
611 | int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | ||
612 | struct vmw_dma_buffer *vmw_bo) | ||
613 | { | ||
614 | struct ttm_buffer_object *bo = &vmw_bo->base; | ||
615 | struct ttm_placement ne_placement = vmw_vram_ne_placement; | ||
616 | int ret = 0; | ||
617 | |||
618 | ne_placement.lpfn = bo->num_pages; | ||
619 | |||
620 | /* interuptable? */ | ||
621 | ret = ttm_write_lock(&vmw_priv->active_master->lock, false); | ||
622 | if (unlikely(ret != 0)) | ||
623 | return ret; | ||
624 | |||
625 | ret = ttm_bo_reserve(bo, false, false, false, 0); | ||
626 | if (unlikely(ret != 0)) | ||
627 | goto err_unlock; | ||
628 | |||
629 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
630 | bo->mem.start < bo->num_pages && | ||
631 | bo->mem.start > 0) | ||
632 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
633 | false, false); | ||
634 | |||
635 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | ||
636 | |||
637 | /* Could probably bug on */ | ||
638 | WARN_ON(bo->offset != 0); | ||
639 | |||
640 | ttm_bo_unreserve(bo); | ||
641 | err_unlock: | ||
642 | ttm_write_unlock(&vmw_priv->active_master->lock); | ||
643 | |||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | int vmw_fb_off(struct vmw_private *vmw_priv) | 595 | int vmw_fb_off(struct vmw_private *vmw_priv) |
648 | { | 596 | { |
649 | struct fb_info *info; | 597 | struct fb_info *info; |
@@ -665,7 +613,8 @@ int vmw_fb_off(struct vmw_private *vmw_priv) | |||
665 | par->bo_ptr = NULL; | 613 | par->bo_ptr = NULL; |
666 | ttm_bo_kunmap(&par->map); | 614 | ttm_bo_kunmap(&par->map); |
667 | 615 | ||
668 | vmw_dmabuf_from_vram(vmw_priv, par->vmw_bo); | 616 | /* move this to system instead of just unpinning it */ |
617 | vmw_dmabuf_to_system(vmw_priv, par->vmw_bo, false); | ||
669 | 618 | ||
670 | return 0; | 619 | return 0; |
671 | } | 620 | } |
@@ -691,7 +640,7 @@ int vmw_fb_on(struct vmw_private *vmw_priv) | |||
691 | /* Make sure that all overlays are stoped when we take over */ | 640 | /* Make sure that all overlays are stoped when we take over */ |
692 | vmw_overlay_stop_all(vmw_priv); | 641 | vmw_overlay_stop_all(vmw_priv); |
693 | 642 | ||
694 | ret = vmw_dmabuf_to_start_of_vram(vmw_priv, par->vmw_bo); | 643 | ret = vmw_dmabuf_to_start_of_vram(vmw_priv, par->vmw_bo, true, false); |
695 | if (unlikely(ret != 0)) { | 644 | if (unlikely(ret != 0)) { |
696 | DRM_ERROR("could not move buffer to start of VRAM\n"); | 645 | DRM_ERROR("could not move buffer to start of VRAM\n"); |
697 | goto err_no_buffer; | 646 | goto err_no_buffer; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index c34866ab352..b3d5120b1f4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -804,7 +804,7 @@ static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb) | |||
804 | 804 | ||
805 | vmw_overlay_pause_all(dev_priv); | 805 | vmw_overlay_pause_all(dev_priv); |
806 | 806 | ||
807 | ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer); | 807 | ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer, true, false); |
808 | 808 | ||
809 | vmw_overlay_resume_all(dev_priv); | 809 | vmw_overlay_resume_all(dev_priv); |
810 | 810 | ||
@@ -824,7 +824,7 @@ static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb) | |||
824 | return 0; | 824 | return 0; |
825 | } | 825 | } |
826 | 826 | ||
827 | return vmw_dmabuf_from_vram(dev_priv, vfbd->buffer); | 827 | return vmw_dmabuf_unpin(dev_priv, vfbd->buffer, false); |
828 | } | 828 | } |
829 | 829 | ||
830 | static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, | 830 | static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index 07ce02da78a..7a7abcdf102 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | |||
@@ -87,48 +87,6 @@ static inline void fill_flush(struct vmw_escape_video_flush *cmd, | |||
87 | } | 87 | } |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Pin or unpin a buffer in vram. | ||
91 | * | ||
92 | * @dev_priv: Driver private. | ||
93 | * @buf: DMA buffer to pin or unpin. | ||
94 | * @pin: Pin buffer in vram if true. | ||
95 | * @interruptible: Use interruptible wait. | ||
96 | * | ||
97 | * Takes the current masters ttm lock in read. | ||
98 | * | ||
99 | * Returns | ||
100 | * -ERESTARTSYS if interrupted by a signal. | ||
101 | */ | ||
102 | static int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv, | ||
103 | struct vmw_dma_buffer *buf, | ||
104 | bool pin, bool interruptible) | ||
105 | { | ||
106 | struct ttm_buffer_object *bo = &buf->base; | ||
107 | struct ttm_placement *overlay_placement = &vmw_vram_placement; | ||
108 | int ret; | ||
109 | |||
110 | ret = ttm_read_lock(&dev_priv->active_master->lock, interruptible); | ||
111 | if (unlikely(ret != 0)) | ||
112 | return ret; | ||
113 | |||
114 | ret = ttm_bo_reserve(bo, interruptible, false, false, 0); | ||
115 | if (unlikely(ret != 0)) | ||
116 | goto err; | ||
117 | |||
118 | if (pin) | ||
119 | overlay_placement = &vmw_vram_ne_placement; | ||
120 | |||
121 | ret = ttm_bo_validate(bo, overlay_placement, interruptible, false, false); | ||
122 | |||
123 | ttm_bo_unreserve(bo); | ||
124 | |||
125 | err: | ||
126 | ttm_read_unlock(&dev_priv->active_master->lock); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Send put command to hw. | 90 | * Send put command to hw. |
133 | * | 91 | * |
134 | * Returns | 92 | * Returns |
@@ -248,6 +206,21 @@ static int vmw_overlay_send_stop(struct vmw_private *dev_priv, | |||
248 | } | 206 | } |
249 | 207 | ||
250 | /** | 208 | /** |
209 | * Move a buffer to vram, and pin it if @pin. | ||
210 | * | ||
211 | * XXX: This function is here to be changed at a later date. | ||
212 | */ | ||
213 | static int vmw_overlay_move_buffer(struct vmw_private *dev_priv, | ||
214 | struct vmw_dma_buffer *buf, | ||
215 | bool pin, bool inter) | ||
216 | { | ||
217 | if (pin) | ||
218 | return vmw_dmabuf_to_vram(dev_priv, buf, true, inter); | ||
219 | else | ||
220 | return vmw_dmabuf_unpin(dev_priv, buf, inter); | ||
221 | } | ||
222 | |||
223 | /** | ||
251 | * Stop or pause a stream. | 224 | * Stop or pause a stream. |
252 | * | 225 | * |
253 | * If the stream is paused the no evict flag is removed from the buffer | 226 | * If the stream is paused the no evict flag is removed from the buffer |
@@ -279,8 +252,8 @@ static int vmw_overlay_stop(struct vmw_private *dev_priv, | |||
279 | return ret; | 252 | return ret; |
280 | 253 | ||
281 | /* We just remove the NO_EVICT flag so no -ENOMEM */ | 254 | /* We just remove the NO_EVICT flag so no -ENOMEM */ |
282 | ret = vmw_dmabuf_pin_in_vram(dev_priv, stream->buf, false, | 255 | ret = vmw_overlay_move_buffer(dev_priv, stream->buf, false, |
283 | interruptible); | 256 | interruptible); |
284 | if (interruptible && ret == -ERESTARTSYS) | 257 | if (interruptible && ret == -ERESTARTSYS) |
285 | return ret; | 258 | return ret; |
286 | else | 259 | else |
@@ -342,7 +315,7 @@ static int vmw_overlay_update_stream(struct vmw_private *dev_priv, | |||
342 | /* We don't start the old stream if we are interrupted. | 315 | /* We don't start the old stream if we are interrupted. |
343 | * Might return -ENOMEM if it can't fit the buffer in vram. | 316 | * Might return -ENOMEM if it can't fit the buffer in vram. |
344 | */ | 317 | */ |
345 | ret = vmw_dmabuf_pin_in_vram(dev_priv, buf, true, interruptible); | 318 | ret = vmw_overlay_move_buffer(dev_priv, buf, true, interruptible); |
346 | if (ret) | 319 | if (ret) |
347 | return ret; | 320 | return ret; |
348 | 321 | ||
@@ -351,7 +324,8 @@ static int vmw_overlay_update_stream(struct vmw_private *dev_priv, | |||
351 | /* This one needs to happen no matter what. We only remove | 324 | /* This one needs to happen no matter what. We only remove |
352 | * the NO_EVICT flag so this is safe from -ENOMEM. | 325 | * the NO_EVICT flag so this is safe from -ENOMEM. |
353 | */ | 326 | */ |
354 | BUG_ON(vmw_dmabuf_pin_in_vram(dev_priv, buf, false, false) != 0); | 327 | BUG_ON(vmw_overlay_move_buffer(dev_priv, buf, false, false) |
328 | != 0); | ||
355 | return ret; | 329 | return ret; |
356 | } | 330 | } |
357 | 331 | ||