xref: /linux/drivers/gpu/drm/xe/display/xe_stolen.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
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