298 lines · c
1/*2 * Copyright 2020 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: Christian König23 */24 25#ifndef _TTM_DEVICE_H_26#define _TTM_DEVICE_H_27 28#include <linux/types.h>29#include <linux/workqueue.h>30#include <drm/ttm/ttm_resource.h>31#include <drm/ttm/ttm_pool.h>32 33struct ttm_device;34struct ttm_placement;35struct ttm_buffer_object;36struct ttm_operation_ctx;37 38/**39 * struct ttm_global - Buffer object driver global data.40 */41extern struct ttm_global {42 43 /**44 * @dummy_read_page: Pointer to a dummy page used for mapping requests45 * of unpopulated pages. Constant after init.46 */47 struct page *dummy_read_page;48 49 /**50 * @device_list: List of buffer object devices. Protected by51 * ttm_global_mutex.52 */53 struct list_head device_list;54 55 /**56 * @bo_count: Number of buffer objects allocated by devices.57 */58 atomic_t bo_count;59} ttm_glob;60 61struct ttm_device_funcs {62 /**63 * ttm_tt_create64 *65 * @bo: The buffer object to create the ttm for.66 * @page_flags: Page flags as identified by TTM_TT_FLAG_XX flags.67 *68 * Create a struct ttm_tt to back data with system memory pages.69 * No pages are actually allocated.70 * Returns:71 * NULL: Out of memory.72 */73 struct ttm_tt *(*ttm_tt_create)(struct ttm_buffer_object *bo,74 uint32_t page_flags);75 76 /**77 * ttm_tt_populate78 *79 * @ttm: The struct ttm_tt to contain the backing pages.80 *81 * Allocate all backing pages82 * Returns:83 * -ENOMEM: Out of memory.84 */85 int (*ttm_tt_populate)(struct ttm_device *bdev,86 struct ttm_tt *ttm,87 struct ttm_operation_ctx *ctx);88 89 /**90 * ttm_tt_unpopulate91 *92 * @ttm: The struct ttm_tt to contain the backing pages.93 *94 * Free all backing page95 */96 void (*ttm_tt_unpopulate)(struct ttm_device *bdev,97 struct ttm_tt *ttm);98 99 /**100 * ttm_tt_destroy101 *102 * @bdev: Pointer to a ttm device103 * @ttm: Pointer to a struct ttm_tt.104 *105 * Destroy the backend. This will be call back from ttm_tt_destroy so106 * don't call ttm_tt_destroy from the callback or infinite loop.107 */108 void (*ttm_tt_destroy)(struct ttm_device *bdev, struct ttm_tt *ttm);109 110 /**111 * struct ttm_bo_driver member eviction_valuable112 *113 * @bo: the buffer object to be evicted114 * @place: placement we need room for115 *116 * Check with the driver if it is valuable to evict a BO to make room117 * for a certain placement.118 */119 bool (*eviction_valuable)(struct ttm_buffer_object *bo,120 const struct ttm_place *place);121 /**122 * struct ttm_bo_driver member evict_flags:123 *124 * @bo: the buffer object to be evicted125 *126 * Return the bo flags for a buffer which is not mapped to the hardware.127 * These will be placed in proposed_flags so that when the move is128 * finished, they'll end up in bo->mem.flags129 * This should not cause multihop evictions, and the core will warn130 * if one is proposed.131 */132 133 void (*evict_flags)(struct ttm_buffer_object *bo,134 struct ttm_placement *placement);135 136 /**137 * struct ttm_bo_driver member move:138 *139 * @bo: the buffer to move140 * @evict: whether this motion is evicting the buffer from141 * the graphics address space142 * @ctx: context for this move with parameters143 * @new_mem: the new memory region receiving the buffer144 * @hop: placement for driver directed intermediate hop145 *146 * Move a buffer between two memory regions.147 * Returns errno -EMULTIHOP if driver requests a hop148 */149 int (*move)(struct ttm_buffer_object *bo, bool evict,150 struct ttm_operation_ctx *ctx,151 struct ttm_resource *new_mem,152 struct ttm_place *hop);153 154 /**155 * Hook to notify driver about a resource delete.156 */157 void (*delete_mem_notify)(struct ttm_buffer_object *bo);158 159 /**160 * notify the driver that we're about to swap out this bo161 */162 void (*swap_notify)(struct ttm_buffer_object *bo);163 164 /**165 * Driver callback on when mapping io memory (for bo_move_memcpy166 * for instance). TTM will take care to call io_mem_free whenever167 * the mapping is not use anymore. io_mem_reserve & io_mem_free168 * are balanced.169 */170 int (*io_mem_reserve)(struct ttm_device *bdev,171 struct ttm_resource *mem);172 void (*io_mem_free)(struct ttm_device *bdev,173 struct ttm_resource *mem);174 175 /**176 * Return the pfn for a given page_offset inside the BO.177 *178 * @bo: the BO to look up the pfn for179 * @page_offset: the offset to look up180 */181 unsigned long (*io_mem_pfn)(struct ttm_buffer_object *bo,182 unsigned long page_offset);183 184 /**185 * Read/write memory buffers for ptrace access186 *187 * @bo: the BO to access188 * @offset: the offset from the start of the BO189 * @buf: pointer to source/destination buffer190 * @len: number of bytes to copy191 * @write: whether to read (0) from or write (non-0) to BO192 *193 * If successful, this function should return the number of194 * bytes copied, -EIO otherwise. If the number of bytes195 * returned is < len, the function may be called again with196 * the remainder of the buffer to copy.197 */198 int (*access_memory)(struct ttm_buffer_object *bo, unsigned long offset,199 void *buf, int len, int write);200 201 /**202 * Notify the driver that we're about to release a BO203 *204 * @bo: BO that is about to be released205 *206 * Gives the driver a chance to do any cleanup, including207 * adding fences that may force a delayed delete208 */209 void (*release_notify)(struct ttm_buffer_object *bo);210};211 212/**213 * struct ttm_device - Buffer object driver device-specific data.214 */215struct ttm_device {216 /**217 * @device_list: Our entry in the global device list.218 * Constant after bo device init219 */220 struct list_head device_list;221 222 /**223 * @funcs: Function table for the device.224 * Constant after bo device init225 */226 const struct ttm_device_funcs *funcs;227 228 /**229 * @sysman: Resource manager for the system domain.230 * Access via ttm_manager_type.231 */232 struct ttm_resource_manager sysman;233 234 /**235 * @man_drv: An array of resource_managers, one per resource type.236 */237 struct ttm_resource_manager *man_drv[TTM_NUM_MEM_TYPES];238 239 /**240 * @vma_manager: Address space manager for finding BOs to mmap.241 */242 struct drm_vma_offset_manager *vma_manager;243 244 /**245 * @pool: page pool for the device.246 */247 struct ttm_pool pool;248 249 /**250 * @lru_lock: Protection for the per manager LRU and ddestroy lists.251 */252 spinlock_t lru_lock;253 254 /**255 * @pinned: Buffer objects which are pinned and so not on any LRU list.256 */257 struct list_head pinned;258 259 /**260 * @dev_mapping: A pointer to the struct address_space for invalidating261 * CPU mappings on buffer move. Protected by load/unload sync.262 */263 struct address_space *dev_mapping;264 265 /**266 * @wq: Work queue structure for the delayed delete workqueue.267 */268 struct workqueue_struct *wq;269};270 271int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags);272int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,273 gfp_t gfp_flags);274 275static inline struct ttm_resource_manager *276ttm_manager_type(struct ttm_device *bdev, int mem_type)277{278 BUILD_BUG_ON(__builtin_constant_p(mem_type)279 && mem_type >= TTM_NUM_MEM_TYPES);280 return bdev->man_drv[mem_type];281}282 283static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type,284 struct ttm_resource_manager *manager)285{286 BUILD_BUG_ON(__builtin_constant_p(type) && type >= TTM_NUM_MEM_TYPES);287 bdev->man_drv[type] = manager;288}289 290int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,291 struct device *dev, struct address_space *mapping,292 struct drm_vma_offset_manager *vma_manager,293 bool use_dma_alloc, bool use_dma32);294void ttm_device_fini(struct ttm_device *bdev);295void ttm_device_clear_dma_mappings(struct ttm_device *bdev);296 297#endif298