xref: /openbmc/linux/include/drm/ttm/ttm_resource.h (revision 31e67366)
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