mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:44:45 +01:00
drm/amdgpu/mes12: Implement reset gfx/compute queue function by mmio
Reset gfx/compute queue through mmio based on me_id and queue_id. Signed-off-by: Jesse Zhang <jesse.zhang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
0f8666138f
commit
a73a83241e
2 changed files with 89 additions and 1 deletions
|
|
@ -26,4 +26,6 @@
|
|||
|
||||
extern const struct amdgpu_ip_block_version gfx_v12_0_ip_block;
|
||||
|
||||
int gfx_v12_0_request_gfx_index_mutex(struct amdgpu_device *adev,
|
||||
bool req);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include "amdgpu.h"
|
||||
#include "gfx_v12_0.h"
|
||||
#include "soc15_common.h"
|
||||
#include "soc21.h"
|
||||
#include "gc/gc_12_0_0_offset.h"
|
||||
|
|
@ -350,6 +351,38 @@ static int mes_v12_0_remove_hw_queue(struct amdgpu_mes *mes,
|
|||
offsetof(union MESAPI__REMOVE_QUEUE, api_status));
|
||||
}
|
||||
|
||||
int gfx_v12_0_request_gfx_index_mutex(struct amdgpu_device *adev,
|
||||
bool req)
|
||||
{
|
||||
u32 i, tmp, val;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
/* Request with MeId=2, PipeId=0 */
|
||||
tmp = REG_SET_FIELD(0, CP_GFX_INDEX_MUTEX, REQUEST, req);
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX, CLIENTID, 4);
|
||||
WREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX, tmp);
|
||||
|
||||
val = RREG32_SOC15(GC, 0, regCP_GFX_INDEX_MUTEX);
|
||||
if (req) {
|
||||
if (val == tmp)
|
||||
break;
|
||||
} else {
|
||||
tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX,
|
||||
REQUEST, 1);
|
||||
|
||||
/* unlocked or locked by firmware */
|
||||
if (val != tmp)
|
||||
break;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
if (i >= adev->usec_timeout)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mes_v12_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)
|
||||
|
|
@ -360,7 +393,60 @@ static int mes_v12_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_typ
|
|||
|
||||
amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
|
||||
|
||||
if (queue_type == AMDGPU_RING_TYPE_SDMA) {
|
||||
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_v12_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_v12_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);
|
||||
} else if (queue_type == AMDGPU_RING_TYPE_SDMA) {
|
||||
dev_info(adev->dev, "reset sdma queue (%d:%d:%d)\n",
|
||||
me_id, pipe_id, queue_id);
|
||||
switch (me_id) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue