1 // SPDX-License-Identifier: MIT 2 /* Copyright © 2025 Intel Corporation */ 3 4 #include <drm/intel/display_parent_interface.h> 5 6 #include "xe_res_cursor.h" 7 #include "xe_stolen.h" 8 #include "xe_ttm_stolen_mgr.h" 9 #include "xe_validation.h" 10 11 struct intel_stolen_node { 12 struct xe_device *xe; 13 struct xe_bo *bo; 14 }; 15 16 static int xe_stolen_insert_node_in_range(struct intel_stolen_node *node, u64 size, 17 unsigned int align, u64 start, u64 end) 18 { 19 struct xe_device *xe = node->xe; 20 21 struct xe_bo *bo; 22 int err = 0; 23 u32 flags = XE_BO_FLAG_PINNED | XE_BO_FLAG_STOLEN; 24 25 if (start < SZ_4K) 26 start = SZ_4K; 27 28 if (align) { 29 size = ALIGN(size, align); 30 start = ALIGN(start, align); 31 } 32 33 bo = xe_bo_create_pin_range_novm(xe, xe_device_get_root_tile(xe), 34 size, start, end, ttm_bo_type_kernel, flags); 35 if (IS_ERR(bo)) { 36 err = PTR_ERR(bo); 37 bo = NULL; 38 return err; 39 } 40 41 node->bo = bo; 42 43 return err; 44 } 45 46 static void xe_stolen_remove_node(struct intel_stolen_node *node) 47 { 48 xe_bo_unpin_map_no_vm(node->bo); 49 node->bo = NULL; 50 } 51 52 static bool xe_stolen_initialized(struct drm_device *drm) 53 { 54 struct xe_device *xe = to_xe_device(drm); 55 56 return ttm_manager_type(&xe->ttm, XE_PL_STOLEN); 57 } 58 59 static bool xe_stolen_node_allocated(const struct intel_stolen_node *node) 60 { 61 return node->bo; 62 } 63 64 static u64 xe_stolen_node_offset(const struct intel_stolen_node *node) 65 { 66 struct xe_res_cursor res; 67 68 xe_res_first(node->bo->ttm.resource, 0, 4096, &res); 69 return res.start; 70 } 71 72 static u64 xe_stolen_node_address(const struct intel_stolen_node *node) 73 { 74 struct xe_device *xe = node->xe; 75 76 return xe_ttm_stolen_gpu_offset(xe) + xe_stolen_node_offset(node); 77 } 78 79 static u64 xe_stolen_node_size(const struct intel_stolen_node *node) 80 { 81 return xe_bo_size(node->bo); 82 } 83 84 static struct intel_stolen_node *xe_stolen_node_alloc(struct drm_device *drm) 85 { 86 struct xe_device *xe = to_xe_device(drm); 87 struct intel_stolen_node *node; 88 89 node = kzalloc_obj(*node); 90 if (!node) 91 return NULL; 92 93 node->xe = xe; 94 95 return node; 96 } 97 98 static void xe_stolen_node_free(const struct intel_stolen_node *node) 99 { 100 kfree(node); 101 } 102 103 const struct intel_display_stolen_interface xe_display_stolen_interface = { 104 .insert_node_in_range = xe_stolen_insert_node_in_range, 105 .remove_node = xe_stolen_remove_node, 106 .initialized = xe_stolen_initialized, 107 .node_allocated = xe_stolen_node_allocated, 108 .node_offset = xe_stolen_node_offset, 109 .node_address = xe_stolen_node_address, 110 .node_size = xe_stolen_node_size, 111 .node_alloc = xe_stolen_node_alloc, 112 .node_free = xe_stolen_node_free, 113 }; 114