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-fence.h> 31 #include <drm/drm_print.h> 32 #include <drm/ttm/ttm_caching.h> 33 34 #define TTM_MAX_BO_PRIORITY 4U 35 36 struct ttm_bo_device; 37 struct ttm_resource_manager; 38 struct ttm_resource; 39 struct ttm_place; 40 struct ttm_buffer_object; 41 42 struct ttm_resource_manager_func { 43 /** 44 * struct ttm_resource_manager_func member alloc 45 * 46 * @man: Pointer to a memory type manager. 47 * @bo: Pointer to the buffer object we're allocating space for. 48 * @placement: Placement details. 49 * @flags: Additional placement flags. 50 * @mem: Pointer to a struct ttm_resource to be filled in. 51 * 52 * This function should allocate space in the memory type managed 53 * by @man. Placement details if 54 * applicable are given by @placement. If successful, 55 * @mem::mm_node should be set to a non-null value, and 56 * @mem::start should be set to a value identifying the beginning 57 * of the range allocated, and the function should return zero. 58 * If the memory region accommodate the buffer object, @mem::mm_node 59 * should be set to NULL, and the function should return 0. 60 * If a system error occurred, preventing the request to be fulfilled, 61 * the function should return a negative error code. 62 * 63 * Note that @mem::mm_node will only be dereferenced by 64 * struct ttm_resource_manager functions and optionally by the driver, 65 * which has knowledge of the underlying type. 66 * 67 * This function may not be called from within atomic context, so 68 * an implementation can and must use either a mutex or a spinlock to 69 * protect any data structures 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 *mem); 75 76 /** 77 * struct ttm_resource_manager_func member free 78 * 79 * @man: Pointer to a memory type manager. 80 * @mem: Pointer to a struct ttm_resource to be filled in. 81 * 82 * This function frees memory type resources previously allocated 83 * and that are identified by @mem::mm_node and @mem::start. May not 84 * be called from within atomic context. 85 */ 86 void (*free)(struct ttm_resource_manager *man, 87 struct ttm_resource *mem); 88 89 /** 90 * struct ttm_resource_manager_func member debug 91 * 92 * @man: Pointer to a memory type manager. 93 * @printer: Prefix to be used in printout to identify the caller. 94 * 95 * This function is called to print out the state of the memory 96 * type manager to aid debugging of out-of-memory conditions. 97 * It may not be called from within atomic context. 98 */ 99 void (*debug)(struct ttm_resource_manager *man, 100 struct drm_printer *printer); 101 }; 102 103 /** 104 * struct ttm_resource_manager 105 * 106 * @use_type: The memory type is enabled. 107 * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory 108 * managed by this memory type. 109 * @gpu_offset: If used, the GPU offset of the first managed page of 110 * fixed memory or the first managed location in an aperture. 111 * @size: Size of the managed region. 112 * @func: structure pointer implementing the range manager. See above 113 * @move_lock: lock for move fence 114 * static information. bdev::driver::io_mem_free is never used. 115 * @lru: The lru list for this memory type. 116 * @move: The fence of the last pipelined move operation. 117 * 118 * This structure is used to identify and manage memory types for a device. 119 */ 120 struct ttm_resource_manager { 121 /* 122 * No protection. Constant from start. 123 */ 124 bool use_type; 125 bool use_tt; 126 uint64_t size; 127 const struct ttm_resource_manager_func *func; 128 spinlock_t move_lock; 129 130 /* 131 * Protected by the global->lru_lock. 132 */ 133 134 struct list_head lru[TTM_MAX_BO_PRIORITY]; 135 136 /* 137 * Protected by @move_lock. 138 */ 139 struct dma_fence *move; 140 }; 141 142 /** 143 * struct ttm_bus_placement 144 * 145 * @addr: mapped virtual address 146 * @offset: physical addr 147 * @is_iomem: is this io memory ? 148 * 149 * Structure indicating the bus placement of an object. 150 */ 151 struct ttm_bus_placement { 152 void *addr; 153 phys_addr_t offset; 154 bool is_iomem; 155 enum ttm_caching caching; 156 }; 157 158 /** 159 * struct ttm_resource 160 * 161 * @mm_node: Memory manager node. 162 * @size: Requested size of memory region. 163 * @num_pages: Actual size of memory region in pages. 164 * @page_alignment: Page alignment. 165 * @placement: Placement flags. 166 * @bus: Placement on io bus accessible to the CPU 167 * 168 * Structure indicating the placement and space resources used by a 169 * buffer object. 170 */ 171 struct ttm_resource { 172 void *mm_node; 173 unsigned long start; 174 unsigned long num_pages; 175 uint32_t page_alignment; 176 uint32_t mem_type; 177 uint32_t placement; 178 struct ttm_bus_placement bus; 179 }; 180 181 /** 182 * ttm_resource_manager_set_used 183 * 184 * @man: A memory manager object. 185 * @used: usage state to set. 186 * 187 * Set the manager in use flag. If disabled the manager is no longer 188 * used for object placement. 189 */ 190 static inline void 191 ttm_resource_manager_set_used(struct ttm_resource_manager *man, bool used) 192 { 193 int i; 194 195 for (i = 0; i < TTM_MAX_BO_PRIORITY; i++) 196 WARN_ON(!list_empty(&man->lru[i])); 197 man->use_type = used; 198 } 199 200 /** 201 * ttm_resource_manager_used 202 * 203 * @man: Manager to get used state for 204 * 205 * Get the in use flag for a manager. 206 * Returns: 207 * true is used, false if not. 208 */ 209 static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man) 210 { 211 return man->use_type; 212 } 213 214 /** 215 * ttm_resource_manager_cleanup 216 * 217 * @man: A memory manager object. 218 * 219 * Cleanup the move fences from the memory manager object. 220 */ 221 static inline void 222 ttm_resource_manager_cleanup(struct ttm_resource_manager *man) 223 { 224 dma_fence_put(man->move); 225 man->move = NULL; 226 } 227 228 int ttm_resource_alloc(struct ttm_buffer_object *bo, 229 const struct ttm_place *place, 230 struct ttm_resource *res); 231 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource *res); 232 233 void ttm_resource_manager_init(struct ttm_resource_manager *man, 234 unsigned long p_size); 235 236 int ttm_resource_manager_evict_all(struct ttm_bo_device *bdev, 237 struct ttm_resource_manager *man); 238 239 void ttm_resource_manager_debug(struct ttm_resource_manager *man, 240 struct drm_printer *p); 241 242 #endif 243