From 9fb7ee45d69133bae634da9aee6f39be58ac9f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Tue, 21 Jul 2026 13:43:21 +0200 Subject: [PATCH] drm/amdgpu/gfx7: Fixup IP block soft reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use basically the same implementation as GFX8, except for the GFX7 specific MQD functions. Reset every block using the GRBM, then proceed to reset the GRBM and SEM blocks using the SRBM. Remove the redundant gfx_v7_0_update_cg() function. The soft reset now calls the clock and powergating functions of the IP block instead. Signed-off-by: Timur Kristóf Reviewed-by: Tvrtko Ursulin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 164 +++++++++++++------------- 1 file changed, 84 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index b7dc019fee3a..a057bba5c3a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -3617,21 +3617,6 @@ static void gfx_v7_0_enable_mgcg(struct amdgpu_device *adev, bool enable) } } -static void gfx_v7_0_update_cg(struct amdgpu_device *adev, - bool enable) -{ - gfx_v7_0_enable_gui_idle_interrupt(adev, false); - /* order matters! */ - if (enable) { - gfx_v7_0_enable_mgcg(adev, true); - gfx_v7_0_enable_cgcg(adev, true); - } else { - gfx_v7_0_enable_cgcg(adev, false); - gfx_v7_0_enable_mgcg(adev, false); - } - gfx_v7_0_enable_gui_idle_interrupt(adev, true); -} - static void gfx_v7_0_enable_sclk_slowdown_on_pu(struct amdgpu_device *adev, bool enable) { @@ -4550,80 +4535,99 @@ static int gfx_v7_0_wait_for_idle(struct amdgpu_ip_block *ip_block) static int gfx_v7_0_soft_reset(struct amdgpu_ip_block *ip_block) { + struct amdgpu_device *adev = ip_block->adev; u32 grbm_soft_reset = 0, srbm_soft_reset = 0; u32 tmp; - struct amdgpu_device *adev = ip_block->adev; + int i; + int r; - /* GRBM_STATUS */ - tmp = RREG32(mmGRBM_STATUS); - if (tmp & (GRBM_STATUS__PA_BUSY_MASK | GRBM_STATUS__SC_BUSY_MASK | - GRBM_STATUS__BCI_BUSY_MASK | GRBM_STATUS__SX_BUSY_MASK | - GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | - GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | - GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | - GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) - grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK | - GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK; + grbm_soft_reset = + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_RLC, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_GFX, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CP, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPF, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPC, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPG, 1); - if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) { - grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK; - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; - } + srbm_soft_reset = + REG_SET_FIELD(0, SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1) | + REG_SET_FIELD(0, SRBM_SOFT_RESET, SOFT_RESET_SEM, 1); - /* GRBM_STATUS2 */ - tmp = RREG32(mmGRBM_STATUS2); - if (tmp & GRBM_STATUS2__RLC_BUSY_MASK) - grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK; + for (i = 0; i < adev->gfx.num_compute_rings; i++) { + struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; - /* SRBM_STATUS */ - tmp = RREG32(mmSRBM_STATUS); - if (tmp & SRBM_STATUS__GRBM_RQ_PENDING_MASK) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; + mutex_lock(&adev->srbm_mutex); + cik_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); + gfx_v7_0_deactivate_hqd(adev, 2); + cik_srbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); - if (grbm_soft_reset || srbm_soft_reset) { - /* disable CG/PG */ - gfx_v7_0_fini_pg(adev); - gfx_v7_0_update_cg(adev, false); - - /* stop the rlc */ - adev->gfx.rlc.funcs->stop(adev); - - /* Disable GFX parsing/prefetching */ - WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); - - /* Disable MEC parsing/prefetching */ - WREG32(mmCP_MEC_CNTL, CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); - - if (grbm_soft_reset) { - tmp = RREG32(mmGRBM_SOFT_RESET); - tmp |= grbm_soft_reset; - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~grbm_soft_reset; - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - } - - if (srbm_soft_reset) { - tmp = RREG32(mmSRBM_SOFT_RESET); - tmp |= srbm_soft_reset; - dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~srbm_soft_reset; - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - } - /* Wait a little for things to settle down */ udelay(50); } + + ip_block->version->funcs->set_clockgating_state(ip_block, AMD_CG_STATE_UNGATE); + ip_block->version->funcs->set_powergating_state(ip_block, AMD_PG_STATE_UNGATE); + ip_block->version->funcs->suspend(ip_block); + + if (grbm_soft_reset || srbm_soft_reset) { + tmp = RREG32(mmGMCON_DEBUG); + tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 1); + tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 1); + WREG32(mmGMCON_DEBUG, tmp); + + udelay(100); + } + + if (grbm_soft_reset) { + tmp = RREG32(mmGRBM_SOFT_RESET); + tmp |= grbm_soft_reset; + dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); + WREG32(mmGRBM_SOFT_RESET, tmp); + tmp = RREG32(mmGRBM_SOFT_RESET); + + udelay(100); + + tmp &= ~grbm_soft_reset; + WREG32(mmGRBM_SOFT_RESET, tmp); + tmp = RREG32(mmGRBM_SOFT_RESET); + + udelay(100); + } + + if (srbm_soft_reset) { + tmp = RREG32(mmSRBM_SOFT_RESET); + tmp |= srbm_soft_reset; + dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); + WREG32(mmSRBM_SOFT_RESET, tmp); + tmp = RREG32(mmSRBM_SOFT_RESET); + + udelay(100); + + tmp &= ~srbm_soft_reset; + WREG32(mmSRBM_SOFT_RESET, tmp); + tmp = RREG32(mmSRBM_SOFT_RESET); + + udelay(100); + } + + if (grbm_soft_reset || srbm_soft_reset) { + tmp = RREG32(mmGMCON_DEBUG); + tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 0); + tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 0); + WREG32(mmGMCON_DEBUG, tmp); + } + + /* Wait a little for things to settle down */ + udelay(100); + + r = ip_block->version->funcs->resume(ip_block); + r |= ip_block->version->funcs->late_init(ip_block); + if (r) + return r; + + ip_block->version->funcs->set_clockgating_state(ip_block, AMD_CG_STATE_GATE); + ip_block->version->funcs->set_powergating_state(ip_block, AMD_PG_STATE_GATE); + return 0; }