Commit | Line | Data |
---|---|---|
ba4e7d97 TH |
1 | /************************************************************************** |
2 | * | |
3 | * Copyright (c) 2006-2009 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 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> | |
29 | */ | |
30 | #ifndef _TTM_BO_DRIVER_H_ | |
31 | #define _TTM_BO_DRIVER_H_ | |
32 | ||
a1ce3928 | 33 | #include <drm/drm_mm.h> |
72525b3f | 34 | #include <drm/drm_vma_manager.h> |
a1ce3928 DH |
35 | #include <linux/workqueue.h> |
36 | #include <linux/fs.h> | |
37 | #include <linux/spinlock.h> | |
52791eee | 38 | #include <linux/dma-resv.h> |
ba4e7d97 | 39 | |
8af8a109 CK |
40 | #include <drm/ttm/ttm_device.h> |
41 | ||
2da83319 | 42 | #include "ttm_bo_api.h" |
3bf3710e | 43 | #include "ttm_kmap_iter.h" |
2da83319 | 44 | #include "ttm_placement.h" |
81f5ec02 | 45 | #include "ttm_tt.h" |
ee5d2a8e | 46 | #include "ttm_pool.h" |
2da83319 | 47 | |
ba4e7d97 TH |
48 | /* |
49 | * ttm_bo.c | |
50 | */ | |
51 | ||
ba4e7d97 TH |
52 | /** |
53 | * ttm_bo_mem_space | |
54 | * | |
55 | * @bo: Pointer to a struct ttm_buffer_object. the data of which | |
56 | * we want to allocate space for. | |
57 | * @proposed_placement: Proposed new placement for the buffer object. | |
2966141a | 58 | * @mem: A struct ttm_resource. |
ba4e7d97 | 59 | * @interruptible: Sleep interruptible when sliping. |
9d87fa21 | 60 | * @no_wait_gpu: Return immediately if the GPU is busy. |
ba4e7d97 TH |
61 | * |
62 | * Allocate memory space for the buffer object pointed to by @bo, using | |
63 | * the placement flags in @mem, potentially evicting other idle buffer objects. | |
64 | * This function may sleep while waiting for space to become available. | |
65 | * Returns: | |
66 | * -EBUSY: No space available (only if no_wait == 1). | |
67 | * -ENOMEM: Could not allocate memory for the buffer object, either due to | |
68 | * fragmentation or concurrent allocators. | |
98ffc415 | 69 | * -ERESTARTSYS: An interruptible sleep was interrupted by a signal. |
ba4e7d97 | 70 | */ |
1144b63a CK |
71 | int ttm_bo_mem_space(struct ttm_buffer_object *bo, |
72 | struct ttm_placement *placement, | |
bfa3357e | 73 | struct ttm_resource **mem, |
c13c55d6 | 74 | struct ttm_operation_ctx *ctx); |
1144b63a | 75 | |
e024e110 DA |
76 | /** |
77 | * ttm_bo_unmap_virtual | |
78 | * | |
79 | * @bo: tear down the virtual mappings for this BO | |
80 | */ | |
1144b63a | 81 | void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); |
ba4e7d97 | 82 | |
34820324 | 83 | /** |
46bca88b | 84 | * ttm_bo_reserve: |
34820324 ML |
85 | * |
86 | * @bo: A pointer to a struct ttm_buffer_object. | |
87 | * @interruptible: Sleep interruptible if waiting. | |
88 | * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. | |
dfd5e50e | 89 | * @ticket: ticket used to acquire the ww_mutex. |
34820324 | 90 | * |
46bca88b DA |
91 | * Locks a buffer object for validation. (Or prevents other processes from |
92 | * locking it for validation), while taking a number of measures to prevent | |
93 | * deadlocks. | |
34820324 ML |
94 | * |
95 | * Returns: | |
96 | * -EDEADLK: The reservation may cause a deadlock. | |
97 | * Release all buffer reservations, wait for @bo to become unreserved and | |
46bca88b | 98 | * try again. |
34820324 ML |
99 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by |
100 | * a signal. Release all buffer reservations and return to user-space. | |
101 | * -EBUSY: The function needed to sleep, but @no_wait was true | |
102 | * -EALREADY: Bo already reserved using @ticket. This error code will only | |
103 | * be returned if @use_ticket is set to true. | |
104 | */ | |
46bca88b DA |
105 | static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, |
106 | bool interruptible, bool no_wait, | |
107 | struct ww_acquire_ctx *ticket) | |
34820324 ML |
108 | { |
109 | int ret = 0; | |
110 | ||
111 | if (no_wait) { | |
112 | bool success; | |
113 | if (WARN_ON(ticket)) | |
114 | return -EBUSY; | |
115 | ||
52791eee | 116 | success = dma_resv_trylock(bo->base.resv); |
34820324 ML |
117 | return success ? 0 : -EBUSY; |
118 | } | |
119 | ||
120 | if (interruptible) | |
52791eee | 121 | ret = dma_resv_lock_interruptible(bo->base.resv, ticket); |
34820324 | 122 | else |
52791eee | 123 | ret = dma_resv_lock(bo->base.resv, ticket); |
34820324 ML |
124 | if (ret == -EINTR) |
125 | return -ERESTARTSYS; | |
126 | return ret; | |
127 | } | |
eba67093 | 128 | |
5e45d7df ML |
129 | /** |
130 | * ttm_bo_reserve_slowpath: | |
131 | * @bo: A pointer to a struct ttm_buffer_object. | |
132 | * @interruptible: Sleep interruptible if waiting. | |
133 | * @sequence: Set (@bo)->sequence to this value after lock | |
134 | * | |
135 | * This is called after ttm_bo_reserve returns -EAGAIN and we backed off | |
136 | * from all our other reservations. Because there are no other reservations | |
137 | * held by us, this function cannot deadlock any more. | |
138 | */ | |
34820324 ML |
139 | static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, |
140 | bool interruptible, | |
141 | struct ww_acquire_ctx *ticket) | |
142 | { | |
46bca88b DA |
143 | if (interruptible) { |
144 | int ret = dma_resv_lock_slow_interruptible(bo->base.resv, | |
145 | ticket); | |
146 | if (ret == -EINTR) | |
147 | ret = -ERESTARTSYS; | |
148 | return ret; | |
149 | } | |
150 | dma_resv_lock_slow(bo->base.resv, ticket); | |
151 | return 0; | |
34820324 | 152 | } |
ba4e7d97 | 153 | |
3d1a88e1 CK |
154 | static inline void |
155 | ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo) | |
20784cdf | 156 | { |
a1f091f8 | 157 | spin_lock(&bo->bdev->lru_lock); |
fee2ede1 | 158 | ttm_bo_move_to_lru_tail(bo); |
a1f091f8 | 159 | spin_unlock(&bo->bdev->lru_lock); |
20784cdf DA |
160 | } |
161 | ||
2ee476f7 DA |
162 | static inline void ttm_bo_assign_mem(struct ttm_buffer_object *bo, |
163 | struct ttm_resource *new_mem) | |
164 | { | |
bfa3357e CK |
165 | WARN_ON(bo->resource); |
166 | bo->resource = new_mem; | |
2ee476f7 DA |
167 | } |
168 | ||
ecfe6953 DA |
169 | /** |
170 | * ttm_bo_move_null = assign memory for a buffer object. | |
171 | * @bo: The bo to assign the memory to | |
172 | * @new_mem: The memory to be assigned. | |
173 | * | |
174 | * Assign the memory from new_mem to the memory of the buffer object bo. | |
175 | */ | |
176 | static inline void ttm_bo_move_null(struct ttm_buffer_object *bo, | |
177 | struct ttm_resource *new_mem) | |
178 | { | |
bfa3357e | 179 | ttm_resource_free(bo, &bo->resource); |
2ee476f7 | 180 | ttm_bo_assign_mem(bo, new_mem); |
ecfe6953 DA |
181 | } |
182 | ||
ecff665f | 183 | /** |
34820324 ML |
184 | * ttm_bo_unreserve |
185 | * | |
95762c2b TH |
186 | * @bo: A pointer to a struct ttm_buffer_object. |
187 | * | |
34820324 | 188 | * Unreserve a previous reservation of @bo. |
95762c2b | 189 | */ |
34820324 ML |
190 | static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) |
191 | { | |
20784cdf | 192 | ttm_bo_move_to_lru_tail_unlocked(bo); |
52791eee | 193 | dma_resv_unlock(bo->base.resv); |
c7523083 TH |
194 | } |
195 | ||
ba4e7d97 TH |
196 | /* |
197 | * ttm_bo_util.c | |
198 | */ | |
8af8a109 | 199 | int ttm_mem_io_reserve(struct ttm_device *bdev, |
2966141a | 200 | struct ttm_resource *mem); |
8af8a109 | 201 | void ttm_mem_io_free(struct ttm_device *bdev, |
2966141a | 202 | struct ttm_resource *mem); |
ba4e7d97 TH |
203 | |
204 | /** | |
205 | * ttm_bo_move_memcpy | |
206 | * | |
207 | * @bo: A pointer to a struct ttm_buffer_object. | |
77dfc28b | 208 | * @interruptible: Sleep interruptible if waiting. |
9d87fa21 | 209 | * @no_wait_gpu: Return immediately if the GPU is busy. |
2966141a | 210 | * @new_mem: struct ttm_resource indicating where to move. |
ba4e7d97 TH |
211 | * |
212 | * Fallback move function for a mappable buffer object in mappable memory. | |
213 | * The function will, if successful, | |
214 | * free any old aperture space, and set (@new_mem)->mm_node to NULL, | |
215 | * and update the (@bo)->mem placement flags. If unsuccessful, the old | |
216 | * data remains untouched, and it's up to the caller to free the | |
217 | * memory space indicated by @new_mem. | |
218 | * Returns: | |
219 | * !0: Failure. | |
220 | */ | |
221 | ||
1144b63a | 222 | int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, |
3e98d829 | 223 | struct ttm_operation_ctx *ctx, |
2966141a | 224 | struct ttm_resource *new_mem); |
ba4e7d97 | 225 | |
ba4e7d97 TH |
226 | /** |
227 | * ttm_bo_move_accel_cleanup. | |
228 | * | |
229 | * @bo: A pointer to a struct ttm_buffer_object. | |
f2c24b83 | 230 | * @fence: A fence object that signals when moving is complete. |
ba4e7d97 | 231 | * @evict: This is an evict move. Don't return until the buffer is idle. |
e46f468f | 232 | * @pipeline: evictions are to be pipelined. |
2966141a | 233 | * @new_mem: struct ttm_resource indicating where to move. |
ba4e7d97 TH |
234 | * |
235 | * Accelerated move function to be called when an accelerated move | |
236 | * has been scheduled. The function will create a new temporary buffer object | |
237 | * representing the old placement, and put the sync object on both buffer | |
238 | * objects. After that the newly created buffer object is unref'd to be | |
239 | * destroyed when the move is complete. This will help pipeline | |
240 | * buffer moves. | |
241 | */ | |
1144b63a CK |
242 | int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, |
243 | struct dma_fence *fence, bool evict, | |
e46f468f | 244 | bool pipeline, |
2966141a | 245 | struct ttm_resource *new_mem); |
3ddf4ad9 | 246 | |
3bf3710e | 247 | /** |
c6346218 | 248 | * ttm_bo_move_sync_cleanup. |
3bf3710e TH |
249 | * |
250 | * @bo: A pointer to a struct ttm_buffer_object. | |
251 | * @new_mem: struct ttm_resource indicating where to move. | |
252 | * | |
253 | * Special case of ttm_bo_move_accel_cleanup where the bo is guaranteed | |
254 | * by the caller to be idle. Typically used after memcpy buffer moves. | |
255 | */ | |
c6346218 MA |
256 | void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo, |
257 | struct ttm_resource *new_mem); | |
3bf3710e | 258 | |
5d951098 CK |
259 | /** |
260 | * ttm_bo_pipeline_gutting. | |
261 | * | |
262 | * @bo: A pointer to a struct ttm_buffer_object. | |
263 | * | |
1e55a53a | 264 | * Pipelined gutting a BO of its backing store. |
5d951098 CK |
265 | */ |
266 | int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo); | |
267 | ||
ba4e7d97 TH |
268 | /** |
269 | * ttm_io_prot | |
270 | * | |
867bcecd CK |
271 | * bo: ttm buffer object |
272 | * res: ttm resource object | |
ba4e7d97 TH |
273 | * @tmp: Page protection flag for a normal, cached mapping. |
274 | * | |
275 | * Utility function that returns the pgprot_t that should be used for | |
276 | * setting up a PTE with the caching model indicated by @c_state. | |
277 | */ | |
867bcecd CK |
278 | pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res, |
279 | pgprot_t tmp); | |
ba4e7d97 | 280 | |
9e9a153b DA |
281 | /** |
282 | * ttm_bo_tt_bind | |
283 | * | |
284 | * Bind the object tt to a memory resource. | |
285 | */ | |
286 | int ttm_bo_tt_bind(struct ttm_buffer_object *bo, struct ttm_resource *mem); | |
287 | ||
2ff6e69c DA |
288 | /** |
289 | * ttm_bo_tt_destroy. | |
290 | */ | |
291 | void ttm_bo_tt_destroy(struct ttm_buffer_object *bo); | |
292 | ||
66907633 | 293 | void ttm_move_memcpy(bool clear, |
3bf3710e TH |
294 | u32 num_pages, |
295 | struct ttm_kmap_iter *dst_iter, | |
296 | struct ttm_kmap_iter *src_iter); | |
297 | ||
298 | struct ttm_kmap_iter * | |
299 | ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io, | |
300 | struct io_mapping *iomap, | |
301 | struct sg_table *st, | |
302 | resource_size_t start); | |
ba4e7d97 | 303 | #endif |