Skip to content

Commit

Permalink
drm/amdgpu/gfx12: Implement the gfx12 kgq pipe reset
Browse files Browse the repository at this point in the history
Implement the GFX12 kgq pipe reset, and temporarily disable
the GFX12 pipe reset until the CPFW fully support it.

Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Prike Liang authored and Alex Deucher committed Apr 7, 2025
1 parent 340f1d9 commit 4aa8de3
Showing 1 changed file with 67 additions and 2 deletions.
69 changes: 67 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -5161,6 +5161,69 @@ static void gfx_v12_ip_dump(struct amdgpu_ip_block *ip_block)
amdgpu_gfx_off_ctrl(adev, true);
}

static bool gfx_v12_pipe_reset_support(struct amdgpu_device *adev)
{
/* Disable the pipe reset until the CPFW fully support it.*/
dev_warn_once(adev->dev, "The CPFW hasn't support pipe reset yet.\n");
return false;
}

static int gfx_v12_reset_gfx_pipe(struct amdgpu_ring *ring)
{
struct amdgpu_device *adev = ring->adev;
uint32_t reset_pipe = 0, clean_pipe = 0;
int r;

if (!gfx_v12_pipe_reset_support(adev))
return -EOPNOTSUPP;

gfx_v12_0_set_safe_mode(adev, 0);
mutex_lock(&adev->srbm_mutex);
soc24_grbm_select(adev, ring->me, ring->pipe, ring->queue, 0);

switch (ring->pipe) {
case 0:
reset_pipe = REG_SET_FIELD(reset_pipe, CP_ME_CNTL,
PFP_PIPE0_RESET, 1);
reset_pipe = REG_SET_FIELD(reset_pipe, CP_ME_CNTL,
ME_PIPE0_RESET, 1);
clean_pipe = REG_SET_FIELD(clean_pipe, CP_ME_CNTL,
PFP_PIPE0_RESET, 0);
clean_pipe = REG_SET_FIELD(clean_pipe, CP_ME_CNTL,
ME_PIPE0_RESET, 0);
break;
case 1:
reset_pipe = REG_SET_FIELD(reset_pipe, CP_ME_CNTL,
PFP_PIPE1_RESET, 1);
reset_pipe = REG_SET_FIELD(reset_pipe, CP_ME_CNTL,
ME_PIPE1_RESET, 1);
clean_pipe = REG_SET_FIELD(clean_pipe, CP_ME_CNTL,
PFP_PIPE1_RESET, 0);
clean_pipe = REG_SET_FIELD(clean_pipe, CP_ME_CNTL,
ME_PIPE1_RESET, 0);
break;
default:
break;
}

WREG32_SOC15(GC, 0, regCP_ME_CNTL, reset_pipe);
WREG32_SOC15(GC, 0, regCP_ME_CNTL, clean_pipe);

r = (RREG32(SOC15_REG_OFFSET(GC, 0, regCP_GFX_RS64_INSTR_PNTR1)) << 2) -
RS64_FW_UC_START_ADDR_LO;
soc24_grbm_select(adev, 0, 0, 0, 0);
mutex_unlock(&adev->srbm_mutex);
gfx_v12_0_unset_safe_mode(adev, 0);

dev_info(adev->dev, "The ring %s pipe reset: %s\n", ring->name,
r == 0 ? "successfully" : "failed");
/* Sometimes the ME start pc counter can't cache correctly, so the
* PC check only as a reference and pipe reset result rely on the
* later ring test.
*/
return 0;
}

static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)
{
struct amdgpu_device *adev = ring->adev;
Expand All @@ -5171,8 +5234,10 @@ static int gfx_v12_0_reset_kgq(struct amdgpu_ring *ring, unsigned int vmid)

r = amdgpu_mes_reset_legacy_queue(ring->adev, ring, vmid, false);
if (r) {
dev_err(adev->dev, "reset via MES failed %d\n", r);
return r;
dev_warn(adev->dev, "reset via MES failed and try pipe reset %d\n", r);
r = gfx_v12_reset_gfx_pipe(ring);
if (r)
return r;
}

r = gfx_v12_0_kgq_init_queue(ring, true);
Expand Down

0 comments on commit 4aa8de3

Please sign in to comment.