|
26 | 26 | #include "amdgpu.h" |
27 | 27 | #include "soc15_common.h" |
28 | 28 | #include "soc21.h" |
| 29 | +#include "gfx_v11_0.h" |
29 | 30 | #include "gc/gc_11_0_0_offset.h" |
30 | 31 | #include "gc/gc_11_0_0_sh_mask.h" |
31 | 32 | #include "gc/gc_11_0_0_default.h" |
@@ -360,9 +361,83 @@ static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes, |
360 | 361 | offsetof(union MESAPI__REMOVE_QUEUE, api_status)); |
361 | 362 | } |
362 | 363 |
|
| 364 | +static int mes_v11_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_type, |
| 365 | + uint32_t me_id, uint32_t pipe_id, |
| 366 | + uint32_t queue_id, uint32_t vmid) |
| 367 | +{ |
| 368 | + struct amdgpu_device *adev = mes->adev; |
| 369 | + uint32_t value; |
| 370 | + int i, r = 0; |
| 371 | + |
| 372 | + amdgpu_gfx_rlc_enter_safe_mode(adev, 0); |
| 373 | + |
| 374 | + if (queue_type == AMDGPU_RING_TYPE_GFX) { |
| 375 | + dev_info(adev->dev, "reset gfx queue (%d:%d:%d: vmid:%d)\n", |
| 376 | + me_id, pipe_id, queue_id, vmid); |
| 377 | + |
| 378 | + mutex_lock(&adev->gfx.reset_sem_mutex); |
| 379 | + gfx_v11_0_request_gfx_index_mutex(adev, true); |
| 380 | + /* all se allow writes */ |
| 381 | + WREG32_SOC15(GC, 0, regGRBM_GFX_INDEX, |
| 382 | + (uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT)); |
| 383 | + value = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid); |
| 384 | + if (pipe_id == 0) |
| 385 | + value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id); |
| 386 | + else |
| 387 | + value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id); |
| 388 | + WREG32_SOC15(GC, 0, regCP_VMID_RESET, value); |
| 389 | + gfx_v11_0_request_gfx_index_mutex(adev, false); |
| 390 | + mutex_unlock(&adev->gfx.reset_sem_mutex); |
| 391 | + |
| 392 | + mutex_lock(&adev->srbm_mutex); |
| 393 | + soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0); |
| 394 | + /* wait till dequeue take effects */ |
| 395 | + for (i = 0; i < adev->usec_timeout; i++) { |
| 396 | + if (!(RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE) & 1)) |
| 397 | + break; |
| 398 | + udelay(1); |
| 399 | + } |
| 400 | + if (i >= adev->usec_timeout) { |
| 401 | + dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n"); |
| 402 | + r = -ETIMEDOUT; |
| 403 | + } |
| 404 | + |
| 405 | + soc21_grbm_select(adev, 0, 0, 0, 0); |
| 406 | + mutex_unlock(&adev->srbm_mutex); |
| 407 | + } else if (queue_type == AMDGPU_RING_TYPE_COMPUTE) { |
| 408 | + dev_info(adev->dev, "reset compute queue (%d:%d:%d)\n", |
| 409 | + me_id, pipe_id, queue_id); |
| 410 | + mutex_lock(&adev->srbm_mutex); |
| 411 | + soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0); |
| 412 | + WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2); |
| 413 | + WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1); |
| 414 | + |
| 415 | + /* wait till dequeue take effects */ |
| 416 | + for (i = 0; i < adev->usec_timeout; i++) { |
| 417 | + if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1)) |
| 418 | + break; |
| 419 | + udelay(1); |
| 420 | + } |
| 421 | + if (i >= adev->usec_timeout) { |
| 422 | + dev_err(adev->dev, "failed to wait on hqd deactivate\n"); |
| 423 | + r = -ETIMEDOUT; |
| 424 | + } |
| 425 | + soc21_grbm_select(adev, 0, 0, 0, 0); |
| 426 | + mutex_unlock(&adev->srbm_mutex); |
| 427 | + } |
| 428 | + |
| 429 | + amdgpu_gfx_rlc_exit_safe_mode(adev, 0); |
| 430 | + return r; |
| 431 | +} |
| 432 | + |
363 | 433 | static int mes_v11_0_reset_hw_queue(struct amdgpu_mes *mes, |
364 | 434 | struct mes_reset_queue_input *input) |
365 | 435 | { |
| 436 | + if (input->use_mmio) |
| 437 | + return mes_v11_0_reset_queue_mmio(mes, input->queue_type, |
| 438 | + input->me_id, input->pipe_id, |
| 439 | + input->queue_id, input->vmid); |
| 440 | + |
366 | 441 | union MESAPI__RESET mes_reset_queue_pkt; |
367 | 442 |
|
368 | 443 | memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt)); |
@@ -648,6 +723,11 @@ static int mes_v11_0_reset_legacy_queue(struct amdgpu_mes *mes, |
648 | 723 | { |
649 | 724 | union MESAPI__RESET mes_reset_queue_pkt; |
650 | 725 |
|
| 726 | + if (input->use_mmio) |
| 727 | + return mes_v11_0_reset_queue_mmio(mes, input->queue_type, |
| 728 | + input->me_id, input->pipe_id, |
| 729 | + input->queue_id, input->vmid); |
| 730 | + |
651 | 731 | memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt)); |
652 | 732 |
|
653 | 733 | mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER; |
|
0 commit comments