1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24 #ifndef __MES_API_DEF_H__ 25 #define __MES_API_DEF_H__ 26 27 #pragma pack(push, 4) 28 29 #define MES_API_VERSION 1 30 31 /* Driver submits one API(cmd) as a single Frame and this command size is same 32 * for all API to ease the debugging and parsing of ring buffer. 33 */ 34 enum { API_FRAME_SIZE_IN_DWORDS = 64 }; 35 36 /* To avoid command in scheduler context to be overwritten whenenver mutilple 37 * interrupts come in, this creates another queue. 38 */ 39 enum { API_NUMBER_OF_COMMAND_MAX = 32 }; 40 41 enum MES_API_TYPE { 42 MES_API_TYPE_SCHEDULER = 1, 43 MES_API_TYPE_MAX 44 }; 45 46 enum MES_SCH_API_OPCODE { 47 MES_SCH_API_SET_HW_RSRC = 0, 48 MES_SCH_API_SET_SCHEDULING_CONFIG = 1, /* agreegated db, quantums, etc */ 49 MES_SCH_API_ADD_QUEUE = 2, 50 MES_SCH_API_REMOVE_QUEUE = 3, 51 MES_SCH_API_PERFORM_YIELD = 4, 52 MES_SCH_API_SET_GANG_PRIORITY_LEVEL = 5, 53 MES_SCH_API_SUSPEND = 6, 54 MES_SCH_API_RESUME = 7, 55 MES_SCH_API_RESET = 8, 56 MES_SCH_API_SET_LOG_BUFFER = 9, 57 MES_SCH_API_CHANGE_GANG_PRORITY = 10, 58 MES_SCH_API_QUERY_SCHEDULER_STATUS = 11, 59 MES_SCH_API_PROGRAM_GDS = 12, 60 MES_SCH_API_SET_DEBUG_VMID = 13, 61 MES_SCH_API_MISC = 14, 62 MES_SCH_API_MAX = 0xFF 63 }; 64 65 union MES_API_HEADER { 66 struct { 67 uint32_t type : 4; /* 0 - Invalid; 1 - Scheduling; 2 - TBD */ 68 uint32_t opcode : 8; 69 uint32_t dwsize : 8; /* including header */ 70 uint32_t reserved : 12; 71 }; 72 73 uint32_t u32All; 74 }; 75 76 enum MES_AMD_PRIORITY_LEVEL { 77 AMD_PRIORITY_LEVEL_LOW = 0, 78 AMD_PRIORITY_LEVEL_NORMAL = 1, 79 AMD_PRIORITY_LEVEL_MEDIUM = 2, 80 AMD_PRIORITY_LEVEL_HIGH = 3, 81 AMD_PRIORITY_LEVEL_REALTIME = 4, 82 AMD_PRIORITY_NUM_LEVELS 83 }; 84 85 enum MES_QUEUE_TYPE { 86 MES_QUEUE_TYPE_GFX, 87 MES_QUEUE_TYPE_COMPUTE, 88 MES_QUEUE_TYPE_SDMA, 89 MES_QUEUE_TYPE_MAX, 90 }; 91 92 struct MES_API_STATUS { 93 uint64_t api_completion_fence_addr; 94 uint64_t api_completion_fence_value; 95 }; 96 97 enum { MAX_COMPUTE_PIPES = 8 }; 98 enum { MAX_GFX_PIPES = 2 }; 99 enum { MAX_SDMA_PIPES = 2 }; 100 101 enum { MAX_COMPUTE_HQD_PER_PIPE = 8 }; 102 enum { MAX_GFX_HQD_PER_PIPE = 8 }; 103 enum { MAX_SDMA_HQD_PER_PIPE = 10 }; 104 105 enum { MAX_QUEUES_IN_A_GANG = 8 }; 106 107 enum VM_HUB_TYPE { 108 VM_HUB_TYPE_GC = 0, 109 VM_HUB_TYPE_MM = 1, 110 VM_HUB_TYPE_MAX, 111 }; 112 113 enum { VMID_INVALID = 0xffff }; 114 115 enum { MAX_VMID_GCHUB = 16 }; 116 enum { MAX_VMID_MMHUB = 16 }; 117 118 enum MES_LOG_OPERATION { 119 MES_LOG_OPERATION_CONTEXT_STATE_CHANGE = 0 120 }; 121 122 enum MES_LOG_CONTEXT_STATE { 123 MES_LOG_CONTEXT_STATE_IDLE = 0, 124 MES_LOG_CONTEXT_STATE_RUNNING = 1, 125 MES_LOG_CONTEXT_STATE_READY = 2, 126 MES_LOG_CONTEXT_STATE_READY_STANDBY = 3, 127 }; 128 129 struct MES_LOG_CONTEXT_STATE_CHANGE { 130 void *h_context; 131 enum MES_LOG_CONTEXT_STATE new_context_state; 132 }; 133 134 struct MES_LOG_ENTRY_HEADER { 135 uint32_t first_free_entry_index; 136 uint32_t wraparound_count; 137 uint64_t number_of_entries; 138 uint64_t reserved[2]; 139 }; 140 141 struct MES_LOG_ENTRY_DATA { 142 uint64_t gpu_time_stamp; 143 uint32_t operation_type; /* operation_type is of MES_LOG_OPERATION type */ 144 uint32_t reserved_operation_type_bits; 145 union { 146 struct MES_LOG_CONTEXT_STATE_CHANGE context_state_change; 147 uint64_t reserved_operation_data[2]; 148 }; 149 }; 150 151 struct MES_LOG_BUFFER { 152 struct MES_LOG_ENTRY_HEADER header; 153 struct MES_LOG_ENTRY_DATA entries[1]; 154 }; 155 156 union MESAPI_SET_HW_RESOURCES { 157 struct { 158 union MES_API_HEADER header; 159 uint32_t vmid_mask_mmhub; 160 uint32_t vmid_mask_gfxhub; 161 uint32_t gds_size; 162 uint32_t paging_vmid; 163 uint32_t compute_hqd_mask[MAX_COMPUTE_PIPES]; 164 uint32_t gfx_hqd_mask[MAX_GFX_PIPES]; 165 uint32_t sdma_hqd_mask[MAX_SDMA_PIPES]; 166 uint32_t agreegated_doorbells[AMD_PRIORITY_NUM_LEVELS]; 167 uint64_t g_sch_ctx_gpu_mc_ptr; 168 uint64_t query_status_fence_gpu_mc_ptr; 169 struct MES_API_STATUS api_status; 170 union { 171 struct { 172 uint32_t disable_reset : 1; 173 uint32_t reserved : 31; 174 }; 175 uint32_t uint32_t_all; 176 }; 177 }; 178 179 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 180 }; 181 182 union MESAPI__ADD_QUEUE { 183 struct { 184 union MES_API_HEADER header; 185 uint32_t process_id; 186 uint64_t page_table_base_addr; 187 uint64_t process_va_start; 188 uint64_t process_va_end; 189 uint64_t process_quantum; 190 uint64_t process_context_addr; 191 uint64_t gang_quantum; 192 uint64_t gang_context_addr; 193 uint32_t inprocess_gang_priority; 194 enum MES_AMD_PRIORITY_LEVEL gang_global_priority_level; 195 uint32_t doorbell_offset; 196 uint64_t mqd_addr; 197 uint64_t wptr_addr; 198 enum MES_QUEUE_TYPE queue_type; 199 uint32_t gds_base; 200 uint32_t gds_size; 201 uint32_t gws_base; 202 uint32_t gws_size; 203 uint32_t oa_mask; 204 205 struct { 206 uint32_t paging : 1; 207 uint32_t debug_vmid : 4; 208 uint32_t program_gds : 1; 209 uint32_t is_gang_suspended : 1; 210 uint32_t is_tmz_queue : 1; 211 uint32_t reserved : 24; 212 }; 213 struct MES_API_STATUS api_status; 214 }; 215 216 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 217 }; 218 219 union MESAPI__REMOVE_QUEUE { 220 struct { 221 union MES_API_HEADER header; 222 uint32_t doorbell_offset; 223 uint64_t gang_context_addr; 224 225 struct { 226 uint32_t unmap_legacy_gfx_queue : 1; 227 uint32_t reserved : 31; 228 }; 229 struct MES_API_STATUS api_status; 230 }; 231 232 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 233 }; 234 235 union MESAPI__SET_SCHEDULING_CONFIG { 236 struct { 237 union MES_API_HEADER header; 238 /* Grace period when preempting another priority band for this 239 * priority band. The value for idle priority band is ignored, 240 * as it never preempts other bands. 241 */ 242 uint64_t grace_period_other_levels[AMD_PRIORITY_NUM_LEVELS]; 243 /* Default quantum for scheduling across processes within 244 * a priority band. 245 */ 246 uint64_t process_quantum_for_level[AMD_PRIORITY_NUM_LEVELS]; 247 /* Default grace period for processes that preempt each other 248 * within a priority band. 249 */ 250 uint64_t process_grace_period_same_level[AMD_PRIORITY_NUM_LEVELS]; 251 /* For normal level this field specifies the target GPU 252 * percentage in situations when it's starved by the high level. 253 * Valid values are between 0 and 50, with the default being 10. 254 */ 255 uint32_t normal_yield_percent; 256 struct MES_API_STATUS api_status; 257 }; 258 259 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 260 }; 261 262 union MESAPI__PERFORM_YIELD { 263 struct { 264 union MES_API_HEADER header; 265 uint32_t dummy; 266 struct MES_API_STATUS api_status; 267 }; 268 269 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 270 }; 271 272 union MESAPI__CHANGE_GANG_PRIORITY_LEVEL { 273 struct { 274 union MES_API_HEADER header; 275 uint32_t inprocess_gang_priority; 276 enum MES_AMD_PRIORITY_LEVEL gang_global_priority_level; 277 uint64_t gang_quantum; 278 uint64_t gang_context_addr; 279 struct MES_API_STATUS api_status; 280 }; 281 282 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 283 }; 284 285 union MESAPI__SUSPEND { 286 struct { 287 union MES_API_HEADER header; 288 /* false - suspend all gangs; true - specific gang */ 289 struct { 290 uint32_t suspend_all_gangs : 1; 291 uint32_t reserved : 31; 292 }; 293 /* gang_context_addr is valid only if suspend_all = false */ 294 uint64_t gang_context_addr; 295 296 uint64_t suspend_fence_addr; 297 uint32_t suspend_fence_value; 298 299 struct MES_API_STATUS api_status; 300 }; 301 302 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 303 }; 304 305 union MESAPI__RESUME { 306 struct { 307 union MES_API_HEADER header; 308 /* false - resume all gangs; true - specified gang */ 309 struct { 310 uint32_t resume_all_gangs : 1; 311 uint32_t reserved : 31; 312 }; 313 /* valid only if resume_all_gangs = false */ 314 uint64_t gang_context_addr; 315 316 struct MES_API_STATUS api_status; 317 }; 318 319 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 320 }; 321 322 union MESAPI__RESET { 323 struct { 324 union MES_API_HEADER header; 325 326 struct { 327 uint32_t reset_queue : 1; 328 uint32_t reserved : 31; 329 }; 330 331 uint64_t gang_context_addr; 332 uint32_t doorbell_offset; /* valid only if reset_queue = true */ 333 struct MES_API_STATUS api_status; 334 }; 335 336 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 337 }; 338 339 union MESAPI__SET_LOGGING_BUFFER { 340 struct { 341 union MES_API_HEADER header; 342 /* There are separate log buffers for each queue type */ 343 enum MES_QUEUE_TYPE log_type; 344 /* Log buffer GPU Address */ 345 uint64_t logging_buffer_addr; 346 /* number of entries in the log buffer */ 347 uint32_t number_of_entries; 348 /* Entry index at which CPU interrupt needs to be signalled */ 349 uint32_t interrupt_entry; 350 351 struct MES_API_STATUS api_status; 352 }; 353 354 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 355 }; 356 357 union MESAPI__QUERY_MES_STATUS { 358 struct { 359 union MES_API_HEADER header; 360 bool mes_healthy; /* 0 - not healthy, 1 - healthy */ 361 struct MES_API_STATUS api_status; 362 }; 363 364 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 365 }; 366 367 union MESAPI__PROGRAM_GDS { 368 struct { 369 union MES_API_HEADER header; 370 uint64_t process_context_addr; 371 uint32_t gds_base; 372 uint32_t gds_size; 373 uint32_t gws_base; 374 uint32_t gws_size; 375 uint32_t oa_mask; 376 struct MES_API_STATUS api_status; 377 }; 378 379 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 380 }; 381 382 union MESAPI__SET_DEBUG_VMID { 383 struct { 384 union MES_API_HEADER header; 385 struct MES_API_STATUS api_status; 386 union { 387 struct { 388 uint32_t use_gds : 1; 389 uint32_t reserved : 31; 390 } flags; 391 uint32_t u32All; 392 }; 393 uint32_t reserved; 394 uint32_t debug_vmid; 395 uint64_t process_context_addr; 396 uint64_t page_table_base_addr; 397 uint64_t process_va_start; 398 uint64_t process_va_end; 399 uint32_t gds_base; 400 uint32_t gds_size; 401 uint32_t gws_base; 402 uint32_t gws_size; 403 uint32_t oa_mask; 404 }; 405 406 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 407 }; 408 409 enum MESAPI_MISC_OPCODE { 410 MESAPI_MISC__MODIFY_REG, 411 MESAPI_MISC__MAX, 412 }; 413 414 enum MODIFY_REG_SUBCODE { 415 MODIFY_REG__OVERWRITE, 416 MODIFY_REG__RMW_OR, 417 MODIFY_REG__RMW_AND, 418 MODIFY_REG__MAX, 419 }; 420 421 enum { MISC_DATA_MAX_SIZE_IN_DWORDS = 20 }; 422 423 union MESAPI__MISC { 424 struct { 425 union MES_API_HEADER header; 426 enum MESAPI_MISC_OPCODE opcode; 427 struct MES_API_STATUS api_status; 428 429 union { 430 struct { 431 enum MODIFY_REG_SUBCODE subcode; 432 uint32_t reg_offset; 433 uint32_t reg_value; 434 } modify_reg; 435 uint32_t data[MISC_DATA_MAX_SIZE_IN_DWORDS]; 436 }; 437 }; 438 439 uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 440 }; 441 442 #pragma pack(pop) 443 #endif 444