1 /* 2 * Copyright 2020 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Christian König 23 */ 24 25 #ifndef _TTM_RESOURCE_H_ 26 #define _TTM_RESOURCE_H_ 27 28 #include <linux/types.h> 29 #include <linux/mutex.h> 30 #include <linux/dma-buf-map.h> 31 #include <linux/dma-fence.h> 32 #include <drm/drm_print.h> 33 #include <drm/ttm/ttm_caching.h> 34 #include <drm/ttm/ttm_kmap_iter.h> 35 36 #define TTM_MAX_BO_PRIORITY 4U 37 38 struct ttm_device; 39 struct ttm_resource_manager; 40 struct ttm_resource; 41 struct ttm_place; 42 struct ttm_buffer_object; 43 struct ttm_placement; 44 struct dma_buf_map; 45 struct io_mapping; 46 struct sg_table; 47 struct scatterlist; 48 49 struct ttm_resource_manager_func { 50 /** 51 * struct ttm_resource_manager_func member alloc 52 * 53 * @man: Pointer to a memory type manager. 54 * @bo: Pointer to the buffer object we're allocating space for. 55 * @place: Placement details. 56 * @res: Resulting pointer to the ttm_resource. 57 * 58 * This function should allocate space in the memory type managed 59 * by @man. Placement details if applicable are given by @place. If 60 * successful, a filled in ttm_resource object should be returned in 61 * @res. @res::start should be set to a value identifying the beginning 62 * of the range allocated, and the function should return zero. 63 * If the manager can't fulfill the request -ENOSPC should be returned. 64 * If a system error occurred, preventing the request to be fulfilled, 65 * the function should return a negative error code. 66 * 67 * This function may not be called from within atomic context and needs 68 * to take care of its own locking to protect any data structures 69 * managing the space. 70 */ 71 int (*alloc)(struct ttm_resource_manager *man, 72 struct ttm_buffer_object *bo, 73 const struct ttm_place *place, 74 struct ttm_resource **res); 75 76 /** 77 * struct ttm_resource_manager_func member free 78 * 79 * @man: Pointer to a memory type manager. 80 * @res: Pointer to a struct ttm_resource to be freed. 81 * 82 * This function frees memory type resources previously allocated. 83 * May not be called from within atomic context. 84 */ 85 void (*free)(struct ttm_resource_manager *man, 86 struct ttm_resource *res); 87 88 /** 89 * struct ttm_resource_manager_func member debug 90 * 91 * @man: Pointer to a memory type manager. 92 * @printer: Prefix to be used in printout to identify the caller. 93 * 94 * This function is called to print out the state of the memory 95 * type manager to aid debugging of out-of-memory conditions. 96 * It may not be called from within atomic context. 97 */ 98 void (*debug)(struct ttm_resource_manager *man, 99 struct drm_printer *printer); 100 }; 101 102 /** 103 * struct ttm_resource_manager 104 * 105 * @use_type: The memory type is enabled. 106 * @use_tt: If a TT object should be used for the backing store. 107 * @size: Size of the managed region. 108 * @bdev: ttm device this manager belongs to 109 * @func: structure pointer implementing the range manager. See above 110 * @move_lock: lock for move fence 111 * @move: The fence of the last pipelined move operation. 112 * @lru: The lru list for this memory type. 113 * 114 * This structure is used to identify and manage memory types for a device. 115 */ 116 struct ttm_resource_manager { 117 /* 118 * No protection. Constant from start. 119 */ 120 bool use_type; 121 bool use_tt; 122 struct ttm_device *bdev; 123 uint64_t size; 124 const struct ttm_resource_manager_func *func; 125 spinlock_t move_lock; 126 127 /* 128 * Protected by @move_lock. 129 */ 130 struct dma_fence *move; 131 132 /* 133 * Protected by the global->lru_lock. 134 */ 135 136 struct list_head lru[TTM_MAX_BO_PRIORITY]; 137 }; 138 139 /** 140 * struct ttm_bus_placement 141 * 142 * @addr: mapped virtual address 143 * @offset: physical addr 144 * @is_iomem: is this io memory ? 145 * @caching: See enum ttm_caching 146 * 147 * Structure indicating the bus placement of an object. 148 */ 149 struct ttm_bus_placement { 150 void *addr; 151 phys_addr_t offset; 152 bool is_iomem; 153 enum ttm_caching caching; 154 }; 155 156 /** 157 * struct ttm_resource 158 * 159 * @start: Start of the allocation. 160 * @num_pages: Actual size of resource in pages. 161 * @mem_type: Resource type of the allocation. 162 * @placement: Placement flags. 163 * @bus: Placement on io bus accessible to the CPU 164 * @bo: weak reference to the BO, protected by ttm_device::lru_lock 165 * 166 * Structure indicating the placement and space resources used by a 167 * buffer object. 168 */ 169 struct ttm_resource { 170 unsigned long start; 171 unsigned long num_pages; 172 uint32_t mem_type; 173 uint32_t placement; 174 struct ttm_bus_placement bus; 175 struct ttm_buffer_object *bo; 176 }; 177 178 /** 179 * struct ttm_kmap_iter_iomap - Specialization for a struct io_mapping + 180 * struct sg_table backed struct ttm_resource. 181 * @base: Embedded struct ttm_kmap_iter providing the usage interface. 182 * @iomap: struct io_mapping representing the underlying linear io_memory. 183 * @st: sg_table into @iomap, representing the memory of the struct ttm_resource. 184 * @start: Offset that needs to be subtracted from @st to make 185 * sg_dma_address(st->sgl) - @start == 0 for @iomap start. 186 * @cache: Scatterlist traversal cache for fast lookups. 187 * @cache.sg: Pointer to the currently cached scatterlist segment. 188 * @cache.i: First index of @sg. PAGE_SIZE granularity. 189 * @cache.end: Last index + 1 of @sg. PAGE_SIZE granularity. 190 * @cache.offs: First offset into @iomap of @sg. PAGE_SIZE granularity. 191 */ 192 struct ttm_kmap_iter_iomap { 193 struct ttm_kmap_iter base; 194 struct io_mapping *iomap; 195 struct sg_table *st; 196 resource_size_t start; 197 struct { 198 struct scatterlist *sg; 199 pgoff_t i; 200 pgoff_t end; 201 pgoff_t offs; 202 } cache; 203 }; 204 205 /** 206 * struct ttm_kmap_iter_linear_io - Iterator specialization for linear io 207 * @base: The base iterator 208 * @dmap: Points to the starting address of the region 209 * @needs_unmap: Whether we need to unmap on fini 210 */ 211 struct ttm_kmap_iter_linear_io { 212 struct ttm_kmap_iter base; 213 struct dma_buf_map dmap; 214 bool needs_unmap; 215 }; 216 217 /** 218 * ttm_resource_manager_set_used 219 * 220 * @man: A memory manager object. 221 * @used: usage state to set. 222 * 223 * Set the manager in use flag. If disabled the manager is no longer 224 * used for object placement. 225 */ 226 static inline void 227 ttm_resource_manager_set_used(struct ttm_resource_manager *man, bool used) 228 { 229 int i; 230 231 for (i = 0; i < TTM_MAX_BO_PRIORITY; i++) 232 WARN_ON(!list_empty(&man->lru[i])); 233 man->use_type = used; 234 } 235 236 /** 237 * ttm_resource_manager_used 238 * 239 * @man: Manager to get used state for 240 * 241 * Get the in use flag for a manager. 242 * Returns: 243 * true is used, false if not. 244 */ 245 static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man) 246 { 247 return man->use_type; 248 } 249 250 /** 251 * ttm_resource_manager_cleanup 252 * 253 * @man: A memory manager object. 254 * 255 * Cleanup the move fences from the memory manager object. 256 */ 257 static inline void 258 ttm_resource_manager_cleanup(struct ttm_resource_manager *man) 259 { 260 dma_fence_put(man->move); 261 man->move = NULL; 262 } 263 264 void ttm_resource_init(struct ttm_buffer_object *bo, 265 const struct ttm_place *place, 266 struct ttm_resource *res); 267 void ttm_resource_fini(struct ttm_resource_manager *man, 268 struct ttm_resource *res); 269 270 int ttm_resource_alloc(struct ttm_buffer_object *bo, 271 const struct ttm_place *place, 272 struct ttm_resource **res); 273 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res); 274 bool ttm_resource_compat(struct ttm_resource *res, 275 struct ttm_placement *placement); 276 void ttm_resource_set_bo(struct ttm_resource *res, 277 struct ttm_buffer_object *bo); 278 279 void ttm_resource_manager_init(struct ttm_resource_manager *man, 280 struct ttm_device *bdev, 281 unsigned long p_size); 282 283 int ttm_resource_manager_evict_all(struct ttm_device *bdev, 284 struct ttm_resource_manager *man); 285 286 void ttm_resource_manager_debug(struct ttm_resource_manager *man, 287 struct drm_printer *p); 288 289 struct ttm_kmap_iter * 290 ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io, 291 struct io_mapping *iomap, 292 struct sg_table *st, 293 resource_size_t start); 294 295 struct ttm_kmap_iter_linear_io; 296 297 struct ttm_kmap_iter * 298 ttm_kmap_iter_linear_io_init(struct ttm_kmap_iter_linear_io *iter_io, 299 struct ttm_device *bdev, 300 struct ttm_resource *mem); 301 302 void ttm_kmap_iter_linear_io_fini(struct ttm_kmap_iter_linear_io *iter_io, 303 struct ttm_device *bdev, 304 struct ttm_resource *mem); 305 #endif 306