On 2016å¹´07æ??19æ?¥ 17:23, Christian König wrote: > Am 19.07.2016 um 10:13 schrieb Chunming Zhou: >> Since all soft reset is though GRBM/SRBM, why not write them at a time. >> This can avoid potiential soft reset sequence problem. > > Well is this really necessary? We actually wanted to avoid exactly > this with the per IP soft resets. I will try per IP soft resets again. Thanks, David Zhou > > Christian. > >> >> Change-Id: I18bc723df863474f3200e5b5852569ef98e9d8ca >> Signed-off-by: Chunming Zhou <David1.Zhou at amd.com> >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 14 ++----- >> drivers/gpu/drm/amd/amdgpu/vi.c | 61 >> ++++++++++++++++++++++++++++++ >> 2 files changed, 64 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> index 2e077e7..d795164 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> @@ -2001,19 +2001,11 @@ static bool amdgpu_need_full_reset(struct >> amdgpu_device *adev) >> static int amdgpu_soft_reset(struct amdgpu_device *adev) >> { >> - int i, r = 0; >> + int r; >> - for (i = 0; i < adev->num_ip_blocks; i++) { >> - if (!adev->ip_block_status[i].valid) >> - continue; >> - if (adev->ip_block_status[i].hang && >> - adev->ip_blocks[i].funcs->soft_reset) >> - r = adev->ip_blocks[i].funcs->soft_reset(adev); >> - if (r) >> - return r; >> - } >> + r = >> adev->ip_blocks[AMD_IP_BLOCK_TYPE_COMMON].funcs->soft_reset(adev); >> - return 0; >> + return r; >> } >> static int amdgpu_post_soft_reset(struct amdgpu_device *adev) >> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c >> b/drivers/gpu/drm/amd/amdgpu/vi.c >> index 1ac0c91..1f8b623 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/vi.c >> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c >> @@ -1651,6 +1651,67 @@ static int vi_common_wait_for_idle(void *handle) >> static int vi_common_soft_reset(void *handle) >> { >> + struct amdgpu_device *adev = (struct amdgpu_device *)handle; >> + u32 grbm_soft_reset = 0, srbm_soft_reset = 0; >> + u32 tmp; >> + int i; >> + >> + for (i = AMD_IP_BLOCK_TYPE_COMMON + 1; i < adev->num_ip_blocks; >> i++) { >> + if (!adev->ip_block_status[i].hang) >> + continue; >> + >> + grbm_soft_reset |= adev->ip_block_status[i].grbm_soft_reset; >> + srbm_soft_reset |= adev->ip_block_status[i].srbm_soft_reset; >> + } >> + >> + if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, >> SOFT_RESET_CP) || >> + REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, >> SOFT_RESET_GFX)) { >> + 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(50); >> + } >> + >> + 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); >> + } >> + >> + if (REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, >> SOFT_RESET_CP) || >> + REG_GET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, >> SOFT_RESET_GFX)) { >> + 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(50); >> + >> return 0; >> } >