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
xe_stolen_insert_node_in_range(struct intel_stolen_node * node,u64 size,unsigned int align,u64 start,u64 end)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
xe_stolen_remove_node(struct intel_stolen_node * node)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
xe_stolen_initialized(struct drm_device * drm)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
xe_stolen_node_allocated(const struct intel_stolen_node * node)59 static bool xe_stolen_node_allocated(const struct intel_stolen_node *node)
60 {
61 return node->bo;
62 }
63
xe_stolen_node_offset(const struct intel_stolen_node * node)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
xe_stolen_node_address(const struct intel_stolen_node * node)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
xe_stolen_node_size(const struct intel_stolen_node * node)79 static u64 xe_stolen_node_size(const struct intel_stolen_node *node)
80 {
81 return xe_bo_size(node->bo);
82 }
83
xe_stolen_node_alloc(struct drm_device * drm)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
xe_stolen_node_free(const struct intel_stolen_node * node)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