1
2
3
4
5
6#include "gt/intel_gt.h"
7#include "gt/intel_lrc.h"
8#include "intel_guc_ads.h"
9#include "intel_uc.h"
10#include "i915_drv.h"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37struct __guc_ads_blob {
38 struct guc_ads ads;
39 struct guc_policies policies;
40 struct guc_gt_system_info system_info;
41 struct guc_clients_info clients_info;
42 struct guc_ct_pool_entry ct_pool[GUC_CT_POOL_SIZE];
43} __packed;
44
45static u32 guc_ads_private_data_size(struct intel_guc *guc)
46{
47 return PAGE_ALIGN(guc->fw.private_data_size);
48}
49
50static u32 guc_ads_private_data_offset(struct intel_guc *guc)
51{
52 return PAGE_ALIGN(sizeof(struct __guc_ads_blob));
53}
54
55static u32 guc_ads_blob_size(struct intel_guc *guc)
56{
57 return guc_ads_private_data_offset(guc) +
58 guc_ads_private_data_size(guc);
59}
60
61static void guc_policy_init(struct guc_policy *policy)
62{
63 policy->execution_quantum = POLICY_DEFAULT_EXECUTION_QUANTUM_US;
64 policy->preemption_time = POLICY_DEFAULT_PREEMPTION_TIME_US;
65 policy->fault_time = POLICY_DEFAULT_FAULT_TIME_US;
66 policy->policy_flags = 0;
67}
68
69static void guc_policies_init(struct guc_policies *policies)
70{
71 struct guc_policy *policy;
72 u32 p, i;
73
74 policies->dpc_promote_time = POLICY_DEFAULT_DPC_PROMOTE_TIME_US;
75 policies->max_num_work_items = POLICY_MAX_NUM_WI;
76
77 for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) {
78 for (i = 0; i < GUC_MAX_ENGINE_CLASSES; i++) {
79 policy = &policies->policy[p][i];
80
81 guc_policy_init(policy);
82 }
83 }
84
85 policies->is_valid = 1;
86}
87
88static void guc_ct_pool_entries_init(struct guc_ct_pool_entry *pool, u32 num)
89{
90 memset(pool, 0, num * sizeof(*pool));
91}
92
93static void guc_mapping_table_init(struct intel_gt *gt,
94 struct guc_gt_system_info *system_info)
95{
96 unsigned int i, j;
97 struct intel_engine_cs *engine;
98 enum intel_engine_id id;
99
100
101 for (i = 0; i < GUC_MAX_ENGINE_CLASSES; ++i)
102 for (j = 0; j < GUC_MAX_INSTANCES_PER_CLASS; ++j)
103 system_info->mapping_table[i][j] =
104 GUC_MAX_INSTANCES_PER_CLASS;
105
106 for_each_engine(engine, gt, id) {
107 u8 guc_class = engine->class;
108
109 system_info->mapping_table[guc_class][engine->instance] =
110 engine->instance;
111 }
112}
113
114
115
116
117
118#define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
119
120static void __guc_ads_init(struct intel_guc *guc)
121{
122 struct intel_gt *gt = guc_to_gt(guc);
123 struct drm_i915_private *i915 = gt->i915;
124 struct __guc_ads_blob *blob = guc->ads_blob;
125 const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE;
126 u32 base;
127 u8 engine_class;
128
129
130 guc_policies_init(&blob->policies);
131
132
133
134
135
136
137
138
139
140 for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; ++engine_class) {
141 if (engine_class == OTHER_CLASS)
142 continue;
143
144
145
146
147 blob->ads.golden_context_lrca[engine_class] = 0;
148 blob->ads.eng_state_size[engine_class] =
149 intel_engine_context_size(guc_to_gt(guc),
150 engine_class) -
151 skipped_size;
152 }
153
154
155 blob->system_info.engine_enabled_masks[RENDER_CLASS] = 1;
156 blob->system_info.engine_enabled_masks[COPY_ENGINE_CLASS] = 1;
157 blob->system_info.engine_enabled_masks[VIDEO_DECODE_CLASS] = VDBOX_MASK(gt);
158 blob->system_info.engine_enabled_masks[VIDEO_ENHANCEMENT_CLASS] = VEBOX_MASK(gt);
159
160 blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
161 hweight8(gt->info.sseu.slice_mask);
162 blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK] =
163 gt->info.vdbox_sfc_access;
164
165 if (INTEL_GEN(i915) >= 12 && !IS_DGFX(i915)) {
166 u32 distdbreg = intel_uncore_read(gt->uncore,
167 GEN12_DIST_DBS_POPULATED);
168 blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI] =
169 ((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) &
170 GEN12_DOORBELLS_PER_SQIDI) + 1;
171 }
172
173 guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
174
175 base = intel_guc_ggtt_offset(guc, guc->ads_vma);
176
177
178 guc_ct_pool_entries_init(blob->ct_pool, ARRAY_SIZE(blob->ct_pool));
179
180 blob->clients_info.clients_num = 1;
181 blob->clients_info.ct_pool_addr = base + ptr_offset(blob, ct_pool);
182 blob->clients_info.ct_pool_count = ARRAY_SIZE(blob->ct_pool);
183
184
185 blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
186 blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
187 blob->ads.clients_info = base + ptr_offset(blob, clients_info);
188
189
190 blob->ads.private_data = base + guc_ads_private_data_offset(guc);
191
192 i915_gem_object_flush_map(guc->ads_vma->obj);
193}
194
195
196
197
198
199
200
201
202int intel_guc_ads_create(struct intel_guc *guc)
203{
204 u32 size;
205 int ret;
206
207 GEM_BUG_ON(guc->ads_vma);
208
209 size = guc_ads_blob_size(guc);
210
211 ret = intel_guc_allocate_and_map_vma(guc, size, &guc->ads_vma,
212 (void **)&guc->ads_blob);
213 if (ret)
214 return ret;
215
216 __guc_ads_init(guc);
217
218 return 0;
219}
220
221void intel_guc_ads_destroy(struct intel_guc *guc)
222{
223 i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
224 guc->ads_blob = NULL;
225}
226
227static void guc_ads_private_data_reset(struct intel_guc *guc)
228{
229 u32 size;
230
231 size = guc_ads_private_data_size(guc);
232 if (!size)
233 return;
234
235 memset((void *)guc->ads_blob + guc_ads_private_data_offset(guc), 0,
236 size);
237}
238
239
240
241
242
243
244
245
246
247void intel_guc_ads_reset(struct intel_guc *guc)
248{
249 if (!guc->ads_vma)
250 return;
251
252 __guc_ads_init(guc);
253
254 guc_ads_private_data_reset(guc);
255}
256