Skip to content

Commit 178ad0e

Browse files
jiadozhualexdeucher
authored andcommitted
drm/amdgpu/mes11: implement mmio queue reset for gfx11
Implement queue reset for graphic and compute queue. v2: use amdgpu_gfx_rlc funcs to enter/exit safe mode. v3: use gfx_v11_0_request_gfx_index_mutex() v4: fix mutex handling Acked-by: Vitaly Prosyak <[email protected]> Signed-off-by: Jiadong Zhu <[email protected]> Reviewed-by: Alex Deucher <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 01b4ae3 commit 178ad0e

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

drivers/gpu/drm/amd/amdgpu/mes_v11_0.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "amdgpu.h"
2727
#include "soc15_common.h"
2828
#include "soc21.h"
29+
#include "gfx_v11_0.h"
2930
#include "gc/gc_11_0_0_offset.h"
3031
#include "gc/gc_11_0_0_sh_mask.h"
3132
#include "gc/gc_11_0_0_default.h"
@@ -360,9 +361,83 @@ static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes,
360361
offsetof(union MESAPI__REMOVE_QUEUE, api_status));
361362
}
362363

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+
363433
static int mes_v11_0_reset_hw_queue(struct amdgpu_mes *mes,
364434
struct mes_reset_queue_input *input)
365435
{
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+
366441
union MESAPI__RESET mes_reset_queue_pkt;
367442

368443
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,
648723
{
649724
union MESAPI__RESET mes_reset_queue_pkt;
650725

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+
651731
memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt));
652732

653733
mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER;

0 commit comments

Comments
 (0)