Subversion Repositories Kolibri OS

Rev

Rev 5078 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5078 Rev 6296
Line 1... Line 1...
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
Line 30... Line 30...
30
#include 
30
#include 
31
#include "vmwgfx_drv.h"
31
#include "vmwgfx_drv.h"
Line 32... Line 32...
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.
-
 
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.
40
 * @interruptible:  Use interruptible wait.
46
 *
41
 *
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
{
Line 55... Line 50...
55
	struct ttm_buffer_object *bo = &buf->base;
50
	struct ttm_buffer_object *bo = &buf->base;
56
	int ret;
51
	int ret;
57
 
52
 
Line 58... Line 53...
58
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
53
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
Line 59... Line 54...
59
//   if (unlikely(ret != 0))
54
	if (unlikely(ret != 0))
60
//       return ret;
55
		return ret;
61
 
56
 
Line 62... Line 57...
62
	vmw_execbuf_release_pinned_bo(dev_priv);
57
	vmw_execbuf_release_pinned_bo(dev_priv);
-
 
58
 
-
 
59
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
Line 63... Line 60...
63
 
60
	if (unlikely(ret != 0))
Line 64... Line 61...
64
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
61
		goto err;
65
	if (unlikely(ret != 0))
62
 
66
		goto err;
63
	ret = ttm_bo_validate(bo, placement, interruptible, false);
67
 
64
	if (!ret)
Line 68... Line 65...
68
	ret = ttm_bo_validate(bo, placement, interruptible, false);
65
		vmw_bo_pin_reserved(buf, true);
69
 
66
 
70
	ttm_bo_unreserve(bo);
67
	ttm_bo_unreserve(bo);
71
 
-
 
72
err:
-
 
73
//   ttm_write_unlock(&vmaster->lock);
68
 
74
	return ret;
69
err:
75
}
70
	ttm_write_unlock(&dev_priv->reservation_sem);
76
 
71
	return ret;
77
/**
72
}
78
 * vmw_dmabuf_to_vram_or_gmr - Move a buffer to vram or gmr.
73
 
79
 *
74
/**
80
 * May only be called by the current master since it assumes that the
75
 * vmw_dmabuf_pin_in_vram_or_gmr - Move a buffer to vram or gmr.
81
 * master lock is the current master's lock.
76
 *
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
 *
-
 
90
 * Returns
84
 *
Line 91... Line 85...
91
 * -ERESTARTSYS if interrupted by a signal.
85
 * Returns
92
 */
86
 * -ERESTARTSYS if interrupted by a signal.
93
int vmw_dmabuf_to_vram_or_gmr(struct vmw_private *dev_priv,
87
 */
Line 94... Line -...
94
			      struct vmw_dma_buffer *buf,
-
 
95
			      bool pin, bool interruptible)
88
int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
Line 96... Line 89...
96
{
89
				  struct vmw_dma_buffer *buf,
97
	struct ttm_buffer_object *bo = &buf->base;
90
				  bool interruptible)
98
	struct ttm_placement *placement;
91
{
Line 99... Line -...
99
	int ret;
-
 
100
 
-
 
101
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
-
 
102
//   if (unlikely(ret != 0))
-
 
103
//       return ret;
-
 
104
 
-
 
105
	if (pin)
-
 
106
		vmw_execbuf_release_pinned_bo(dev_priv);
-
 
107
 
92
	struct ttm_buffer_object *bo = &buf->base;
108
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
93
	int ret;
109
	if (unlikely(ret != 0))
-
 
110
		goto err;
-
 
111
 
-
 
112
	/**
94
 
113
	 * Put BO in VRAM if there is space, otherwise as a GMR.
95
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
Line -... Line 96...
-
 
96
	if (unlikely(ret != 0))
Line 114... Line -...
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.
97
		return ret;
117
	 */
-
 
118
 
-
 
119
	if (pin)
98
 
120
		placement = &vmw_vram_gmr_ne_placement;
-
 
121
	else
-
 
122
		placement = &vmw_vram_gmr_placement;
99
	vmw_execbuf_release_pinned_bo(dev_priv);
Line 123... Line -...
123
 
-
 
124
	ret = ttm_bo_validate(bo, placement, interruptible, false);
-
 
125
	if (likely(ret == 0) || ret == -ERESTARTSYS)
-
 
126
		goto err_unreserve;
100
 
127
 
101
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
128
 
102
	if (unlikely(ret != 0))
129
	/**
103
		goto err;
130
	 * If that failed, try VRAM again, this time evicting
104
 
Line 131... Line 105...
131
	 * previous contents.
105
	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
132
	 */
106
			      false);
133
 
107
	if (likely(ret == 0) || ret == -ERESTARTSYS)
134
	if (pin)
108
		goto out_unreserve;
135
		placement = &vmw_vram_ne_placement;
109
 
136
	else
-
 
137
		placement = &vmw_vram_placement;
110
	ret = ttm_bo_validate(bo, &vmw_vram_placement, interruptible, false);
138
 
111
 
139
	ret = ttm_bo_validate(bo, placement, interruptible, false);
112
out_unreserve:
140
 
-
 
141
err_unreserve:
113
	if (!ret)
142
	ttm_bo_unreserve(bo);
114
		vmw_bo_pin_reserved(buf, true);
143
err:
115
 
144
//   ttm_write_unlock(&vmaster->lock);
116
	ttm_bo_unreserve(bo);
145
	return ret;
117
err:
146
}
118
	ttm_write_unlock(&dev_priv->reservation_sem);
147
 
119
	return ret;
148
/**
120
}
149
 * vmw_dmabuf_to_vram - Move a buffer to vram.
121
 
150
 *
-
 
151
 * May only be called by the current master since it assumes that the
-
 
152
 * master lock is the current master's lock.
-
 
153
 * This function takes the master's lock in write mode.
-
 
154
 *
-
 
155
 * @dev_priv:  Driver private.
-
 
156
 * @buf:  DMA buffer to move.
-
 
157
 * @pin:  Pin buffer in vram if true.
122
/**
158
 * @interruptible:  Use interruptible wait.
-
 
159
 *
123
 * vmw_dmabuf_pin_in_vram - Move a buffer to vram.
160
 * Returns
124
 *
Line 161... Line 125...
161
 * -ERESTARTSYS if interrupted by a signal.
125
 * This function takes the reservation_sem in write mode.
162
 */
126
 * Flushes and unpins the query bo to avoid failures.
163
int vmw_dmabuf_to_vram(struct vmw_private *dev_priv,
127
 *
164
		       struct vmw_dma_buffer *buf,
-
 
165
		       bool pin, bool interruptible)
-
 
166
{
128
 * @dev_priv:  Driver private.
167
	struct ttm_placement *placement;
129
 * @buf:  DMA buffer to move.
168
 
130
 * @interruptible:  Use interruptible wait.
169
	if (pin)
131
 *
170
		placement = &vmw_vram_ne_placement;
132
 * Returns
171
	else
-
 
172
		placement = &vmw_vram_placement;
133
 * -ERESTARTSYS if interrupted by a signal.
173
 
134
 */
174
	return vmw_dmabuf_to_placement(dev_priv, buf,
135
int vmw_dmabuf_pin_in_vram(struct vmw_private *dev_priv,
175
				       placement,
136
			   struct vmw_dma_buffer *buf,
176
				       interruptible);
137
			   bool interruptible)
177
}
138
{
178
 
139
	return vmw_dmabuf_pin_in_placement(dev_priv, buf, &vmw_vram_placement,
179
/**
140
					   interruptible);
180
 * vmw_dmabuf_to_start_of_vram - Move a buffer to start of vram.
141
}
181
 *
142
 
182
 * May only be called by the current master since it assumes that the
143
/**
-
 
144
 * vmw_dmabuf_pin_in_start_of_vram - Move a buffer to start of vram.
183
 * master lock is the current master's lock.
145
 *
Line -... Line 146...
-
 
146
 * This function takes the reservation_sem in write mode.
184
 * This function takes the master's lock in write mode.
147
 * Flushes and unpins the query bo to avoid failures.
185
 * Flushes and unpins the query bo if @pin == true to avoid failures.
148
 *
186
 *
149
 * @dev_priv:  Driver private.
187
 * @dev_priv:  Driver private.
150
 * @buf:  DMA buffer to pin.
188
 * @buf:  DMA buffer to move.
151
 * @interruptible:  Use interruptible wait.
189
 * @pin:  Pin buffer in vram if true.
152
 *
190
 * @interruptible:  Use interruptible wait.
153
 * Returns
191
 *
154
 * -ERESTARTSYS if interrupted by a signal.
192
 * Returns
155
 */
Line 193... Line -...
193
 * -ERESTARTSYS if interrupted by a signal.
-
 
194
 */
156
int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
195
int vmw_dmabuf_to_start_of_vram(struct vmw_private *dev_priv,
157
				    struct vmw_dma_buffer *buf,
196
				struct vmw_dma_buffer *buf,
158
				    bool interruptible)
197
				bool pin, bool interruptible)
159
{
Line -... Line 160...
-
 
160
	struct ttm_buffer_object *bo = &buf->base;
198
{
161
	struct ttm_placement placement;
-
 
162
	struct ttm_place place;
-
 
163
	int ret = 0;
-
 
164
 
199
	struct ttm_buffer_object *bo = &buf->base;
165
	place = vmw_vram_placement.placement[0];
200
	struct ttm_placement placement;
166
	place.lpfn = bo->num_pages;
201
	int ret = 0;
167
	placement.num_placement = 1;
202
 
168
	placement.placement = &place;
Line 203... Line 169...
203
	if (pin)
169
	placement.num_busy_placement = 1;
Line 204... Line 170...
204
		placement = vmw_vram_ne_placement;
170
	placement.busy_placement = &place;
205
	else
171
 
-
 
172
	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
-
 
173
	if (unlikely(ret != 0))
Line 206... Line 174...
206
		placement = vmw_vram_placement;
174
		return ret;
207
	placement.lpfn = bo->num_pages;
175
 
208
 
176
	vmw_execbuf_release_pinned_bo(dev_priv);
Line 209... Line 177...
209
//   ret = ttm_write_lock(&vmaster->lock, interruptible);
177
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
210
//   if (unlikely(ret != 0))
178
	if (unlikely(ret != 0))
Line 211... Line -...
211
//       return ret;
-
 
212
 
179
		goto err_unlock;
213
	if (pin)
180
 
214
		vmw_execbuf_release_pinned_bo(dev_priv);
181
	/*
215
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
-
 
216
	if (unlikely(ret != 0))
-
 
217
		goto err_unlock;
182
	 * Is this buffer already in vram but not at the start of it?
218
 
183
	 * In that case, evict it first because TTM isn't good at handling
219
	/* Is this buffer already in vram but not at the start of it? */
184
	 * that situation.
220
	if (bo->mem.mem_type == TTM_PL_VRAM &&
185
	 */
221
	    bo->mem.start < bo->num_pages &&
186
	if (bo->mem.mem_type == TTM_PL_VRAM &&
222
	    bo->mem.start > 0)
187
	    bo->mem.start < bo->num_pages &&
Line 251... Line 216...
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
{
-
 
221
	struct ttm_buffer_object *bo = &buf->base;
-
 
222
	int ret;
256
	/*
223
 
257
	 * We could in theory early out if the buffer is
224
	ret = ttm_read_lock(&dev_priv->reservation_sem, interruptible);
258
	 * unpinned but we need to lock and reserve the buffer
225
	if (unlikely(ret != 0))
259
	 * anyways so we don't gain much by that.
226
		return ret;
260
	 */
227
 
261
	return vmw_dmabuf_to_placement(dev_priv, buf,
228
	ret = ttm_bo_reserve(bo, interruptible, false, false, NULL);
262
				       &vmw_evictable_placement,
229
	if (unlikely(ret != 0))
263
				       interruptible);
230
		goto err;
264
}
-
 
Line -... Line 231...
-
 
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;
Line 265... Line 239...
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
Line 283... Line 257...
283
	}
257
	}
284
}
258
}
Line 285... Line 259...
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
{
-
 
270
	struct ttm_place pl;
296
	uint32_t pl_flags;
271
	struct ttm_placement placement;
297
	struct ttm_placement placement;
272
	struct ttm_buffer_object *bo = &vbo->base;
Line 298... Line 273...
298
	uint32_t old_mem_type = bo->mem.mem_type;
273
	uint32_t old_mem_type = bo->mem.mem_type;
Line -... Line 274...
-
 
274
	int ret;
-
 
275
 
-
 
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;
299
	int ret;
285
	}
300
 
286
 
301
	lockdep_assert_held(&bo->resv->lock.base);
287
	pl.fpfn = 0;
302
 
288
	pl.lpfn = 0;
Line 303... Line 289...
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)
Line 306... Line 292...
306
		pl_flags |= TTM_PL_FLAG_NO_EVICT;
292
		pl.flags |= TTM_PL_FLAG_NO_EVICT;
Line 307... Line 293...
307
 
293
 
308
	memset(&placement, 0, sizeof(placement));
294
	memset(&placement, 0, sizeof(placement));