1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <drm/ttm/ttm_placement.h>
29
30#include <drm/drmP.h>
31#include "vmwgfx_drv.h"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50int vmw_dmabuf_to_placement(struct vmw_private *dev_priv,
51 struct vmw_dma_buffer *buf,
52 struct ttm_placement *placement,
53 bool interruptible)
54{
55 struct vmw_master *vmaster = dev_priv->active_master;
56 struct ttm_buffer_object *bo = &buf->base;
57 int ret;
58
59 ret = ttm_write_lock(&vmaster->lock, interruptible);
60 if (unlikely(ret != 0))
61 return ret;
62
63 vmw_execbuf_release_pinned_bo(dev_priv);
64
65 ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
66 if (unlikely(ret != 0))
67 goto err;
68
69 ret = ttm_bo_validate(bo, placement, interruptible, false);
70
71 ttm_bo_unreserve(bo);
72
73err:
74 ttm_write_unlock(&vmaster->lock);
75 return ret;
76}
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv,
95 struct vmw_dma_buffer *buf,
96 bool pin, bool interruptible)
97{
98 struct vmw_master *vmaster = dev_priv->active_master;
99 struct ttm_buffer_object *bo = &buf->base;
100 struct ttm_placement *placement;
101 int ret;
102
103 ret = ttm_write_lock(&vmaster->lock, interruptible);
104 if (unlikely(ret != 0))
105 return ret;
106
107 if (pin)
108 vmw_execbuf_release_pinned_bo(dev_priv);
109
110 ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
111 if (unlikely(ret != 0))
112 goto err;
113
114
115
116
117
118
119
120
121 if (pin)
122 placement = &vmw_vram_gmr_ne_placement;
123 else
124 placement = &vmw_vram_gmr_placement;
125
126 ret = ttm_bo_validate(bo, placement, interruptible, false);
127 if (likely(ret == 0) || ret == -ERESTARTSYS)
128 goto err_unreserve;
129
130
131
132
133
134
135
136 if (pin)
137 placement = &vmw_vram_ne_placement;
138 else
139 placement = &vmw_vram_placement;
140
141 ret = ttm_bo_validate(bo, placement, interruptible, false);
142
143err_unreserve:
144 ttm_bo_unreserve(bo);
145err:
146 ttm_write_unlock(&vmaster->lock);
147 return ret;
148}
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165int vmw_dmabuf_to_vram(struct vmw_private *dev_priv,
166 struct vmw_dma_buffer *buf,
167 bool pin, bool interruptible)
168{
169 struct ttm_placement *placement;
170
171 if (pin)
172 placement = &vmw_vram_ne_placement;
173 else
174 placement = &vmw_vram_placement;
175
176 return vmw_dmabuf_to_placement(dev_priv, buf,
177 placement,
178 interruptible);
179}
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv,
198 struct vmw_dma_buffer *buf,
199 bool pin, bool interruptible)
200{
201 struct vmw_master *vmaster = dev_priv->active_master;
202 struct ttm_buffer_object *bo = &buf->base;
203 struct ttm_placement placement;
204 int ret = 0;
205
206 if (pin)
207 placement = vmw_vram_ne_placement;
208 else
209 placement = vmw_vram_placement;
210 placement.lpfn = bo->num_pages;
211
212 ret = ttm_write_lock(&vmaster->lock, interruptible);
213 if (unlikely(ret != 0))
214 return ret;
215
216 if (pin)
217 vmw_execbuf_release_pinned_bo(dev_priv);
218 ret = ttm_bo_reserve(bo, interruptible, false, false, 0);
219 if (unlikely(ret != 0))
220 goto err_unlock;
221
222
223 if (bo->mem.mem_type == TTM_PL_VRAM &&
224 bo->mem.start < bo->num_pages &&
225 bo->mem.start > 0)
226 (void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
227
228 ret = ttm_bo_validate(bo, &placement, interruptible, false);
229
230
231 WARN_ON(ret == 0 && bo->offset != 0);
232
233 ttm_bo_unreserve(bo);
234err_unlock:
235 ttm_write_unlock(&vmaster->lock);
236
237 return ret;
238}
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255int vmw_dmabuf_unpin(struct vmw_private *dev_priv,
256 struct vmw_dma_buffer *buf,
257 bool interruptible)
258{
259
260
261
262
263
264 return vmw_dmabuf_to_placement(dev_priv, buf,
265 &vmw_evictable_placement,
266 interruptible);
267}
268
269
270
271
272
273
274
275
276
277void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo,
278 SVGAGuestPtr *ptr)
279{
280 if (bo->mem.mem_type == TTM_PL_VRAM) {
281 ptr->gmrId = SVGA_GMR_FRAMEBUFFER;
282 ptr->offset = bo->offset;
283 } else {
284 ptr->gmrId = bo->mem.start;
285 ptr->offset = 0;
286 }
287}
288
289
290
291
292
293
294
295
296
297
298void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin)
299{
300 uint32_t pl_flags;
301 struct ttm_placement placement;
302 uint32_t old_mem_type = bo->mem.mem_type;
303 int ret;
304
305 BUG_ON(!ttm_bo_is_reserved(bo));
306 BUG_ON(old_mem_type != TTM_PL_VRAM &&
307 old_mem_type != VMW_PL_GMR);
308
309 pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED;
310 if (pin)
311 pl_flags |= TTM_PL_FLAG_NO_EVICT;
312
313 memset(&placement, 0, sizeof(placement));
314 placement.num_placement = 1;
315 placement.placement = &pl_flags;
316
317 ret = ttm_bo_validate(bo, &placement, false, true);
318
319 BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type);
320}
321