18af8a109SChristian König /* 28af8a109SChristian König * Copyright 2020 Advanced Micro Devices, Inc. 38af8a109SChristian König * 48af8a109SChristian König * Permission is hereby granted, free of charge, to any person obtaining a 58af8a109SChristian König * copy of this software and associated documentation files (the "Software"), 68af8a109SChristian König * to deal in the Software without restriction, including without limitation 78af8a109SChristian König * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88af8a109SChristian König * and/or sell copies of the Software, and to permit persons to whom the 98af8a109SChristian König * Software is furnished to do so, subject to the following conditions: 108af8a109SChristian König * 118af8a109SChristian König * The above copyright notice and this permission notice shall be included in 128af8a109SChristian König * all copies or substantial portions of the Software. 138af8a109SChristian König * 148af8a109SChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 158af8a109SChristian König * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 168af8a109SChristian König * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 178af8a109SChristian König * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 188af8a109SChristian König * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 198af8a109SChristian König * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 208af8a109SChristian König * OTHER DEALINGS IN THE SOFTWARE. 218af8a109SChristian König * 228af8a109SChristian König * Authors: Christian König 238af8a109SChristian König */ 248af8a109SChristian König 258af8a109SChristian König #ifndef _TTM_DEVICE_H_ 268af8a109SChristian König #define _TTM_DEVICE_H_ 278af8a109SChristian König 288af8a109SChristian König #include <linux/types.h> 298af8a109SChristian König #include <linux/workqueue.h> 308af8a109SChristian König #include <drm/ttm/ttm_resource.h> 318af8a109SChristian König #include <drm/ttm/ttm_pool.h> 328af8a109SChristian König 338af8a109SChristian König #define TTM_NUM_MEM_TYPES 8 348af8a109SChristian König 358af8a109SChristian König struct ttm_device; 368af8a109SChristian König struct ttm_placement; 378af8a109SChristian König struct ttm_buffer_object; 388af8a109SChristian König struct ttm_operation_ctx; 398af8a109SChristian König 408af8a109SChristian König /** 418af8a109SChristian König * struct ttm_global - Buffer object driver global data. 428af8a109SChristian König * 438af8a109SChristian König * @dummy_read_page: Pointer to a dummy page used for mapping requests 448af8a109SChristian König * of unpopulated pages. 458af8a109SChristian König * @shrink: A shrink callback object used for buffer object swap. 468af8a109SChristian König * @device_list_mutex: Mutex protecting the device list. 478af8a109SChristian König * This mutex is held while traversing the device list for pm options. 488af8a109SChristian König * @lru_lock: Spinlock protecting the bo subsystem lru lists. 498af8a109SChristian König * @device_list: List of buffer object devices. 508af8a109SChristian König * @swap_lru: Lru list of buffer objects used for swapping. 518af8a109SChristian König */ 528af8a109SChristian König extern struct ttm_global { 538af8a109SChristian König 548af8a109SChristian König /** 558af8a109SChristian König * Constant after init. 568af8a109SChristian König */ 578af8a109SChristian König 588af8a109SChristian König struct page *dummy_read_page; 598af8a109SChristian König spinlock_t lru_lock; 608af8a109SChristian König 618af8a109SChristian König /** 628af8a109SChristian König * Protected by ttm_global_mutex. 638af8a109SChristian König */ 648af8a109SChristian König struct list_head device_list; 658af8a109SChristian König 668af8a109SChristian König /** 678af8a109SChristian König * Internal protection. 688af8a109SChristian König */ 698af8a109SChristian König atomic_t bo_count; 708af8a109SChristian König } ttm_glob; 718af8a109SChristian König 728af8a109SChristian König struct ttm_device_funcs { 738af8a109SChristian König /** 748af8a109SChristian König * ttm_tt_create 758af8a109SChristian König * 768af8a109SChristian König * @bo: The buffer object to create the ttm for. 778af8a109SChristian König * @page_flags: Page flags as identified by TTM_PAGE_FLAG_XX flags. 788af8a109SChristian König * 798af8a109SChristian König * Create a struct ttm_tt to back data with system memory pages. 808af8a109SChristian König * No pages are actually allocated. 818af8a109SChristian König * Returns: 828af8a109SChristian König * NULL: Out of memory. 838af8a109SChristian König */ 848af8a109SChristian König struct ttm_tt *(*ttm_tt_create)(struct ttm_buffer_object *bo, 858af8a109SChristian König uint32_t page_flags); 868af8a109SChristian König 878af8a109SChristian König /** 888af8a109SChristian König * ttm_tt_populate 898af8a109SChristian König * 908af8a109SChristian König * @ttm: The struct ttm_tt to contain the backing pages. 918af8a109SChristian König * 928af8a109SChristian König * Allocate all backing pages 938af8a109SChristian König * Returns: 948af8a109SChristian König * -ENOMEM: Out of memory. 958af8a109SChristian König */ 968af8a109SChristian König int (*ttm_tt_populate)(struct ttm_device *bdev, 978af8a109SChristian König struct ttm_tt *ttm, 988af8a109SChristian König struct ttm_operation_ctx *ctx); 998af8a109SChristian König 1008af8a109SChristian König /** 1018af8a109SChristian König * ttm_tt_unpopulate 1028af8a109SChristian König * 1038af8a109SChristian König * @ttm: The struct ttm_tt to contain the backing pages. 1048af8a109SChristian König * 1058af8a109SChristian König * Free all backing page 1068af8a109SChristian König */ 1078af8a109SChristian König void (*ttm_tt_unpopulate)(struct ttm_device *bdev, 1088af8a109SChristian König struct ttm_tt *ttm); 1098af8a109SChristian König 1108af8a109SChristian König /** 1118af8a109SChristian König * ttm_tt_destroy 1128af8a109SChristian König * 1138af8a109SChristian König * @bdev: Pointer to a ttm device 1148af8a109SChristian König * @ttm: Pointer to a struct ttm_tt. 1158af8a109SChristian König * 1168af8a109SChristian König * Destroy the backend. This will be call back from ttm_tt_destroy so 1178af8a109SChristian König * don't call ttm_tt_destroy from the callback or infinite loop. 1188af8a109SChristian König */ 1198af8a109SChristian König void (*ttm_tt_destroy)(struct ttm_device *bdev, struct ttm_tt *ttm); 1208af8a109SChristian König 1218af8a109SChristian König /** 1228af8a109SChristian König * struct ttm_bo_driver member eviction_valuable 1238af8a109SChristian König * 1248af8a109SChristian König * @bo: the buffer object to be evicted 1258af8a109SChristian König * @place: placement we need room for 1268af8a109SChristian König * 1278af8a109SChristian König * Check with the driver if it is valuable to evict a BO to make room 1288af8a109SChristian König * for a certain placement. 1298af8a109SChristian König */ 1308af8a109SChristian König bool (*eviction_valuable)(struct ttm_buffer_object *bo, 1318af8a109SChristian König const struct ttm_place *place); 1328af8a109SChristian König /** 1338af8a109SChristian König * struct ttm_bo_driver member evict_flags: 1348af8a109SChristian König * 1358af8a109SChristian König * @bo: the buffer object to be evicted 1368af8a109SChristian König * 1378af8a109SChristian König * Return the bo flags for a buffer which is not mapped to the hardware. 1388af8a109SChristian König * These will be placed in proposed_flags so that when the move is 1398af8a109SChristian König * finished, they'll end up in bo->mem.flags 1408af8a109SChristian König * This should not cause multihop evictions, and the core will warn 1418af8a109SChristian König * if one is proposed. 1428af8a109SChristian König */ 1438af8a109SChristian König 1448af8a109SChristian König void (*evict_flags)(struct ttm_buffer_object *bo, 1458af8a109SChristian König struct ttm_placement *placement); 1468af8a109SChristian König 1478af8a109SChristian König /** 1488af8a109SChristian König * struct ttm_bo_driver member move: 1498af8a109SChristian König * 1508af8a109SChristian König * @bo: the buffer to move 1518af8a109SChristian König * @evict: whether this motion is evicting the buffer from 1528af8a109SChristian König * the graphics address space 1538af8a109SChristian König * @ctx: context for this move with parameters 1548af8a109SChristian König * @new_mem: the new memory region receiving the buffer 1558af8a109SChristian König @ @hop: placement for driver directed intermediate hop 1568af8a109SChristian König * 1578af8a109SChristian König * Move a buffer between two memory regions. 1588af8a109SChristian König * Returns errno -EMULTIHOP if driver requests a hop 1598af8a109SChristian König */ 1608af8a109SChristian König int (*move)(struct ttm_buffer_object *bo, bool evict, 1618af8a109SChristian König struct ttm_operation_ctx *ctx, 1628af8a109SChristian König struct ttm_resource *new_mem, 1638af8a109SChristian König struct ttm_place *hop); 1648af8a109SChristian König 1658af8a109SChristian König /** 1668af8a109SChristian König * struct ttm_bo_driver_member verify_access 1678af8a109SChristian König * 1688af8a109SChristian König * @bo: Pointer to a buffer object. 1698af8a109SChristian König * @filp: Pointer to a struct file trying to access the object. 1708af8a109SChristian König * 1718af8a109SChristian König * Called from the map / write / read methods to verify that the 1728af8a109SChristian König * caller is permitted to access the buffer object. 1738af8a109SChristian König * This member may be set to NULL, which will refuse this kind of 1748af8a109SChristian König * access for all buffer objects. 1758af8a109SChristian König * This function should return 0 if access is granted, -EPERM otherwise. 1768af8a109SChristian König */ 1778af8a109SChristian König int (*verify_access)(struct ttm_buffer_object *bo, 1788af8a109SChristian König struct file *filp); 1798af8a109SChristian König 1808af8a109SChristian König /** 1818af8a109SChristian König * Hook to notify driver about a resource delete. 1828af8a109SChristian König */ 1838af8a109SChristian König void (*delete_mem_notify)(struct ttm_buffer_object *bo); 1848af8a109SChristian König 1858af8a109SChristian König /** 1868af8a109SChristian König * notify the driver that we're about to swap out this bo 1878af8a109SChristian König */ 1888af8a109SChristian König void (*swap_notify)(struct ttm_buffer_object *bo); 1898af8a109SChristian König 1908af8a109SChristian König /** 1918af8a109SChristian König * Driver callback on when mapping io memory (for bo_move_memcpy 1928af8a109SChristian König * for instance). TTM will take care to call io_mem_free whenever 1938af8a109SChristian König * the mapping is not use anymore. io_mem_reserve & io_mem_free 1948af8a109SChristian König * are balanced. 1958af8a109SChristian König */ 1968af8a109SChristian König int (*io_mem_reserve)(struct ttm_device *bdev, 1978af8a109SChristian König struct ttm_resource *mem); 1988af8a109SChristian König void (*io_mem_free)(struct ttm_device *bdev, 1998af8a109SChristian König struct ttm_resource *mem); 2008af8a109SChristian König 2018af8a109SChristian König /** 2028af8a109SChristian König * Return the pfn for a given page_offset inside the BO. 2038af8a109SChristian König * 2048af8a109SChristian König * @bo: the BO to look up the pfn for 2058af8a109SChristian König * @page_offset: the offset to look up 2068af8a109SChristian König */ 2078af8a109SChristian König unsigned long (*io_mem_pfn)(struct ttm_buffer_object *bo, 2088af8a109SChristian König unsigned long page_offset); 2098af8a109SChristian König 2108af8a109SChristian König /** 2118af8a109SChristian König * Read/write memory buffers for ptrace access 2128af8a109SChristian König * 2138af8a109SChristian König * @bo: the BO to access 2148af8a109SChristian König * @offset: the offset from the start of the BO 2158af8a109SChristian König * @buf: pointer to source/destination buffer 2168af8a109SChristian König * @len: number of bytes to copy 2178af8a109SChristian König * @write: whether to read (0) from or write (non-0) to BO 2188af8a109SChristian König * 2198af8a109SChristian König * If successful, this function should return the number of 2208af8a109SChristian König * bytes copied, -EIO otherwise. If the number of bytes 2218af8a109SChristian König * returned is < len, the function may be called again with 2228af8a109SChristian König * the remainder of the buffer to copy. 2238af8a109SChristian König */ 2248af8a109SChristian König int (*access_memory)(struct ttm_buffer_object *bo, unsigned long offset, 2258af8a109SChristian König void *buf, int len, int write); 2268af8a109SChristian König 2278af8a109SChristian König /** 2288af8a109SChristian König * struct ttm_bo_driver member del_from_lru_notify 2298af8a109SChristian König * 2308af8a109SChristian König * @bo: the buffer object deleted from lru 2318af8a109SChristian König * 2328af8a109SChristian König * notify driver that a BO was deleted from LRU. 2338af8a109SChristian König */ 2348af8a109SChristian König void (*del_from_lru_notify)(struct ttm_buffer_object *bo); 2358af8a109SChristian König 2368af8a109SChristian König /** 2378af8a109SChristian König * Notify the driver that we're about to release a BO 2388af8a109SChristian König * 2398af8a109SChristian König * @bo: BO that is about to be released 2408af8a109SChristian König * 2418af8a109SChristian König * Gives the driver a chance to do any cleanup, including 2428af8a109SChristian König * adding fences that may force a delayed delete 2438af8a109SChristian König */ 2448af8a109SChristian König void (*release_notify)(struct ttm_buffer_object *bo); 2458af8a109SChristian König }; 2468af8a109SChristian König 2478af8a109SChristian König /** 2488af8a109SChristian König * struct ttm_device - Buffer object driver device-specific data. 2498af8a109SChristian König * 2508af8a109SChristian König * @device_list: Our entry in the global device list. 2518af8a109SChristian König * @funcs: Function table for the device. 2528af8a109SChristian König * @sysman: Resource manager for the system domain. 2538af8a109SChristian König * @man_drv: An array of resource_managers. 2548af8a109SChristian König * @vma_manager: Address space manager. 2558af8a109SChristian König * @pool: page pool for the device. 2568af8a109SChristian König * @dev_mapping: A pointer to the struct address_space representing the 2578af8a109SChristian König * device address space. 2588af8a109SChristian König * @wq: Work queue structure for the delayed delete workqueue. 2598af8a109SChristian König */ 2608af8a109SChristian König struct ttm_device { 2618af8a109SChristian König /* 2628af8a109SChristian König * Constant after bo device init 2638af8a109SChristian König */ 2648af8a109SChristian König struct list_head device_list; 2658af8a109SChristian König struct ttm_device_funcs *funcs; 2668af8a109SChristian König 2678af8a109SChristian König /* 2688af8a109SChristian König * Access via ttm_manager_type. 2698af8a109SChristian König */ 2708af8a109SChristian König struct ttm_resource_manager sysman; 2718af8a109SChristian König struct ttm_resource_manager *man_drv[TTM_NUM_MEM_TYPES]; 2728af8a109SChristian König 2738af8a109SChristian König /* 2748af8a109SChristian König * Protected by internal locks. 2758af8a109SChristian König */ 2768af8a109SChristian König struct drm_vma_offset_manager *vma_manager; 2778af8a109SChristian König struct ttm_pool pool; 2788af8a109SChristian König 2798af8a109SChristian König /* 2808af8a109SChristian König * Protected by the global:lru lock. 2818af8a109SChristian König */ 2828af8a109SChristian König struct list_head ddestroy; 2838af8a109SChristian König 2848af8a109SChristian König /* 2858af8a109SChristian König * Protected by load / firstopen / lastclose /unload sync. 2868af8a109SChristian König */ 2878af8a109SChristian König struct address_space *dev_mapping; 2888af8a109SChristian König 2898af8a109SChristian König /* 2908af8a109SChristian König * Internal protection. 2918af8a109SChristian König */ 2928af8a109SChristian König struct delayed_work wq; 2938af8a109SChristian König }; 2948af8a109SChristian König 295ebd59851SChristian König int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags); 296*f9e2a03eSChristian König int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx, 297*f9e2a03eSChristian König gfp_t gfp_flags); 298ebd59851SChristian König 2998af8a109SChristian König static inline struct ttm_resource_manager * 3008af8a109SChristian König ttm_manager_type(struct ttm_device *bdev, int mem_type) 3018af8a109SChristian König { 3028af8a109SChristian König return bdev->man_drv[mem_type]; 3038af8a109SChristian König } 3048af8a109SChristian König 3058af8a109SChristian König static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type, 3068af8a109SChristian König struct ttm_resource_manager *manager) 3078af8a109SChristian König { 3088af8a109SChristian König bdev->man_drv[type] = manager; 3098af8a109SChristian König } 3108af8a109SChristian König 3118af8a109SChristian König int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs, 3128af8a109SChristian König struct device *dev, struct address_space *mapping, 3138af8a109SChristian König struct drm_vma_offset_manager *vma_manager, 3148af8a109SChristian König bool use_dma_alloc, bool use_dma32); 3158af8a109SChristian König void ttm_device_fini(struct ttm_device *bdev); 3168af8a109SChristian König 3178af8a109SChristian König #endif 318