Rev 5078 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6296 | ||
---|---|---|---|
1 | /************************************************************************** |
1 | /************************************************************************** |
2 | * |
2 | * |
3 | * Copyright © 2011 VMware, Inc., Palo Alto, CA., USA |
3 | * Copyright © 2011-2015 VMware, Inc., Palo Alto, CA., USA |
4 | * All Rights Reserved. |
4 | * All Rights Reserved. |
5 | * |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the |
7 | * copy of this software and associated documentation files (the |
8 | * "Software"), to deal in the Software without restriction, including |
8 | * "Software"), to deal in the Software without restriction, including |
9 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * without limitation the rights to use, copy, modify, merge, publish, |
10 | * distribute, sub license, and/or sell copies of the Software, and to |
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 |
11 | * permit persons to whom the Software is furnished to do so, subject to |
12 | * the following conditions: |
12 | * the following conditions: |
13 | * |
13 | * |
14 | * The above copyright notice and this permission notice (including the |
14 | * The above copyright notice and this permission notice (including the |
15 | * next paragraph) shall be included in all copies or substantial portions |
15 | * next paragraph) shall be included in all copies or substantial portions |
16 | * of the Software. |
16 | * of the Software. |
17 | * |
17 | * |
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
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, |
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
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, |
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 |
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 |
23 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | * |
25 | * |
26 | **************************************************************************/ |
26 | **************************************************************************/ |
27 | 27 | ||
28 | #include |
28 | #include |
29 | 29 | ||
30 | #include |
30 | #include |
31 | #include "vmwgfx_drv.h" |
31 | #include "vmwgfx_drv.h" |
32 | 32 | ||
33 | 33 | ||
34 | /** |
34 | /** |
35 | * vmw_dmabuf_to_placement - Validate a buffer to placement. |
35 | * vmw_dmabuf_pin_in_placement - Validate a buffer to placement. |
36 | * |
36 | * |
37 | * @dev_priv: Driver private. |
37 | * @dev_priv: Driver private. |
38 | * @buf: DMA buffer to move. |
38 | * @buf: DMA buffer to move. |
39 | * @pin: Pin buffer if true. |
39 | * @placement: The placement to pin it. |
40 | * @interruptible: Use interruptible wait. |
40 | * @interruptible: Use interruptible wait. |
41 | * |
41 | * |
42 | * May only be called by the current master since it assumes that the |
- | |
43 | * master lock is the current master's lock. |
- | |
44 | * This function takes the master's lock in write mode. |
- | |
45 | * Flushes and unpins the query bo to avoid failures. |
- | |
46 | * |
- | |
47 | * Returns |
42 | * Returns |
48 | * -ERESTARTSYS if interrupted by a signal. |
43 | * -ERESTARTSYS if interrupted by a signal. |
49 | */ |
44 | */ |
50 | int vmw_dmabuf_to_placement(struct vmw_private *dev_priv, |
45 | int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv, |
51 | struct vmw_dma_buffer *buf, |
46 | struct vmw_dma_buffer *buf, |
52 | struct ttm_placement *placement, |
47 | struct ttm_placement *placement, |
53 | bool interruptible) |
48 | bool interruptible) |
54 | { |
49 | { |
55 | struct ttm_buffer_object *bo = &buf->base; |
50 | struct ttm_buffer_object *bo = &buf->base; |
56 | int ret; |
51 | int ret; |
57 | 52 | ||
58 | // ret = ttm_write_lock(&vmaster->lock, interruptible); |
53 | ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible); |
59 | // if (unlikely(ret != 0)) |
54 | if (unlikely(ret != 0)) |
60 | // return ret; |
55 | return ret; |
61 | 56 | ||
62 | vmw_execbuf_release_pinned_bo(dev_priv); |
57 | vmw_execbuf_release_pinned_bo(dev_priv); |
63 | 58 | ||
64 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
59 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
65 | if (unlikely(ret != 0)) |
60 | if (unlikely(ret != 0)) |
66 | goto err; |
61 | goto err; |
67 | 62 | ||
68 | ret = ttm_bo_validate(bo, placement, interruptible, false); |
63 | ret = ttm_bo_validate(bo, placement, interruptible, false); |
- | 64 | if (!ret) |
|
- | 65 | vmw_bo_pin_reserved(buf, true); |
|
69 | 66 | ||
70 | ttm_bo_unreserve(bo); |
67 | ttm_bo_unreserve(bo); |
71 | 68 | ||
72 | err: |
69 | err: |
73 | // ttm_write_unlock(&vmaster->lock); |
70 | ttm_write_unlock(&dev_priv->reservation_sem); |
74 | return ret; |
71 | return ret; |
75 | } |
72 | } |
76 | 73 | ||
77 | /** |
74 | /** |
78 | * vmw_dmabuf_to_vram_or_gmr - Move a buffer to vram or gmr. |
75 | * vmw_dmabuf_pin_in_vram_or_gmr - Move a buffer to vram or gmr. |
79 | * |
76 | * |
80 | * May only be called by the current master since it assumes that the |
- | |
81 | * master lock is the current master's lock. |
- | |
82 | * This function takes the master's lock in write mode. |
77 | * This function takes the reservation_sem in write mode. |
83 | * Flushes and unpins the query bo if @pin == true to avoid failures. |
78 | * Flushes and unpins the query bo to avoid failures. |
84 | * |
79 | * |
85 | * @dev_priv: Driver private. |
80 | * @dev_priv: Driver private. |
86 | * @buf: DMA buffer to move. |
81 | * @buf: DMA buffer to move. |
87 | * @pin: Pin buffer if true. |
82 | * @pin: Pin buffer if true. |
88 | * @interruptible: Use interruptible wait. |
83 | * @interruptible: Use interruptible wait. |
89 | * |
84 | * |
90 | * Returns |
85 | * Returns |
91 | * -ERESTARTSYS if interrupted by a signal. |
86 | * -ERESTARTSYS if interrupted by a signal. |
92 | */ |
87 | */ |
93 | int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv, |
88 | int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv, |
94 | struct vmw_dma_buffer *buf, |
89 | struct vmw_dma_buffer *buf, |
95 | bool pin, bool interruptible) |
90 | bool interruptible) |
96 | { |
91 | { |
97 | struct ttm_buffer_object *bo = &buf->base; |
92 | struct ttm_buffer_object *bo = &buf->base; |
98 | struct ttm_placement *placement; |
- | |
99 | int ret; |
93 | int ret; |
100 | 94 | ||
101 | // ret = ttm_write_lock(&vmaster->lock, interruptible); |
95 | ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible); |
102 | // if (unlikely(ret != 0)) |
96 | if (unlikely(ret != 0)) |
103 | // return ret; |
- | |
104 | 97 | return ret; |
|
105 | if (pin) |
98 | |
106 | vmw_execbuf_release_pinned_bo(dev_priv); |
99 | vmw_execbuf_release_pinned_bo(dev_priv); |
107 | 100 | ||
108 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
101 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
109 | if (unlikely(ret != 0)) |
102 | if (unlikely(ret != 0)) |
110 | goto err; |
103 | goto err; |
111 | - | ||
112 | /** |
- | |
113 | * Put BO in VRAM if there is space, otherwise as a GMR. |
- | |
114 | * If there is no space in VRAM and GMR ids are all used up, |
- | |
115 | * start evicting GMRs to make room. If the DMA buffer can't be |
- | |
116 | * used as a GMR, this will return -ENOMEM. |
- | |
117 | */ |
- | |
118 | - | ||
119 | if (pin) |
104 | |
120 | placement = &vmw_vram_gmr_ne_placement; |
105 | ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible, |
121 | else |
- | |
122 | placement = &vmw_vram_gmr_placement; |
- | |
123 | - | ||
124 | ret = ttm_bo_validate(bo, placement, interruptible, false); |
106 | false); |
125 | if (likely(ret == 0) || ret == -ERESTARTSYS) |
107 | if (likely(ret == 0) || ret == -ERESTARTSYS) |
- | 108 | goto out_unreserve; |
|
126 | goto err_unreserve; |
- | |
127 | - | ||
128 | 109 | ||
129 | /** |
- | |
130 | * If that failed, try VRAM again, this time evicting |
- | |
131 | * previous contents. |
110 | ret = ttm_bo_validate(bo, &vmw_vram_placement, interruptible, false); |
132 | */ |
- | |
133 | - | ||
134 | if (pin) |
111 | |
135 | placement = &vmw_vram_ne_placement; |
- | |
136 | else |
- | |
137 | placement = &vmw_vram_placement; |
- | |
138 | 112 | out_unreserve: |
|
139 | ret = ttm_bo_validate(bo, placement, interruptible, false); |
113 | if (!ret) |
140 | 114 | vmw_bo_pin_reserved(buf, true); |
|
141 | err_unreserve: |
115 | |
142 | ttm_bo_unreserve(bo); |
116 | ttm_bo_unreserve(bo); |
143 | err: |
117 | err: |
144 | // ttm_write_unlock(&vmaster->lock); |
118 | ttm_write_unlock(&dev_priv->reservation_sem); |
145 | return ret; |
119 | return ret; |
146 | } |
120 | } |
147 | 121 | ||
148 | /** |
122 | /** |
149 | * vmw_dmabuf_to_vram - Move a buffer to vram. |
123 | * vmw_dmabuf_pin_in_vram - Move a buffer to vram. |
150 | * |
124 | * |
151 | * May only be called by the current master since it assumes that the |
125 | * This function takes the reservation_sem in write mode. |
152 | * master lock is the current master's lock. |
126 | * Flushes and unpins the query bo to avoid failures. |
153 | * This function takes the master's lock in write mode. |
- | |
154 | * |
127 | * |
155 | * @dev_priv: Driver private. |
128 | * @dev_priv: Driver private. |
156 | * @buf: DMA buffer to move. |
129 | * @buf: DMA buffer to move. |
157 | * @pin: Pin buffer in vram if true. |
- | |
158 | * @interruptible: Use interruptible wait. |
130 | * @interruptible: Use interruptible wait. |
159 | * |
131 | * |
160 | * Returns |
132 | * Returns |
161 | * -ERESTARTSYS if interrupted by a signal. |
133 | * -ERESTARTSYS if interrupted by a signal. |
162 | */ |
134 | */ |
163 | int vmw_dmabuf_to_vram(struct vmw_private *dev_priv, |
135 | int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv, |
164 | struct vmw_dma_buffer *buf, |
136 | struct vmw_dma_buffer *buf, |
165 | bool pin, bool interruptible) |
137 | bool interruptible) |
166 | { |
138 | { |
167 | struct ttm_placement *placement; |
- | |
168 | - | ||
169 | if (pin) |
- | |
170 | placement = &vmw_vram_ne_placement; |
- | |
171 | else |
- | |
172 | placement = &vmw_vram_placement; |
- | |
173 | - | ||
174 | return vmw_dmabuf_to_placement(dev_priv, buf, |
139 | return vmw_dmabuf_pin_in_placement(dev_priv, buf, &vmw_vram_placement, |
175 | placement, |
- | |
176 | interruptible); |
140 | interruptible); |
177 | } |
141 | } |
178 | 142 | ||
179 | /** |
143 | /** |
180 | * vmw_dmabuf_to_start_of_vram - Move a buffer to start of vram. |
144 | * vmw_dmabuf_pin_in_start_of_vram - Move a buffer to start of vram. |
181 | * |
145 | * |
182 | * May only be called by the current master since it assumes that the |
- | |
183 | * master lock is the current master's lock. |
- | |
184 | * This function takes the master's lock in write mode. |
146 | * This function takes the reservation_sem in write mode. |
185 | * Flushes and unpins the query bo if @pin == true to avoid failures. |
147 | * Flushes and unpins the query bo to avoid failures. |
186 | * |
148 | * |
187 | * @dev_priv: Driver private. |
149 | * @dev_priv: Driver private. |
188 | * @buf: DMA buffer to move. |
150 | * @buf: DMA buffer to pin. |
189 | * @pin: Pin buffer in vram if true. |
- | |
190 | * @interruptible: Use interruptible wait. |
151 | * @interruptible: Use interruptible wait. |
191 | * |
152 | * |
192 | * Returns |
153 | * Returns |
193 | * -ERESTARTSYS if interrupted by a signal. |
154 | * -ERESTARTSYS if interrupted by a signal. |
194 | */ |
155 | */ |
195 | int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv, |
156 | int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv, |
196 | struct vmw_dma_buffer *buf, |
157 | struct vmw_dma_buffer *buf, |
197 | bool pin, bool interruptible) |
158 | bool interruptible) |
198 | { |
159 | { |
199 | struct ttm_buffer_object *bo = &buf->base; |
160 | struct ttm_buffer_object *bo = &buf->base; |
200 | struct ttm_placement placement; |
161 | struct ttm_placement placement; |
- | 162 | struct ttm_place place; |
|
201 | int ret = 0; |
163 | int ret = 0; |
202 | - | ||
203 | if (pin) |
164 | |
204 | placement = vmw_vram_ne_placement; |
- | |
205 | else |
165 | place = vmw_vram_placement.placement[0]; |
206 | placement = vmw_vram_placement; |
166 | place.lpfn = bo->num_pages; |
207 | placement.lpfn = bo->num_pages; |
- | |
208 | 167 | placement.num_placement = 1; |
|
209 | // ret = ttm_write_lock(&vmaster->lock, interruptible); |
168 | placement.placement = &place; |
210 | // if (unlikely(ret != 0)) |
169 | placement.num_busy_placement = 1; |
- | 170 | placement.busy_placement = &place; |
|
- | 171 | ||
211 | // return ret; |
172 | ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible); |
- | 173 | if (unlikely(ret != 0)) |
|
212 | 174 | return ret; |
|
213 | if (pin) |
175 | |
214 | vmw_execbuf_release_pinned_bo(dev_priv); |
176 | vmw_execbuf_release_pinned_bo(dev_priv); |
215 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
177 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
216 | if (unlikely(ret != 0)) |
178 | if (unlikely(ret != 0)) |
217 | goto err_unlock; |
179 | goto err_unlock; |
- | 180 | ||
218 | 181 | /* |
|
- | 182 | * Is this buffer already in vram but not at the start of it? |
|
- | 183 | * In that case, evict it first because TTM isn't good at handling |
|
- | 184 | * that situation. |
|
219 | /* Is this buffer already in vram but not at the start of it? */ |
185 | */ |
220 | if (bo->mem.mem_type == TTM_PL_VRAM && |
186 | if (bo->mem.mem_type == TTM_PL_VRAM && |
221 | bo->mem.start < bo->num_pages && |
187 | bo->mem.start < bo->num_pages && |
222 | bo->mem.start > 0) |
188 | bo->mem.start > 0) |
223 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, false); |
189 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, false); |
224 | 190 | ||
225 | ret = ttm_bo_validate(bo, &placement, interruptible, false); |
191 | ret = ttm_bo_validate(bo, &placement, interruptible, false); |
226 | 192 | ||
227 | /* For some reason we didn't up at the start of vram */ |
193 | /* For some reason we didn't end up at the start of vram */ |
- | 194 | WARN_ON(ret == 0 && bo->offset != 0); |
|
- | 195 | if (!ret) |
|
228 | WARN_ON(ret == 0 && bo->offset != 0); |
196 | vmw_bo_pin_reserved(buf, true); |
229 | 197 | ||
230 | ttm_bo_unreserve(bo); |
198 | ttm_bo_unreserve(bo); |
231 | err_unlock: |
199 | err_unlock: |
232 | // ttm_write_unlock(&vmaster->lock); |
200 | ttm_write_unlock(&dev_priv->reservation_sem); |
233 | 201 | ||
234 | return ret; |
202 | return ret; |
235 | } |
203 | } |
236 | - | ||
237 | 204 | ||
238 | /** |
205 | /** |
239 | * vmw_dmabuf_upin - Unpin the buffer given buffer, does not move the buffer. |
206 | * vmw_dmabuf_unpin - Unpin the buffer given buffer, does not move the buffer. |
240 | * |
- | |
241 | * May only be called by the current master since it assumes that the |
- | |
242 | * master lock is the current master's lock. |
207 | * |
243 | * This function takes the master's lock in write mode. |
208 | * This function takes the reservation_sem in write mode. |
244 | * |
209 | * |
245 | * @dev_priv: Driver private. |
210 | * @dev_priv: Driver private. |
246 | * @buf: DMA buffer to unpin. |
211 | * @buf: DMA buffer to unpin. |
247 | * @interruptible: Use interruptible wait. |
212 | * @interruptible: Use interruptible wait. |
248 | * |
213 | * |
249 | * Returns |
214 | * Returns |
250 | * -ERESTARTSYS if interrupted by a signal. |
215 | * -ERESTARTSYS if interrupted by a signal. |
251 | */ |
216 | */ |
252 | int vmw_dmabuf_unpin(struct vmw_private *dev_priv, |
217 | int vmw_dmabuf_unpin(struct vmw_private *dev_priv, |
253 | struct vmw_dma_buffer *buf, |
218 | struct vmw_dma_buffer *buf, |
254 | bool interruptible) |
219 | bool interruptible) |
255 | { |
220 | { |
256 | /* |
- | |
257 | * We could in theory early out if the buffer is |
221 | struct ttm_buffer_object *bo = &buf->base; |
258 | * unpinned but we need to lock and reserve the buffer |
- | |
259 | * anyways so we don't gain much by that. |
- | |
260 | */ |
222 | int ret; |
261 | return vmw_dmabuf_to_placement(dev_priv, buf, |
- | |
262 | &vmw_evictable_placement, |
- | |
263 | interruptible); |
- | |
264 | } |
- | |
- | 223 | ||
- | 224 | ret = ttm_read_lock(&dev_priv->reservation_sem, interruptible); |
|
- | 225 | if (unlikely(ret != 0)) |
|
- | 226 | return ret; |
|
- | 227 | ||
- | 228 | ret = ttm_bo_reserve(bo, interruptible, false, false, NULL); |
|
- | 229 | if (unlikely(ret != 0)) |
|
- | 230 | goto err; |
|
- | 231 | ||
- | 232 | vmw_bo_pin_reserved(buf, false); |
|
- | 233 | ||
- | 234 | ttm_bo_unreserve(bo); |
|
- | 235 | ||
- | 236 | err: |
|
- | 237 | ttm_read_unlock(&dev_priv->reservation_sem); |
|
- | 238 | return ret; |
|
265 | 239 | } |
|
266 | 240 | ||
267 | /** |
241 | /** |
268 | * vmw_bo_get_guest_ptr - Get the guest ptr representing the current placement |
242 | * vmw_bo_get_guest_ptr - Get the guest ptr representing the current placement |
269 | * of a buffer. |
243 | * of a buffer. |
270 | * |
244 | * |
271 | * @bo: Pointer to a struct ttm_buffer_object. Must be pinned or reserved. |
245 | * @bo: Pointer to a struct ttm_buffer_object. Must be pinned or reserved. |
272 | * @ptr: SVGAGuestPtr returning the result. |
246 | * @ptr: SVGAGuestPtr returning the result. |
273 | */ |
247 | */ |
274 | void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo, |
248 | void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *bo, |
275 | SVGAGuestPtr *ptr) |
249 | SVGAGuestPtr *ptr) |
276 | { |
250 | { |
277 | if (bo->mem.mem_type == TTM_PL_VRAM) { |
251 | if (bo->mem.mem_type == TTM_PL_VRAM) { |
278 | ptr->gmrId = SVGA_GMR_FRAMEBUFFER; |
252 | ptr->gmrId = SVGA_GMR_FRAMEBUFFER; |
279 | ptr->offset = bo->offset; |
253 | ptr->offset = bo->offset; |
280 | } else { |
254 | } else { |
281 | ptr->gmrId = bo->mem.start; |
255 | ptr->gmrId = bo->mem.start; |
282 | ptr->offset = 0; |
256 | ptr->offset = 0; |
283 | } |
257 | } |
284 | } |
258 | } |
285 | 259 | ||
286 | 260 | ||
287 | /** |
261 | /** |
288 | * vmw_bo_pin - Pin or unpin a buffer object without moving it. |
262 | * vmw_bo_pin_reserved - Pin or unpin a buffer object without moving it. |
289 | * |
263 | * |
290 | * @bo: The buffer object. Must be reserved. |
264 | * @vbo: The buffer object. Must be reserved. |
291 | * @pin: Whether to pin or unpin. |
265 | * @pin: Whether to pin or unpin. |
292 | * |
266 | * |
293 | */ |
267 | */ |
294 | void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) |
268 | void vmw_bo_pin_reserved(struct vmw_dma_buffer *vbo, bool pin) |
295 | { |
269 | { |
296 | uint32_t pl_flags; |
270 | struct ttm_place pl; |
297 | struct ttm_placement placement; |
271 | struct ttm_placement placement; |
- | 272 | struct ttm_buffer_object *bo = &vbo->base; |
|
298 | uint32_t old_mem_type = bo->mem.mem_type; |
273 | uint32_t old_mem_type = bo->mem.mem_type; |
299 | int ret; |
274 | int ret; |
300 | 275 | ||
301 | lockdep_assert_held(&bo->resv->lock.base); |
276 | lockdep_assert_held(&bo->resv->lock.base); |
- | 277 | ||
- | 278 | if (pin) { |
|
- | 279 | if (vbo->pin_count++ > 0) |
|
- | 280 | return; |
|
- | 281 | } else { |
|
- | 282 | WARN_ON(vbo->pin_count <= 0); |
|
- | 283 | if (--vbo->pin_count > 0) |
|
- | 284 | return; |
|
- | 285 | } |
|
- | 286 | ||
- | 287 | pl.fpfn = 0; |
|
302 | 288 | pl.lpfn = 0; |
|
303 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | VMW_PL_FLAG_MOB |
289 | pl.flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | VMW_PL_FLAG_MOB |
304 | | TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED; |
290 | | TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED; |
305 | if (pin) |
291 | if (pin) |
306 | pl_flags |= TTM_PL_FLAG_NO_EVICT; |
292 | pl.flags |= TTM_PL_FLAG_NO_EVICT; |
307 | 293 | ||
308 | memset(&placement, 0, sizeof(placement)); |
294 | memset(&placement, 0, sizeof(placement)); |
309 | placement.num_placement = 1; |
295 | placement.num_placement = 1; |
310 | placement.placement = &pl_flags; |
296 | placement.placement = &pl; |
311 | 297 | ||
312 | ret = ttm_bo_validate(bo, &placement, false, true); |
298 | ret = ttm_bo_validate(bo, &placement, false, true); |
313 | 299 | ||
314 | BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type); |
300 | BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type); |
315 | }> |
301 | }=>> |