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 */ 38enum { 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 */ 44enum { API_NUMBER_OF_COMMAND_MAX = 32 }; 45 46enum { UMSCH_INSTANCE_DB_OFFSET_MAX = 16 }; 47 48enum UMSCH_API_TYPE { 49 UMSCH_API_TYPE_SCHEDULER = 1, 50 UMSCH_API_TYPE_MAX 51}; 52 53enum 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 61enum 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 70struct UMSCH_INSTANCE_DB_OFFSET { 71 uint32_t instance_index; 72 uint32_t doorbell_offset; 73}; 74 75struct UMSCH_LOG_CONTEXT_STATE_CHANGE { 76 uint64_t h_context; 77 enum UMSCH_MS_LOG_CONTEXT_STATE new_context_state; 78}; 79 80struct UMSCH_LOG_QUEUE_NEW_WORK { 81 uint64_t h_queue; 82 uint64_t reserved; 83}; 84 85struct UMSCH_LOG_QUEUE_UNWAIT_SYNC_OBJECT { 86 uint64_t h_queue; 87 uint64_t h_sync_object; 88}; 89 90struct UMSCH_LOG_QUEUE_NO_MORE_WORK { 91 uint64_t h_queue; 92 uint64_t reserved; 93}; 94 95struct UMSCH_LOG_QUEUE_WAIT_SYNC_OBJECT { 96 uint64_t h_queue; 97 uint64_t h_sync_object; 98}; 99 100struct 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 107struct 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 121struct UMSCH_LOG_BUFFER { 122 struct UMSCH_LOG_ENTRY_HEADER header; 123 struct UMSCH_LOG_ENTRY_DATA entries[1]; 124}; 125 126enum 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 142union 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 153enum 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 161enum 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 173union 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 182struct UMSCH_API_STATUS { 183 uint64_t api_completion_fence_addr; 184 uint32_t api_completion_fence_value; 185}; 186 187enum { MAX_VCN0_INSTANCES = 1 }; 188enum { MAX_VCN1_INSTANCES = 1 }; 189enum { MAX_VCN_INSTANCES = 2 }; 190 191enum { MAX_VPE_INSTANCES = 1 }; 192 193enum { MAX_VCN_QUEUES = 4 }; 194enum { MAX_VPE_QUEUES = 8 }; 195 196enum { MAX_QUEUES_IN_A_CONTEXT = 1 }; 197 198enum { UMSCH_MAX_HWIP_SEGMENT = 8 }; 199 200enum VM_HUB_TYPE { 201 VM_HUB_TYPE_GC = 0, 202 VM_HUB_TYPE_MM = 1, 203 VM_HUB_TYPE_MAX, 204}; 205 206enum { VMID_INVALID = 0xffff }; 207 208enum { MAX_VMID_MMHUB = 16 }; 209 210union 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}; 246static_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 249union 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 277union 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 313union 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 327union 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 337union 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 351enum UMSCH_RESUME_OPTION { 352 CONTEXT_RESUME = 0, 353 ENGINE_SCHEDULE_RESUME = 1, 354}; 355 356union 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 371enum UMSCH_RESET_OPTION { 372 HANG_DETECT_AND_RESET = 0, 373 HANG_DETECT_ONLY = 1, 374}; 375 376union 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 390union 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 408union 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 420union 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 434union 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