1 | /* SPDX-License-Identifier: MIT */ |
2 | /* |
3 | * Copyright 2023 Advanced Micro Devices, Inc. |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * copy of this software and associated documentation files (the "Software"), |
7 | * to deal in the Software without restriction, including without limitation |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
9 | * and/or sell copies of the Software, and to permit persons to whom the |
10 | * Software is furnished to do so, subject to the following conditions: |
11 | * |
12 | * The above copyright notice and this permission notice shall be included in |
13 | * all copies or substantial portions of the Software. |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * |
23 | */ |
24 | |
25 | #ifndef __UMSCH_MM_API_DEF_H__ |
26 | #define __UMSCH_MM_API_DEF_H__ |
27 | |
28 | #pragma once |
29 | |
30 | #pragma pack(push, 4) |
31 | |
32 | #define UMSCH_API_VERSION 1 |
33 | |
34 | /* |
35 | * Driver submits one API(cmd) as a single Frame and this command size is same for all API |
36 | * to ease the debugging and parsing of ring buffer. |
37 | */ |
38 | enum { API_FRAME_SIZE_IN_DWORDS = 64 }; |
39 | |
40 | /* |
41 | * To avoid command in scheduler context to be overwritten whenever multiple interrupts come in, |
42 | * this creates another queue. |
43 | */ |
44 | enum { API_NUMBER_OF_COMMAND_MAX = 32 }; |
45 | |
46 | enum { UMSCH_INSTANCE_DB_OFFSET_MAX = 16 }; |
47 | |
48 | enum UMSCH_API_TYPE { |
49 | UMSCH_API_TYPE_SCHEDULER = 1, |
50 | UMSCH_API_TYPE_MAX |
51 | }; |
52 | |
53 | enum UMSCH_MS_LOG_CONTEXT_STATE { |
54 | UMSCH_LOG_CONTEXT_STATE_IDLE = 0, |
55 | UMSCH_LOG_CONTEXT_STATE_RUNNING = 1, |
56 | UMSCH_LOG_CONTEXT_STATE_READY = 2, |
57 | UMSCH_LOG_CONTEXT_STATE_READY_STANDBY = 3, |
58 | UMSCH_LOG_CONTEXT_STATE_INVALID = 0xF, |
59 | }; |
60 | |
61 | enum UMSCH_MS_LOG_OPERATION { |
62 | UMSCH_LOG_OPERATION_CONTEXT_STATE_CHANGE = 0, |
63 | UMSCH_LOG_OPERATION_QUEUE_NEW_WORK = 1, |
64 | UMSCH_LOG_OPERATION_QUEUE_UNWAIT_SYNC_OBJECT = 2, |
65 | UMSCH_LOG_OPERATION_QUEUE_NO_MORE_WORK = 3, |
66 | UMSCH_LOG_OPERATION_QUEUE_WAIT_SYNC_OBJECT = 4, |
67 | UMSCH_LOG_OPERATION_QUEUE_INVALID = 0xF, |
68 | }; |
69 | |
70 | struct UMSCH_INSTANCE_DB_OFFSET { |
71 | uint32_t instance_index; |
72 | uint32_t doorbell_offset; |
73 | }; |
74 | |
75 | struct UMSCH_LOG_CONTEXT_STATE_CHANGE { |
76 | uint64_t h_context; |
77 | enum UMSCH_MS_LOG_CONTEXT_STATE new_context_state; |
78 | }; |
79 | |
80 | struct UMSCH_LOG_QUEUE_NEW_WORK { |
81 | uint64_t h_queue; |
82 | uint64_t reserved; |
83 | }; |
84 | |
85 | struct UMSCH_LOG_QUEUE_UNWAIT_SYNC_OBJECT { |
86 | uint64_t h_queue; |
87 | uint64_t h_sync_object; |
88 | }; |
89 | |
90 | struct UMSCH_LOG_QUEUE_NO_MORE_WORK { |
91 | uint64_t h_queue; |
92 | uint64_t reserved; |
93 | }; |
94 | |
95 | struct UMSCH_LOG_QUEUE_WAIT_SYNC_OBJECT { |
96 | uint64_t h_queue; |
97 | uint64_t h_sync_object; |
98 | }; |
99 | |
100 | struct { |
101 | uint32_t ; |
102 | uint32_t ; |
103 | uint64_t ; |
104 | uint64_t [2]; |
105 | }; |
106 | |
107 | struct UMSCH_LOG_ENTRY_DATA { |
108 | uint64_t gpu_time_stamp; |
109 | uint32_t operation_type; /* operation_type is of UMSCH_LOG_OPERATION type */ |
110 | uint32_t reserved_operation_type_bits; |
111 | union { |
112 | struct UMSCH_LOG_CONTEXT_STATE_CHANGE context_state_change; |
113 | struct UMSCH_LOG_QUEUE_NEW_WORK queue_new_work; |
114 | struct UMSCH_LOG_QUEUE_UNWAIT_SYNC_OBJECT queue_unwait_sync_object; |
115 | struct UMSCH_LOG_QUEUE_NO_MORE_WORK queue_no_more_work; |
116 | struct UMSCH_LOG_QUEUE_WAIT_SYNC_OBJECT queue_wait_sync_object; |
117 | uint64_t all[2]; |
118 | }; |
119 | }; |
120 | |
121 | struct UMSCH_LOG_BUFFER { |
122 | struct UMSCH_LOG_ENTRY_HEADER ; |
123 | struct UMSCH_LOG_ENTRY_DATA entries[1]; |
124 | }; |
125 | |
126 | enum UMSCH_API_OPCODE { |
127 | UMSCH_API_SET_HW_RSRC = 0x00, |
128 | UMSCH_API_SET_SCHEDULING_CONFIG = 0x1, |
129 | UMSCH_API_ADD_QUEUE = 0x2, |
130 | UMSCH_API_REMOVE_QUEUE = 0x3, |
131 | UMSCH_API_PERFORM_YIELD = 0x4, |
132 | UMSCH_API_SUSPEND = 0x5, |
133 | UMSCH_API_RESUME = 0x6, |
134 | UMSCH_API_RESET = 0x7, |
135 | UMSCH_API_SET_LOG_BUFFER = 0x8, |
136 | UMSCH_API_CHANGE_CONTEXT_PRIORITY = 0x9, |
137 | UMSCH_API_QUERY_SCHEDULER_STATUS = 0xA, |
138 | UMSCH_API_UPDATE_AFFINITY = 0xB, |
139 | UMSCH_API_MAX = 0xFF |
140 | }; |
141 | |
142 | union { |
143 | struct { |
144 | uint32_t : 4; /* 0 - Invalid; 1 - Scheduling; 2 - TBD */ |
145 | uint32_t : 8; |
146 | uint32_t : 8; |
147 | uint32_t : 12; |
148 | }; |
149 | |
150 | uint32_t ; |
151 | }; |
152 | |
153 | enum UMSCH_AMD_PRIORITY_LEVEL { |
154 | AMD_PRIORITY_LEVEL_IDLE = 0, |
155 | AMD_PRIORITY_LEVEL_NORMAL = 1, |
156 | AMD_PRIORITY_LEVEL_FOCUS = 2, |
157 | AMD_PRIORITY_LEVEL_REALTIME = 3, |
158 | AMD_PRIORITY_NUM_LEVELS |
159 | }; |
160 | |
161 | enum UMSCH_ENGINE_TYPE { |
162 | UMSCH_ENGINE_TYPE_VCN0 = 0, |
163 | UMSCH_ENGINE_TYPE_VCN1 = 1, |
164 | UMSCH_ENGINE_TYPE_VCN = 2, |
165 | UMSCH_ENGINE_TYPE_VPE = 3, |
166 | UMSCH_ENGINE_TYPE_MAX |
167 | }; |
168 | |
169 | #define AFFINITY_DISABLE 0 |
170 | #define AFFINITY_ENABLE 1 |
171 | #define AFFINITY_MAX 2 |
172 | |
173 | union UMSCH_AFFINITY { |
174 | struct { |
175 | unsigned int vcn0Affinity : 2; /* enable 1 disable 0 */ |
176 | unsigned int vcn1Affinity : 2; |
177 | unsigned int reserved : 28; |
178 | }; |
179 | unsigned int u32All; |
180 | }; |
181 | |
182 | struct UMSCH_API_STATUS { |
183 | uint64_t api_completion_fence_addr; |
184 | uint32_t api_completion_fence_value; |
185 | }; |
186 | |
187 | enum { MAX_VCN0_INSTANCES = 1 }; |
188 | enum { MAX_VCN1_INSTANCES = 1 }; |
189 | enum { MAX_VCN_INSTANCES = 2 }; |
190 | |
191 | enum { MAX_VPE_INSTANCES = 1 }; |
192 | |
193 | enum { MAX_VCN_QUEUES = 4 }; |
194 | enum { MAX_VPE_QUEUES = 8 }; |
195 | |
196 | enum { MAX_QUEUES_IN_A_CONTEXT = 1 }; |
197 | |
198 | enum { UMSCH_MAX_HWIP_SEGMENT = 8 }; |
199 | |
200 | enum VM_HUB_TYPE { |
201 | VM_HUB_TYPE_GC = 0, |
202 | VM_HUB_TYPE_MM = 1, |
203 | VM_HUB_TYPE_MAX, |
204 | }; |
205 | |
206 | enum { VMID_INVALID = 0xffff }; |
207 | |
208 | enum { MAX_VMID_MMHUB = 16 }; |
209 | |
210 | union UMSCHAPI__SET_HW_RESOURCES { |
211 | struct { |
212 | union UMSCH_API_HEADER ; |
213 | uint32_t vmid_mask_mm_vcn; |
214 | uint32_t vmid_mask_mm_vpe; |
215 | uint32_t collaboration_mask_vpe; |
216 | uint32_t engine_mask; |
217 | uint32_t logging_vmid; |
218 | uint32_t vcn0_hqd_mask[MAX_VCN0_INSTANCES]; |
219 | uint32_t vcn1_hqd_mask[MAX_VCN1_INSTANCES]; |
220 | uint32_t vcn_hqd_mask[MAX_VCN_INSTANCES]; |
221 | uint32_t vpe_hqd_mask[MAX_VPE_INSTANCES]; |
222 | uint64_t g_sch_ctx_gpu_mc_ptr; |
223 | uint32_t mmhub_base[UMSCH_MAX_HWIP_SEGMENT]; |
224 | uint32_t mmhub_version; |
225 | uint32_t osssys_base[UMSCH_MAX_HWIP_SEGMENT]; |
226 | uint32_t osssys_version; |
227 | uint32_t vcn_version; |
228 | uint32_t vpe_version; |
229 | struct UMSCH_API_STATUS api_status; |
230 | union { |
231 | struct { |
232 | uint32_t disable_reset : 1; |
233 | uint32_t disable_umsch_log : 1; |
234 | uint32_t enable_level_process_quantum_check : 1; |
235 | uint32_t is_vcn0_enabled : 1; |
236 | uint32_t is_vcn1_enabled : 1; |
237 | uint32_t use_rs64mem_for_proc_ctx_csa : 1; |
238 | uint32_t reserved : 26; |
239 | }; |
240 | uint32_t uint32_all; |
241 | }; |
242 | }; |
243 | |
244 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
245 | }; |
246 | static_assert(sizeof(union UMSCHAPI__SET_HW_RESOURCES) <= API_FRAME_SIZE_IN_DWORDS * sizeof(uint32_t), |
247 | "size of UMSCHAPI__SET_HW_RESOURCES must be less than 256 bytes" ); |
248 | |
249 | union UMSCHAPI__SET_SCHEDULING_CONFIG { |
250 | struct { |
251 | union UMSCH_API_HEADER ; |
252 | /* |
253 | * Grace period when preempting another priority band for this priority band. |
254 | * The value for idle priority band is ignored, as it never preempts other bands. |
255 | */ |
256 | uint64_t grace_period_other_levels[AMD_PRIORITY_NUM_LEVELS]; |
257 | |
258 | /* Default quantum for scheduling across processes within a priority band. */ |
259 | uint64_t process_quantum_for_level[AMD_PRIORITY_NUM_LEVELS]; |
260 | |
261 | /* Default grace period for processes that preempt each other within a priority band. */ |
262 | uint64_t process_grace_period_same_level[AMD_PRIORITY_NUM_LEVELS]; |
263 | |
264 | /* |
265 | * For normal level this field specifies the target GPU percentage in situations |
266 | * when it's starved by the high level. Valid values are between 0 and 50, |
267 | * with the default being 10. |
268 | */ |
269 | uint32_t normal_yield_percent; |
270 | |
271 | struct UMSCH_API_STATUS api_status; |
272 | }; |
273 | |
274 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
275 | }; |
276 | |
277 | union UMSCHAPI__ADD_QUEUE { |
278 | struct { |
279 | union UMSCH_API_HEADER ; |
280 | uint32_t process_id; |
281 | uint64_t page_table_base_addr; |
282 | uint64_t process_va_start; |
283 | uint64_t process_va_end; |
284 | uint64_t process_quantum; |
285 | uint64_t process_csa_addr; |
286 | uint64_t context_quantum; |
287 | uint64_t context_csa_addr; |
288 | uint32_t inprocess_context_priority; |
289 | enum UMSCH_AMD_PRIORITY_LEVEL context_global_priority_level; |
290 | uint32_t doorbell_offset_0; |
291 | uint32_t doorbell_offset_1; |
292 | union UMSCH_AFFINITY affinity; |
293 | uint64_t mqd_addr; |
294 | uint64_t h_context; |
295 | uint64_t h_queue; |
296 | enum UMSCH_ENGINE_TYPE engine_type; |
297 | uint32_t vm_context_cntl; |
298 | |
299 | struct { |
300 | uint32_t is_context_suspended : 1; |
301 | uint32_t collaboration_mode : 1; |
302 | uint32_t reserved : 30; |
303 | }; |
304 | struct UMSCH_API_STATUS api_status; |
305 | uint32_t process_csa_array_index; |
306 | uint32_t context_csa_array_index; |
307 | }; |
308 | |
309 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
310 | }; |
311 | |
312 | |
313 | union UMSCHAPI__REMOVE_QUEUE { |
314 | struct { |
315 | union UMSCH_API_HEADER ; |
316 | uint32_t doorbell_offset_0; |
317 | uint32_t doorbell_offset_1; |
318 | uint64_t context_csa_addr; |
319 | |
320 | struct UMSCH_API_STATUS api_status; |
321 | uint32_t context_csa_array_index; |
322 | }; |
323 | |
324 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
325 | }; |
326 | |
327 | union UMSCHAPI__PERFORM_YIELD { |
328 | struct { |
329 | union UMSCH_API_HEADER ; |
330 | uint32_t dummy; |
331 | struct UMSCH_API_STATUS api_status; |
332 | }; |
333 | |
334 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
335 | }; |
336 | |
337 | union UMSCHAPI__SUSPEND { |
338 | struct { |
339 | union UMSCH_API_HEADER ; |
340 | uint64_t context_csa_addr; |
341 | uint64_t suspend_fence_addr; |
342 | uint32_t suspend_fence_value; |
343 | |
344 | struct UMSCH_API_STATUS api_status; |
345 | uint32_t context_csa_array_index; |
346 | }; |
347 | |
348 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
349 | }; |
350 | |
351 | enum UMSCH_RESUME_OPTION { |
352 | CONTEXT_RESUME = 0, |
353 | ENGINE_SCHEDULE_RESUME = 1, |
354 | }; |
355 | |
356 | union UMSCHAPI__RESUME { |
357 | struct { |
358 | union UMSCH_API_HEADER ; |
359 | |
360 | enum UMSCH_RESUME_OPTION resume_option; |
361 | uint64_t context_csa_addr; /* valid only for UMSCH_SWIP_CONTEXT_RESUME */ |
362 | enum UMSCH_ENGINE_TYPE engine_type; |
363 | |
364 | struct UMSCH_API_STATUS api_status; |
365 | uint32_t context_csa_array_index; |
366 | }; |
367 | |
368 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
369 | }; |
370 | |
371 | enum UMSCH_RESET_OPTION { |
372 | HANG_DETECT_AND_RESET = 0, |
373 | HANG_DETECT_ONLY = 1, |
374 | }; |
375 | |
376 | union UMSCHAPI__RESET { |
377 | struct { |
378 | union UMSCH_API_HEADER ; |
379 | |
380 | enum UMSCH_RESET_OPTION reset_option; |
381 | uint64_t doorbell_offset_addr; |
382 | enum UMSCH_ENGINE_TYPE engine_type; |
383 | |
384 | struct UMSCH_API_STATUS api_status; |
385 | }; |
386 | |
387 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
388 | }; |
389 | |
390 | union UMSCHAPI__SET_LOGGING_BUFFER { |
391 | struct { |
392 | union UMSCH_API_HEADER ; |
393 | /* There are separate log buffers for each queue type */ |
394 | enum UMSCH_ENGINE_TYPE log_type; |
395 | /* Log buffer GPU Address */ |
396 | uint64_t logging_buffer_addr; |
397 | /* Number of entries in the log buffer */ |
398 | uint32_t number_of_entries; |
399 | /* Entry index at which CPU interrupt needs to be signalled */ |
400 | uint32_t interrupt_entry; |
401 | |
402 | struct UMSCH_API_STATUS api_status; |
403 | }; |
404 | |
405 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
406 | }; |
407 | |
408 | union UMSCHAPI__UPDATE_AFFINITY { |
409 | struct { |
410 | union UMSCH_API_HEADER ; |
411 | union UMSCH_AFFINITY affinity; |
412 | uint64_t context_csa_addr; |
413 | struct UMSCH_API_STATUS api_status; |
414 | uint32_t context_csa_array_index; |
415 | }; |
416 | |
417 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
418 | }; |
419 | |
420 | union UMSCHAPI__CHANGE_CONTEXT_PRIORITY_LEVEL { |
421 | struct { |
422 | union UMSCH_API_HEADER ; |
423 | uint32_t inprocess_context_priority; |
424 | enum UMSCH_AMD_PRIORITY_LEVEL context_global_priority_level; |
425 | uint64_t context_quantum; |
426 | uint64_t context_csa_addr; |
427 | struct UMSCH_API_STATUS api_status; |
428 | uint32_t context_csa_array_index; |
429 | }; |
430 | |
431 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
432 | }; |
433 | |
434 | union UMSCHAPI__QUERY_UMSCH_STATUS { |
435 | struct { |
436 | union UMSCH_API_HEADER ; |
437 | bool umsch_mm_healthy; /* 0 - not healthy, 1 - healthy */ |
438 | struct UMSCH_API_STATUS api_status; |
439 | }; |
440 | |
441 | uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; |
442 | }; |
443 | |
444 | #pragma pack(pop) |
445 | |
446 | #endif |
447 | |