Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu/mes11: initiate mes v11 support

Initiate mes v11 code base from mes v10, rename function
and register names.

Signed-off-by: Jack Xiao <Jack.Xiao@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Jack Xiao and committed by
Alex Deucher
028c3fb3 289bcffb

+1814 -1
+2 -1
drivers/gpu/drm/amd/amdgpu/Makefile
··· 146 146 # add MES block 147 147 amdgpu-y += \ 148 148 amdgpu_mes.o \ 149 - mes_v10_1.o 149 + mes_v10_1.o \ 150 + mes_v11_0.o 150 151 151 152 # add UVD block 152 153 amdgpu-y += \
+1204
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
··· 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 + #include <linux/firmware.h> 25 + #include <linux/module.h> 26 + #include "amdgpu.h" 27 + #include "soc15_common.h" 28 + #include "soc21.h" 29 + #include "gc/gc_11_0_0_offset.h" 30 + #include "gc/gc_11_0_0_sh_mask.h" 31 + #include "v10_structs.h" 32 + #include "mes_v11_api_def.h" 33 + 34 + MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes.bin"); 35 + MODULE_FIRMWARE("amdgpu/gc_11_0_0_mes1.bin"); 36 + 37 + static int mes_v11_0_hw_fini(void *handle); 38 + static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev); 39 + static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev); 40 + 41 + #define MES_EOP_SIZE 2048 42 + 43 + static void mes_v11_0_ring_set_wptr(struct amdgpu_ring *ring) 44 + { 45 + struct amdgpu_device *adev = ring->adev; 46 + 47 + if (ring->use_doorbell) { 48 + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, 49 + ring->wptr); 50 + WDOORBELL64(ring->doorbell_index, ring->wptr); 51 + } else { 52 + BUG(); 53 + } 54 + } 55 + 56 + static u64 mes_v11_0_ring_get_rptr(struct amdgpu_ring *ring) 57 + { 58 + return *ring->rptr_cpu_addr; 59 + } 60 + 61 + static u64 mes_v11_0_ring_get_wptr(struct amdgpu_ring *ring) 62 + { 63 + u64 wptr; 64 + 65 + if (ring->use_doorbell) 66 + wptr = atomic64_read((atomic64_t *)ring->wptr_cpu_addr); 67 + else 68 + BUG(); 69 + return wptr; 70 + } 71 + 72 + static const struct amdgpu_ring_funcs mes_v11_0_ring_funcs = { 73 + .type = AMDGPU_RING_TYPE_MES, 74 + .align_mask = 1, 75 + .nop = 0, 76 + .support_64bit_ptrs = true, 77 + .get_rptr = mes_v11_0_ring_get_rptr, 78 + .get_wptr = mes_v11_0_ring_get_wptr, 79 + .set_wptr = mes_v11_0_ring_set_wptr, 80 + .insert_nop = amdgpu_ring_insert_nop, 81 + }; 82 + 83 + static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes, 84 + void *pkt, int size) 85 + { 86 + int ndw = size / 4; 87 + signed long r; 88 + union MESAPI__ADD_QUEUE *x_pkt = pkt; 89 + struct amdgpu_device *adev = mes->adev; 90 + struct amdgpu_ring *ring = &mes->ring; 91 + 92 + BUG_ON(size % 4 != 0); 93 + 94 + if (amdgpu_ring_alloc(ring, ndw)) 95 + return -ENOMEM; 96 + 97 + amdgpu_ring_write_multiple(ring, pkt, ndw); 98 + amdgpu_ring_commit(ring); 99 + 100 + DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode); 101 + 102 + r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq, 103 + adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1)); 104 + if (r < 1) { 105 + DRM_ERROR("MES failed to response msg=%d\n", 106 + x_pkt->header.opcode); 107 + return -ETIMEDOUT; 108 + } 109 + 110 + return 0; 111 + } 112 + 113 + static int convert_to_mes_queue_type(int queue_type) 114 + { 115 + if (queue_type == AMDGPU_RING_TYPE_GFX) 116 + return MES_QUEUE_TYPE_GFX; 117 + else if (queue_type == AMDGPU_RING_TYPE_COMPUTE) 118 + return MES_QUEUE_TYPE_COMPUTE; 119 + else if (queue_type == AMDGPU_RING_TYPE_SDMA) 120 + return MES_QUEUE_TYPE_SDMA; 121 + else 122 + BUG(); 123 + return -1; 124 + } 125 + 126 + static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes, 127 + struct mes_add_queue_input *input) 128 + { 129 + struct amdgpu_device *adev = mes->adev; 130 + union MESAPI__ADD_QUEUE mes_add_queue_pkt; 131 + struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_GFXHUB_0]; 132 + uint32_t vm_cntx_cntl = hub->vm_cntx_cntl; 133 + 134 + memset(&mes_add_queue_pkt, 0, sizeof(mes_add_queue_pkt)); 135 + 136 + mes_add_queue_pkt.header.type = MES_API_TYPE_SCHEDULER; 137 + mes_add_queue_pkt.header.opcode = MES_SCH_API_ADD_QUEUE; 138 + mes_add_queue_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 139 + 140 + mes_add_queue_pkt.process_id = input->process_id; 141 + mes_add_queue_pkt.page_table_base_addr = input->page_table_base_addr; 142 + mes_add_queue_pkt.process_va_start = input->process_va_start; 143 + mes_add_queue_pkt.process_va_end = input->process_va_end; 144 + mes_add_queue_pkt.process_quantum = input->process_quantum; 145 + mes_add_queue_pkt.process_context_addr = input->process_context_addr; 146 + mes_add_queue_pkt.gang_quantum = input->gang_quantum; 147 + mes_add_queue_pkt.gang_context_addr = input->gang_context_addr; 148 + mes_add_queue_pkt.inprocess_gang_priority = 149 + input->inprocess_gang_priority; 150 + mes_add_queue_pkt.gang_global_priority_level = 151 + input->gang_global_priority_level; 152 + mes_add_queue_pkt.doorbell_offset = input->doorbell_offset; 153 + mes_add_queue_pkt.mqd_addr = input->mqd_addr; 154 + mes_add_queue_pkt.wptr_addr = input->wptr_addr; 155 + mes_add_queue_pkt.queue_type = 156 + convert_to_mes_queue_type(input->queue_type); 157 + mes_add_queue_pkt.paging = input->paging; 158 + mes_add_queue_pkt.vm_context_cntl = vm_cntx_cntl; 159 + mes_add_queue_pkt.gws_base = input->gws_base; 160 + mes_add_queue_pkt.gws_size = input->gws_size; 161 + mes_add_queue_pkt.trap_handler_addr = input->tba_addr; 162 + mes_add_queue_pkt.tma_addr = input->tma_addr; 163 + 164 + mes_add_queue_pkt.api_status.api_completion_fence_addr = 165 + mes->ring.fence_drv.gpu_addr; 166 + mes_add_queue_pkt.api_status.api_completion_fence_value = 167 + ++mes->ring.fence_drv.sync_seq; 168 + 169 + return mes_v11_0_submit_pkt_and_poll_completion(mes, 170 + &mes_add_queue_pkt, sizeof(mes_add_queue_pkt)); 171 + } 172 + 173 + static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes, 174 + struct mes_remove_queue_input *input) 175 + { 176 + union MESAPI__REMOVE_QUEUE mes_remove_queue_pkt; 177 + 178 + memset(&mes_remove_queue_pkt, 0, sizeof(mes_remove_queue_pkt)); 179 + 180 + mes_remove_queue_pkt.header.type = MES_API_TYPE_SCHEDULER; 181 + mes_remove_queue_pkt.header.opcode = MES_SCH_API_REMOVE_QUEUE; 182 + mes_remove_queue_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 183 + 184 + mes_remove_queue_pkt.doorbell_offset = input->doorbell_offset; 185 + mes_remove_queue_pkt.gang_context_addr = input->gang_context_addr; 186 + 187 + mes_remove_queue_pkt.api_status.api_completion_fence_addr = 188 + mes->ring.fence_drv.gpu_addr; 189 + mes_remove_queue_pkt.api_status.api_completion_fence_value = 190 + ++mes->ring.fence_drv.sync_seq; 191 + 192 + return mes_v11_0_submit_pkt_and_poll_completion(mes, 193 + &mes_remove_queue_pkt, sizeof(mes_remove_queue_pkt)); 194 + } 195 + 196 + static int mes_v11_0_unmap_legacy_queue(struct amdgpu_mes *mes, 197 + struct mes_unmap_legacy_queue_input *input) 198 + { 199 + union MESAPI__REMOVE_QUEUE mes_remove_queue_pkt; 200 + 201 + memset(&mes_remove_queue_pkt, 0, sizeof(mes_remove_queue_pkt)); 202 + 203 + mes_remove_queue_pkt.header.type = MES_API_TYPE_SCHEDULER; 204 + mes_remove_queue_pkt.header.opcode = MES_SCH_API_REMOVE_QUEUE; 205 + mes_remove_queue_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 206 + 207 + mes_remove_queue_pkt.doorbell_offset = input->doorbell_offset << 2; 208 + mes_remove_queue_pkt.gang_context_addr = 0; 209 + 210 + mes_remove_queue_pkt.pipe_id = input->pipe_id; 211 + mes_remove_queue_pkt.queue_id = input->queue_id; 212 + 213 + if (input->action == PREEMPT_QUEUES_NO_UNMAP) { 214 + mes_remove_queue_pkt.preempt_legacy_gfx_queue = 1; 215 + mes_remove_queue_pkt.tf_addr = input->trail_fence_addr; 216 + mes_remove_queue_pkt.tf_data = 217 + lower_32_bits(input->trail_fence_data); 218 + } else { 219 + if (input->queue_type == AMDGPU_RING_TYPE_GFX) 220 + mes_remove_queue_pkt.unmap_legacy_gfx_queue = 1; 221 + else 222 + mes_remove_queue_pkt.unmap_kiq_utility_queue = 1; 223 + } 224 + 225 + mes_remove_queue_pkt.api_status.api_completion_fence_addr = 226 + mes->ring.fence_drv.gpu_addr; 227 + mes_remove_queue_pkt.api_status.api_completion_fence_value = 228 + ++mes->ring.fence_drv.sync_seq; 229 + 230 + return mes_v11_0_submit_pkt_and_poll_completion(mes, 231 + &mes_remove_queue_pkt, sizeof(mes_remove_queue_pkt)); 232 + } 233 + 234 + static int mes_v11_0_suspend_gang(struct amdgpu_mes *mes, 235 + struct mes_suspend_gang_input *input) 236 + { 237 + return 0; 238 + } 239 + 240 + static int mes_v11_0_resume_gang(struct amdgpu_mes *mes, 241 + struct mes_resume_gang_input *input) 242 + { 243 + return 0; 244 + } 245 + 246 + static int mes_v11_0_query_sched_status(struct amdgpu_mes *mes) 247 + { 248 + union MESAPI__QUERY_MES_STATUS mes_status_pkt; 249 + 250 + memset(&mes_status_pkt, 0, sizeof(mes_status_pkt)); 251 + 252 + mes_status_pkt.header.type = MES_API_TYPE_SCHEDULER; 253 + mes_status_pkt.header.opcode = MES_SCH_API_QUERY_SCHEDULER_STATUS; 254 + mes_status_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 255 + 256 + mes_status_pkt.api_status.api_completion_fence_addr = 257 + mes->ring.fence_drv.gpu_addr; 258 + mes_status_pkt.api_status.api_completion_fence_value = 259 + ++mes->ring.fence_drv.sync_seq; 260 + 261 + return mes_v11_0_submit_pkt_and_poll_completion(mes, 262 + &mes_status_pkt, sizeof(mes_status_pkt)); 263 + } 264 + 265 + static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes) 266 + { 267 + int i; 268 + struct amdgpu_device *adev = mes->adev; 269 + union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; 270 + 271 + memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); 272 + 273 + mes_set_hw_res_pkt.header.type = MES_API_TYPE_SCHEDULER; 274 + mes_set_hw_res_pkt.header.opcode = MES_SCH_API_SET_HW_RSRC; 275 + mes_set_hw_res_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS; 276 + 277 + mes_set_hw_res_pkt.vmid_mask_mmhub = mes->vmid_mask_mmhub; 278 + mes_set_hw_res_pkt.vmid_mask_gfxhub = mes->vmid_mask_gfxhub; 279 + mes_set_hw_res_pkt.gds_size = adev->gds.gds_size; 280 + mes_set_hw_res_pkt.paging_vmid = 0; 281 + mes_set_hw_res_pkt.g_sch_ctx_gpu_mc_ptr = mes->sch_ctx_gpu_addr; 282 + mes_set_hw_res_pkt.query_status_fence_gpu_mc_ptr = 283 + mes->query_status_fence_gpu_addr; 284 + 285 + for (i = 0; i < MAX_COMPUTE_PIPES; i++) 286 + mes_set_hw_res_pkt.compute_hqd_mask[i] = 287 + mes->compute_hqd_mask[i]; 288 + 289 + for (i = 0; i < MAX_GFX_PIPES; i++) 290 + mes_set_hw_res_pkt.gfx_hqd_mask[i] = mes->gfx_hqd_mask[i]; 291 + 292 + for (i = 0; i < MAX_SDMA_PIPES; i++) 293 + mes_set_hw_res_pkt.sdma_hqd_mask[i] = mes->sdma_hqd_mask[i]; 294 + 295 + for (i = 0; i < AMD_PRIORITY_NUM_LEVELS; i++) 296 + mes_set_hw_res_pkt.aggregated_doorbells[i] = 297 + mes->agreegated_doorbells[i]; 298 + 299 + for (i = 0; i < 5; i++) { 300 + mes_set_hw_res_pkt.gc_base[i] = adev->reg_offset[GC_HWIP][0][i]; 301 + mes_set_hw_res_pkt.mmhub_base[i] = 302 + adev->reg_offset[MMHUB_HWIP][0][i]; 303 + mes_set_hw_res_pkt.osssys_base[i] = 304 + adev->reg_offset[OSSSYS_HWIP][0][i]; 305 + } 306 + 307 + mes_set_hw_res_pkt.disable_reset = 1; 308 + mes_set_hw_res_pkt.disable_mes_log = 1; 309 + mes_set_hw_res_pkt.use_different_vmid_compute = 1; 310 + 311 + mes_set_hw_res_pkt.api_status.api_completion_fence_addr = 312 + mes->ring.fence_drv.gpu_addr; 313 + mes_set_hw_res_pkt.api_status.api_completion_fence_value = 314 + ++mes->ring.fence_drv.sync_seq; 315 + 316 + return mes_v11_0_submit_pkt_and_poll_completion(mes, 317 + &mes_set_hw_res_pkt, sizeof(mes_set_hw_res_pkt)); 318 + } 319 + 320 + static const struct amdgpu_mes_funcs mes_v11_0_funcs = { 321 + .add_hw_queue = mes_v11_0_add_hw_queue, 322 + .remove_hw_queue = mes_v11_0_remove_hw_queue, 323 + .unmap_legacy_queue = mes_v11_0_unmap_legacy_queue, 324 + .suspend_gang = mes_v11_0_suspend_gang, 325 + .resume_gang = mes_v11_0_resume_gang, 326 + }; 327 + 328 + static int mes_v11_0_init_microcode(struct amdgpu_device *adev, 329 + enum admgpu_mes_pipe pipe) 330 + { 331 + char fw_name[30]; 332 + char ucode_prefix[30]; 333 + int err; 334 + const struct mes_firmware_header_v1_0 *mes_hdr; 335 + struct amdgpu_firmware_info *info; 336 + 337 + amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); 338 + 339 + if (pipe == AMDGPU_MES_SCHED_PIPE) 340 + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin", 341 + ucode_prefix); 342 + else 343 + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin", 344 + ucode_prefix); 345 + 346 + err = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev); 347 + if (err) 348 + return err; 349 + 350 + err = amdgpu_ucode_validate(adev->mes.fw[pipe]); 351 + if (err) { 352 + release_firmware(adev->mes.fw[pipe]); 353 + adev->mes.fw[pipe] = NULL; 354 + return err; 355 + } 356 + 357 + mes_hdr = (const struct mes_firmware_header_v1_0 *) 358 + adev->mes.fw[pipe]->data; 359 + adev->mes.ucode_fw_version[pipe] = 360 + le32_to_cpu(mes_hdr->mes_ucode_version); 361 + adev->mes.ucode_fw_version[pipe] = 362 + le32_to_cpu(mes_hdr->mes_ucode_data_version); 363 + adev->mes.uc_start_addr[pipe] = 364 + le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) | 365 + ((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32); 366 + adev->mes.data_start_addr[pipe] = 367 + le32_to_cpu(mes_hdr->mes_data_start_addr_lo) | 368 + ((uint64_t)(le32_to_cpu(mes_hdr->mes_data_start_addr_hi)) << 32); 369 + 370 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { 371 + int ucode, ucode_data; 372 + 373 + if (pipe == AMDGPU_MES_SCHED_PIPE) { 374 + ucode = AMDGPU_UCODE_ID_CP_MES; 375 + ucode_data = AMDGPU_UCODE_ID_CP_MES_DATA; 376 + } else { 377 + ucode = AMDGPU_UCODE_ID_CP_MES1; 378 + ucode_data = AMDGPU_UCODE_ID_CP_MES1_DATA; 379 + } 380 + 381 + info = &adev->firmware.ucode[ucode]; 382 + info->ucode_id = ucode; 383 + info->fw = adev->mes.fw[pipe]; 384 + adev->firmware.fw_size += 385 + ALIGN(le32_to_cpu(mes_hdr->mes_ucode_size_bytes), 386 + PAGE_SIZE); 387 + 388 + info = &adev->firmware.ucode[ucode_data]; 389 + info->ucode_id = ucode_data; 390 + info->fw = adev->mes.fw[pipe]; 391 + adev->firmware.fw_size += 392 + ALIGN(le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes), 393 + PAGE_SIZE); 394 + } 395 + 396 + return 0; 397 + } 398 + 399 + static void mes_v11_0_free_microcode(struct amdgpu_device *adev, 400 + enum admgpu_mes_pipe pipe) 401 + { 402 + release_firmware(adev->mes.fw[pipe]); 403 + adev->mes.fw[pipe] = NULL; 404 + } 405 + 406 + static int mes_v11_0_allocate_ucode_buffer(struct amdgpu_device *adev, 407 + enum admgpu_mes_pipe pipe) 408 + { 409 + int r; 410 + const struct mes_firmware_header_v1_0 *mes_hdr; 411 + const __le32 *fw_data; 412 + unsigned fw_size; 413 + 414 + mes_hdr = (const struct mes_firmware_header_v1_0 *) 415 + adev->mes.fw[pipe]->data; 416 + 417 + fw_data = (const __le32 *)(adev->mes.fw[pipe]->data + 418 + le32_to_cpu(mes_hdr->mes_ucode_offset_bytes)); 419 + fw_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes); 420 + 421 + r = amdgpu_bo_create_reserved(adev, fw_size, 422 + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, 423 + &adev->mes.ucode_fw_obj[pipe], 424 + &adev->mes.ucode_fw_gpu_addr[pipe], 425 + (void **)&adev->mes.ucode_fw_ptr[pipe]); 426 + if (r) { 427 + dev_err(adev->dev, "(%d) failed to create mes fw bo\n", r); 428 + return r; 429 + } 430 + 431 + memcpy(adev->mes.ucode_fw_ptr[pipe], fw_data, fw_size); 432 + 433 + amdgpu_bo_kunmap(adev->mes.ucode_fw_obj[pipe]); 434 + amdgpu_bo_unreserve(adev->mes.ucode_fw_obj[pipe]); 435 + 436 + return 0; 437 + } 438 + 439 + static int mes_v11_0_allocate_ucode_data_buffer(struct amdgpu_device *adev, 440 + enum admgpu_mes_pipe pipe) 441 + { 442 + int r; 443 + const struct mes_firmware_header_v1_0 *mes_hdr; 444 + const __le32 *fw_data; 445 + unsigned fw_size; 446 + 447 + mes_hdr = (const struct mes_firmware_header_v1_0 *) 448 + adev->mes.fw[pipe]->data; 449 + 450 + fw_data = (const __le32 *)(adev->mes.fw[pipe]->data + 451 + le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes)); 452 + fw_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes); 453 + 454 + r = amdgpu_bo_create_reserved(adev, fw_size, 455 + 64 * 1024, AMDGPU_GEM_DOMAIN_VRAM, 456 + &adev->mes.data_fw_obj[pipe], 457 + &adev->mes.data_fw_gpu_addr[pipe], 458 + (void **)&adev->mes.data_fw_ptr[pipe]); 459 + if (r) { 460 + dev_err(adev->dev, "(%d) failed to create mes data fw bo\n", r); 461 + return r; 462 + } 463 + 464 + memcpy(adev->mes.data_fw_ptr[pipe], fw_data, fw_size); 465 + 466 + amdgpu_bo_kunmap(adev->mes.data_fw_obj[pipe]); 467 + amdgpu_bo_unreserve(adev->mes.data_fw_obj[pipe]); 468 + 469 + return 0; 470 + } 471 + 472 + static void mes_v11_0_free_ucode_buffers(struct amdgpu_device *adev, 473 + enum admgpu_mes_pipe pipe) 474 + { 475 + amdgpu_bo_free_kernel(&adev->mes.data_fw_obj[pipe], 476 + &adev->mes.data_fw_gpu_addr[pipe], 477 + (void **)&adev->mes.data_fw_ptr[pipe]); 478 + 479 + amdgpu_bo_free_kernel(&adev->mes.ucode_fw_obj[pipe], 480 + &adev->mes.ucode_fw_gpu_addr[pipe], 481 + (void **)&adev->mes.ucode_fw_ptr[pipe]); 482 + } 483 + 484 + static void mes_v11_0_enable(struct amdgpu_device *adev, bool enable) 485 + { 486 + uint64_t ucode_addr; 487 + uint32_t pipe, data = 0; 488 + 489 + if (enable) { 490 + data = RREG32_SOC15(GC, 0, regCP_MES_CNTL); 491 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE0_RESET, 1); 492 + data = REG_SET_FIELD(data, CP_MES_CNTL, 493 + MES_PIPE1_RESET, adev->enable_mes_kiq ? 1 : 0); 494 + WREG32_SOC15(GC, 0, regCP_MES_CNTL, data); 495 + 496 + mutex_lock(&adev->srbm_mutex); 497 + for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) { 498 + if (!adev->enable_mes_kiq && 499 + pipe == AMDGPU_MES_KIQ_PIPE) 500 + continue; 501 + 502 + soc21_grbm_select(adev, 3, pipe, 0, 0); 503 + 504 + ucode_addr = adev->mes.uc_start_addr[pipe] >> 2; 505 + WREG32_SOC15(GC, 0, regCP_MES_PRGRM_CNTR_START, 506 + lower_32_bits(ucode_addr)); 507 + WREG32_SOC15(GC, 0, regCP_MES_PRGRM_CNTR_START_HI, 508 + upper_32_bits(ucode_addr)); 509 + } 510 + soc21_grbm_select(adev, 0, 0, 0, 0); 511 + mutex_unlock(&adev->srbm_mutex); 512 + 513 + /* unhalt MES and activate pipe0 */ 514 + data = REG_SET_FIELD(0, CP_MES_CNTL, MES_PIPE0_ACTIVE, 1); 515 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE1_ACTIVE, 516 + adev->enable_mes_kiq ? 1 : 0); 517 + WREG32_SOC15(GC, 0, regCP_MES_CNTL, data); 518 + 519 + if (amdgpu_emu_mode) 520 + msleep(100); 521 + else 522 + udelay(50); 523 + } else { 524 + data = RREG32_SOC15(GC, 0, regCP_MES_CNTL); 525 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE0_ACTIVE, 0); 526 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE1_ACTIVE, 0); 527 + data = REG_SET_FIELD(data, CP_MES_CNTL, 528 + MES_INVALIDATE_ICACHE, 1); 529 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE0_RESET, 1); 530 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_PIPE1_RESET, 531 + adev->enable_mes_kiq ? 1 : 0); 532 + data = REG_SET_FIELD(data, CP_MES_CNTL, MES_HALT, 1); 533 + WREG32_SOC15(GC, 0, regCP_MES_CNTL, data); 534 + } 535 + } 536 + 537 + /* This function is for backdoor MES firmware */ 538 + static int mes_v11_0_load_microcode(struct amdgpu_device *adev, 539 + enum admgpu_mes_pipe pipe) 540 + { 541 + int r; 542 + uint32_t data; 543 + uint64_t ucode_addr; 544 + 545 + mes_v11_0_enable(adev, false); 546 + 547 + if (!adev->mes.fw[pipe]) 548 + return -EINVAL; 549 + 550 + r = mes_v11_0_allocate_ucode_buffer(adev, pipe); 551 + if (r) 552 + return r; 553 + 554 + r = mes_v11_0_allocate_ucode_data_buffer(adev, pipe); 555 + if (r) { 556 + mes_v11_0_free_ucode_buffers(adev, pipe); 557 + return r; 558 + } 559 + 560 + mutex_lock(&adev->srbm_mutex); 561 + /* me=3, pipe=0, queue=0 */ 562 + soc21_grbm_select(adev, 3, pipe, 0, 0); 563 + 564 + WREG32_SOC15(GC, 0, regCP_MES_IC_BASE_CNTL, 0); 565 + 566 + /* set ucode start address */ 567 + ucode_addr = adev->mes.uc_start_addr[pipe] >> 2; 568 + WREG32_SOC15(GC, 0, regCP_MES_PRGRM_CNTR_START, 569 + lower_32_bits(ucode_addr)); 570 + WREG32_SOC15(GC, 0, regCP_MES_PRGRM_CNTR_START_HI, 571 + upper_32_bits(ucode_addr)); 572 + 573 + /* set ucode fimrware address */ 574 + WREG32_SOC15(GC, 0, regCP_MES_IC_BASE_LO, 575 + lower_32_bits(adev->mes.ucode_fw_gpu_addr[pipe])); 576 + WREG32_SOC15(GC, 0, regCP_MES_IC_BASE_HI, 577 + upper_32_bits(adev->mes.ucode_fw_gpu_addr[pipe])); 578 + 579 + /* set ucode instruction cache boundary to 2M-1 */ 580 + WREG32_SOC15(GC, 0, regCP_MES_MIBOUND_LO, 0x1FFFFF); 581 + 582 + /* set ucode data firmware address */ 583 + WREG32_SOC15(GC, 0, regCP_MES_MDBASE_LO, 584 + lower_32_bits(adev->mes.data_fw_gpu_addr[pipe])); 585 + WREG32_SOC15(GC, 0, regCP_MES_MDBASE_HI, 586 + upper_32_bits(adev->mes.data_fw_gpu_addr[pipe])); 587 + 588 + /* Set 0x3FFFF (256K-1) to CP_MES_MDBOUND_LO */ 589 + WREG32_SOC15(GC, 0, regCP_MES_MDBOUND_LO, 0x3FFFF); 590 + 591 + /* invalidate ICACHE */ 592 + data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); 593 + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 0); 594 + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, INVALIDATE_CACHE, 1); 595 + WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); 596 + 597 + /* prime the ICACHE. */ 598 + data = RREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL); 599 + data = REG_SET_FIELD(data, CP_MES_IC_OP_CNTL, PRIME_ICACHE, 1); 600 + WREG32_SOC15(GC, 0, regCP_MES_IC_OP_CNTL, data); 601 + 602 + soc21_grbm_select(adev, 0, 0, 0, 0); 603 + mutex_unlock(&adev->srbm_mutex); 604 + 605 + return 0; 606 + } 607 + 608 + static int mes_v11_0_allocate_eop_buf(struct amdgpu_device *adev, 609 + enum admgpu_mes_pipe pipe) 610 + { 611 + int r; 612 + u32 *eop; 613 + 614 + r = amdgpu_bo_create_reserved(adev, MES_EOP_SIZE, PAGE_SIZE, 615 + AMDGPU_GEM_DOMAIN_GTT, 616 + &adev->mes.eop_gpu_obj[pipe], 617 + &adev->mes.eop_gpu_addr[pipe], 618 + (void **)&eop); 619 + if (r) { 620 + dev_warn(adev->dev, "(%d) create EOP bo failed\n", r); 621 + return r; 622 + } 623 + 624 + memset(eop, 0, 625 + adev->mes.eop_gpu_obj[pipe]->tbo.base.size); 626 + 627 + amdgpu_bo_kunmap(adev->mes.eop_gpu_obj[pipe]); 628 + amdgpu_bo_unreserve(adev->mes.eop_gpu_obj[pipe]); 629 + 630 + return 0; 631 + } 632 + 633 + static int mes_v11_0_mqd_init(struct amdgpu_ring *ring) 634 + { 635 + struct amdgpu_device *adev = ring->adev; 636 + struct v10_compute_mqd *mqd = ring->mqd_ptr; 637 + uint64_t hqd_gpu_addr, wb_gpu_addr, eop_base_addr; 638 + uint32_t tmp; 639 + 640 + mqd->header = 0xC0310800; 641 + mqd->compute_pipelinestat_enable = 0x00000001; 642 + mqd->compute_static_thread_mgmt_se0 = 0xffffffff; 643 + mqd->compute_static_thread_mgmt_se1 = 0xffffffff; 644 + mqd->compute_static_thread_mgmt_se2 = 0xffffffff; 645 + mqd->compute_static_thread_mgmt_se3 = 0xffffffff; 646 + mqd->compute_misc_reserved = 0x00000007; 647 + 648 + eop_base_addr = ring->eop_gpu_addr >> 8; 649 + mqd->cp_hqd_eop_base_addr_lo = eop_base_addr; 650 + mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr); 651 + 652 + /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ 653 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_EOP_CONTROL); 654 + tmp = REG_SET_FIELD(tmp, CP_HQD_EOP_CONTROL, EOP_SIZE, 655 + (order_base_2(MES_EOP_SIZE / 4) - 1)); 656 + 657 + mqd->cp_hqd_eop_control = tmp; 658 + 659 + /* enable doorbell? */ 660 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL); 661 + 662 + if (ring->use_doorbell) { 663 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 664 + DOORBELL_OFFSET, ring->doorbell_index); 665 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 666 + DOORBELL_EN, 1); 667 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 668 + DOORBELL_SOURCE, 0); 669 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 670 + DOORBELL_HIT, 0); 671 + } 672 + else 673 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 674 + DOORBELL_EN, 0); 675 + 676 + mqd->cp_hqd_pq_doorbell_control = tmp; 677 + 678 + /* disable the queue if it's active */ 679 + ring->wptr = 0; 680 + mqd->cp_hqd_dequeue_request = 0; 681 + mqd->cp_hqd_pq_rptr = 0; 682 + mqd->cp_hqd_pq_wptr_lo = 0; 683 + mqd->cp_hqd_pq_wptr_hi = 0; 684 + 685 + /* set the pointer to the MQD */ 686 + mqd->cp_mqd_base_addr_lo = ring->mqd_gpu_addr & 0xfffffffc; 687 + mqd->cp_mqd_base_addr_hi = upper_32_bits(ring->mqd_gpu_addr); 688 + 689 + /* set MQD vmid to 0 */ 690 + tmp = RREG32_SOC15(GC, 0, regCP_MQD_CONTROL); 691 + tmp = REG_SET_FIELD(tmp, CP_MQD_CONTROL, VMID, 0); 692 + mqd->cp_mqd_control = tmp; 693 + 694 + /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */ 695 + hqd_gpu_addr = ring->gpu_addr >> 8; 696 + mqd->cp_hqd_pq_base_lo = hqd_gpu_addr; 697 + mqd->cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr); 698 + 699 + /* set up the HQD, this is similar to CP_RB0_CNTL */ 700 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_PQ_CONTROL); 701 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, QUEUE_SIZE, 702 + (order_base_2(ring->ring_size / 4) - 1)); 703 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE, 704 + ((order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1) << 8)); 705 + #ifdef __BIG_ENDIAN 706 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1); 707 + #endif 708 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); 709 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); 710 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); 711 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); 712 + mqd->cp_hqd_pq_control = tmp; 713 + 714 + /* set the wb address whether it's enabled or not */ 715 + wb_gpu_addr = ring->rptr_gpu_addr;; 716 + mqd->cp_hqd_pq_rptr_report_addr_lo = wb_gpu_addr & 0xfffffffc; 717 + mqd->cp_hqd_pq_rptr_report_addr_hi = 718 + upper_32_bits(wb_gpu_addr) & 0xffff; 719 + 720 + /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */ 721 + wb_gpu_addr = ring->wptr_gpu_addr; 722 + mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffffff8; 723 + mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff; 724 + 725 + tmp = 0; 726 + /* enable the doorbell if requested */ 727 + if (ring->use_doorbell) { 728 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL); 729 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 730 + DOORBELL_OFFSET, ring->doorbell_index); 731 + 732 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 733 + DOORBELL_EN, 1); 734 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 735 + DOORBELL_SOURCE, 0); 736 + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL, 737 + DOORBELL_HIT, 0); 738 + } 739 + 740 + mqd->cp_hqd_pq_doorbell_control = tmp; 741 + 742 + /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */ 743 + ring->wptr = 0; 744 + mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR); 745 + 746 + /* set the vmid for the queue */ 747 + mqd->cp_hqd_vmid = 0; 748 + 749 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_PERSISTENT_STATE); 750 + tmp = REG_SET_FIELD(tmp, CP_HQD_PERSISTENT_STATE, PRELOAD_SIZE, 0x55); 751 + mqd->cp_hqd_persistent_state = tmp; 752 + 753 + /* set MIN_IB_AVAIL_SIZE */ 754 + tmp = RREG32_SOC15(GC, 0, regCP_HQD_IB_CONTROL); 755 + tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3); 756 + mqd->cp_hqd_ib_control = tmp; 757 + 758 + /* activate the queue */ 759 + mqd->cp_hqd_active = 1; 760 + return 0; 761 + } 762 + 763 + static void mes_v11_0_queue_init_register(struct amdgpu_ring *ring) 764 + { 765 + struct v10_compute_mqd *mqd = ring->mqd_ptr; 766 + struct amdgpu_device *adev = ring->adev; 767 + uint32_t data = 0; 768 + 769 + mutex_lock(&adev->srbm_mutex); 770 + soc21_grbm_select(adev, 3, ring->pipe, 0, 0); 771 + 772 + /* set CP_HQD_VMID.VMID = 0. */ 773 + data = RREG32_SOC15(GC, 0, regCP_HQD_VMID); 774 + data = REG_SET_FIELD(data, CP_HQD_VMID, VMID, 0); 775 + WREG32_SOC15(GC, 0, regCP_HQD_VMID, data); 776 + 777 + /* set CP_HQD_PQ_DOORBELL_CONTROL.DOORBELL_EN=0 */ 778 + data = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL); 779 + data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL, 780 + DOORBELL_EN, 0); 781 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, data); 782 + 783 + /* set CP_MQD_BASE_ADDR/HI with the MQD base address */ 784 + WREG32_SOC15(GC, 0, regCP_MQD_BASE_ADDR, mqd->cp_mqd_base_addr_lo); 785 + WREG32_SOC15(GC, 0, regCP_MQD_BASE_ADDR_HI, mqd->cp_mqd_base_addr_hi); 786 + 787 + /* set CP_MQD_CONTROL.VMID=0 */ 788 + data = RREG32_SOC15(GC, 0, regCP_MQD_CONTROL); 789 + data = REG_SET_FIELD(data, CP_MQD_CONTROL, VMID, 0); 790 + WREG32_SOC15(GC, 0, regCP_MQD_CONTROL, 0); 791 + 792 + /* set CP_HQD_PQ_BASE/HI with the ring buffer base address */ 793 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_BASE, mqd->cp_hqd_pq_base_lo); 794 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_BASE_HI, mqd->cp_hqd_pq_base_hi); 795 + 796 + /* set CP_HQD_PQ_RPTR_REPORT_ADDR/HI */ 797 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR_REPORT_ADDR, 798 + mqd->cp_hqd_pq_rptr_report_addr_lo); 799 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR_REPORT_ADDR_HI, 800 + mqd->cp_hqd_pq_rptr_report_addr_hi); 801 + 802 + /* set CP_HQD_PQ_CONTROL */ 803 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_CONTROL, mqd->cp_hqd_pq_control); 804 + 805 + /* set CP_HQD_PQ_WPTR_POLL_ADDR/HI */ 806 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_POLL_ADDR, 807 + mqd->cp_hqd_pq_wptr_poll_addr_lo); 808 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_POLL_ADDR_HI, 809 + mqd->cp_hqd_pq_wptr_poll_addr_hi); 810 + 811 + /* set CP_HQD_PQ_DOORBELL_CONTROL */ 812 + WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, 813 + mqd->cp_hqd_pq_doorbell_control); 814 + 815 + /* set CP_HQD_PERSISTENT_STATE.PRELOAD_SIZE=0x53 */ 816 + WREG32_SOC15(GC, 0, regCP_HQD_PERSISTENT_STATE, mqd->cp_hqd_persistent_state); 817 + 818 + /* set CP_HQD_ACTIVE.ACTIVE=1 */ 819 + WREG32_SOC15(GC, 0, regCP_HQD_ACTIVE, mqd->cp_hqd_active); 820 + 821 + soc21_grbm_select(adev, 0, 0, 0, 0); 822 + mutex_unlock(&adev->srbm_mutex); 823 + } 824 + 825 + #if 0 826 + static int mes_v11_0_kiq_enable_queue(struct amdgpu_device *adev) 827 + { 828 + struct amdgpu_kiq *kiq = &adev->gfx.kiq; 829 + struct amdgpu_ring *kiq_ring = &adev->gfx.kiq.ring; 830 + int r; 831 + 832 + if (!kiq->pmf || !kiq->pmf->kiq_map_queues) 833 + return -EINVAL; 834 + 835 + r = amdgpu_ring_alloc(kiq_ring, kiq->pmf->map_queues_size); 836 + if (r) { 837 + DRM_ERROR("Failed to lock KIQ (%d).\n", r); 838 + return r; 839 + } 840 + 841 + kiq->pmf->kiq_map_queues(kiq_ring, &adev->mes.ring); 842 + 843 + r = amdgpu_ring_test_ring(kiq_ring); 844 + if (r) { 845 + DRM_ERROR("kfq enable failed\n"); 846 + kiq_ring->sched.ready = false; 847 + } 848 + return r; 849 + } 850 + #endif 851 + 852 + static int mes_v11_0_queue_init(struct amdgpu_device *adev, 853 + enum admgpu_mes_pipe pipe) 854 + { 855 + struct amdgpu_ring *ring; 856 + int r; 857 + 858 + if (pipe == AMDGPU_MES_KIQ_PIPE) 859 + ring = &adev->gfx.kiq.ring; 860 + else if (pipe == AMDGPU_MES_SCHED_PIPE) 861 + ring = &adev->mes.ring; 862 + else 863 + BUG(); 864 + 865 + r = mes_v11_0_mqd_init(ring); 866 + if (r) 867 + return r; 868 + 869 + #if 0 870 + if (pipe == AMDGPU_MES_SCHED_PIPE) { 871 + r = mes_v11_0_kiq_enable_queue(adev); 872 + if (r) 873 + return r; 874 + } else { 875 + mes_v11_0_queue_init_register(ring); 876 + } 877 + #else 878 + mes_v11_0_queue_init_register(ring); 879 + #endif 880 + 881 + return 0; 882 + } 883 + 884 + static int mes_v11_0_ring_init(struct amdgpu_device *adev) 885 + { 886 + struct amdgpu_ring *ring; 887 + 888 + ring = &adev->mes.ring; 889 + 890 + ring->funcs = &mes_v11_0_ring_funcs; 891 + 892 + ring->me = 3; 893 + ring->pipe = 0; 894 + ring->queue = 0; 895 + 896 + ring->ring_obj = NULL; 897 + ring->use_doorbell = true; 898 + ring->doorbell_index = adev->doorbell_index.mes_ring0 << 1; 899 + ring->eop_gpu_addr = adev->mes.eop_gpu_addr[AMDGPU_MES_SCHED_PIPE]; 900 + ring->no_scheduler = true; 901 + sprintf(ring->name, "mes_%d.%d.%d", ring->me, ring->pipe, ring->queue); 902 + 903 + return amdgpu_ring_init(adev, ring, 1024, NULL, 0, 904 + AMDGPU_RING_PRIO_DEFAULT, NULL); 905 + } 906 + 907 + static int mes_v11_0_kiq_ring_init(struct amdgpu_device *adev) 908 + { 909 + struct amdgpu_ring *ring; 910 + 911 + spin_lock_init(&adev->gfx.kiq.ring_lock); 912 + 913 + ring = &adev->gfx.kiq.ring; 914 + 915 + ring->me = 3; 916 + ring->pipe = 1; 917 + ring->queue = 0; 918 + 919 + ring->adev = NULL; 920 + ring->ring_obj = NULL; 921 + ring->use_doorbell = true; 922 + ring->doorbell_index = adev->doorbell_index.mes_ring1 << 1; 923 + ring->eop_gpu_addr = adev->mes.eop_gpu_addr[AMDGPU_MES_KIQ_PIPE]; 924 + ring->no_scheduler = true; 925 + sprintf(ring->name, "mes_kiq_%d.%d.%d", 926 + ring->me, ring->pipe, ring->queue); 927 + 928 + return amdgpu_ring_init(adev, ring, 1024, NULL, 0, 929 + AMDGPU_RING_PRIO_DEFAULT, NULL); 930 + } 931 + 932 + static int mes_v11_0_mqd_sw_init(struct amdgpu_device *adev, 933 + enum admgpu_mes_pipe pipe) 934 + { 935 + int r, mqd_size = sizeof(struct v10_compute_mqd); 936 + struct amdgpu_ring *ring; 937 + 938 + if (pipe == AMDGPU_MES_KIQ_PIPE) 939 + ring = &adev->gfx.kiq.ring; 940 + else if (pipe == AMDGPU_MES_SCHED_PIPE) 941 + ring = &adev->mes.ring; 942 + else 943 + BUG(); 944 + 945 + if (ring->mqd_obj) 946 + return 0; 947 + 948 + r = amdgpu_bo_create_kernel(adev, mqd_size, PAGE_SIZE, 949 + AMDGPU_GEM_DOMAIN_GTT, &ring->mqd_obj, 950 + &ring->mqd_gpu_addr, &ring->mqd_ptr); 951 + if (r) { 952 + dev_warn(adev->dev, "failed to create ring mqd bo (%d)", r); 953 + return r; 954 + } 955 + 956 + memset(ring->mqd_ptr, 0, mqd_size); 957 + 958 + /* prepare MQD backup */ 959 + adev->mes.mqd_backup[pipe] = kmalloc(mqd_size, GFP_KERNEL); 960 + if (!adev->mes.mqd_backup[pipe]) 961 + dev_warn(adev->dev, 962 + "no memory to create MQD backup for ring %s\n", 963 + ring->name); 964 + 965 + return 0; 966 + } 967 + 968 + static int mes_v11_0_sw_init(void *handle) 969 + { 970 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 971 + int pipe, r; 972 + 973 + adev->mes.adev = adev; 974 + adev->mes.funcs = &mes_v11_0_funcs; 975 + adev->mes.kiq_hw_init = &mes_v11_0_kiq_hw_init; 976 + adev->mes.kiq_hw_fini = &mes_v11_0_kiq_hw_fini; 977 + 978 + r = amdgpu_mes_init(adev); 979 + if (r) 980 + return r; 981 + 982 + for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) { 983 + if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE) 984 + continue; 985 + 986 + r = mes_v11_0_init_microcode(adev, pipe); 987 + if (r) 988 + return r; 989 + 990 + r = mes_v11_0_allocate_eop_buf(adev, pipe); 991 + if (r) 992 + return r; 993 + 994 + r = mes_v11_0_mqd_sw_init(adev, pipe); 995 + if (r) 996 + return r; 997 + } 998 + 999 + if (adev->enable_mes_kiq) { 1000 + r = mes_v11_0_kiq_ring_init(adev); 1001 + if (r) 1002 + return r; 1003 + } 1004 + 1005 + r = mes_v11_0_ring_init(adev); 1006 + if (r) 1007 + return r; 1008 + 1009 + return 0; 1010 + } 1011 + 1012 + static int mes_v11_0_sw_fini(void *handle) 1013 + { 1014 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1015 + int pipe; 1016 + 1017 + amdgpu_device_wb_free(adev, adev->mes.sch_ctx_offs); 1018 + amdgpu_device_wb_free(adev, adev->mes.query_status_fence_offs); 1019 + 1020 + for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) { 1021 + kfree(adev->mes.mqd_backup[pipe]); 1022 + 1023 + amdgpu_bo_free_kernel(&adev->mes.eop_gpu_obj[pipe], 1024 + &adev->mes.eop_gpu_addr[pipe], 1025 + NULL); 1026 + 1027 + mes_v11_0_free_microcode(adev, pipe); 1028 + } 1029 + 1030 + amdgpu_bo_free_kernel(&adev->gfx.kiq.ring.mqd_obj, 1031 + &adev->gfx.kiq.ring.mqd_gpu_addr, 1032 + &adev->gfx.kiq.ring.mqd_ptr); 1033 + 1034 + amdgpu_bo_free_kernel(&adev->mes.ring.mqd_obj, 1035 + &adev->mes.ring.mqd_gpu_addr, 1036 + &adev->mes.ring.mqd_ptr); 1037 + 1038 + amdgpu_ring_fini(&adev->gfx.kiq.ring); 1039 + amdgpu_ring_fini(&adev->mes.ring); 1040 + 1041 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { 1042 + mes_v11_0_free_ucode_buffers(adev, AMDGPU_MES_KIQ_PIPE); 1043 + mes_v11_0_free_ucode_buffers(adev, AMDGPU_MES_SCHED_PIPE); 1044 + } 1045 + 1046 + amdgpu_mes_fini(adev); 1047 + return 0; 1048 + } 1049 + 1050 + static void mes_v11_0_kiq_setting(struct amdgpu_ring *ring) 1051 + { 1052 + uint32_t tmp; 1053 + struct amdgpu_device *adev = ring->adev; 1054 + 1055 + /* tell RLC which is KIQ queue */ 1056 + tmp = RREG32_SOC15(GC, 0, regRLC_CP_SCHEDULERS); 1057 + tmp &= 0xffffff00; 1058 + tmp |= (ring->me << 5) | (ring->pipe << 3) | (ring->queue); 1059 + WREG32_SOC15(GC, 0, regRLC_CP_SCHEDULERS, tmp); 1060 + tmp |= 0x80; 1061 + WREG32_SOC15(GC, 0, regRLC_CP_SCHEDULERS, tmp); 1062 + } 1063 + 1064 + static int mes_v11_0_kiq_hw_init(struct amdgpu_device *adev) 1065 + { 1066 + int r = 0; 1067 + 1068 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { 1069 + r = mes_v11_0_load_microcode(adev, AMDGPU_MES_KIQ_PIPE); 1070 + if (r) { 1071 + DRM_ERROR("failed to load MES kiq fw, r=%d\n", r); 1072 + return r; 1073 + } 1074 + 1075 + r = mes_v11_0_load_microcode(adev, AMDGPU_MES_SCHED_PIPE); 1076 + if (r) { 1077 + DRM_ERROR("failed to load MES fw, r=%d\n", r); 1078 + return r; 1079 + } 1080 + } 1081 + 1082 + mes_v11_0_enable(adev, true); 1083 + 1084 + mes_v11_0_kiq_setting(&adev->gfx.kiq.ring); 1085 + 1086 + r = mes_v11_0_queue_init(adev, AMDGPU_MES_KIQ_PIPE); 1087 + if (r) 1088 + goto failure; 1089 + 1090 + return r; 1091 + 1092 + failure: 1093 + mes_v11_0_hw_fini(adev); 1094 + return r; 1095 + } 1096 + 1097 + static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev) 1098 + { 1099 + mes_v11_0_enable(adev, false); 1100 + return 0; 1101 + } 1102 + 1103 + static int mes_v11_0_hw_init(void *handle) 1104 + { 1105 + int r; 1106 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1107 + 1108 + if (!adev->enable_mes_kiq) { 1109 + if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { 1110 + r = mes_v11_0_load_microcode(adev, 1111 + AMDGPU_MES_SCHED_PIPE); 1112 + if (r) { 1113 + DRM_ERROR("failed to MES fw, r=%d\n", r); 1114 + return r; 1115 + } 1116 + } 1117 + 1118 + mes_v11_0_enable(adev, true); 1119 + } 1120 + 1121 + r = mes_v11_0_queue_init(adev, AMDGPU_MES_SCHED_PIPE); 1122 + if (r) 1123 + goto failure; 1124 + 1125 + r = mes_v11_0_set_hw_resources(&adev->mes); 1126 + if (r) 1127 + goto failure; 1128 + 1129 + r = mes_v11_0_query_sched_status(&adev->mes); 1130 + if (r) { 1131 + DRM_ERROR("MES is busy\n"); 1132 + goto failure; 1133 + } 1134 + 1135 + /* 1136 + * Disable KIQ ring usage from the driver once MES is enabled. 1137 + * MES uses KIQ ring exclusively so driver cannot access KIQ ring 1138 + * with MES enabled. 1139 + */ 1140 + adev->gfx.kiq.ring.sched.ready = false; 1141 + 1142 + return 0; 1143 + 1144 + failure: 1145 + mes_v11_0_hw_fini(adev); 1146 + return r; 1147 + } 1148 + 1149 + static int mes_v11_0_hw_fini(void *handle) 1150 + { 1151 + return 0; 1152 + } 1153 + 1154 + static int mes_v11_0_suspend(void *handle) 1155 + { 1156 + int r; 1157 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1158 + 1159 + r = amdgpu_mes_suspend(adev); 1160 + if (r) 1161 + return r; 1162 + 1163 + return mes_v11_0_hw_fini(adev); 1164 + } 1165 + 1166 + static int mes_v11_0_resume(void *handle) 1167 + { 1168 + int r; 1169 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1170 + 1171 + r = mes_v11_0_hw_init(adev); 1172 + if (r) 1173 + return r; 1174 + 1175 + return amdgpu_mes_resume(adev); 1176 + } 1177 + 1178 + static int mes_v11_0_late_init(void *handle) 1179 + { 1180 + struct amdgpu_device *adev = (struct amdgpu_device *)handle; 1181 + 1182 + amdgpu_mes_self_test(adev); 1183 + 1184 + return 0; 1185 + } 1186 + 1187 + static const struct amd_ip_funcs mes_v11_0_ip_funcs = { 1188 + .name = "mes_v11_0", 1189 + .late_init = mes_v11_0_late_init, 1190 + .sw_init = mes_v11_0_sw_init, 1191 + .sw_fini = mes_v11_0_sw_fini, 1192 + .hw_init = mes_v11_0_hw_init, 1193 + .hw_fini = mes_v11_0_hw_fini, 1194 + .suspend = mes_v11_0_suspend, 1195 + .resume = mes_v11_0_resume, 1196 + }; 1197 + 1198 + const struct amdgpu_ip_block_version mes_v11_0_ip_block = { 1199 + .type = AMD_IP_BLOCK_TYPE_MES, 1200 + .major = 11, 1201 + .minor = 0, 1202 + .rev = 0, 1203 + .funcs = &mes_v11_0_ip_funcs, 1204 + };
+29
drivers/gpu/drm/amd/amdgpu/mes_v11_0.h
··· 1 + /* 2 + * Copyright 2021 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_V11_0_H__ 25 + #define __MES_V11_0_H__ 26 + 27 + extern const struct amdgpu_ip_block_version mes_v11_0_ip_block; 28 + 29 + #endif
+579
drivers/gpu/drm/amd/include/mes_v11_api_def.h
··· 1 + /* 2 + * Copyright 2022 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_UPDATE_ROOT_PAGE_TABLE = 15, 63 + MES_SCH_API_AMD_LOG = 16, 64 + MES_SCH_API_MAX = 0xFF 65 + }; 66 + 67 + union MES_API_HEADER { 68 + struct { 69 + uint32_t type : 4; /* 0 - Invalid; 1 - Scheduling; 2 - TBD */ 70 + uint32_t opcode : 8; 71 + uint32_t dwsize : 8; /* including header */ 72 + uint32_t reserved : 12; 73 + }; 74 + 75 + uint32_t u32All; 76 + }; 77 + 78 + enum MES_AMD_PRIORITY_LEVEL { 79 + AMD_PRIORITY_LEVEL_LOW = 0, 80 + AMD_PRIORITY_LEVEL_NORMAL = 1, 81 + AMD_PRIORITY_LEVEL_MEDIUM = 2, 82 + AMD_PRIORITY_LEVEL_HIGH = 3, 83 + AMD_PRIORITY_LEVEL_REALTIME = 4, 84 + AMD_PRIORITY_NUM_LEVELS 85 + }; 86 + 87 + enum MES_QUEUE_TYPE { 88 + MES_QUEUE_TYPE_GFX, 89 + MES_QUEUE_TYPE_COMPUTE, 90 + MES_QUEUE_TYPE_SDMA, 91 + MES_QUEUE_TYPE_MAX, 92 + }; 93 + 94 + struct MES_API_STATUS { 95 + uint64_t api_completion_fence_addr; 96 + uint64_t api_completion_fence_value; 97 + }; 98 + 99 + enum { MAX_COMPUTE_PIPES = 8 }; 100 + enum { MAX_GFX_PIPES = 2 }; 101 + enum { MAX_SDMA_PIPES = 2 }; 102 + 103 + enum { MAX_COMPUTE_HQD_PER_PIPE = 8 }; 104 + enum { MAX_GFX_HQD_PER_PIPE = 8 }; 105 + enum { MAX_SDMA_HQD_PER_PIPE = 10 }; 106 + enum { MAX_SDMA_HQD_PER_PIPE_11_0 = 8 }; 107 + 108 + enum { MAX_QUEUES_IN_A_GANG = 8 }; 109 + 110 + enum VM_HUB_TYPE { 111 + VM_HUB_TYPE_GC = 0, 112 + VM_HUB_TYPE_MM = 1, 113 + VM_HUB_TYPE_MAX, 114 + }; 115 + 116 + enum { VMID_INVALID = 0xffff }; 117 + 118 + enum { MAX_VMID_GCHUB = 16 }; 119 + enum { MAX_VMID_MMHUB = 16 }; 120 + 121 + enum SET_DEBUG_VMID_OPERATIONS { 122 + DEBUG_VMID_OP_PROGRAM = 0, 123 + DEBUG_VMID_OP_ALLOCATE = 1, 124 + DEBUG_VMID_OP_RELEASE = 2 125 + }; 126 + 127 + enum MES_LOG_OPERATION { 128 + MES_LOG_OPERATION_CONTEXT_STATE_CHANGE = 0, 129 + MES_LOG_OPERATION_QUEUE_NEW_WORK = 1, 130 + MES_LOG_OPERATION_QUEUE_UNWAIT_SYNC_OBJECT = 2, 131 + MES_LOG_OPERATION_QUEUE_NO_MORE_WORK = 3, 132 + MES_LOG_OPERATION_QUEUE_WAIT_SYNC_OBJECT = 4, 133 + MES_LOG_OPERATION_QUEUE_INVALID = 0xF, 134 + }; 135 + 136 + enum MES_LOG_CONTEXT_STATE { 137 + MES_LOG_CONTEXT_STATE_IDLE = 0, 138 + MES_LOG_CONTEXT_STATE_RUNNING = 1, 139 + MES_LOG_CONTEXT_STATE_READY = 2, 140 + MES_LOG_CONTEXT_STATE_READY_STANDBY = 3, 141 + MES_LOG_CONTEXT_STATE_INVALID = 0xF, 142 + }; 143 + 144 + struct MES_LOG_CONTEXT_STATE_CHANGE { 145 + void *h_context; 146 + enum MES_LOG_CONTEXT_STATE new_context_state; 147 + }; 148 + 149 + struct MES_LOG_QUEUE_NEW_WORK { 150 + uint64_t h_queue; 151 + uint64_t reserved; 152 + }; 153 + 154 + struct MES_LOG_QUEUE_UNWAIT_SYNC_OBJECT { 155 + uint64_t h_queue; 156 + uint64_t h_sync_object; 157 + }; 158 + 159 + struct MES_LOG_QUEUE_NO_MORE_WORK { 160 + uint64_t h_queue; 161 + uint64_t reserved; 162 + }; 163 + 164 + struct MES_LOG_QUEUE_WAIT_SYNC_OBJECT { 165 + uint64_t h_queue; 166 + uint64_t h_sync_object; 167 + }; 168 + 169 + struct MES_LOG_ENTRY_HEADER { 170 + uint32_t first_free_entry_index; 171 + uint32_t wraparound_count; 172 + uint64_t number_of_entries; 173 + uint64_t reserved[2]; 174 + }; 175 + 176 + struct MES_LOG_ENTRY_DATA { 177 + uint64_t gpu_time_stamp; 178 + uint32_t operation_type; /* operation_type is of MES_LOG_OPERATION type */ 179 + uint32_t reserved_operation_type_bits; 180 + union { 181 + struct MES_LOG_CONTEXT_STATE_CHANGE context_state_change; 182 + struct MES_LOG_QUEUE_NEW_WORK queue_new_work; 183 + struct MES_LOG_QUEUE_UNWAIT_SYNC_OBJECT queue_unwait_sync_object; 184 + struct MES_LOG_QUEUE_NO_MORE_WORK queue_no_more_work; 185 + struct MES_LOG_QUEUE_WAIT_SYNC_OBJECT queue_wait_sync_object; 186 + uint64_t all[2]; 187 + }; 188 + }; 189 + 190 + struct MES_LOG_BUFFER { 191 + struct MES_LOG_ENTRY_HEADER header; 192 + struct MES_LOG_ENTRY_DATA entries[1]; 193 + }; 194 + 195 + enum MES_SWIP_TO_HWIP_DEF { 196 + MES_MAX_HWIP_SEGMENT = 6, 197 + }; 198 + 199 + union MESAPI_SET_HW_RESOURCES { 200 + struct { 201 + union MES_API_HEADER header; 202 + uint32_t vmid_mask_mmhub; 203 + uint32_t vmid_mask_gfxhub; 204 + uint32_t gds_size; 205 + uint32_t paging_vmid; 206 + uint32_t compute_hqd_mask[MAX_COMPUTE_PIPES]; 207 + uint32_t gfx_hqd_mask[MAX_GFX_PIPES]; 208 + uint32_t sdma_hqd_mask[MAX_SDMA_PIPES]; 209 + uint32_t aggregated_doorbells[AMD_PRIORITY_NUM_LEVELS]; 210 + uint64_t g_sch_ctx_gpu_mc_ptr; 211 + uint64_t query_status_fence_gpu_mc_ptr; 212 + uint32_t gc_base[MES_MAX_HWIP_SEGMENT]; 213 + uint32_t mmhub_base[MES_MAX_HWIP_SEGMENT]; 214 + uint32_t osssys_base[MES_MAX_HWIP_SEGMENT]; 215 + struct MES_API_STATUS api_status; 216 + union { 217 + struct { 218 + uint32_t disable_reset : 1; 219 + uint32_t use_different_vmid_compute : 1; 220 + uint32_t disable_mes_log : 1; 221 + uint32_t apply_mmhub_pgvm_invalidate_ack_loss_wa : 1; 222 + uint32_t apply_grbm_remote_register_dummy_read_wa : 1; 223 + uint32_t second_gfx_pipe_enabled : 1; 224 + uint32_t enable_level_process_quantum_check : 1; 225 + uint32_t reserved : 25; 226 + }; 227 + uint32_t uint32_t_all; 228 + }; 229 + }; 230 + 231 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 232 + }; 233 + 234 + union MESAPI__ADD_QUEUE { 235 + struct { 236 + union MES_API_HEADER header; 237 + uint32_t process_id; 238 + uint64_t page_table_base_addr; 239 + uint64_t process_va_start; 240 + uint64_t process_va_end; 241 + uint64_t process_quantum; 242 + uint64_t process_context_addr; 243 + uint64_t gang_quantum; 244 + uint64_t gang_context_addr; 245 + uint32_t inprocess_gang_priority; 246 + enum MES_AMD_PRIORITY_LEVEL gang_global_priority_level; 247 + uint32_t doorbell_offset; 248 + uint64_t mqd_addr; 249 + uint64_t wptr_addr; 250 + uint64_t h_context; 251 + uint64_t h_queue; 252 + enum MES_QUEUE_TYPE queue_type; 253 + uint32_t gds_base; 254 + uint32_t gds_size; 255 + uint32_t gws_base; 256 + uint32_t gws_size; 257 + uint32_t oa_mask; 258 + uint64_t trap_handler_addr; 259 + uint32_t vm_context_cntl; 260 + 261 + struct { 262 + uint32_t paging : 1; 263 + uint32_t debug_vmid : 4; 264 + uint32_t program_gds : 1; 265 + uint32_t is_gang_suspended : 1; 266 + uint32_t is_tmz_queue : 1; 267 + uint32_t map_kiq_utility_queue : 1; 268 + uint32_t reserved : 23; 269 + }; 270 + struct MES_API_STATUS api_status; 271 + uint64_t tma_addr; 272 + }; 273 + 274 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 275 + }; 276 + 277 + union MESAPI__REMOVE_QUEUE { 278 + struct { 279 + union MES_API_HEADER header; 280 + uint32_t doorbell_offset; 281 + uint64_t gang_context_addr; 282 + 283 + struct { 284 + uint32_t unmap_legacy_gfx_queue : 1; 285 + uint32_t unmap_kiq_utility_queue : 1; 286 + uint32_t preempt_legacy_gfx_queue : 1; 287 + uint32_t reserved : 29; 288 + }; 289 + struct MES_API_STATUS api_status; 290 + 291 + uint32_t pipe_id; 292 + uint32_t queue_id; 293 + 294 + uint64_t tf_addr; 295 + uint32_t tf_data; 296 + }; 297 + 298 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 299 + }; 300 + 301 + union MESAPI__SET_SCHEDULING_CONFIG { 302 + struct { 303 + union MES_API_HEADER header; 304 + /* Grace period when preempting another priority band for this 305 + * priority band. The value for idle priority band is ignored, 306 + * as it never preempts other bands. 307 + */ 308 + uint64_t grace_period_other_levels[AMD_PRIORITY_NUM_LEVELS]; 309 + /* Default quantum for scheduling across processes within 310 + * a priority band. 311 + */ 312 + uint64_t process_quantum_for_level[AMD_PRIORITY_NUM_LEVELS]; 313 + /* Default grace period for processes that preempt each other 314 + * within a priority band. 315 + */ 316 + uint64_t process_grace_period_same_level[AMD_PRIORITY_NUM_LEVELS]; 317 + /* For normal level this field specifies the target GPU 318 + * percentage in situations when it's starved by the high level. 319 + * Valid values are between 0 and 50, with the default being 10. 320 + */ 321 + uint32_t normal_yield_percent; 322 + struct MES_API_STATUS api_status; 323 + }; 324 + 325 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 326 + }; 327 + 328 + union MESAPI__PERFORM_YIELD { 329 + struct { 330 + union MES_API_HEADER header; 331 + uint32_t dummy; 332 + struct MES_API_STATUS api_status; 333 + }; 334 + 335 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 336 + }; 337 + 338 + union MESAPI__CHANGE_GANG_PRIORITY_LEVEL { 339 + struct { 340 + union MES_API_HEADER header; 341 + uint32_t inprocess_gang_priority; 342 + enum MES_AMD_PRIORITY_LEVEL gang_global_priority_level; 343 + uint64_t gang_quantum; 344 + uint64_t gang_context_addr; 345 + struct MES_API_STATUS api_status; 346 + }; 347 + 348 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 349 + }; 350 + 351 + union MESAPI__SUSPEND { 352 + struct { 353 + union MES_API_HEADER header; 354 + /* false - suspend all gangs; true - specific gang */ 355 + struct { 356 + uint32_t suspend_all_gangs : 1; 357 + uint32_t reserved : 31; 358 + }; 359 + /* gang_context_addr is valid only if suspend_all = false */ 360 + uint64_t gang_context_addr; 361 + 362 + uint64_t suspend_fence_addr; 363 + uint32_t suspend_fence_value; 364 + 365 + struct MES_API_STATUS api_status; 366 + }; 367 + 368 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 369 + }; 370 + 371 + union MESAPI__RESUME { 372 + struct { 373 + union MES_API_HEADER header; 374 + /* false - resume all gangs; true - specified gang */ 375 + struct { 376 + uint32_t resume_all_gangs : 1; 377 + uint32_t reserved : 31; 378 + }; 379 + /* valid only if resume_all_gangs = false */ 380 + uint64_t gang_context_addr; 381 + 382 + struct MES_API_STATUS api_status; 383 + }; 384 + 385 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 386 + }; 387 + 388 + union MESAPI__RESET { 389 + struct { 390 + union MES_API_HEADER header; 391 + 392 + struct { 393 + /* Only reset the queue given by doorbell_offset (not entire gang) */ 394 + uint32_t reset_queue_only : 1; 395 + /* Hang detection first then reset any queues that are hung */ 396 + uint32_t hang_detect_then_reset : 1; 397 + /* Only do hang detection (no reset) */ 398 + uint32_t hang_detect_only : 1; 399 + /* Rest HP and LP kernel queues not managed by MES */ 400 + uint32_t reset_legacy_gfx : 1; 401 + uint32_t reserved : 28; 402 + }; 403 + 404 + uint64_t gang_context_addr; 405 + 406 + /* valid only if reset_queue_only = true */ 407 + uint32_t doorbell_offset; 408 + 409 + /* valid only if hang_detect_then_reset = true */ 410 + uint64_t doorbell_offset_addr; 411 + enum MES_QUEUE_TYPE queue_type; 412 + 413 + /* valid only if reset_legacy_gfx = true */ 414 + uint32_t pipe_id_lp; 415 + uint32_t queue_id_lp; 416 + uint32_t vmid_id_lp; 417 + uint64_t mqd_mc_addr_lp; 418 + uint32_t doorbell_offset_lp; 419 + uint64_t wptr_addr_lp; 420 + 421 + uint32_t pipe_id_hp; 422 + uint32_t queue_id_hp; 423 + uint32_t vmid_id_hp; 424 + uint64_t mqd_mc_addr_hp; 425 + uint32_t doorbell_offset_hp; 426 + uint64_t wptr_addr_hp; 427 + 428 + struct MES_API_STATUS api_status; 429 + }; 430 + 431 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 432 + }; 433 + 434 + union MESAPI__SET_LOGGING_BUFFER { 435 + struct { 436 + union MES_API_HEADER header; 437 + /* There are separate log buffers for each queue type */ 438 + enum MES_QUEUE_TYPE log_type; 439 + /* Log buffer GPU Address */ 440 + uint64_t logging_buffer_addr; 441 + /* number of entries in the log buffer */ 442 + uint32_t number_of_entries; 443 + /* Entry index at which CPU interrupt needs to be signalled */ 444 + uint32_t interrupt_entry; 445 + 446 + struct MES_API_STATUS api_status; 447 + }; 448 + 449 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 450 + }; 451 + 452 + union MESAPI__QUERY_MES_STATUS { 453 + struct { 454 + union MES_API_HEADER header; 455 + bool mes_healthy; /* 0 - not healthy, 1 - healthy */ 456 + struct MES_API_STATUS api_status; 457 + }; 458 + 459 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 460 + }; 461 + 462 + union MESAPI__PROGRAM_GDS { 463 + struct { 464 + union MES_API_HEADER header; 465 + uint64_t process_context_addr; 466 + uint32_t gds_base; 467 + uint32_t gds_size; 468 + uint32_t gws_base; 469 + uint32_t gws_size; 470 + uint32_t oa_mask; 471 + struct MES_API_STATUS api_status; 472 + }; 473 + 474 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 475 + }; 476 + 477 + union MESAPI__SET_DEBUG_VMID { 478 + struct { 479 + union MES_API_HEADER header; 480 + struct MES_API_STATUS api_status; 481 + union { 482 + struct { 483 + uint32_t use_gds : 1; 484 + uint32_t operation : 2; 485 + uint32_t reserved : 29; 486 + } flags; 487 + uint32_t u32All; 488 + }; 489 + uint32_t reserved; 490 + uint32_t debug_vmid; 491 + uint64_t process_context_addr; 492 + uint64_t page_table_base_addr; 493 + uint64_t process_va_start; 494 + uint64_t process_va_end; 495 + uint32_t gds_base; 496 + uint32_t gds_size; 497 + uint32_t gws_base; 498 + uint32_t gws_size; 499 + uint32_t oa_mask; 500 + 501 + /* output addr of the acquired vmid value */ 502 + uint64_t output_addr; 503 + }; 504 + 505 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 506 + }; 507 + 508 + enum MESAPI_MISC_OPCODE { 509 + MESAPI_MISC__MODIFY_REG, 510 + MESAPI_MISC__INV_GART, 511 + MESAPI_MISC__QUERY_STATUS, 512 + MESAPI_MISC__MAX, 513 + }; 514 + 515 + enum MODIFY_REG_SUBCODE { 516 + MODIFY_REG__OVERWRITE, 517 + MODIFY_REG__RMW_OR, 518 + MODIFY_REG__RMW_AND, 519 + MODIFY_REG__MAX, 520 + }; 521 + 522 + enum { MISC_DATA_MAX_SIZE_IN_DWORDS = 20 }; 523 + 524 + struct MODIFY_REG { 525 + enum MODIFY_REG_SUBCODE subcode; 526 + uint32_t reg_offset; 527 + uint32_t reg_value; 528 + }; 529 + 530 + struct INV_GART { 531 + uint64_t inv_range_va_start; 532 + uint64_t inv_range_size; 533 + }; 534 + 535 + struct QUERY_STATUS { 536 + uint32_t context_id; 537 + }; 538 + 539 + union MESAPI__MISC { 540 + struct { 541 + union MES_API_HEADER header; 542 + enum MESAPI_MISC_OPCODE opcode; 543 + struct MES_API_STATUS api_status; 544 + 545 + union { 546 + struct MODIFY_REG modify_reg; 547 + struct INV_GART inv_gart; 548 + struct QUERY_STATUS query_status; 549 + uint32_t data[MISC_DATA_MAX_SIZE_IN_DWORDS]; 550 + }; 551 + }; 552 + 553 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 554 + }; 555 + 556 + union MESAPI__UPDATE_ROOT_PAGE_TABLE { 557 + struct { 558 + union MES_API_HEADER header; 559 + uint64_t page_table_base_addr; 560 + uint64_t process_context_addr; 561 + struct MES_API_STATUS api_status; 562 + }; 563 + 564 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 565 + }; 566 + 567 + union MESAPI_AMD_LOG { 568 + struct { 569 + union MES_API_HEADER header; 570 + uint64_t p_buffer_memory; 571 + uint64_t p_buffer_size_used; 572 + struct MES_API_STATUS api_status; 573 + }; 574 + 575 + uint32_t max_dwords_in_api[API_FRAME_SIZE_IN_DWORDS]; 576 + }; 577 + 578 + #pragma pack(pop) 579 + #endif