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 dma_buf_map; 44 struct io_mapping; 45 struct sg_table; 46 struct scatterlist; 47 48 struct ttm_resource_manager_func { 49 /** 50 * struct ttm_resource_manager_func member alloc 51 * 52 * @man: Pointer to a memory type manager. 53 * @bo: Pointer to the buffer object we're allocating space for. 54 * @place: Placement details. 55 * @res: Resulting pointer to the ttm_resource. 56 * 57 * This function should allocate space in the memory type managed 58 * by @man. Placement details if applicable are given by @place. If 59 * successful, a filled in ttm_resource object should be returned in 60 * @res. @res::start should be set to a value identifying the beginning 61 * of the range allocated, and the function should return zero. 62 * If the manager can't fulfill the request -ENOSPC should be returned. 63 * If a system error occurred, preventing the request to be fulfilled, 64 * the function should return a negative error code. 65 * 66 * This function may not be called from within atomic context and needs 67 * to take care of its own locking to protect any data structures 68 * managing the space. 69 */ 70 int (*alloc)(struct ttm_resource_manager *man, 71 struct ttm_buffer_object *bo, 72 const struct ttm_place *place, 73 struct ttm_resource **res); 74 75 /** 76 * struct ttm_resource_manager_func member free 77 * 78 * @man: Pointer to a memory type manager. 79 * @res: Pointer to a struct ttm_resource to be freed. 80 * 81 * This function frees memory type resources previously allocated. 82 * May not be called from within atomic context. 83 */ 84 void (*free)(struct ttm_resource_manager *man, 85 struct ttm_resource *res); 86 87 /** 88 * struct ttm_resource_manager_func member debug 89 * 90 * @man: Pointer to a memory type manager. 91 * @printer: Prefix to be used in printout to identify the caller. 92 * 93 * This function is called to print out the state of the memory 94 * type manager to aid debugging of out-of-memory conditions. 95 * It may not be called from within atomic context. 96 */ 97 void (*debug)(struct ttm_resource_manager *man, 98 struct drm_printer *printer); 99 }; 100 101 /** 102 * struct ttm_resource_manager 103 * 104 * @use_type: The memory type is enabled. 105 * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory 106 * managed by this memory type. 107 * @gpu_offset: If used, the GPU offset of the first managed page of 108 * fixed memory or the first managed location in an aperture. 109 * @size: Size of the managed region. 110 * @func: structure pointer implementing the range manager. See above 111 * @move_lock: lock for move fence 112 * static information. bdev::driver::io_mem_free is never used. 113 * @lru: The lru list for this memory type. 114 * @move: The fence of the last pipelined move operation. 115 * 116 * This structure is used to identify and manage memory types for a device. 117 */ 118 struct ttm_resource_manager { 119 /* 120 * No protection. Constant from start. 121 */ 122 bool use_type; 123 bool use_tt; 124 uint64_t size; 125 const struct ttm_resource_manager_func *func; 126 spinlock_t move_lock; 127 128 /* 129 * Protected by the global->lru_lock. 130 */ 131 132 struct list_head lru[TTM_MAX_BO_PRIORITY]; 133 134 /* 135 * Protected by @move_lock. 136 */ 137 struct dma_fence *move; 138 }; 139 140 /** 141 * struct ttm_bus_placement 142 * 143 * @addr: mapped virtual address 144 * @offset: physical addr 145 * @is_iomem: is this io memory ? 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 * 165 * Structure indicating the placement and space resources used by a 166 * buffer object. 167 */ 168 struct ttm_resource { 169 unsigned long start; 170 unsigned long num_pages; 171 uint32_t mem_type; 172 uint32_t placement; 173 struct ttm_bus_placement bus; 174 }; 175 176 /** 177 * struct ttm_kmap_iter_iomap - Specialization for a struct io_mapping + 178 * struct sg_table backed struct ttm_resource. 179 * @base: Embedded struct ttm_kmap_iter providing the usage interface. 180 * @iomap: struct io_mapping representing the underlying linear io_memory. 181 * @st: sg_table into @iomap, representing the memory of the struct ttm_resource. 182 * @start: Offset that needs to be subtracted from @st to make 183 * sg_dma_address(st->sgl) - @start == 0 for @iomap start. 184 * @cache: Scatterlist traversal cache for fast lookups. 185 * @cache.sg: Pointer to the currently cached scatterlist segment. 186 * @cache.i: First index of @sg. PAGE_SIZE granularity. 187 * @cache.end: Last index + 1 of @sg. PAGE_SIZE granularity. 188 * @cache.offs: First offset into @iomap of @sg. PAGE_SIZE granularity. 189 */ 190 struct ttm_kmap_iter_iomap { 191 struct ttm_kmap_iter base; 192 struct io_mapping *iomap; 193 struct sg_table *st; 194 resource_size_t start; 195 struct { 196 struct scatterlist *sg; 197 pgoff_t i; 198 pgoff_t end; 199 pgoff_t offs; 200 } cache; 201 }; 202 203 /** 204 * struct ttm_kmap_iter_linear_io - Iterator specialization for linear io 205 * @base: The base iterator 206 * @dmap: Points to the starting address of the region 207 * @needs_unmap: Whether we need to unmap on fini 208 */ 209 struct ttm_kmap_iter_linear_io { 210 struct ttm_kmap_iter base; 211 struct dma_buf_map dmap; 212 bool needs_unmap; 213 }; 214 215 /** 216 * ttm_resource_manager_set_used 217 * 218 * @man: A memory manager object. 219 * @used: usage state to set. 220 * 221 * Set the manager in use flag. If disabled the manager is no longer 222 * used for object placement. 223 */ 224 static inline void 225 ttm_resource_manager_set_used(struct ttm_resource_manager *man, bool used) 226 { 227 int i; 228 229 for (i = 0; i < TTM_MAX_BO_PRIORITY; i++) 230 WARN_ON(!list_empty(&man->lru[i])); 231 man->use_type = used; 232 } 233 234 /** 235 * ttm_resource_manager_used 236 * 237 * @man: Manager to get used state for 238 * 239 * Get the in use flag for a manager. 240 * Returns: 241 * true is used, false if not. 242 */ 243 static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man) 244 { 245 return man->use_type; 246 } 247 248 /** 249 * ttm_resource_manager_cleanup 250 * 251 * @man: A memory manager object. 252 * 253 * Cleanup the move fences from the memory manager object. 254 */ 255 static inline void 256 ttm_resource_manager_cleanup(struct ttm_resource_manager *man) 257 { 258 dma_fence_put(man->move); 259 man->move = NULL; 260 } 261 262 void ttm_resource_init(struct ttm_buffer_object *bo, 263 const struct ttm_place *place, 264 struct ttm_resource *res); 265 int ttm_resource_alloc(struct ttm_buffer_object *bo, 266 const struct ttm_place *place, 267 struct ttm_resource **res); 268 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res); 269 270 void ttm_resource_manager_init(struct ttm_resource_manager *man, 271 unsigned long p_size); 272 273 int ttm_resource_manager_evict_all(struct ttm_device *bdev, 274 struct ttm_resource_manager *man); 275 276 void ttm_resource_manager_debug(struct ttm_resource_manager *man, 277 struct drm_printer *p); 278 279 struct ttm_kmap_iter * 280 ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io, 281 struct io_mapping *iomap, 282 struct sg_table *st, 283 resource_size_t start); 284 285 struct ttm_kmap_iter_linear_io; 286 287 struct ttm_kmap_iter * 288 ttm_kmap_iter_linear_io_init(struct ttm_kmap_iter_linear_io *iter_io, 289 struct ttm_device *bdev, 290 struct ttm_resource *mem); 291 292 void ttm_kmap_iter_linear_io_fini(struct ttm_kmap_iter_linear_io *iter_io, 293 struct ttm_device *bdev, 294 struct ttm_resource *mem); 295 #endif 296