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 UMSCH_LOG_ENTRY_HEADER { 101 uint32_t first_free_entry_index; 102 uint32_t wraparound_count; 103 uint64_t number_of_entries; 104 uint64_t reserved[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 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 UMSCH_API_HEADER { 143 struct { 144 uint32_t type : 4; /* 0 - Invalid; 1 - Scheduling; 2 - TBD */ 145 uint32_t opcode : 8; 146 uint32_t dwsize : 8; 147 uint32_t reserved : 12; 148 }; 149 150 uint32_t u32All; 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 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 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 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 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 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 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 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 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 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 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 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 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