Commit 178ad0e2 authored by Jiadong Zhu's avatar Jiadong Zhu Committed by Alex Deucher

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: default avatarVitaly Prosyak <vitaly.prosyak@amd.com>
Signed-off-by: default avatarJiadong Zhu <Jiadong.Zhu@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 01b4ae38
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "amdgpu.h" #include "amdgpu.h"
#include "soc15_common.h" #include "soc15_common.h"
#include "soc21.h" #include "soc21.h"
#include "gfx_v11_0.h"
#include "gc/gc_11_0_0_offset.h" #include "gc/gc_11_0_0_offset.h"
#include "gc/gc_11_0_0_sh_mask.h" #include "gc/gc_11_0_0_sh_mask.h"
#include "gc/gc_11_0_0_default.h" #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,9 +361,83 @@ static int mes_v11_0_remove_hw_queue(struct amdgpu_mes *mes,
offsetof(union MESAPI__REMOVE_QUEUE, api_status)); offsetof(union MESAPI__REMOVE_QUEUE, api_status));
} }
static int mes_v11_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_type,
uint32_t me_id, uint32_t pipe_id,
uint32_t queue_id, uint32_t vmid)
{
struct amdgpu_device *adev = mes->adev;
uint32_t value;
int i, r = 0;
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
if (queue_type == AMDGPU_RING_TYPE_GFX) {
dev_info(adev->dev, "reset gfx queue (%d:%d:%d: vmid:%d)\n",
me_id, pipe_id, queue_id, vmid);
mutex_lock(&adev->gfx.reset_sem_mutex);
gfx_v11_0_request_gfx_index_mutex(adev, true);
/* all se allow writes */
WREG32_SOC15(GC, 0, regGRBM_GFX_INDEX,
(uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT));
value = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
if (pipe_id == 0)
value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id);
else
value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id);
WREG32_SOC15(GC, 0, regCP_VMID_RESET, value);
gfx_v11_0_request_gfx_index_mutex(adev, false);
mutex_unlock(&adev->gfx.reset_sem_mutex);
mutex_lock(&adev->srbm_mutex);
soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
/* wait till dequeue take effects */
for (i = 0; i < adev->usec_timeout; i++) {
if (!(RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE) & 1))
break;
udelay(1);
}
if (i >= adev->usec_timeout) {
dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n");
r = -ETIMEDOUT;
}
soc21_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
} else if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
dev_info(adev->dev, "reset compute queue (%d:%d:%d)\n",
me_id, pipe_id, queue_id);
mutex_lock(&adev->srbm_mutex);
soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2);
WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1);
/* wait till dequeue take effects */
for (i = 0; i < adev->usec_timeout; i++) {
if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
break;
udelay(1);
}
if (i >= adev->usec_timeout) {
dev_err(adev->dev, "failed to wait on hqd deactivate\n");
r = -ETIMEDOUT;
}
soc21_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
}
amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
return r;
}
static int mes_v11_0_reset_hw_queue(struct amdgpu_mes *mes, static int mes_v11_0_reset_hw_queue(struct amdgpu_mes *mes,
struct mes_reset_queue_input *input) struct mes_reset_queue_input *input)
{ {
if (input->use_mmio)
return mes_v11_0_reset_queue_mmio(mes, input->queue_type,
input->me_id, input->pipe_id,
input->queue_id, input->vmid);
union MESAPI__RESET mes_reset_queue_pkt; union MESAPI__RESET mes_reset_queue_pkt;
memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt)); 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,6 +723,11 @@ static int mes_v11_0_reset_legacy_queue(struct amdgpu_mes *mes,
{ {
union MESAPI__RESET mes_reset_queue_pkt; union MESAPI__RESET mes_reset_queue_pkt;
if (input->use_mmio)
return mes_v11_0_reset_queue_mmio(mes, input->queue_type,
input->me_id, input->pipe_id,
input->queue_id, input->vmid);
memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt)); memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt));
mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER; mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment